Path: blob/master/SonicMania/Objects/Helpers/ReplayDB.c
338 views
// ---------------------------------------------------------------------1// RSDK Project: Sonic Mania2// Object Description: ReplayDB Object3// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges4// Decompiled by: Rubberduckycooly & RMGRich5// ---------------------------------------------------------------------67#include "Game.h"89#if MANIA_USE_PLUS10ObjectReplayDB *ReplayDB;1112void ReplayDB_Update(void) {}1314void ReplayDB_LateUpdate(void) {}1516void ReplayDB_StaticUpdate(void) {}1718void ReplayDB_Draw(void) {}1920void ReplayDB_Create(void *data) {}2122void ReplayDB_StageLoad(void) {}2324void ReplayDB_CreateDB(void)25{26globals->replayTableID = API.InitUserDB("ReplayDB.bin", DBVAR_UINT32, "score", DBVAR_UINT8, "zoneID", DBVAR_UINT8, "act", DBVAR_UINT8,27"characterID", DBVAR_UINT8, "encore", DBVAR_UINT32, "zoneSortVal", NULL);2829if (globals->replayTableID == -1)30globals->replayTableLoaded = STATUS_ERROR;31else32globals->replayTableLoaded = STATUS_OK;33}3435void ReplayDB_LoadDB(void (*callback)(bool32 success))36{37if ((globals->replayTableID != -1 && globals->replayTableLoaded == STATUS_OK) || globals->replayTableLoaded == STATUS_CONTINUE) {38if (callback)39callback(false);40}41else {42LogHelpers_Print("Loading Replay DB");43globals->replayTableLoaded = STATUS_CONTINUE;4445ReplayDB->loadEntity = SceneInfo->entity;46ReplayDB->loadCallback = callback;47globals->replayTableID = API.LoadUserDB("ReplayDB.bin", ReplayDB_LoadDBCallback);4849if (globals->replayTableID == -1) {50LogHelpers_Print("Couldn't claim a slot for loading %s", "ReplayDB.bin");51globals->replayTableLoaded = STATUS_ERROR;52}53}54}5556void ReplayDB_SaveDB(void (*callback)(bool32 success))57{58if (API_GetNoSave() || globals->replayTableID == (uint16)-1 || globals->replayTableLoaded != STATUS_OK) {59if (callback)60callback(false);61}62else {63LogHelpers_Print("Saving Replay DB");64ReplayDB->saveEntity = SceneInfo->entity;65ReplayDB->saveCallback = callback;66API.SaveUserDB(globals->replayTableID, ReplayDB_SaveDBCallback);67}68}6970uint32 ReplayDB_AddReplay(uint8 zoneID, uint8 act, uint8 characterID, int32 score, uint8 encore)71{72if (globals->replayTableLoaded == STATUS_OK) {73uint32 rowID = API.AddUserDBRow(globals->replayTableID);74int32 zoneStortVal = (score & 0x3FFFFFF) | (((zoneID << 2) | (act & 1) | ((encore & 1) << 1)) << 26);7576API.SetUserDBValue(globals->replayTableID, rowID, DBVAR_UINT32, "score", &score);77API.SetUserDBValue(globals->replayTableID, rowID, DBVAR_UINT8, "zoneID", &zoneID);78API.SetUserDBValue(globals->replayTableID, rowID, DBVAR_UINT8, "act", &act);79API.SetUserDBValue(globals->replayTableID, rowID, DBVAR_UINT8, "characterID", &characterID);80API.SetUserDBValue(globals->replayTableID, rowID, DBVAR_UINT8, "encore", &encore);81API.SetUserDBValue(globals->replayTableID, rowID, DBVAR_UINT32, "zoneSortVal", &zoneStortVal);8283uint32 UUID = API.GetUserDBRowUUID(globals->replayTableID, rowID);84char createTime[24];85sprintf_s(createTime, (int32)sizeof(createTime), "");86API.GetUserDBRowCreationTime(globals->replayTableID, rowID, createTime, sizeof(createTime) - 1, "%Y/%m/%d %H:%M:%S");8788LogHelpers_Print("Replay DB Added Entry");89LogHelpers_Print("Created at %s", createTime);90LogHelpers_Print("Row ID: %d", rowID);91LogHelpers_Print("UUID: %08X", UUID);9293return rowID;94}9596return -1;97}9899void ReplayDB_DeleteReplay(int32 row, void (*callback)(bool32 success), bool32 useAltCB)100{101int32 id = API.GetUserDBRowUUID(globals->replayTableID, row);102int32 replayID = 0;103104ReplayDB->deleteEntity = SceneInfo->entity;105ReplayDB->deleteCallback = callback;106API.RemoveDBRow(globals->replayTableID, row);107TimeAttackData->loaded = false;108109API.SetupUserDBRowSorting(globals->taTableID);110API.AddRowSortFilter(globals->taTableID, DBVAR_UINT32, "replayID", &id);111112int32 count = API.GetSortedUserDBRowCount(globals->taTableID);113for (int32 i = 0; i < count; ++i) {114uint32 uuid = API.GetSortedUserDBRowID(globals->taTableID, i);115LogHelpers_Print("Deleting Time Attack replay from row #%d", uuid);116API.SetUserDBValue(globals->taTableID, uuid, DBVAR_UINT32, "replayID", &replayID);117}118119char filename[0x20];120sprintf_s(filename, (int32)sizeof(filename), "Replay_%08X.bin", id);121if (!useAltCB)122API.DeleteUserFile(filename, ReplayDB_DeleteReplay_CB);123else124API.DeleteUserFile(filename, ReplayDB_DeleteReplaySave2_CB);125}126127void ReplayDB_DeleteReplay_CB(int32 status)128{129LogHelpers_Print("DeleteReplay_CB(%d)", status);130131API.SaveUserDB(globals->replayTableID, ReplayDB_DeleteReplaySave_CB);132}133134void ReplayDB_DeleteReplaySave_CB(int32 status)135{136LogHelpers_Print("DeleteReplaySave_CB(%d)", status);137138API.SaveUserDB(globals->taTableID, ReplayDB_DeleteReplaySave2_CB);139}140141void ReplayDB_DeleteReplaySave2_CB(int32 status)142{143LogHelpers_Print("DeleteReplaySave2_CB(%d)", status);144145if (ReplayDB->deleteCallback) {146Entity *store = SceneInfo->entity;147if (ReplayDB->deleteEntity)148SceneInfo->entity = ReplayDB->deleteEntity;149ReplayDB->deleteCallback(status == STATUS_OK);150SceneInfo->entity = store;151152ReplayDB->deleteCallback = NULL;153ReplayDB->deleteEntity = NULL;154}155}156157void ReplayDB_LoadDBCallback(int32 status)158{159if (status == STATUS_OK) {160globals->replayTableLoaded = STATUS_OK;161API.SetupUserDBRowSorting(globals->replayTableID);162LogHelpers_Print("Load Succeeded! Replay count: %d", API.GetSortedUserDBRowCount(globals->replayTableID));163}164else {165LogHelpers_Print("Load Failed! Creating new Replay DB");166ReplayDB_CreateDB();167}168169LogHelpers_Print("Replay DB Slot => %d, Load Status => %d", globals->replayTableID, globals->replayTableLoaded);170171if (ReplayDB->loadCallback) {172Entity *store = SceneInfo->entity;173if (ReplayDB->loadEntity)174SceneInfo->entity = ReplayDB->loadEntity;175ReplayDB->loadCallback(status == STATUS_OK);176SceneInfo->entity = store;177178ReplayDB->loadCallback = NULL;179ReplayDB->loadEntity = NULL;180}181}182183void ReplayDB_SaveDBCallback(int32 status)184{185if (ReplayDB->saveCallback) {186Entity *store = SceneInfo->entity;187if (ReplayDB->saveEntity)188SceneInfo->entity = ReplayDB->saveEntity;189ReplayDB->saveCallback(status == STATUS_OK);190SceneInfo->entity = store;191192ReplayDB->saveCallback = NULL;193ReplayDB->saveEntity = NULL;194}195}196197void ReplayDB_LoadCallback(bool32 success) {}198199int32 ReplayDB_Buffer_PackEntry(uint8 *compressed, void *uncompressed)200{201ReplayFrame *framePtr = (ReplayFrame *)uncompressed;202203compressed[0] = framePtr->info;204compressed[1] = framePtr->changedValues;205bool32 forcePack = framePtr->info == REPLAY_INFO_STATECHANGE || framePtr->info == REPLAY_INFO_PASSEDGATE;206uint8 changes = framePtr->changedValues;207208uint8 *compressedBuffer = &compressed[2];209210// input211if (forcePack || (changes & REPLAY_CHANGED_INPUT)) {212*compressedBuffer = framePtr->inputs;213++compressedBuffer;214}215216// position217if (forcePack || (changes & REPLAY_CHANGED_POS)) {218*((int32 *)compressedBuffer) = framePtr->position.x;219compressedBuffer += sizeof(int32);220221*((int32 *)compressedBuffer) = framePtr->position.y;222compressedBuffer += sizeof(int32);223}224225// velocity226if (forcePack || (changes & REPLAY_CHANGED_VEL)) {227*((int32 *)compressedBuffer) = framePtr->velocity.x;228compressedBuffer += sizeof(int32);229230*((int32 *)compressedBuffer) = framePtr->velocity.y;231compressedBuffer += sizeof(int32);232}233234// rotation235if (forcePack || (changes & REPLAY_CHANGED_ROT)) {236*compressedBuffer = framePtr->rotation >> 1;237compressedBuffer += sizeof(uint8);238}239240// direction241if (forcePack || (changes & REPLAY_CHANGED_DIR)) {242*compressedBuffer = framePtr->direction;243++compressedBuffer;244}245246// anim247if (forcePack || (changes & REPLAY_CHANGED_ANIM)) {248*compressedBuffer = framePtr->anim;249++compressedBuffer;250}251252// frame253if (forcePack || (changes & REPLAY_CHANGED_FRAME)) {254*compressedBuffer = framePtr->frame;255++compressedBuffer;256}257258return (int32)(compressedBuffer - compressed);259}260261int32 ReplayDB_Buffer_UnpackEntry(void *uncompressed, uint8 *compressed)262{263ReplayFrame *framePtr = (ReplayFrame *)uncompressed;264265// compress state266framePtr->info = compressed[0];267268bool32 forceUnpack = *compressed == REPLAY_INFO_STATECHANGE || *compressed == REPLAY_INFO_PASSEDGATE;269uint8 changes = compressed[1];270framePtr->changedValues = changes;271272uint8 *compressedBuffer = &compressed[2];273274// input275if (forceUnpack || (changes & REPLAY_CHANGED_INPUT)) {276framePtr->inputs = *compressedBuffer++;277}278279// position280if (forceUnpack || (changes & REPLAY_CHANGED_POS)) {281int32 x = *(int32 *)compressedBuffer;282compressedBuffer += sizeof(int32);283284int32 y = *(int32 *)compressedBuffer;285compressedBuffer += sizeof(int32);286287framePtr->position.x = x;288framePtr->position.y = y;289}290291// velocity292if (forceUnpack || (changes & REPLAY_CHANGED_VEL)) {293int32 x = *(int32 *)compressedBuffer;294compressedBuffer += sizeof(int32);295296int32 y = *(int32 *)compressedBuffer;297compressedBuffer += sizeof(int32);298299framePtr->velocity.x = x;300framePtr->velocity.y = y;301}302303// rotation304if (forceUnpack || (changes & REPLAY_CHANGED_ROT)) {305int32 rotation = *compressedBuffer++;306framePtr->rotation = rotation << 1;307}308309// direction310if (forceUnpack || (changes & REPLAY_CHANGED_DIR)) {311framePtr->direction = *compressedBuffer++;312}313314// anim315if (forceUnpack || (changes & REPLAY_CHANGED_ANIM)) {316framePtr->anim = *compressedBuffer++;317}318319// frame320if (forceUnpack || (changes & REPLAY_CHANGED_FRAME)) {321framePtr->frame = *compressedBuffer++;322}323324return (int32)(compressedBuffer - compressed);325}326327#if GAME_INCLUDE_EDITOR328void ReplayDB_EditorDraw(void) {}329330void ReplayDB_EditorLoad(void) {}331#endif332333void ReplayDB_Serialize(void) {}334#endif335336337