Path: blob/master/RSDKv5/RSDK/User/Core/UserStorage.hpp
1163 views
#ifndef USER_STORAGE_H1#define USER_STORAGE_H23namespace RSDK4{5namespace SKU6{78#if RETRO_REV02910#define RETRO_USERDB_MAX (8)11#define RETRO_USERDB_COL_MAX (8)12#define RETRO_USERDB_ROW_MAX (0x400)1314// no clue what this is...15// most signatures are recognisable like "SCN" for scenes16// but as far as I can tell, this one is just random numbers?17#define RETRO_USERDB_SIGNATURE (0x80074B1E)1819// This is the base struct, it serves as the base for any API-specific stats20// This struct should never be removed21struct UserStorage {22virtual ~UserStorage() = default;2324virtual void FrameInit()25{26if (!saveStatus) {27if (authStatus == STATUS_ERROR || storageStatus == STATUS_ERROR)28saveStatus = STATUS_ERROR;29else if (storageStatus == STATUS_OK)30saveStatus = STATUS_OK;31}32}33virtual void StageLoad() { saveStatus = STATUS_NONE; }34virtual void OnUnknownEvent() {}35virtual int32 TryAuth() { return 0; }36virtual int32 TryInitStorage() { return 0; }37virtual bool32 GetUsername(String *userName) { return false; }38virtual bool32 TryLoadUserFile(const char *filename, void *buffer, uint32 size, void (*callback)(int32 status)) { return false; }39virtual bool32 TrySaveUserFile(const char *filename, void *buffer, uint32 size, void (*callback)(int32 status), bool32 compress) { return false; }40virtual bool32 TryDeleteUserFile(const char *filename, void (*callback)(int32 status)) { return false; }41virtual void ClearPrerollErrors() {}4243int32 authStatus = STATUS_NONE;44int32 storageStatus = STATUS_NONE;45int32 saveStatus = STATUS_NONE;46int32 noSaveActive = false;47};4849static char dbVarTypes[18][16] = {50"unknown", // unused (in Sonic Mania)51"bool", // unused (in Sonic Mania)52"uint8", // used (in Sonic Mania)53"uint16", // unused (in Sonic Mania)54"uint32", // used (in Sonic Mania)55"uint64", // unimplemented in RSDKv556"int8", // unused (in Sonic Mania)57"int16", // unused (in Sonic Mania)58"int32", // unused (in Sonic Mania)59"int64", // unimplemented in RSDKv560"float", // unused (in Sonic Mania)61"double", // unimplemented in RSDKv562"Vector2", // unimplemented in RSDKv563"Vector3", // unimplemented in RSDKv564"Vector4", // unimplemented in RSDKv565"Color", // unused (in Sonic Mania)66"String", // unused (in Sonic Mania)67"HashMD5" // unimplemented in RSDKv568};6970enum DBVarTypes {71DBVAR_UNKNOWN,72DBVAR_BOOL,73DBVAR_UINT8,74DBVAR_UINT16,75DBVAR_UINT32,76DBVAR_UINT64, // unimplemented in RSDKv577DBVAR_INT8,78DBVAR_INT16,79DBVAR_INT32,80DBVAR_INT64, // unimplemented in RSDKv581DBVAR_FLOAT,82DBVAR_DOUBLE, // unimplemented in RSDKv583DBVAR_VECTOR2, // unimplemented in RSDKv584DBVAR_VECTOR3, // unimplemented in RSDKv585DBVAR_VECTOR4, // unimplemented in RSDKv586DBVAR_COLOR,87DBVAR_STRING,88DBVAR_HASHMD5, // unimplemented in RSDKv589};9091extern UserStorage *userStorage;9293struct UserDB;94struct UserDBRow;9596struct UserDBValue {97UserDBValue() { memset(data, 0, sizeof(data)); }98~UserDBValue() {}99100bool32 CheckMatch(int32 row, int32 column);101void Set(int32 type, void *data);102void Get(int32 type, void *data);103104UserDBRow *parent = NULL;105uint8 size = 0;106uint8 data[0x10];107};108109struct UserDBRow {110UserDBRow()111{112memset(&createTime, 0, sizeof(createTime));113memset(&changeTime, 0, sizeof(changeTime));114memset(values, 0, sizeof(values));115}116~UserDBRow() {}117118bool32 AddValue(int32 type, char *name, void *value);119bool32 GetValue(int32 type, char *name, void *value);120121bool32 Compare(UserDBRow *other, int32 type, char *name, bool32 sortAscending);122123UserDB *parent = NULL;124uint32 uuid = 0;125tm createTime;126tm changeTime;127UserDBValue values[8];128};129130struct UserDB {131UserDB()132{133MEM_ZERO(sortedRowIDs);134MEM_ZERO(columnTypes);135MEM_ZERO(columnNames);136MEM_ZERO(columnUUIDs);137MEM_ZERO(rows);138}139~UserDB() { sortedRowList.Clear(true); }140141void Init(va_list list);142bool32 Load(uint8 *buffer);143void Save(int32 totalSize, uint8 *buffer);144void Clear();145146int32 GetColumnID(const char *name);147148int32 AddRow();149uint16 GetRowByID(uint32 uuid);150bool32 RemoveRow(uint32 row);151bool32 RemoveAllRows();152153void FilterValues(UserDBValue *value, int32 column);154void AddSortFilter(const char *name, void *value);155156void SetupRowSortIDs();157void RefreshSortList();158void SortRows(int32 type, char *name, bool32 sortAscending);159160uint32 CreateRowUUID();161void Refresh();162size_t GetSize();163164const char *name = "";165uint32 uuid = 0;166uint8 loaded = false;167uint8 active = false;168uint8 valid = false;169UserDB *parent = NULL;170uint8 rowsChanged = false;171List<int32> sortedRowList;172int32 sortedRowIDs[RETRO_USERDB_ROW_MAX];173int32 sortedRowCount = 0;174int32 columnCount = 0;175int32 columnTypes[RETRO_USERDB_COL_MAX];176char columnNames[RETRO_USERDB_COL_MAX][0x10];177uint32 columnUUIDs[RETRO_USERDB_COL_MAX];178uint16 rowCount = 0;179UserDBRow rows[RETRO_USERDB_ROW_MAX];180};181182struct UserDBStorage {183UserDBStorage();184185uint16 InitUserDB(const char *name, va_list list);186uint16 LoadUserDB(const char *filename, void (*callback)(int32 status));187bool32 SaveUserDB(uint16 tableID, void (*callback)(int32 status));188void ClearUserDB(uint16 tableID);189void ClearAllUserDBs();190191static bool32 LoadCB(uint16 tableID, int32 status);192static bool32 SaveCB(uint16 tableID, int32 status);193194UserDB userDB[RETRO_USERDB_MAX];195uint8 unknown;196int32 *writeBuffer[RETRO_USERDB_MAX];197void *readBuffer[RETRO_USERDB_MAX];198void (*loadCallback[RETRO_USERDB_MAX])(int32 status);199void (*saveCallback[RETRO_USERDB_MAX])(int32 status);200bool32 (*dbLoadCB[RETRO_USERDB_MAX])(uint16 table, int32 status);201bool32 (*dbSaveCB[RETRO_USERDB_MAX])(uint16 table, int32 status);202void (*callbacks[RETRO_USERDB_MAX])(int32);203int32 unused[RETRO_USERDB_MAX];204};205206extern UserDBStorage *userDBStorage;207208// ====================209// API Cores210// ====================211212// Dummy API213#if RETRO_USERCORE_DUMMY214#include "RSDK/User/Dummy/DummyStorage.hpp"215#endif216217// Steam API218#if RETRO_USERCORE_STEAM219#include "RSDK/User/Steam/SteamStorage.hpp"220#endif221222// Epic Games API223#if RETRO_USERCORE_EOS224#include "RSDK/User/EOS/EOSStorage.hpp"225#endif226227// Switch API228#if RETRO_USERCORE_NX229#include "RSDK/User/NX/NXStorage.hpp"230#endif231232// =======================233// USER STORAGE234// =======================235236inline int32 TryAuth() { return userStorage->TryAuth(); }237inline int32 TryInitStorage() { return userStorage->TryInitStorage(); }238inline bool32 GetUsername(String *userName) { return userStorage->GetUsername(userName); }239inline bool32 TryLoadUserFile(const char *filename, void *buffer, uint32 size, void (*callback)(int32 status))240{241return userStorage->TryLoadUserFile(filename, buffer, size, callback);242}243inline bool32 TrySaveUserFile(const char *filename, void *buffer, uint32 size, void (*callback)(int32 status), bool32 compressed)244{245return userStorage->TrySaveUserFile(filename, buffer, size, callback, compressed);246}247inline bool32 TryDeleteUserFile(const char *filename, void (*callback)(int32 status)) { return userStorage->TryDeleteUserFile(filename, callback); }248inline void ClearPrerollErrors() { userStorage->ClearPrerollErrors(); }249250inline int32 GetUserAuthStatus() { return userStorage->authStatus; }251inline int32 GetUserStorageStatus()252{253if (userStorage->saveStatus == STATUS_ERROR)254return STATUS_ERROR;255else256return userStorage->storageStatus;257}258259inline int32 GetSaveStatus()260{261if (userStorage->noSaveActive)262return STATUS_OK;263else264return userStorage->saveStatus;265}266inline void SetSaveStatusOK()267{268if (userStorage->saveStatus == STATUS_CONTINUE)269userStorage->saveStatus = STATUS_OK;270}271inline void SetSaveStatusForbidden()272{273if (userStorage->saveStatus == STATUS_CONTINUE)274userStorage->saveStatus = STATUS_FORBIDDEN;275}276inline void SetSaveStatusError()277{278if (userStorage->saveStatus == STATUS_CONTINUE)279userStorage->saveStatus = STATUS_ERROR;280}281inline void ClearSaveStatus() { userStorage->saveStatus = STATUS_NONE; }282inline void SetSaveStatusContinue() { userStorage->saveStatus = STATUS_CONTINUE; }283inline void SetUserStorageNoSave(bool32 noSave) { userStorage->noSaveActive = noSave; }284inline bool32 GetUserStorageNoSave() { return userStorage->noSaveActive; }285286// =======================287// USER DB API288// =======================289290// UserDB management291inline uint16 InitUserDB(const char *name, ...)292{293va_list list;294va_start(list, name);295uint16 id = userDBStorage->InitUserDB(name, list);296va_end(list);297return id;298}299inline uint16 LoadUserDB(const char *filename, void (*callback)(int32 status)) { return userDBStorage->LoadUserDB(filename, callback); }300inline bool32 SaveUserDB(uint16 tableID, void (*callback)(int32 status)) { return userDBStorage->SaveUserDB(tableID, callback); }301inline void ClearUserDB(uint16 tableID) { userDBStorage->ClearUserDB(tableID); }302inline void ClearAllUserDBs() { userDBStorage->ClearAllUserDBs(); }303304// UserDB rows305inline int32 AddUserDBRow(uint16 tableID)306{307if (tableID == (uint16)-1)308return -1;309UserDB *userDB = &userDBStorage->userDB[tableID];310if (!userDB->active)311return -1;312313return userDB->AddRow();314}315inline bool32 RemoveDBRow(uint16 tableID, uint16 rowID)316{317if (tableID == (uint16)-1 || rowID == (uint16)-1)318return false;319320UserDB *userDB = &userDBStorage->userDB[tableID];321if (!userDB->active)322return false;323324return userDB->RemoveRow(rowID);325}326inline bool32 RemoveAllDBRows(uint16 tableID)327{328if (tableID == (uint16)-1)329return false;330331UserDB *userDB = &userDBStorage->userDB[tableID];332if (!userDB->active)333return false;334335return userDB->RemoveAllRows();336}337inline uint16 GetUserDBRowByID(uint16 tableID, uint32 uuid)338{339if (tableID == (uint16)-1 || !uuid)340return -1;341342UserDB *userDB = &userDBStorage->userDB[tableID];343if (!userDB->active)344return -1;345346return userDB->GetRowByID(uuid);347}348349inline uint32 GetDBRowUUID(uint16 tableID, uint16 rowID)350{351if (tableID == (uint16)-1 || rowID == (uint16)-1)352return 0;353354UserDB *userDB = &userDBStorage->userDB[tableID];355if (!userDB->active)356return 0;357358return userDB->rows[rowID].uuid;359}360361// UserDB Row Sorting362uint16 SetupUserDBRowSorting(uint16 tableID);363int32 AddUserDBRowSortFilter(uint16 tableID, int32 type, const char *name, void *value);364int32 SortUserDBRows(uint16 tableID, int32 type, const char *name, bool32 sortAscending);365int32 GetSortedUserDBRowCount(uint16 tableID);366int32 GetSortedUserDBRowID(uint16 tableID, uint16 entryID);367368// UserDB Values369bool32 GetUserDBValue(uint16 tableID, uint32 rowID, int32 type, char *name, void *value);370bool32 SetUserDBValue(uint16 tableID, uint32 rowID, int32 type, char *name, void *value);371372// UserDB Misc373bool32 GetUserDBRowsChanged(uint16 tableID);374void GetUserDBRowCreationTime(uint16 tableID, uint16 rowID, char *buf, size_t size, char *format);375376// =======================377// USER DB CALLBACKS378// =======================379380void UserDBStorage_LoadCB1(int32 status);381void UserDBStorage_LoadCB2(int32 status);382void UserDBStorage_LoadCB3(int32 status);383void UserDBStorage_LoadCB4(int32 status);384void UserDBStorage_LoadCB5(int32 status);385void UserDBStorage_LoadCB6(int32 status);386void UserDBStorage_LoadCB7(int32 status);387void UserDBStorage_LoadCB8(int32 status);388389void UserDBStorage_SaveCB1(int32 status);390void UserDBStorage_SaveCB2(int32 status);391void UserDBStorage_SaveCB3(int32 status);392void UserDBStorage_SaveCB4(int32 status);393void UserDBStorage_SaveCB5(int32 status);394void UserDBStorage_SaveCB6(int32 status);395void UserDBStorage_SaveCB7(int32 status);396void UserDBStorage_SaveCB8(int32 status);397#endif398399extern void (*preLoadSaveFileCB)();400extern void (*postLoadSaveFileCB)();401extern char userFileDir[0x100];402403inline void SetUserFileCallbacks(const char *userDir, void (*preCB)(), void (*postCB)())404{405preLoadSaveFileCB = preCB;406postLoadSaveFileCB = postCB;407strcpy(userFileDir, userDir);408}409410bool32 LoadUserFile(const char *filename, void *buffer, uint32 bufSize);411bool32 SaveUserFile(const char *filename, void *buffer, uint32 bufSize);412bool32 DeleteUserFile(const char *filename);413414#if !RETRO_REV02415bool32 TryLoadUserFile(const char *filename, void *buffer, uint32 size, void (*callback)(int32 status));416bool32 TrySaveUserFile(const char *filename, void *buffer, uint32 size, void (*callback)(int32 status));417#endif418419void InitUserDirectory();420421} // namespace SKU422} // namespace RSDK423424#endif425426