diff --git a/ZAPDTR/ZAPDUtils/ZAPDUtils.vcxproj b/ZAPDTR/ZAPDUtils/ZAPDUtils.vcxproj index b74fe75f9..81df37e72 100644 --- a/ZAPDTR/ZAPDUtils/ZAPDUtils.vcxproj +++ b/ZAPDTR/ZAPDUtils/ZAPDUtils.vcxproj @@ -29,26 +29,26 @@ StaticLibrary false - v142 + v143 Unicode StaticLibrary false - v142 + v143 true Unicode StaticLibrary true - v142 + v143 MultiByte StaticLibrary false - v142 + v143 true Unicode diff --git a/libultraship/libultraship/ConfigFile.h b/libultraship/libultraship/ConfigFile.h index 17e3720f8..b94e22f88 100644 --- a/libultraship/libultraship/ConfigFile.h +++ b/libultraship/libultraship/ConfigFile.h @@ -1,3 +1,6 @@ +#ifndef CONFIG_FILE_H +#define CONFIG_FILE_H + #pragma once #include @@ -35,3 +38,5 @@ namespace Ship { mINI::INIFile File; }; } + +#endif diff --git a/libultraship/libultraship/GameVersions.h b/libultraship/libultraship/GameVersions.h index a25463bf4..8d3753b21 100644 --- a/libultraship/libultraship/GameVersions.h +++ b/libultraship/libultraship/GameVersions.h @@ -1,3 +1,6 @@ +#ifndef GAME_VERSION_H +#define GAME_VERSION_H + #pragma once #define OOT_NTSC_10 0xEC7011B7 @@ -17,4 +20,6 @@ #define OOT_PAL_GC_MQ_DBG 0x917D18F6 #define OOT_IQUE_TW 0x3D81FB3E #define OOT_IQUE_CN 0xB1E1E07B -#define OOT_UNKNOWN 0xFFFFFFFF \ No newline at end of file +#define OOT_UNKNOWN 0xFFFFFFFF + +#endif diff --git a/libultraship/libultraship/GlobalCtx2.h b/libultraship/libultraship/GlobalCtx2.h index a10421ec0..1ed512347 100644 --- a/libultraship/libultraship/GlobalCtx2.h +++ b/libultraship/libultraship/GlobalCtx2.h @@ -1,3 +1,6 @@ +#ifndef GLOBAL_CTX_2 +#define GLOBAL_CTX_2 + #pragma once #ifdef __cplusplus @@ -38,4 +41,6 @@ namespace Ship { std::string PatchesPath; }; } -#endif \ No newline at end of file +#endif + +#endif diff --git a/libultraship/libultraship/libultraship.vcxproj b/libultraship/libultraship/libultraship.vcxproj index b3448e7b0..da4ffa3a5 100644 --- a/libultraship/libultraship/libultraship.vcxproj +++ b/libultraship/libultraship/libultraship.vcxproj @@ -38,19 +38,19 @@ StaticLibrary true - v142 + v143 Unicode StaticLibrary true - v142 + v143 Unicode StaticLibrary false - v142 + v143 true Unicode diff --git a/soh/include/functions.h b/soh/include/functions.h index 4cbc285a3..6d76617f7 100644 --- a/soh/include/functions.h +++ b/soh/include/functions.h @@ -2405,6 +2405,7 @@ void Heaps_Free(void); #ifdef __cplusplus }; +#undef this #endif #endif diff --git a/soh/include/libc/stddef.h b/soh/include/libc/stddef.h index c30e392f8..e5fbe2d22 100644 --- a/soh/include/libc/stddef.h +++ b/soh/include/libc/stddef.h @@ -1,7 +1,12 @@ #ifndef STDDEF_H #define STDDEF_H +#ifndef __cplusplus #define NULL ((void*)0) +#else +#define NULL nullptr +#endif + #if 0 #define size_t unsigned long #define ssize_t long diff --git a/soh/soh.vcxproj b/soh/soh.vcxproj index 418fdd057..c3419d7cb 100644 --- a/soh/soh.vcxproj +++ b/soh/soh.vcxproj @@ -29,14 +29,14 @@ Application true - v142 + v143 Unicode false Application false - v142 + v143 true Unicode false @@ -44,13 +44,13 @@ Application true - v142 + v143 Unicode Application false - v142 + v143 true Unicode @@ -180,6 +180,7 @@ + @@ -926,6 +927,7 @@ + diff --git a/soh/soh.vcxproj.filters b/soh/soh.vcxproj.filters index a8455a4c8..4f77fdb7c 100644 --- a/soh/soh.vcxproj.filters +++ b/soh/soh.vcxproj.filters @@ -2190,6 +2190,9 @@ Source Files\soh\Enhancements\debugger + + Source Files\soh\Enhancements + @@ -3740,6 +3743,9 @@ Header Files\soh + + Header Files\soh\Enhancements + Header Files\soh\Enhancements\debugger diff --git a/soh/soh/Enhancements/debugconsole.cpp b/soh/soh/Enhancements/debugconsole.cpp index 189230798..91fc0a2a4 100644 --- a/soh/soh/Enhancements/debugconsole.cpp +++ b/soh/soh/Enhancements/debugconsole.cpp @@ -1,8 +1,11 @@ #include "debugconsole.h" #include "../libultraship/SohImGuiImpl.h" +#include "savestates.h" + #include #include + #define Path _Path #define PATH_HACK #include @@ -303,6 +306,17 @@ static bool EntranceHandler(const std::vector& args) { gSaveContext.nextTransition = 11; } +static bool SaveStateHandler(const std::vector& args) { + SaveState::Save(0); + return CMD_SUCCESS; +} + +static bool LoadStateHandler(const std::vector& args) { + SaveState::Load(0); + return CMD_SUCCESS; +} + + #define VARTYPE_INTEGER 0 #define VARTYPE_FLOAT 1 #define VARTYPE_STRING 2 @@ -416,11 +430,10 @@ void DebugConsole_Init(void) { { { "slot", ArgumentType::NUMBER }, { "item id", ArgumentType::NUMBER } } }); CMD_REGISTER("entrance", { EntranceHandler, "Sends player to the entered entrance (hex)", { { "entrance", ArgumentType::NUMBER } } }); -} -template bool is_number(const std::string& s) { - Numeric n; - return ((std::istringstream(s) >> n >> std::ws).eof()); + CMD_REGISTER("save_state", { SaveStateHandler, "Save a state." }); + CMD_REGISTER("load_state", { LoadStateHandler, "Load a state." }); + DebugConsole_LoadCVars(); } void DebugConsole_LoadCVars() diff --git a/soh/soh/Enhancements/savestates.cpp b/soh/soh/Enhancements/savestates.cpp new file mode 100644 index 000000000..9eca20db1 --- /dev/null +++ b/soh/soh/Enhancements/savestates.cpp @@ -0,0 +1,84 @@ +#include "savestates.h" + +#include "GameVersions.h" +#include +//#include "global.h" +//#include + +std::array gSaveStates; + + +SaveState::SaveState() { + +} +#if 0 + +SaveState::~SaveState() { +} +#endif + +void SaveState::Init(void) { + gSaveStates[0] = nullptr; + gSaveStates[1] = nullptr; + gSaveStates[2] = nullptr; +} + +void SaveState::WriteHeader(SaveStateHeader& header) { + //OTRGlobals::Instance->context->GetResourceManager()->GetGameVersion(); + // header.gameVersion = ResourceMgr_GetGameVersion(); +} + +extern "C" MtxF* sMatrixStack; // "Matrix_stack" +extern "C" MtxF* sCurrentMatrix; // "Matrix_now" +extern "C" LightsBuffer sLightsBuffer; + +extern "C" SaveStateReturn SaveState::Save(unsigned int slot) { + if (slot > 2) { + return SaveStateReturn::FAIL_INVALID_SLOT; + } + if (gSaveStates[slot] == nullptr) { + gSaveStates[slot] = new SaveState; + if (gSaveStates[slot] == nullptr) { + return SaveStateReturn::FAIL_NO_MEMORY; + } + } + + gSaveStates[slot]->stateHeader.gameVersion = 0; + gSaveStates[slot]->stateHeader.stateVersion = 0; + + memcpy(&gSaveStates[slot]->sysHeapCopy, &gSystemHeap, 1024 * 1024 * 4 /* sizeof(gSystemHeap) */); + memcpy(&gSaveStates[slot]->saveContextCopy, &gSaveContext, sizeof(gSaveContext)); + memcpy(&gSaveStates[slot]->gameInfoCopy, gGameInfo, sizeof(*gGameInfo)); + // memcpy(&gSaveStates[slot]->audioContextCopy, &gAudioContext, sizeof(AudioContext)); + memcpy(&gSaveStates[slot]->lightBufferCopy, &sLightsBuffer, sizeof(sLightsBuffer)); + memcpy(&gSaveStates[slot]->mtxStackCopy, &sMatrixStack, sizeof(MtxF) * 20); + memcpy(&gSaveStates[slot]->currentMtxCopy, &sCurrentMatrix, sizeof(MtxF)); + //TODO RNG seed + + return SaveStateReturn::SUCCESS; + +} + +SaveStateReturn SaveState::Load(unsigned int slot) { + if (slot > 2) { + return SaveStateReturn::FAIL_INVALID_SLOT; + } + if (gSaveStates[slot] == nullptr) { + return SaveStateReturn::FAIL_STATE_EMPTY; + } + + //gSaveStates[slot]->stateHeader.gameVersion = 0; + //gSaveStates[slot]->stateHeader.stateVersion = 0; + + memcpy(&gSystemHeap, &gSaveStates[slot]->sysHeapCopy, 1024 * 1024 * 4); + memcpy(&gSaveContext, &gSaveStates[slot]->saveContextCopy, sizeof(gSaveContext)); + memcpy(gGameInfo, &gSaveStates[slot]->gameInfoCopy, sizeof(*gGameInfo)); + //memcpy(&gAudioContext, &gSaveStates[slot]->audioContextCopy, sizeof(AudioContext)); + memcpy(&sLightsBuffer, &gSaveStates[slot]->lightBufferCopy, sizeof(sLightsBuffer)); + memcpy(&sMatrixStack, &gSaveStates[slot]->mtxStackCopy, sizeof(MtxF) * 20); + memcpy(&sCurrentMatrix, &gSaveStates[slot]->currentMtxCopy, sizeof(MtxF)); + //TODO RNG seed + + + return SaveStateReturn::SUCCESS; +} diff --git a/soh/soh/Enhancements/savestates.h b/soh/soh/Enhancements/savestates.h new file mode 100644 index 000000000..cfc9f6e31 --- /dev/null +++ b/soh/soh/Enhancements/savestates.h @@ -0,0 +1,60 @@ +#ifndef SAVE_STATES_H +#define SAVE_STATES_H +#include "z64.h" +#include "z64save.h" + +#include +#include + +// FROM z_lights.c +// I didn't feel like moving it into a header file. +#define LIGHTS_BUFFER_SIZE 32 +//#define LIGHTS_BUFFER_SIZE 1024 // Kill me + +typedef struct { + /* 0x000 */ s32 numOccupied; + /* 0x004 */ s32 searchIndex; + /* 0x008 */ LightNode buf[LIGHTS_BUFFER_SIZE]; +} LightsBuffer; // size = 0x188 + + +enum class SaveStateReturn { + SUCCESS, + FAIL_INVALID_SLOT, + FAIL_NO_MEMORY, + FAIL_STATE_EMPTY, +}; + +typedef struct SaveStateHeader { + uint32_t stateVersion; + uint32_t gameVersion; +} SaveStateHeader; + +class SaveState { + public: + SaveState(); + ~SaveState() = delete; + SaveState& operator=(const SaveState& rhs) = delete; + SaveState(const SaveState& rhs) = delete; + + void Init(void); + static SaveStateReturn Save(unsigned int slot); + static SaveStateReturn Load(unsigned int slot); + + private: + static void WriteHeader(SaveStateHeader& header); + static void ReadHeader(SaveStateHeader& header); + SaveStateHeader stateHeader; + unsigned char sysHeapCopy[1024 * 1024 * 4]; //TODO, make a macro for this + SaveContext saveContextCopy; + GameInfo gameInfoCopy; + LightsBuffer lightBufferCopy; + //AudioContext audioContextCopy; + std::array mtxStackCopy; // always 20 matricies + MtxF currentMtxCopy; + uint32_t rngSeed; + + +}; + +#endif diff --git a/soh/soh/OTRGlobals.h b/soh/soh/OTRGlobals.h index 339613b25..a09dcf6ef 100644 --- a/soh/soh/OTRGlobals.h +++ b/soh/soh/OTRGlobals.h @@ -1,3 +1,6 @@ +#ifndef OTR_GLOBALS_H +#define OTR_GLOBALS_H + #pragma once #include "GlobalCtx2.h" @@ -68,3 +71,5 @@ void AudioPlayer_Play(const uint8_t* buf, uint32_t len); void AudioMgr_CreateNextAudioBuffer(s16* samples, u32 num_samples); int Controller_ShouldRumble(size_t i); #endif + +#endif \ No newline at end of file