Files
GTASource/game/text/TextFile.h
T
expvintl 419f2e4752 init
2025-02-23 17:40:52 +08:00

258 lines
8.6 KiB
C++

/////////////////////////////////////////////////////////////////////////////////
//
// FILE : TextFile.h
// PURPOSE : Deals with reading text from the text files
// AUTHOR : KRH 13/05/98
// NICKED BY : Obbe. (Thanks Keith)
// NICKED FURTHER BY: Derek Payne - modifying all this 17/04/09
//
/////////////////////////////////////////////////////////////////////////////////
// NOTES - this is still work in progress - a lot of stuff still needs shifting around
#ifndef TEXTFILE_H
#define TEXTFILE_H
// Rage headers
#if __BANK
#include "atl/map.h"
#endif // __BANK
#include "atl\array.h"
#include "atl/binmap.h"
#include "file\asynchstream.h"
#include "string\unicode.h"
#include "system\tls.h"
// Game headers
#include "..\system\filemgr.h"
#include "..\scene\ExtraContentDefs.h"
namespace rage { class fiPackfile; }
enum
{
MISSION_TEXT_SLOT,
PHONE_TEXT_SLOT,
ODDJOB_TEXT_SLOT,
MINIGAME_TEXT_SLOT,
SHOP_TEXT_SLOT,
OBJECT_TEXT_SLOT,
MISSION_DIALOGUE_TEXT_SLOT,
AMBIENT_DIALOGUE_TEXT_SLOT,
MP_STATS_TEXT_SLOT,
MENU_TEXT_SLOT,
PROPERTY_TEXT_SLOT,
DLC_TEXT_SLOT0,
DLC_TEXT_SLOT1,
DLC_TEXT_SLOT2,
DLC_MISSION_DIALOGUE_TEXT_SLOT,
DLC_AMBIENT_DIALOGUE_TEXT_SLOT,
RADIO_WHEEL_TEXT_SLOT,
BINK_MOVIE_TEXT_SLOT,
BINK_MOVIE_TEXT_SLOT1,
BINK_MOVIE_TEXT_SLOT2,
DLC_MISSION_DIALOGUE_TEXT_SLOT2,
CREDITS_TEXT_SLOT,
GTA5_GLOBAL_TEXT_SLOT,
NUM_TEXT_SLOTS,
};
#define NUM_BINK_MOVIE_TEXT_SLOTS ((BINK_MOVIE_TEXT_SLOT2 - BINK_MOVIE_TEXT_SLOT)+1)
#define MISSION_NAME_LENGTH (8)
#define TEXT_KEY_SIZE (16)
#if __BANK
class CDebugString
{
public:
CDebugString() : m_string(NULL) {}
~CDebugString() {if(m_string) delete[] m_string;}
void Set(const char* pText);
void SetFlaggedForDeletion(bool bDelete) { m_bFlaggedForDeletion = bDelete; }
bool GetFlaggedForDeletion() { return m_bFlaggedForDeletion; }
char *GetString() const { return m_string; }
private:
char* m_string;
bool m_bFlaggedForDeletion;
};
// Use a critical section to avoid clashes between Add() and GetString()
// Instead of removing entries immediately on the Update thread, flag them for removal and
// only actually remove the flagged strings in CGtaRenderThreadGameInterface::PerformSafeModeOperations()
class CDebugStrings
{
public:
void Add(const char *pTextKey, const char *pTextToDisplay);
void FlagForDeletion(const char *pTextKey);
void FlagAllForDeletion();
void DeleteAllFlagged();
char *GetString(u32 textHash);
private:
atMap<u32, CDebugString> m_DebugStringMap;
};
#endif // __BANK
struct CGxt2Entry {
u32 Hash; // Hash of the text code
u32 Offset; // Byte offset, relative to the header, of the string.
};
struct CGxt2Header {
u32 Magic; // 'GXT2' in native endian
u32 Count; // Number of strings in file
CGxt2Entry Entries[0]; // Directory of Count objects, followed by a dummy object with final offset
const char *GetStringByIndex(size_t i);
const char *GetStringByHash(u32 hash);
};
class CExtraTextFile
{
public:
CExtraTextFile(bool hasAdditionalTextSlots, bool hasGlobalTextSlots, bool isTitleUpdate);
~CExtraTextFile();
void Init(const char* deviceName);
void Shutdown();
const char* GetMountName() {return m_mountName;}
fiPackfile* GetPackFile() {return m_PackFile;}
bool GetHasGlobalText() {return m_bHasGlobalTextSlot;}
bool GetHasAdditionalText() {return m_bHasAdditionalTextSlots;}
bool GetIsTitleUpdate() {return m_bIsTitleUpdate;}
private:
fiPackfile *m_PackFile;
bool m_bIsLoaded;
bool m_bHasGlobalTextSlot;
bool m_bHasAdditionalTextSlots;
bool m_bIsTitleUpdate;
char m_mountName[RAGE_MAX_PATH];
};
//
//
//
class CTextFile
{
public:
CTextFile(void);
~CTextFile(void);
enum eSource
{
TEXT_SOURCE_DISK,
TEXT_SOURCE_TU,
TEXT_SOURCE_TU2,
TEXT_SOURCE_PATCH,
TEXT_SOURCE_DLC,
};
enum eLocationOfTextBlock
{
TEXT_LOCATION_GTA5_WITH_POSSIBLE_PATCH, // We expect the block name to exist in the GTA5 text. We'll also search for an additional patch in the DLC text.
TEXT_LOCATION_ADDED_FOR_DLC, // Only search DLC for the block name
TEXT_LOCATION_CHECK_BOTH_GTA5_AND_DLC // If block name exists in GTA5 text then search for an additional patch in the DLC text. If name doesn't exist in GTA5 then search for the block in DLC
};
// void GetNameOfLoadedMissionText(char *pStringToFill);
bool IsBasicTextLoaded(void) { return m_bTextIsLoaded; }
void LoadOrReadSizes(bool bLoad, u32 GxtFileIndx, u32 &OffsetsTableInfo, u32 &TextKeyChunkInfo, u32 &TextDataChunkInfo, bool bUseSystemLanguage);
void ReloadAfterLanguageChange();
void Load(bool bUseSystemLanguage = false);
void InitAdditionalText(int SlotNumber);
s32 GetAdditionalTextIndex(const char* pMissionTextStem);
void RequestAdditionalText(const char *pMissionTextStem, s32 SlotNumber, eLocationOfTextBlock textLocation = TEXT_LOCATION_GTA5_WITH_POSSIBLE_PATCH);
bool HasAdditionalTextLoaded(int SlotNumber);
bool HasThisAdditionalTextLoaded(const char *pMissionTextStem, s32 SlotNumber);
bool IsRequestingAdditionalText(int SlotNumber);
bool IsRequestingThisAdditionalText(const char *pMissionTextStem, s32 SlotNumber);
const char* GetTextStemForAdditonalSlot(const int idx) const;
void ProcessStreamingAdditionalText();
void LoadAdditionalText(fiStream* pStream, s32 SlotNumber);
void LoadAdditionalText(const char *pMissionTextStem, s32 SlotNumber, eLocationOfTextBlock textLocation = TEXT_LOCATION_GTA5_WITH_POSSIBLE_PATCH);
const char* GetGxtDirectory(s32 index);
const char* GetLanguageFile(char *buffer, size_t bufferSize, bool bUseSystemLanguage, eSource eTextSource, bool isDLCpatch = false);
const char* GetMissionTextFilename(s32 missionTextIndex, char* pBuffer);
const char* GetGxtFilename(s32 missionTextIndex, char* pBuffer, bool bUseSystemLanguage);
void Unload(bool unloadExtra = false);
void UnloadCore(){Unload(false);}
void UnloadExtra(){Unload(true);}
char* Get(const char *Ident);
char* Get(const u32 hashkey, const char *);
char* Get( atHashString const locKey ) { return Get( locKey.GetHash(), locKey.TryGetCStr() ); }
bool IsDLCDevice(const char* deviceName) const;
bool DoesTextLabelExist(const char *Ident);
bool DoesTextLabelExist(const u32 hashkey);
void AppendToExtraGlobals(const char* device, bool remove, bool titleUpdate);
void SetUpdatedErrorText(CGxt2Header* text, bool remove = false);
inline bool IsJapanese(void) { return (m_LanguageCode=='j');}
s32 GetBlockContainingLastReturnedString() { return m_TextBlockContainingTheLastStringReturnedByGetFunction; }
int GetLanguageFromName(const char* pLanguage);
#if __BANK
bool bShowTextIdOnly;
void AddToDebugStringMap(const char *pTextKey, const char *pTextToDisplay);
void FlagForDeletionFromDebugStringMap(const char *pTextKey);
void FlagAllForDeletionFromDebugStringMap();
void DeleteAllFlaggedEntriesFromDebugStringMap();
#endif // __BANK
void FreeTextSlot(s32 slot, bool extraText);
atMap<atHashString,CExtraTextFile*>& GetExtraText() {return m_extraText;}
void AddExtracontentText(const char* deviceName, bool hasAdditionalTextSlots, bool hasGlobalTextSlot, bool isTitleUpdate);
void AddExtracontentTextFromMetafile(const char* fileName);
void RemoveExtracontentTextFromMetafile(const char* fileName);
void RemoveExtracontentText(const char* deviceName);
private:
char *GetInternal(u32 hashcode);
s32 GetTextIndexInternal(const char* pMissionTextStem, fiPackfile* packFile);
char *SearchForText(u32 hashcode, CGxt2Header* textSlot);
void LoadTextIntoSlot(s32 slot,const char *stem,bool blocking, eLocationOfTextBlock textLocation);
void StreamIntoSlots(const char* name, bool blocking,CGxt2Header *& _textSlot, u8 &_TextState, char* _TextBlockLoadedIntoThisSlot,const char* stem BANK_ONLY(, s32 slot));
atRangeArray<CGxt2Header *,NUM_TEXT_SLOTS> m_Text; // We load global table into slot 0, everything else is biased by one
atRangeArray<CGxt2Header *,NUM_TEXT_SLOTS> m_PatchText; // We load global table into slot 0, everything else is biased by one
char m_TextBlockLoadedIntoThisSlot[NUM_TEXT_SLOTS][MISSION_NAME_LENGTH];
fiPackfile *m_Packfile;
atRangeArray<u8,NUM_TEXT_SLOTS> m_TextState;
atRangeArray<u8,NUM_TEXT_SLOTS> m_PatchTextState;
atMap<atHashString, CExtraTextFile*> m_extraText;
atBinaryMap<char*, u32> m_extraGlobals;
atBinaryMap<char*, u32> m_updatedErrorText;
atMap<atHashString, CExtraTextMetaFile*> m_extraTextMetafiles;
#if __BANK
CDebugStrings m_DebugStrings;
#endif
s32 m_TextBlockContainingTheLastStringReturnedByGetFunction;
char m_LanguageCode;
bool m_bUsesMultipleTextChunks;
bool m_bTextIsLoaded;
char GetUpperCase (const char C);
};
// wrapper class needed to interface with game skeleton code
class CTextFileWrapper
{
public:
static void Load(unsigned);
};
extern CTextFile TheText; // For all our text needs
#endif