4jcraft/4J.Storage/4J_Storage.h
2026-03-30 02:17:54 -05:00

379 lines
14 KiB
C++

#pragma once
#include <cstdint>
#include <ctime>
#include <string>
#include <vector>
// #include <xtms.h>
#include "../4J.Common/4J_Compat.h"
class C4JStringTable;
#define MAX_DISPLAYNAME_LENGTH 128 // CELL_SAVEDATA_SYSP_SUBTITLE_SIZE on PS3
#define MAX_DETAILS_LENGTH 128 // CELL_SAVEDATA_SYSP_SUBTITLE_SIZE on PS3
#define MAX_SAVEFILENAME_LENGTH 32 // CELL_SAVEDATA_DIRNAME_SIZE
typedef struct {
time_t modifiedTime;
unsigned int dataSize;
unsigned int thumbnailSize;
} CONTAINER_METADATA;
typedef struct {
char UTF8SaveFilename[MAX_SAVEFILENAME_LENGTH];
char UTF8SaveTitle[MAX_DISPLAYNAME_LENGTH];
CONTAINER_METADATA metaData;
std::uint8_t* thumbnailData;
} SAVE_INFO, *PSAVE_INFO;
typedef struct {
int iSaveC;
PSAVE_INFO SaveInfoA;
} SAVE_DETAILS, *PSAVE_DETAILS;
typedef std::vector<PXMARKETPLACE_CONTENTOFFER_INFO> OfferDataArray;
typedef std::vector<PXCONTENT_DATA> XContentDataArray;
// typedef std::vector <PSAVE_DETAILS> SaveDetailsArray;
// Current version of the dlc data creator
#define CURRENT_DLC_VERSION_NUM 3
class C4JStorage {
public:
// Structs defined in the DLC_Creator, but added here to be used in the app
typedef struct {
unsigned int uiFileSize;
std::uint32_t dwType;
std::uint32_t dwWchCount; // count of wchar_t in next array
wchar_t wchFile[1];
} DLC_FILE_DETAILS, *PDLC_FILE_DETAILS;
typedef struct {
std::uint32_t dwType;
std::uint32_t dwWchCount; // count of wchar_t in next array;
wchar_t wchData[1]; // will be an array of size dwBytes
} DLC_FILE_PARAM, *PDLC_FILE_PARAM;
// End of DLC_Creator structs
typedef struct {
wchar_t wchDisplayName[XCONTENT_MAX_DISPLAYNAME_LENGTH];
char szFileName[XCONTENT_MAX_FILENAME_LENGTH];
std::uint32_t dwImageOffset;
std::uint32_t dwImageBytes;
} CACHEINFOSTRUCT;
// structure to hold DLC info in TMS
typedef struct {
std::uint32_t dwVersion;
std::uint32_t dwNewOffers;
std::uint32_t dwTotalOffers;
std::uint32_t dwInstalledTotalOffers;
std::uint8_t bPadding[1024 - sizeof(std::uint32_t) * 4];
// future expansion
} DLC_TMS_DETAILS;
enum eGTS_FileTypes { eGTS_Type_Skin = 0, eGTS_Type_Cape, eGTS_Type_MAX };
enum eGlobalStorage {
// eGlobalStorage_GameClip=0,
eGlobalStorage_Title = 0,
eGlobalStorage_TitleUser,
eGlobalStorage_Max
};
enum EMessageResult {
EMessage_Undefined = 0,
EMessage_Busy,
EMessage_Pending,
EMessage_Cancelled,
EMessage_ResultAccept,
EMessage_ResultDecline,
EMessage_ResultThirdOption,
EMessage_ResultFourthOption
};
enum ESaveGameControlState {
ESaveGameControl_Idle = 0,
ESaveGameControl_Save,
ESaveGameControl_InternalRequestingDevice,
ESaveGameControl_InternalGetSaveName,
ESaveGameControl_InternalSaving,
ESaveGameControl_CopySave,
ESaveGameControl_CopyingSave,
};
enum ESaveGameState {
ESaveGame_Idle = 0,
ESaveGame_Save,
ESaveGame_InternalRequestingDevice,
ESaveGame_InternalGetSaveName,
ESaveGame_InternalSaving,
ESaveGame_CopySave,
ESaveGame_CopyingSave,
ESaveGame_Load,
ESaveGame_GetSavesInfo,
ESaveGame_Rename,
ESaveGame_Delete,
ESaveGame_GetSaveThumbnail // Not used as an actual state in the PS4,
// but the game expects this to be returned
// to indicate success when getting a
// thumbnail
};
enum ELoadGameStatus {
ELoadGame_Idle = 0,
ELoadGame_InProgress,
ELoadGame_NoSaves,
ELoadGame_ChangedDevice,
ELoadGame_DeviceRemoved
};
enum EDeleteGameStatus {
EDeleteGame_Idle = 0,
EDeleteGame_InProgress,
};
enum ESGIStatus {
ESGIStatus_Error = 0,
ESGIStatus_Idle,
ESGIStatus_ReadInProgress,
ESGIStatus_NoSaves,
};
enum EDLCStatus {
EDLC_Error = 0,
EDLC_Idle,
EDLC_NoOffers,
EDLC_AlreadyEnumeratedAllOffers,
EDLC_NoInstalledDLC,
EDLC_Pending,
EDLC_LoadInProgress,
EDLC_Loaded,
EDLC_ChangedDevice
};
enum ESavingMessage {
ESavingMessage_None = 0,
ESavingMessage_Short,
ESavingMessage_Long
};
enum ETMSStatus {
ETMSStatus_Idle = 0,
ETMSStatus_Fail,
ETMSStatus_Fail_ReadInProgress,
ETMSStatus_Fail_WriteInProgress,
ETMSStatus_Pending,
};
enum eTMS_FileType {
eTMS_FileType_Normal = 0,
eTMS_FileType_Graphic,
};
enum eTMS_FILETYPEVAL {
TMS_FILETYPE_BINARY,
TMS_FILETYPE_CONFIG,
TMS_FILETYPE_JSON,
TMS_FILETYPE_MAX
};
enum eTMS_UGCTYPE { TMS_UGCTYPE_NONE, TMS_UGCTYPE_IMAGE, TMS_UGCTYPE_MAX };
typedef struct {
char szFilename[256];
int iFileSize;
eTMS_FILETYPEVAL eFileTypeVal;
} TMSPP_FILE_DETAILS, *PTMSPP_FILE_DETAILS;
typedef struct {
int iCount;
PTMSPP_FILE_DETAILS FileDetailsA;
} TMSPP_FILE_LIST, *PTMSPP_FILE_LIST;
typedef struct {
unsigned int size;
std::uint8_t* pbData;
} TMSPP_FILEDATA, *PTMSPP_FILEDATA;
C4JStorage();
void Tick(void);
// Messages
C4JStorage::EMessageResult RequestMessageBox(
unsigned int uiTitle, unsigned int uiText, unsigned int* uiOptionA,
unsigned int uiOptionC, unsigned int pad = XUSER_INDEX_ANY,
int (*Func)(void*, int, const C4JStorage::EMessageResult) = nullptr,
void* lpParam = nullptr, C4JStringTable* pStringTable = nullptr,
wchar_t* pwchFormatString = nullptr, unsigned int focusButton = 0);
C4JStorage::EMessageResult GetMessageBoxResult();
// save device
bool SetSaveDevice(int (*Func)(void*, const bool), void* lpParam,
bool bForceResetOfSaveDevice = false);
// savegame
void Init(unsigned int uiSaveVersion, const wchar_t* pwchDefaultSaveName,
char* pszSavePackName, int iMinimumSaveSize,
int (*Func)(void*, const ESavingMessage, int), void* lpParam,
const char* szGroupID);
void ResetSaveData(); // Call before a new save to clear out stored save
// file name
void SetDefaultSaveNameForKeyboardDisplay(
const wchar_t* pwchDefaultSaveName);
void SetSaveTitle(const wchar_t* pwchDefaultSaveName);
bool GetSaveUniqueNumber(int* piVal);
bool GetSaveUniqueFilename(char* pszName);
void SetSaveUniqueFilename(char* szFilename);
void SetState(ESaveGameControlState eControlState,
int (*Func)(void*, const bool), void* lpParam);
void SetSaveDisabled(bool bDisable);
bool GetSaveDisabled(void);
unsigned int GetSaveSize();
void GetSaveData(void* pvData, unsigned int* puiBytes);
void* AllocateSaveData(unsigned int uiBytes);
void SetSaveImages(
std::uint8_t* pbThumbnail, unsigned int thumbnailBytes,
std::uint8_t* pbImage, unsigned int imageBytes,
std::uint8_t* pbTextData,
unsigned int textDataBytes); // Sets the thumbnail & image for the
// save, optionally setting the
// metadata in the png
C4JStorage::ESaveGameState SaveSaveData(int (*Func)(void*, const bool),
void* lpParam);
void CopySaveDataToNewSave(std::uint8_t* pbThumbnail,
unsigned int cbThumbnail, wchar_t* wchNewName,
int (*Func)(void* lpParam, bool), void* lpParam);
void SetSaveDeviceSelected(unsigned int uiPad, bool bSelected);
bool GetSaveDeviceSelected(unsigned int iPad);
C4JStorage::ESaveGameState DoesSaveExist(bool* pbExists);
bool EnoughSpaceForAMinSaveGame();
void SetSaveMessageVPosition(
float fY); // The 'Saving' message will display at a default position
// unless changed
// Get the info for the saves
C4JStorage::ESaveGameState GetSavesInfo(
int iPad,
int (*Func)(void* lpParam, SAVE_DETAILS* pSaveDetails, const bool),
void* lpParam, char* pszSavePackName);
PSAVE_DETAILS ReturnSavesInfo();
void ClearSavesInfo(); // Clears results
C4JStorage::ESaveGameState LoadSaveDataThumbnail(
PSAVE_INFO pSaveInfo,
int (*Func)(void* lpParam, std::uint8_t* thumbnailData,
unsigned int thumbnailBytes),
void* lpParam); // Get the thumbnail for an individual save referenced
// by pSaveInfo
void GetSaveCacheFileInfo(unsigned int fileIndex,
XCONTENT_DATA& xContentData);
void GetSaveCacheFileInfo(unsigned int fileIndex,
std::uint8_t** ppbImageData,
unsigned int* pImageBytes);
// Load the save. Need to call GetSaveData once the callback is called
C4JStorage::ESaveGameState LoadSaveData(PSAVE_INFO pSaveInfo,
int (*Func)(void* lpParam,
const bool, const bool),
void* lpParam);
C4JStorage::ESaveGameState DeleteSaveData(PSAVE_INFO pSaveInfo,
int (*Func)(void* lpParam,
const bool),
void* lpParam);
// DLC
void RegisterMarketplaceCountsCallback(
int (*Func)(void* lpParam, C4JStorage::DLC_TMS_DETAILS*, int),
void* lpParam);
void SetDLCPackageRoot(char* pszDLCRoot);
C4JStorage::EDLCStatus GetDLCOffers(
int iPad, int (*Func)(void*, int, std::uint32_t, int), void* lpParam,
std::uint32_t dwOfferTypesBitmask = XMARKETPLACE_OFFERING_TYPE_CONTENT);
unsigned int CancelGetDLCOffers();
void ClearDLCOffers();
XMARKETPLACE_CONTENTOFFER_INFO& GetOffer(unsigned int dw);
int GetOfferCount();
unsigned int InstallOffer(int iOfferIDC, std::uint64_t* ullOfferIDA,
int (*Func)(void*, int, int), void* lpParam,
bool bTrial = false);
unsigned int GetAvailableDLCCount(int iPad);
C4JStorage::EDLCStatus GetInstalledDLC(int iPad,
int (*Func)(void*, int, int),
void* lpParam);
XCONTENT_DATA& GetDLC(unsigned int dw);
std::uint32_t MountInstalledDLC(int iPad, std::uint32_t dwDLC,
int (*Func)(void*, int, std::uint32_t,
std::uint32_t),
void* lpParam,
const char* szMountDrive = nullptr);
unsigned int UnmountInstalledDLC(const char* szMountDrive = nullptr);
void GetMountedDLCFileList(const char* szMountDrive,
std::vector<std::string>& fileList);
std::string GetMountedPath(std::string szMount);
// Global title storage
C4JStorage::ETMSStatus ReadTMSFile(
int iQuadrant, eGlobalStorage eStorageFacility,
C4JStorage::eTMS_FileType eFileType, wchar_t* pwchFilename,
std::uint8_t** ppBuffer, unsigned int* pBufferSize,
int (*Func)(void*, wchar_t*, int, bool, int) = nullptr,
void* lpParam = nullptr, int iAction = 0);
bool WriteTMSFile(int iQuadrant, eGlobalStorage eStorageFacility,
wchar_t* pwchFilename, std::uint8_t* pBuffer,
unsigned int bufferSize);
bool DeleteTMSFile(int iQuadrant, eGlobalStorage eStorageFacility,
wchar_t* pwchFilename);
void StoreTMSPathName(wchar_t* pwchName = nullptr);
// TMS++
#ifdef _XBOX
C4JStorage::ETMSStatus WriteTMSFile(
int iPad, C4JStorage::eGlobalStorage eStorageFacility,
C4JStorage::eTMS_FileType eFileType, char* pchFilePath, char* pchBuffer,
unsigned int bufferSize, TMSCLIENT_CALLBACK Func, void* lpParam);
int GetUserQuotaInfo(int iPad, TMSCLIENT_CALLBACK Func, void* lpParam);
#endif
// Older TMS++ write/quota entry points were kept in platform-specific
// implementations and are intentionally not part of this shared API.
C4JStorage::ETMSStatus TMSPP_ReadFile(
int iPad, C4JStorage::eGlobalStorage eStorageFacility,
C4JStorage::eTMS_FILETYPEVAL eFileTypeVal, const char* szFilename,
int (*Func)(void*, int, int, PTMSPP_FILEDATA, const char*) = nullptr,
void* lpParam = nullptr, int iUserData = 0);
// Older TMS++ list/delete helpers stayed platform-specific. The shared
// surface keeps the read path plus CRC/subfile helpers below.
// enum eXBLWS
// {
// eXBLWS_GET,
// eXBLWS_POST,
// eXBLWS_PUT,
// eXBLWS_DELETE,
// };
// bool
// XBLWS_Command(eXBLWS eCommand);
unsigned int CRC(unsigned char* buf, int len);
int AddSubfile(int regionIndex);
unsigned int GetSubfileCount();
void GetSubfileDetails(unsigned int i, int* regionIndex, void** data,
unsigned int* size);
void ResetSubfiles();
void UpdateSubfile(int index, void* data, unsigned int size);
void SaveSubfiles(int (*Func)(void*, const bool), void* param);
ESaveGameState GetSaveState();
void ContinueIncompleteOperation();
C4JStringTable* m_pStringTable;
};
extern C4JStorage StorageManager;