mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2024-11-10 11:35:19 -05:00
3914781ebf
Co-authored-by: briaguya <briaguya> Co-authored-by: Christopher Leggett <chris@leggett.dev> Co-authored-by: David Chavez <davi@dcvz.io>
977 lines
40 KiB
C++
977 lines
40 KiB
C++
#include "savestates.h"
|
|
|
|
#include <GameVersions.h>
|
|
|
|
#include <cstdio> // std::sprintf
|
|
|
|
#include <spdlog/spdlog.h>
|
|
#include <spdlog/fmt/fmt.h>
|
|
|
|
#include <soh/OTRGlobals.h>
|
|
#include <soh/OTRAudio.h>
|
|
|
|
#include <ImGuiImpl.h>
|
|
|
|
#include "z64.h"
|
|
#include "z64save.h"
|
|
#include <variables.h>
|
|
#include <functions.h>
|
|
#include "z64map_mark.h"
|
|
#include "../../src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.h"
|
|
#include "../../src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.h"
|
|
#include "../../src/overlays/actors/ovl_Boss_Tw/z_boss_tw.h"
|
|
#include "../../src/overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.h"
|
|
#include "../../src/overlays/actors/ovl_En_Fr/z_en_fr.h"
|
|
|
|
extern "C" PlayState* gPlayState;
|
|
|
|
template <> struct fmt::formatter<RequestType> {
|
|
constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
|
|
|
|
template <typename FormatContext>
|
|
auto format(const RequestType& type, FormatContext& ctx) {
|
|
switch (type) {
|
|
case RequestType::SAVE: return fmt::format_to(ctx.out(), "Save");
|
|
case RequestType::LOAD: return fmt::format_to(ctx.out(), "Load");
|
|
default: return fmt::format_to(ctx.out(), "Unknown");
|
|
}
|
|
}
|
|
};
|
|
|
|
// FROM z_lights.c
|
|
// I didn't feel like moving it into a header file.
|
|
#define LIGHTS_BUFFER_SIZE 32
|
|
|
|
typedef struct {
|
|
/* 0x000 */ s32 numOccupied;
|
|
/* 0x004 */ s32 searchIndex;
|
|
/* 0x008 */ LightNode buf[LIGHTS_BUFFER_SIZE];
|
|
} LightsBuffer; // size = 0x188
|
|
|
|
#include "savestates_extern.inc"
|
|
|
|
typedef struct SaveStateInfo {
|
|
unsigned char sysHeapCopy[SYSTEM_HEAP_SIZE];
|
|
unsigned char audioHeapCopy[AUDIO_HEAP_SIZE];
|
|
|
|
SaveContext saveContextCopy;
|
|
GameInfo gameInfoCopy;
|
|
LightsBuffer lightBufferCopy;
|
|
AudioContext audioContextCopy;
|
|
MtxF mtxStackCopy[20]; // always 20 matricies
|
|
MtxF currentMtxCopy;
|
|
uint32_t rngSeed;
|
|
int16_t blueWarpTimerCopy; /* From door_warp_1 */
|
|
|
|
SeqScriptState seqScriptStateCopy[4];// Unrelocated
|
|
unk_D_8016E750 unk_D_8016E750Copy[4];
|
|
|
|
ActiveSound gActiveSoundsCopy[7][MAX_CHANNELS_PER_BANK];
|
|
uint8_t gSoundBankMutedCopy[7];
|
|
|
|
u8 D_801333F0_copy;
|
|
u8 gAudioSfxSwapOff_copy;
|
|
uint16_t gAudioSfxSwapSource_copy[10];
|
|
uint16_t gAudioSfxSwapTarget_copy[10];
|
|
uint8_t gAudioSfxSwapMode_copy[10];
|
|
void (*D_801755D0_copy)(void);
|
|
MapMarkData** sLoadedMarkDataTableCopy;
|
|
|
|
//Static Data
|
|
|
|
//Camera data
|
|
int32_t sInitRegs_copy;
|
|
int32_t gDbgCamEnabled_copy;
|
|
int32_t sDbgModeIdx_copy;
|
|
int16_t sNextUID_copy;
|
|
int32_t sCameraInterfaceFlags_copy;
|
|
int32_t sCameraInterfaceAlpha_copy;
|
|
int32_t sCameraShrinkWindowVal_copy;
|
|
int32_t D_8011D3AC_copy;
|
|
int32_t sDemo5PrevAction12Frame_copy;
|
|
int32_t sDemo5PrevSfxFrame_copy;
|
|
int32_t D_8011D3F0_copy;
|
|
OnePointCsFull D_8011D6AC_copy[3];
|
|
OnePointCsFull D_8011D724_copy[3];
|
|
OnePointCsFull D_8011D79C_copy[3];
|
|
OnePointCsFull D_8011D83C_copy[2];
|
|
OnePointCsFull D_8011D88C_copy[2];
|
|
OnePointCsFull D_8011D8DC_copy[3];
|
|
OnePointCsFull D_8011D954_copy[4];
|
|
OnePointCsFull D_8011D9F4_copy[3];
|
|
int16_t depthPhase_copy;
|
|
int16_t screenPlanePhase_copy;
|
|
int32_t sOOBTimer_copy;
|
|
f32 D_8015CE50_copy;
|
|
f32 D_8015CE54_copy;
|
|
CamColChk D_8015CE58_copy;
|
|
|
|
//Gameover
|
|
uint16_t gGameOverTimer_copy;
|
|
|
|
//One point demo
|
|
uint32_t sPrevFrameCs1100_copy;
|
|
CutsceneCameraPoint D_8012013C_copy[14];
|
|
CutsceneCameraPoint D_8012021C_copy[14];
|
|
CutsceneCameraPoint D_801204D4_copy[14];
|
|
CutsceneCameraPoint D_801205B4_copy[14];
|
|
OnePointCsFull D_801208EC_copy[3];
|
|
OnePointCsFull D_80120964_copy[2];
|
|
OnePointCsFull D_801209B4_copy[4];
|
|
OnePointCsFull D_80120ACC_copy[5];
|
|
OnePointCsFull D_80120B94_copy[11];
|
|
OnePointCsFull D_80120D4C_copy[7];
|
|
OnePointCsFull D_80120FA4_copy[6];
|
|
OnePointCsFull D_80121184_copy[2];
|
|
OnePointCsFull D_801211D4_copy[2];
|
|
OnePointCsFull D_8012133C_copy[3];
|
|
OnePointCsFull D_801213B4_copy[5];
|
|
OnePointCsFull D_8012151C_copy[2];
|
|
OnePointCsFull D_8012156C_copy[2];
|
|
OnePointCsFull D_801215BC_copy[1];
|
|
OnePointCsFull D_80121C24_copy[7];
|
|
OnePointCsFull D_80121D3C_copy[3];
|
|
OnePointCsFull D_80121F1C_copy[4];
|
|
OnePointCsFull D_80121FBC_copy[4];
|
|
OnePointCsFull D_801220D4_copy[5];
|
|
OnePointCsFull D_80122714_copy[4];
|
|
OnePointCsFull D_80122CB4_copy[2];
|
|
OnePointCsFull D_80122D04_copy[2];
|
|
OnePointCsFull D_80122E44_copy[2][7];
|
|
OnePointCsFull D_8012313C_copy[3];
|
|
OnePointCsFull D_801231B4_copy[4];
|
|
OnePointCsFull D_80123254_copy[2];
|
|
OnePointCsFull D_801232A4_copy[1];
|
|
OnePointCsFull D_80123894_copy[3];
|
|
OnePointCsFull D_8012390C_copy[2];
|
|
OnePointCsFull D_8012395C_copy[3];
|
|
OnePointCsFull D_801239D4_copy[3];
|
|
|
|
uint16_t gTimeIncrement_copy;
|
|
|
|
//Overlay static data
|
|
// z_bg_ddan_kd
|
|
Vec3f sBgDdanKdVelocity_copy;
|
|
Vec3f sBgDdanKdAccel_copy;
|
|
|
|
// z_bg_dodoago
|
|
s16 sBgDodoagoFirstExplosiveFlag_copy;
|
|
u8 sBgDodoagoDisableBombCatcher_copy;
|
|
s32 sBgDodoagoTimer_copy;
|
|
|
|
// z_bg_haka_trap
|
|
uint32_t D_80880F30_copy;
|
|
uint32_t D_80881014_copy;
|
|
|
|
// z_bg_hidan_rock
|
|
float D_8088BFC0_copy;
|
|
|
|
// z_bg_menkuri_eye
|
|
int32_t D_8089C1A0_copy;
|
|
|
|
// z_bg_mori_hineri
|
|
int16_t sBgMoriHineriNextCamIdx_copy;
|
|
|
|
// z_bg_po_event
|
|
uint8_t sBgPoEventBlocksAtRest_copy;
|
|
uint8_t sBgPoEventPuzzleState_copy;
|
|
float sBgPoEventblockPushDist_copy;
|
|
|
|
// z_bg_relay_objects
|
|
uint32_t D_808A9508_copy;
|
|
|
|
// z_bg_spot18_basket
|
|
int16_t D_808B85D0_copy;
|
|
|
|
// z_boss_ganon
|
|
uint32_t sBossGanonSeed1_copy;
|
|
uint32_t sBossGanonSeed2_copy;
|
|
uint32_t sBossGanonSeed3_copy;
|
|
void* sBossGanonGanondorf_copy;
|
|
void* sBossGanonZelda_copy;
|
|
void* sBossGanonCape_copy;
|
|
GanondorfEffect sBossGanonEffectBuf_copy[200];
|
|
|
|
// z_boss_ganon
|
|
uint32_t sBossGanonSeed1;
|
|
uint32_t sBossGanonSeed2;
|
|
uint32_t sBossGanonSeed3;
|
|
void* sBossGanonGanondorf;
|
|
void* sBossGanonZelda;
|
|
void* sBossGanonCape;
|
|
GanondorfEffect sBossGanonEffectBuf[200];
|
|
|
|
// z_boss_ganon2
|
|
Vec3f D_8090EB20_copy;
|
|
int8_t D_80910638_copy;
|
|
void* sBossGanon2Zelda_copy;
|
|
void* D_8090EB30_copy;
|
|
int32_t sBossGanon2Seed1_copy;
|
|
int32_t sBossGanon2Seed2_copy;
|
|
int32_t sBossGanon2Seed3_copy;
|
|
Vec3f D_809105D8_copy[4];
|
|
Vec3f D_80910608_copy[4];
|
|
BossGanon2Effect sBossGanon2Particles_copy[100];
|
|
|
|
// z_boss_tw
|
|
uint8_t sTwInitalized_copy;
|
|
BossTwEffect sTwEffects_copy[150];
|
|
|
|
// z_demo_6k
|
|
Vec3f sDemo6kVelocity_copy;
|
|
|
|
// z_demo_du
|
|
int32_t D_8096CE94_copy;
|
|
|
|
// z_demo_kekkai
|
|
Vec3f demoKekkaiVel_copy;
|
|
|
|
// z_en_bw
|
|
int32_t sSlugGroup_copy;
|
|
|
|
// z_en_clear_tag
|
|
uint8_t sClearTagIsEffectInitialized_copy;
|
|
EnClearTagEffect sClearTagEffects_copy[CLEAR_TAG_EFFECT_MAX_COUNT];
|
|
|
|
// z_en_fr
|
|
EnFrPointers sEnFrPointers_copy;
|
|
|
|
// z_en_goma
|
|
uint8_t sSpawnNum_copy;
|
|
|
|
// z_en_insect
|
|
float D_80A7DEB0_copy;
|
|
int16_t D_80A7DEB4_copy;
|
|
int16_t D_80A7DEB8_copy;
|
|
|
|
// z_en_ishi
|
|
int16_t sRockRotSpeedX_copy;
|
|
int16_t sRockRotSpeedY_copy;
|
|
|
|
// z_en_niw
|
|
int16_t D_80AB85E0_copy;
|
|
uint8_t sLowerRiverSpawned_copy;
|
|
uint8_t sUpperRiverSpawned_copy;
|
|
|
|
// z_en_po_field
|
|
int32_t sEnPoFieldNumSpawned_copy;
|
|
Vec3s sEnPoFieldSpawnPositions_copy[10];
|
|
u8 sEnPoFieldSpawnSwitchFlags_copy[10];
|
|
|
|
// z_en_takara_man
|
|
uint8_t sTakaraIsInitialized_copy;
|
|
|
|
// z_en_xc
|
|
int32_t D_80B41D90_copy;
|
|
int32_t sEnXcFlameSpawned_copy;
|
|
int32_t D_80B41DA8_copy;
|
|
int32_t D_80B41DAC_copy;
|
|
|
|
// z_en_zf
|
|
int16_t D_80B4A1B0_copy;
|
|
int16_t D_80B4A1B4_copy;
|
|
|
|
int32_t D_80B5A468_copy;
|
|
int32_t D_80B5A494_copy;
|
|
int32_t D_80B5A4BC_copy;
|
|
|
|
uint8_t sKankyoIsSpawned_copy;
|
|
int16_t sTrailingFairies_copy;
|
|
|
|
// z_en_heishi1
|
|
uint32_t sHeishi1PlayerIsCaughtCopy;
|
|
|
|
|
|
//Misc static data
|
|
// z_map_exp
|
|
|
|
s16 sPlayerInitialPosX_copy;
|
|
s16 sPlayerInitialPosZ_copy;
|
|
s16 sPlayerInitialDirection_copy;
|
|
|
|
// code_800E(something. fill me in later)
|
|
u8 sOcarinaInpEnabled_copy;
|
|
s8 D_80130F10_copy;
|
|
u8 sCurOcarinaBtnVal_copy;
|
|
u8 sPrevOcarinaNoteVal_copy;
|
|
u8 sCurOcarinaBtnIdx_copy;
|
|
u8 sLearnSongLastBtn_copy;
|
|
f32 D_80130F24_copy;
|
|
f32 D_80130F28_copy;
|
|
s8 D_80130F2C_copy;
|
|
s8 D_80130F30_copy;
|
|
s8 D_80130F34_copy;
|
|
u8 sDisplayedNoteValue_copy;
|
|
u8 sPlaybackState_copy;
|
|
u32 D_80130F3C_copy;
|
|
u32 sNotePlaybackTimer_copy;
|
|
u16 sPlaybackNotePos_copy;
|
|
u16 sStaffPlaybackPos_copy;
|
|
|
|
u32 sCurOcarinaBtnPress_copy;
|
|
u32 D_8016BA10_copy;
|
|
u32 sPrevOcarinaBtnPress_copy;
|
|
s32 D_8016BA18_copy;
|
|
s32 D_8016BA1C_copy;
|
|
u8 sCurOcarinaSong_copy[8];
|
|
u8 sOcarinaSongAppendPos_copy;
|
|
u8 sOcarinaHasStartedSong_copy;
|
|
u8 sOcarinaSongNoteStartIdx_copy;
|
|
u8 sOcarinaSongCnt_copy;
|
|
u16 sOcarinaAvailSongs_copy;
|
|
u8 sStaffPlayingPos_copy;
|
|
u16 sLearnSongPos_copy[0x10];
|
|
u16 D_8016BA50_copy[0x10];
|
|
u16 D_8016BA70_copy[0x10];
|
|
u8 sLearnSongExpectedNote_copy[0x10];
|
|
OcarinaNote D_8016BAA0_copy;
|
|
u8 sAudioHasMalonBgm_copy;
|
|
f32 sAudioMalonBgmDist_copy;
|
|
|
|
// Message_PAL
|
|
s16 sOcarinaNoteBufPos_copy;
|
|
s16 sOcarinaNoteBufLen_copy;
|
|
u8 sOcarinaNoteBuf_copy[12];
|
|
|
|
u8 D_8014B2F4_copy;
|
|
u8 sTextboxSkipped_copy;
|
|
u16 sNextTextId_copy;
|
|
s16 sLastPlayedSong_copy;
|
|
s16 sHasSunsSong_copy;
|
|
s16 sMessageHasSetSfx_copy;
|
|
u16 sOcarinaSongBitFlags_copy;
|
|
|
|
|
|
} SaveStateInfo;
|
|
|
|
class SaveState {
|
|
friend class SaveStateMgr;
|
|
|
|
public:
|
|
SaveState(std::shared_ptr<SaveStateMgr> mgr, unsigned int slot);
|
|
|
|
private:
|
|
unsigned int slot;
|
|
std::shared_ptr<SaveStateMgr> saveStateMgr;
|
|
std::shared_ptr<SaveStateInfo> info;
|
|
|
|
void Save(void);
|
|
void Load(void);
|
|
void BackupSeqScriptState(void);
|
|
void LoadSeqScriptState(void);
|
|
void BackupCameraData(void);
|
|
void LoadCameraData(void);
|
|
void SaveOnePointDemoData(void);
|
|
void LoadOnePointDemoData(void);
|
|
void SaveOverlayStaticData(void);
|
|
void LoadOverlayStaticData(void);
|
|
|
|
void SaveMiscCodeData(void);
|
|
void LoadMiscCodeData(void);
|
|
|
|
SaveStateInfo* GetSaveStateInfo(void);
|
|
};
|
|
|
|
SaveStateMgr::SaveStateMgr() {
|
|
this->SetCurrentSlot(0);
|
|
}
|
|
SaveStateMgr::~SaveStateMgr() {
|
|
this->states.clear();
|
|
}
|
|
|
|
SaveState::SaveState(std::shared_ptr<SaveStateMgr> mgr, unsigned int slot) : saveStateMgr(mgr), slot(slot), info(nullptr) {
|
|
this->info = std::make_shared<SaveStateInfo>();
|
|
}
|
|
|
|
void SaveState::BackupSeqScriptState(void) {
|
|
for (unsigned int i = 0; i < 4; i++) {
|
|
info->seqScriptStateCopy[i].value = gAudioContext.seqPlayers[i].scriptState.value;
|
|
|
|
info->seqScriptStateCopy[i].remLoopIters[0] = gAudioContext.seqPlayers[i].scriptState.remLoopIters[0];
|
|
info->seqScriptStateCopy[i].remLoopIters[1] = gAudioContext.seqPlayers[i].scriptState.remLoopIters[1];
|
|
info->seqScriptStateCopy[i].remLoopIters[2] = gAudioContext.seqPlayers[i].scriptState.remLoopIters[2];
|
|
info->seqScriptStateCopy[i].remLoopIters[3] = gAudioContext.seqPlayers[i].scriptState.remLoopIters[3];
|
|
|
|
info->seqScriptStateCopy[i].depth = gAudioContext.seqPlayers[i].scriptState.depth;
|
|
|
|
info->seqScriptStateCopy[i].pc = (u8*)((uintptr_t)gAudioContext.seqPlayers[i].scriptState.pc - (uintptr_t)gAudioHeap);
|
|
|
|
info->seqScriptStateCopy[i].stack[0] =
|
|
(u8*)((uintptr_t)gAudioContext.seqPlayers[i].scriptState.stack[0] - (uintptr_t)gAudioHeap);
|
|
info->seqScriptStateCopy[i].stack[1] =
|
|
(u8*)((uintptr_t)gAudioContext.seqPlayers[i].scriptState.stack[1] - (uintptr_t)gAudioHeap);
|
|
info->seqScriptStateCopy[i].stack[2] =
|
|
(u8*)((uintptr_t)gAudioContext.seqPlayers[i].scriptState.stack[2] - (uintptr_t)gAudioHeap);
|
|
info->seqScriptStateCopy[i].stack[3] =
|
|
(u8*)((uintptr_t)gAudioContext.seqPlayers[i].scriptState.stack[3] - (uintptr_t)gAudioHeap);
|
|
}
|
|
}
|
|
|
|
void SaveState::LoadSeqScriptState(void) {
|
|
for (unsigned int i = 0; i < 4; i++) {
|
|
gAudioContext.seqPlayers[i].scriptState.value = info->seqScriptStateCopy[i].value;
|
|
|
|
gAudioContext.seqPlayers[i].scriptState.remLoopIters[0] = info->seqScriptStateCopy[i].remLoopIters[0];
|
|
gAudioContext.seqPlayers[i].scriptState.remLoopIters[1] = info->seqScriptStateCopy[i].remLoopIters[1];
|
|
gAudioContext.seqPlayers[i].scriptState.remLoopIters[2] = info->seqScriptStateCopy[i].remLoopIters[2];
|
|
gAudioContext.seqPlayers[i].scriptState.remLoopIters[3] = info->seqScriptStateCopy[i].remLoopIters[3];
|
|
|
|
gAudioContext.seqPlayers[i].scriptState.depth = info->seqScriptStateCopy[i].depth;
|
|
|
|
gAudioContext.seqPlayers[i].scriptState.pc =
|
|
(u8*)((uintptr_t)info->seqScriptStateCopy[i].pc + (uintptr_t)gAudioHeap);
|
|
|
|
gAudioContext.seqPlayers[i].scriptState.stack[0] =
|
|
(u8*)((uintptr_t)info->seqScriptStateCopy[i].stack[0] + (uintptr_t)gAudioHeap);
|
|
gAudioContext.seqPlayers[i].scriptState.stack[1] =
|
|
(u8*)((uintptr_t)info->seqScriptStateCopy[i].stack[1] + (uintptr_t)gAudioHeap);
|
|
gAudioContext.seqPlayers[i].scriptState.stack[2] =
|
|
(u8*)((uintptr_t)info->seqScriptStateCopy[i].stack[2] + (uintptr_t)gAudioHeap);
|
|
gAudioContext.seqPlayers[i].scriptState.stack[3] =
|
|
(u8*)((uintptr_t)info->seqScriptStateCopy[i].stack[3] + (uintptr_t)gAudioHeap);
|
|
}
|
|
}
|
|
|
|
void SaveState::BackupCameraData(void) {
|
|
info->sInitRegs_copy = sInitRegs;
|
|
info->gDbgCamEnabled_copy = gDbgCamEnabled;
|
|
info->sNextUID_copy = sNextUID;
|
|
info->sCameraInterfaceFlags_copy = sCameraInterfaceFlags;
|
|
info->sCameraInterfaceAlpha_copy = sCameraInterfaceAlpha;
|
|
info->sCameraShrinkWindowVal_copy = sCameraShrinkWindowVal;
|
|
info->D_8011D3AC_copy = D_8011D3AC;
|
|
info->sDemo5PrevAction12Frame_copy = sDemo5PrevAction12Frame;
|
|
info->sDemo5PrevSfxFrame_copy = sDemo5PrevSfxFrame;
|
|
info->D_8011D3F0_copy = D_8011D3F0;
|
|
memcpy(info->D_8011D6AC_copy, D_8011D6AC, sizeof(info->D_8011D6AC_copy));
|
|
memcpy(info->D_8011D724_copy, D_8011D724, sizeof(info->D_8011D724_copy));
|
|
memcpy(info->D_8011D79C_copy, D_8011D79C, sizeof(info->D_8011D79C_copy));
|
|
memcpy(info->D_8011D83C_copy, D_8011D83C, sizeof(info->D_8011D83C_copy));
|
|
memcpy(info->D_8011D88C_copy, D_8011D88C, sizeof(info->D_8011D88C_copy));
|
|
memcpy(info->D_8011D8DC_copy, D_8011D8DC, sizeof(info->D_8011D8DC_copy));
|
|
memcpy(info->D_8011D954_copy, D_8011D954, sizeof(info->D_8011D954_copy));
|
|
memcpy(info->D_8011D9F4_copy, D_8011D9F4, sizeof(info->D_8011D9F4_copy));
|
|
info->depthPhase_copy = depthPhase;
|
|
info->screenPlanePhase_copy = screenPlanePhase;
|
|
info->sOOBTimer_copy = sOOBTimer;
|
|
info->D_8015CE50_copy = D_8015CE50;
|
|
info->D_8015CE54_copy = D_8015CE54;
|
|
memcpy(&info->D_8015CE58_copy, &D_8015CE58, sizeof(info->D_8015CE58_copy));
|
|
}
|
|
|
|
void SaveState::LoadCameraData(void) {
|
|
sInitRegs = info->sInitRegs_copy;
|
|
gDbgCamEnabled = info->gDbgCamEnabled_copy;
|
|
sDbgModeIdx = info->sDbgModeIdx_copy;
|
|
sNextUID = info->sNextUID_copy;
|
|
sCameraInterfaceAlpha = info->sCameraInterfaceAlpha_copy;
|
|
sCameraInterfaceFlags = info->sCameraInterfaceFlags_copy;
|
|
sCameraShrinkWindowVal = info->sCameraShrinkWindowVal_copy;
|
|
D_8011D3AC = info->D_8011D3AC_copy;
|
|
sDemo5PrevAction12Frame = info->sDemo5PrevAction12Frame_copy;
|
|
sDemo5PrevSfxFrame = info->sDemo5PrevSfxFrame_copy;
|
|
D_8011D3F0 = info->D_8011D3F0_copy;
|
|
memcpy(D_8011D6AC, info->D_8011D6AC_copy, sizeof(info->D_8011D6AC_copy));
|
|
memcpy(D_8011D724, info->D_8011D724_copy, sizeof(info->D_8011D724_copy));
|
|
memcpy(D_8011D79C, info->D_8011D79C_copy, sizeof(info->D_8011D79C_copy));
|
|
memcpy(D_8011D83C, info->D_8011D83C_copy, sizeof(info->D_8011D83C_copy));
|
|
memcpy(D_8011D88C, info->D_8011D88C_copy, sizeof(info->D_8011D88C_copy));
|
|
memcpy(D_8011D8DC, info->D_8011D8DC_copy, sizeof(info->D_8011D8DC_copy));
|
|
memcpy(D_8011D954, info->D_8011D954_copy, sizeof(info->D_8011D954_copy));
|
|
memcpy(D_8011D9F4, info->D_8011D9F4_copy, sizeof(info->D_8011D9F4_copy));
|
|
depthPhase = info->depthPhase_copy;
|
|
screenPlanePhase = info->screenPlanePhase_copy;
|
|
sOOBTimer = info->sOOBTimer_copy;
|
|
D_8015CE50 = info->D_8015CE50_copy;
|
|
D_8015CE54 = info->D_8015CE54_copy;
|
|
memcpy(&D_8015CE58, &info->D_8015CE58_copy, sizeof(info->D_8015CE58_copy));
|
|
}
|
|
|
|
void SaveState::SaveOnePointDemoData(void) {
|
|
info->sPrevFrameCs1100_copy = sPrevFrameCs1100;
|
|
memcpy(info->D_8012013C_copy, D_8012013C, sizeof(info->D_8012013C_copy));
|
|
memcpy(info->D_8012021C_copy, D_8012021C, sizeof(info->D_8012021C_copy));
|
|
memcpy(info->D_801204D4_copy, D_801204D4, sizeof(info->D_801204D4_copy));
|
|
memcpy(info->D_801205B4_copy, D_801205B4, sizeof(info->D_801205B4_copy));
|
|
memcpy(info->D_801208EC_copy, D_801208EC, sizeof(info->D_801208EC_copy));
|
|
memcpy(info->D_80120964_copy, D_80120964, sizeof(info->D_80120964_copy));
|
|
memcpy(info->D_801209B4_copy, D_801209B4, sizeof(info->D_801209B4_copy));
|
|
memcpy(info->D_80120ACC_copy, D_80120ACC, sizeof(info->D_80120ACC_copy));
|
|
memcpy(info->D_80120B94_copy, D_80120B94, sizeof(info->D_80120B94_copy));
|
|
memcpy(info->D_80120D4C_copy, D_80120D4C, sizeof(info->D_80120D4C_copy));
|
|
memcpy(info->D_80120FA4_copy, D_80120FA4, sizeof(info->D_80120FA4_copy));
|
|
memcpy(info->D_80121184_copy, D_80121184, sizeof(info->D_80121184_copy));
|
|
memcpy(info->D_801211D4_copy, D_801211D4, sizeof(info->D_801211D4_copy));
|
|
memcpy(info->D_8012133C_copy, D_8012133C, sizeof(info->D_8012133C_copy));
|
|
memcpy(info->D_801213B4_copy, D_801213B4, sizeof(info->D_801213B4_copy));
|
|
memcpy(info->D_8012151C_copy, D_8012151C, sizeof(info->D_8012151C_copy));
|
|
memcpy(info->D_8012156C_copy, D_8012156C, sizeof(info->D_8012156C_copy));
|
|
memcpy(info->D_801215BC_copy, D_801215BC, sizeof(info->D_801215BC_copy));
|
|
memcpy(info->D_80121C24_copy, D_80121C24, sizeof(info->D_80121C24_copy));
|
|
memcpy(info->D_80121D3C_copy, D_80121D3C, sizeof(info->D_80121D3C_copy));
|
|
memcpy(info->D_80121F1C_copy, D_80121F1C, sizeof(info->D_80121F1C_copy));
|
|
memcpy(info->D_80121FBC_copy, D_80121FBC, sizeof(info->D_80121FBC_copy));
|
|
memcpy(info->D_801220D4_copy, D_801220D4, sizeof(info->D_801220D4_copy));
|
|
memcpy(info->D_80122714_copy, D_80122714, sizeof(info->D_80122714_copy));
|
|
memcpy(info->D_80122CB4_copy, D_80122CB4, sizeof(info->D_80122CB4_copy));
|
|
memcpy(info->D_80122D04_copy, D_80122D04, sizeof(info->D_80122D04_copy));
|
|
memcpy(info->D_80122E44_copy, D_80122E44, sizeof(info->D_80122E44_copy));
|
|
memcpy(info->D_8012313C_copy, D_8012313C, sizeof(info->D_8012313C_copy));
|
|
memcpy(info->D_801231B4_copy, D_801231B4, sizeof(info->D_801231B4_copy));
|
|
memcpy(info->D_80123254_copy, D_80123254, sizeof(info->D_80123254_copy));
|
|
memcpy(info->D_801232A4_copy, D_801232A4, sizeof(info->D_801232A4_copy));
|
|
memcpy(info->D_80123894_copy, D_80123894, sizeof(info->D_80123894_copy));
|
|
memcpy(info->D_8012390C_copy, D_8012390C, sizeof(info->D_8012390C_copy));
|
|
memcpy(info->D_8012395C_copy, D_8012395C, sizeof(info->D_8012395C_copy));
|
|
memcpy(info->D_801239D4_copy, D_801239D4, sizeof(info->D_801239D4_copy));
|
|
}
|
|
|
|
void SaveState::LoadOnePointDemoData(void) {
|
|
sPrevFrameCs1100 = info->sPrevFrameCs1100_copy;
|
|
memcpy(D_8012013C, info->D_8012013C_copy, sizeof(info->D_8012013C_copy));
|
|
memcpy(D_8012021C, info->D_8012021C_copy, sizeof(info->D_8012021C_copy));
|
|
memcpy(D_801204D4, info->D_801204D4_copy, sizeof(info->D_801204D4_copy));
|
|
memcpy(D_801205B4, info->D_801205B4_copy, sizeof(info->D_801205B4_copy));
|
|
memcpy(D_801208EC, info->D_801208EC_copy, sizeof(info->D_801208EC_copy));
|
|
memcpy(D_80120964, info->D_80120964_copy, sizeof(info->D_80120964_copy));
|
|
memcpy(D_801209B4, info->D_801209B4_copy, sizeof(info->D_801209B4_copy));
|
|
memcpy(D_80120ACC, info->D_80120ACC_copy, sizeof(info->D_80120ACC_copy));
|
|
memcpy(D_80120B94, info->D_80120B94_copy, sizeof(info->D_80120B94_copy));
|
|
memcpy(D_80120D4C, info->D_80120D4C_copy, sizeof(info->D_80120D4C_copy));
|
|
memcpy(D_80120FA4, info->D_80120FA4_copy, sizeof(info->D_80120FA4_copy));
|
|
memcpy(D_80121184, info->D_80121184_copy, sizeof(info->D_80121184_copy));
|
|
memcpy(D_801211D4, info->D_801211D4_copy, sizeof(info->D_801211D4_copy));
|
|
memcpy(D_8012133C, info->D_8012133C_copy, sizeof(info->D_8012133C_copy));
|
|
memcpy(D_801213B4, info->D_801213B4_copy, sizeof(info->D_801213B4_copy));
|
|
memcpy(D_8012151C, info->D_8012151C_copy, sizeof(info->D_8012151C_copy));
|
|
memcpy(D_8012156C, info->D_8012156C_copy, sizeof(info->D_8012156C_copy));
|
|
memcpy(D_801215BC, info->D_801215BC_copy, sizeof(info->D_801215BC_copy));
|
|
memcpy(D_80121C24, info->D_80121C24_copy, sizeof(info->D_80121C24_copy));
|
|
memcpy(D_80121D3C, info->D_80121D3C_copy, sizeof(info->D_80121D3C_copy));
|
|
memcpy(D_80121F1C, info->D_80121F1C_copy, sizeof(info->D_80121F1C_copy));
|
|
memcpy(D_80121FBC, info->D_80121FBC_copy, sizeof(info->D_80121FBC_copy));
|
|
memcpy(D_801220D4, info->D_801220D4_copy, sizeof(info->D_801220D4_copy));
|
|
memcpy(D_80122714, info->D_80122714_copy, sizeof(info->D_80122714_copy));
|
|
memcpy(D_80122CB4, info->D_80122CB4_copy, sizeof(info->D_80122CB4_copy));
|
|
memcpy(D_80122D04, info->D_80122D04_copy, sizeof(info->D_80122D04_copy));
|
|
memcpy(D_80122E44, info->D_80122E44_copy, sizeof(info->D_80122E44_copy));
|
|
memcpy(D_8012313C, info->D_8012313C_copy, sizeof(info->D_8012313C_copy));
|
|
memcpy(D_801231B4, info->D_801231B4_copy, sizeof(info->D_801231B4_copy));
|
|
memcpy(D_80123254, info->D_80123254_copy, sizeof(info->D_80123254_copy));
|
|
memcpy(D_801232A4, info->D_801232A4_copy, sizeof(info->D_801232A4_copy));
|
|
memcpy(D_80123894, info->D_80123894_copy, sizeof(info->D_80123894_copy));
|
|
memcpy(D_8012390C, info->D_8012390C_copy, sizeof(info->D_8012390C_copy));
|
|
memcpy(D_8012395C, info->D_8012395C_copy, sizeof(info->D_8012395C_copy));
|
|
memcpy(D_801239D4, info->D_801239D4_copy, sizeof(info->D_801239D4_copy));
|
|
}
|
|
|
|
void SaveState::SaveOverlayStaticData(void) {
|
|
info->sBgDdanKdVelocity_copy = sBgDdanKdVelocity;
|
|
info->sBgDdanKdAccel_copy = sBgDdanKdAccel;
|
|
info->sBgDodoagoFirstExplosiveFlag_copy = sBgDodoagoFirstExplosiveFlag;
|
|
info->sBgDodoagoDisableBombCatcher_copy = sBgDodoagoDisableBombCatcher;
|
|
info->sBgDodoagoTimer_copy = sBgDodoagoTimer;
|
|
info->D_80880F30_copy = D_80880F30;
|
|
info->D_80881014_copy = D_80881014;
|
|
info->D_8088BFC0_copy = D_8088BFC0;
|
|
info->sBgMoriHineriNextCamIdx_copy = sBgMoriHineriNextCamIdx;
|
|
info->sBgPoEventBlocksAtRest_copy = sBgPoEventBlocksAtRest;
|
|
info->sBgPoEventPuzzleState_copy = sBgPoEventPuzzleState;
|
|
info->sBgPoEventblockPushDist_copy = sBgPoEventblockPushDist;
|
|
info->D_808A9508_copy = D_808A9508;
|
|
info->D_808B85D0_copy = D_808B85D0;
|
|
info->sBossGanonSeed1_copy = sBossGanonSeed1;
|
|
info->sBossGanonSeed2_copy = sBossGanonSeed2;
|
|
info->sBossGanonSeed3_copy = sBossGanonSeed3;
|
|
info->sBossGanonGanondorf_copy = sBossGanonGanondorf;
|
|
info->sBossGanonZelda_copy = sBossGanonZelda;
|
|
info->sBossGanonCape_copy = sBossGanonCape;
|
|
memcpy(info->sBossGanonEffectBuf_copy, sBossGanonEffectBuf, sizeof(info->sBossGanonEffectBuf_copy));
|
|
info->D_8090EB20_copy = D_8090EB20;
|
|
info->D_80910638_copy = D_80910638;
|
|
info->sBossGanon2Zelda_copy = sBossGanon2Zelda;
|
|
info->D_8090EB30_copy = D_8090EB30;
|
|
info->sBossGanon2Seed1_copy = sBossGanon2Seed1;
|
|
info->sBossGanon2Seed2_copy = sBossGanon2Seed2;
|
|
info->sBossGanon2Seed3_copy = sBossGanon2Seed3;
|
|
memcpy(info->D_809105D8_copy, D_809105D8, sizeof(D_809105D8));
|
|
memcpy(info->D_80910608_copy, D_80910608, sizeof(D_80910608));
|
|
memcpy(info->sBossGanon2Particles_copy, sBossGanon2Particles, sizeof(sBossGanon2Particles));
|
|
info->sTwInitalized_copy = sTwInitalized;
|
|
memcpy(info->sTwEffects_copy, sTwEffects, sizeof(sTwEffects));
|
|
info->sDemo6kVelocity_copy = sDemo6kVelocity;
|
|
info->D_8096CE94_copy = D_8096CE94;
|
|
info->demoKekkaiVel_copy = demoKekkaiVel;
|
|
info->sSlugGroup_copy = sSlugGroup;
|
|
info->sClearTagIsEffectInitialized_copy = sClearTagIsEffectsInitialized;
|
|
memcpy(info->sClearTagEffects_copy, sClearTagEffects, sizeof(sClearTagEffects));
|
|
|
|
memcpy(&info->sEnFrPointers_copy, &sEnFrPointers, sizeof(info->sEnFrPointers_copy));
|
|
info->sSpawnNum_copy = sSpawnNum;
|
|
|
|
info->D_80A7DEB0_copy = D_80A7DEB0;
|
|
info->D_80A7DEB4_copy = D_80A7DEB4;
|
|
info->D_80A7DEB8_copy = D_80A7DEB8;
|
|
info->sRockRotSpeedX_copy = sRockRotSpeedX;
|
|
info->sRockRotSpeedY_copy = sRockRotSpeedY;
|
|
info->D_80AB85E0_copy = D_80AB85E0;
|
|
info->sLowerRiverSpawned_copy = sLowerRiverSpawned;
|
|
info->sUpperRiverSpawned_copy = sUpperRiverSpawned;
|
|
info->sEnPoFieldNumSpawned_copy = sEnPoFieldNumSpawned;
|
|
memcpy(info->sEnPoFieldSpawnPositions_copy, sEnPoFieldSpawnPositions, sizeof(info->sEnPoFieldSpawnPositions_copy));
|
|
memcpy(info->sEnPoFieldSpawnSwitchFlags_copy, sEnPoFieldSpawnSwitchFlags, sizeof(info->sEnPoFieldSpawnSwitchFlags_copy));
|
|
|
|
info->sTakaraIsInitialized_copy = sTakaraIsInitialized;
|
|
info->D_80B41D90_copy = D_80B41D90;
|
|
info->sEnXcFlameSpawned_copy = sEnXcFlameSpawned;
|
|
info->D_80B41DA8_copy = D_80B41DA8;
|
|
info->D_80B41DAC_copy = D_80B41DAC;
|
|
info->D_80B4A1B0_copy = D_80B4A1B0;
|
|
info->D_80B4A1B4_copy = D_80B4A1B4;
|
|
info->D_80B5A468_copy = D_80B5A468;
|
|
info->D_80B5A494_copy = D_80B5A494;
|
|
info->D_80B5A4BC_copy = D_80B5A4BC;
|
|
info->sKankyoIsSpawned_copy = sKankyoIsSpawned;
|
|
info->sTrailingFairies_copy = sTrailingFairies;
|
|
|
|
info->sHeishi1PlayerIsCaughtCopy = sHeishi1PlayerIsCaught;
|
|
|
|
}
|
|
|
|
void SaveState::LoadOverlayStaticData(void) {
|
|
sBgDdanKdVelocity = info->sBgDdanKdVelocity_copy;
|
|
sBgDdanKdAccel = info->sBgDdanKdAccel_copy;
|
|
sBgDodoagoFirstExplosiveFlag = info->sBgDodoagoFirstExplosiveFlag_copy;
|
|
sBgDodoagoDisableBombCatcher = info->sBgDodoagoDisableBombCatcher_copy;
|
|
sBgDodoagoTimer = info->sBgDodoagoTimer_copy;
|
|
D_80880F30 = info->D_80880F30_copy;
|
|
D_80881014 = info->D_80881014_copy;
|
|
D_8088BFC0 = info->D_8088BFC0_copy;
|
|
sBgMoriHineriNextCamIdx = info->sBgMoriHineriNextCamIdx_copy;
|
|
sBgPoEventBlocksAtRest = info->sBgPoEventBlocksAtRest_copy;
|
|
sBgPoEventPuzzleState = info->sBgPoEventPuzzleState_copy;
|
|
sBgPoEventblockPushDist = info->sBgPoEventblockPushDist_copy;
|
|
D_808A9508 = info->D_808A9508_copy;
|
|
D_808B85D0 = info->D_808B85D0_copy;
|
|
sBossGanonSeed1 = info->sBossGanonSeed1_copy;
|
|
sBossGanonSeed2 = info->sBossGanonSeed2_copy;
|
|
sBossGanonSeed3 = info->sBossGanonSeed3_copy;
|
|
sBossGanonGanondorf = info->sBossGanonGanondorf_copy;
|
|
sBossGanonZelda = info->sBossGanonZelda_copy;
|
|
sBossGanonCape = info->sBossGanonCape_copy;
|
|
memcpy(sBossGanonEffectBuf, info->sBossGanonEffectBuf_copy, sizeof(info->sBossGanonEffectBuf_copy));
|
|
|
|
D_8090EB20 = info->D_8090EB20_copy;
|
|
D_80910638 = info->D_80910638_copy;
|
|
sBossGanon2Zelda = info->sBossGanon2Zelda_copy;
|
|
D_8090EB30 = info->D_8090EB30_copy;
|
|
sBossGanon2Seed1 = info->sBossGanon2Seed1_copy;
|
|
sBossGanon2Seed2 = info->sBossGanon2Seed2_copy;
|
|
sBossGanon2Seed3 = info->sBossGanon2Seed3_copy;
|
|
memcpy(D_809105D8, info->D_809105D8_copy, sizeof(D_809105D8));
|
|
memcpy(D_80910608, info->D_80910608_copy, sizeof(D_80910608));
|
|
memcpy(sBossGanon2Particles, info->sBossGanon2Particles_copy, sizeof(sBossGanon2Particles));
|
|
sTwInitalized = info->sTwInitalized_copy;
|
|
memcpy(sTwEffects, info->sTwEffects_copy, sizeof(sTwEffects));
|
|
sDemo6kVelocity = info->sDemo6kVelocity_copy;
|
|
|
|
D_8096CE94 = info->D_8096CE94_copy;
|
|
demoKekkaiVel = info->demoKekkaiVel_copy;
|
|
sSlugGroup = info->sSlugGroup_copy;
|
|
sClearTagIsEffectsInitialized = info->sClearTagIsEffectInitialized_copy;
|
|
memcpy(sClearTagEffects, info->sClearTagEffects_copy, sizeof(sClearTagEffects));
|
|
|
|
D_80A7DEB0 = info->D_80A7DEB0_copy;
|
|
D_80A7DEB4 = info->D_80A7DEB4_copy;
|
|
D_80A7DEB8 = info->D_80A7DEB8_copy;
|
|
sRockRotSpeedX = info->sRockRotSpeedX_copy;
|
|
sRockRotSpeedY = info->sRockRotSpeedY_copy;
|
|
D_80AB85E0 = info->D_80AB85E0_copy;
|
|
sLowerRiverSpawned = info->sLowerRiverSpawned_copy;
|
|
sUpperRiverSpawned = info->sUpperRiverSpawned_copy;
|
|
sEnPoFieldNumSpawned = info->sEnPoFieldNumSpawned_copy;
|
|
memcpy(sEnPoFieldSpawnPositions, info->sEnPoFieldSpawnPositions_copy, sizeof(info->sEnPoFieldSpawnPositions_copy));
|
|
memcpy(sEnPoFieldSpawnSwitchFlags, info->sEnPoFieldSpawnSwitchFlags_copy, sizeof(info->sEnPoFieldSpawnSwitchFlags_copy));
|
|
|
|
sTakaraIsInitialized = info->sTakaraIsInitialized_copy;
|
|
D_80B41D90 = info->D_80B41D90_copy;
|
|
sEnXcFlameSpawned = info->sEnXcFlameSpawned_copy;
|
|
D_80B41DA8 = info->D_80B41DA8_copy;
|
|
D_80B41DAC = info->D_80B41DAC_copy;
|
|
D_80B4A1B0 = info->D_80B4A1B0_copy;
|
|
D_80B4A1B4 = info->D_80B4A1B4_copy;
|
|
D_80B5A468 = info->D_80B5A468_copy;
|
|
D_80B5A494 = info->D_80B5A494_copy;
|
|
D_80B5A4BC = info->D_80B5A4BC_copy;
|
|
sKankyoIsSpawned = info->sKankyoIsSpawned_copy;
|
|
sTrailingFairies = info->sTrailingFairies_copy;
|
|
|
|
sHeishi1PlayerIsCaught = info->sHeishi1PlayerIsCaughtCopy;
|
|
}
|
|
|
|
void SaveState::SaveMiscCodeData(void) {
|
|
info->gGameOverTimer_copy = gGameOverTimer;
|
|
info->gTimeIncrement_copy = gTimeIncrement;
|
|
info->sLoadedMarkDataTableCopy = sLoadedMarkDataTable;
|
|
|
|
info->sPlayerInitialPosX_copy = sPlayerInitialPosX;
|
|
info->sPlayerInitialPosZ_copy = sPlayerInitialPosZ;
|
|
info->sPlayerInitialDirection_copy = sPlayerInitialDirection;
|
|
|
|
info->sOcarinaInpEnabled_copy = sOcarinaInpEnabled;
|
|
info->D_80130F10_copy = D_80130F10;
|
|
info->sCurOcarinaBtnVal_copy = sCurOcarinaBtnVal;
|
|
info->sPrevOcarinaNoteVal_copy = sPrevOcarinaNoteVal;
|
|
info->sCurOcarinaBtnIdx_copy = sCurOcarinaBtnIdx;
|
|
info->sLearnSongLastBtn_copy = sLearnSongLastBtn;
|
|
info->D_80130F24_copy = D_80130F24;
|
|
info->D_80130F28_copy = D_80130F28;
|
|
info->D_80130F2C_copy = D_80130F2C;
|
|
info->D_80130F30_copy = D_80130F30;
|
|
info->D_80130F34_copy = D_80130F34;
|
|
info->sPlaybackState_copy = sPlaybackState;
|
|
info->D_80130F3C_copy = D_80130F3C;
|
|
info->sNotePlaybackTimer_copy = sNotePlaybackTimer;
|
|
info->sPlaybackNotePos_copy = sPlaybackNotePos;
|
|
info->sStaffPlaybackPos_copy = sStaffPlaybackPos;
|
|
|
|
|
|
info->sCurOcarinaBtnPress_copy = sCurOcarinaBtnPress;
|
|
info->D_8016BA10_copy = D_8016BA10;
|
|
info->sPrevOcarinaBtnPress_copy = sPrevOcarinaBtnPress;
|
|
info->D_8016BA18_copy = D_8016BA18;
|
|
info->D_8016BA1C_copy = D_8016BA1C;
|
|
memcpy(info->sCurOcarinaSong_copy, sCurOcarinaSong, sizeof(sCurOcarinaSong));
|
|
info->sOcarinaSongAppendPos_copy = sOcarinaSongAppendPos;
|
|
info->sOcarinaHasStartedSong_copy = sOcarinaHasStartedSong;
|
|
info->sOcarinaSongNoteStartIdx_copy = sOcarinaSongNoteStartIdx;
|
|
info->sOcarinaSongCnt_copy = sOcarinaSongCnt;
|
|
info->sOcarinaAvailSongs_copy = sOcarinaAvailSongs;
|
|
info->sStaffPlayingPos_copy = sStaffPlayingPos;
|
|
memcpy(info->sLearnSongPos_copy, sLearnSongPos, sizeof(sLearnSongPos));
|
|
memcpy(info->D_8016BA50_copy, D_8016BA50, sizeof(D_8016BA50));
|
|
memcpy(info->D_8016BA70_copy, D_8016BA70, sizeof(D_8016BA70));
|
|
memcpy(info->sLearnSongExpectedNote_copy, sLearnSongExpectedNote, sizeof(sLearnSongExpectedNote));
|
|
memcpy(&info->D_8016BAA0_copy, &D_8016BAA0, sizeof(D_8016BAA0));
|
|
info->sAudioHasMalonBgm_copy = sAudioHasMalonBgm;
|
|
info->sAudioMalonBgmDist_copy = sAudioMalonBgmDist;
|
|
info->sDisplayedNoteValue_copy = sDisplayedNoteValue;
|
|
|
|
|
|
info->sOcarinaNoteBufPos_copy = sOcarinaNoteBufPos;
|
|
info->sOcarinaNoteBufLen_copy = sOcarinaNoteBufLen;
|
|
memcpy(info->sOcarinaNoteBuf_copy, sOcarinaNoteBuf, sizeof(sOcarinaNoteBuf));
|
|
info->D_8014B2F4_copy = D_8014B2F4;
|
|
info->sTextboxSkipped_copy = sTextboxSkipped;
|
|
info->sNextTextId_copy = sNextTextId;
|
|
info->sLastPlayedSong_copy = sLastPlayedSong;
|
|
info->sHasSunsSong_copy = sHasSunsSong;
|
|
info->sMessageHasSetSfx_copy = sMessageHasSetSfx;
|
|
info->sOcarinaSongBitFlags_copy = sOcarinaSongBitFlags;
|
|
}
|
|
|
|
void SaveState::LoadMiscCodeData(void) {
|
|
gGameOverTimer = info->gGameOverTimer_copy;
|
|
gTimeIncrement = info->gTimeIncrement_copy;
|
|
sLoadedMarkDataTable = info->sLoadedMarkDataTableCopy;
|
|
|
|
sPlayerInitialPosX = info->sPlayerInitialPosX_copy;
|
|
sPlayerInitialPosZ = info->sPlayerInitialPosZ_copy;
|
|
sPlayerInitialDirection = info->sPlayerInitialDirection_copy;
|
|
|
|
sOcarinaInpEnabled = info->sOcarinaInpEnabled_copy;
|
|
D_80130F10 = info->D_80130F10_copy;
|
|
sCurOcarinaBtnVal = info->sCurOcarinaBtnVal_copy;
|
|
sPrevOcarinaNoteVal = info->sPrevOcarinaNoteVal_copy;
|
|
sCurOcarinaBtnIdx = info->sCurOcarinaBtnIdx_copy;
|
|
sLearnSongLastBtn = info->sLearnSongLastBtn_copy;
|
|
D_80130F24 = info->D_80130F24_copy;
|
|
D_80130F28 = info->D_80130F28_copy;
|
|
D_80130F2C = info->D_80130F2C_copy;
|
|
D_80130F30 = info->D_80130F30_copy;
|
|
D_80130F34 = info->D_80130F34_copy;
|
|
sPlaybackState = info->sPlaybackState_copy;
|
|
D_80130F3C = info->D_80130F3C_copy;
|
|
sNotePlaybackTimer = info->sNotePlaybackTimer_copy;
|
|
sPlaybackNotePos = info->sPlaybackNotePos_copy;
|
|
sStaffPlaybackPos = info->sStaffPlaybackPos_copy;
|
|
|
|
sCurOcarinaBtnPress = info->sCurOcarinaBtnPress_copy;
|
|
D_8016BA10 = info->D_8016BA10_copy;
|
|
sPrevOcarinaBtnPress = info->sPrevOcarinaBtnPress_copy;
|
|
D_8016BA18 = info->D_8016BA18_copy;
|
|
D_8016BA1C = info->D_8016BA1C_copy;
|
|
memcpy(sCurOcarinaSong, info->sCurOcarinaSong_copy, sizeof(sCurOcarinaSong));
|
|
sOcarinaSongAppendPos = info->sOcarinaSongAppendPos_copy;
|
|
sOcarinaHasStartedSong = info->sOcarinaHasStartedSong_copy;
|
|
sOcarinaSongNoteStartIdx = info->sOcarinaSongNoteStartIdx_copy;
|
|
sOcarinaSongCnt = info->sOcarinaSongCnt_copy;
|
|
sOcarinaAvailSongs = info->sOcarinaAvailSongs_copy;
|
|
sStaffPlayingPos = info->sStaffPlayingPos_copy;
|
|
memcpy(info->sLearnSongPos_copy, info->sLearnSongPos_copy, sizeof(sLearnSongPos));
|
|
memcpy(info->D_8016BA50_copy, info->D_8016BA50_copy, sizeof(D_8016BA50));
|
|
memcpy(info->D_8016BA70_copy, info->D_8016BA70_copy, sizeof(D_8016BA70));
|
|
memcpy(info->sLearnSongExpectedNote_copy, info->sLearnSongExpectedNote_copy, sizeof(sLearnSongExpectedNote));
|
|
memcpy(&D_8016BAA0, &info->D_8016BAA0_copy, sizeof(D_8016BAA0));
|
|
sAudioHasMalonBgm = info->sAudioHasMalonBgm_copy;
|
|
sAudioMalonBgmDist = info->sAudioMalonBgmDist_copy;
|
|
sDisplayedNoteValue = info->sDisplayedNoteValue_copy;
|
|
|
|
sOcarinaNoteBufPos = info->sOcarinaNoteBufPos_copy;
|
|
sOcarinaNoteBufLen = info->sOcarinaNoteBufLen_copy;
|
|
memcpy(sOcarinaNoteBuf, info->sOcarinaNoteBuf_copy, sizeof(sOcarinaNoteBuf));
|
|
|
|
D_8014B2F4 = info->D_8014B2F4_copy;
|
|
sTextboxSkipped = info->sTextboxSkipped_copy;
|
|
sNextTextId = info->sNextTextId_copy;
|
|
sLastPlayedSong = info->sLastPlayedSong_copy;
|
|
sHasSunsSong = info->sHasSunsSong_copy;
|
|
sMessageHasSetSfx = info->sMessageHasSetSfx_copy;
|
|
sOcarinaSongBitFlags = info->sOcarinaSongBitFlags_copy;
|
|
|
|
|
|
}
|
|
|
|
extern "C" void ProcessSaveStateRequests(void) {
|
|
OTRGlobals::Instance->gSaveStateMgr->ProcessSaveStateRequests();
|
|
}
|
|
|
|
void SaveStateMgr::SetCurrentSlot(unsigned int slot) {
|
|
SohImGui::GetGameOverlay()->TextDrawNotification(1.0f, true, "slot %u set", slot);
|
|
this->currentSlot = slot;
|
|
}
|
|
|
|
unsigned int SaveStateMgr::GetCurrentSlot(void) {
|
|
return this->currentSlot;
|
|
}
|
|
|
|
void SaveStateMgr::ProcessSaveStateRequests(void) {
|
|
while (!this->requests.empty()) {
|
|
const auto& request = this->requests.front();
|
|
|
|
switch (request.type) {
|
|
case RequestType::SAVE:
|
|
if (!this->states.contains(request.slot)) {
|
|
this->states[request.slot] = std::make_shared<SaveState>(OTRGlobals::Instance->gSaveStateMgr, request.slot);
|
|
}
|
|
this->states[request.slot]->Save();
|
|
SohImGui::GetGameOverlay()->TextDrawNotification(1.0f, true, "saved state %u", request.slot);
|
|
break;
|
|
case RequestType::LOAD:
|
|
if (this->states.contains(request.slot)) {
|
|
this->states[request.slot]->Load();
|
|
SohImGui::GetGameOverlay()->TextDrawNotification(1.0f, true, "loaded state %u", request.slot);
|
|
} else {
|
|
SPDLOG_ERROR("Invalid SaveState slot: {}", request.type);
|
|
}
|
|
break;
|
|
[[unlikely]] default:
|
|
SPDLOG_ERROR("Invalid SaveState request type: {}", request.type);
|
|
break;
|
|
}
|
|
this->requests.pop();
|
|
}
|
|
}
|
|
|
|
SaveStateReturn SaveStateMgr::AddRequest(const SaveStateRequest request) {
|
|
if (gPlayState == nullptr) {
|
|
SPDLOG_ERROR("[SOH] Can not save or load a state outside of \"GamePlay\"");
|
|
SohImGui::GetGameOverlay()->TextDrawNotification(1.0f, true, "states not available here", request.slot);
|
|
return SaveStateReturn::FAIL_WRONG_GAMESTATE;
|
|
}
|
|
|
|
switch (request.type) {
|
|
case RequestType::SAVE:
|
|
requests.push(request);
|
|
return SaveStateReturn::SUCCESS;
|
|
case RequestType::LOAD:
|
|
if (states.contains(request.slot)) {
|
|
requests.push(request);
|
|
return SaveStateReturn::SUCCESS;
|
|
} else {
|
|
SPDLOG_ERROR("Invalid SaveState slot: {}", request.type);
|
|
SohImGui::GetGameOverlay()->TextDrawNotification(1.0f, true, "state slot %u empty", request.slot);
|
|
return SaveStateReturn::FAIL_INVALID_SLOT;
|
|
}
|
|
[[unlikely]] default:
|
|
SPDLOG_ERROR("Invalid SaveState request type: {}", request.type);
|
|
return SaveStateReturn::FAIL_BAD_REQUEST;
|
|
}
|
|
}
|
|
|
|
void SaveState::Save(void) {
|
|
std::unique_lock<std::mutex> Lock(audio.mutex);
|
|
memcpy(&info->sysHeapCopy, gSystemHeap, SYSTEM_HEAP_SIZE /* sizeof(gSystemHeap) */);
|
|
memcpy(&info->audioHeapCopy, gAudioHeap, AUDIO_HEAP_SIZE /* sizeof(gAudioContext) */);
|
|
|
|
memcpy(&info->audioContextCopy, &gAudioContext, sizeof(AudioContext));
|
|
memcpy(&info->unk_D_8016E750Copy, D_8016E750, sizeof(info->unk_D_8016E750Copy));
|
|
BackupSeqScriptState();
|
|
|
|
memcpy(info->gActiveSoundsCopy, gActiveSounds, sizeof(gActiveSounds));
|
|
memcpy(&info->gSoundBankMutedCopy, gSoundBankMuted, sizeof(info->gSoundBankMutedCopy));
|
|
|
|
info->D_801333F0_copy = D_801333F0;
|
|
info->gAudioSfxSwapOff_copy = gAudioSfxSwapOff;
|
|
|
|
memcpy(&info->gAudioSfxSwapSource_copy, gAudioSfxSwapSource,
|
|
sizeof(info->gAudioSfxSwapSource_copy));
|
|
memcpy(&info->gAudioSfxSwapTarget_copy, gAudioSfxSwapTarget,
|
|
sizeof(info->gAudioSfxSwapTarget_copy));
|
|
memcpy(&info->gAudioSfxSwapMode_copy, gAudioSfxSwapMode,
|
|
sizeof(info->gAudioSfxSwapMode_copy));
|
|
|
|
info->D_801755D0_copy = D_801755D0;
|
|
|
|
memcpy(&info->saveContextCopy, &gSaveContext, sizeof(gSaveContext));
|
|
memcpy(&info->gameInfoCopy, gGameInfo, sizeof(*gGameInfo));
|
|
memcpy(&info->lightBufferCopy, &sLightsBuffer, sizeof(sLightsBuffer));
|
|
memcpy(&info->mtxStackCopy, sMatrixStack, sizeof(MtxF) * 20);
|
|
memcpy(&info->currentMtxCopy, sCurrentMatrix, sizeof(MtxF));
|
|
|
|
//Various static data
|
|
info->blueWarpTimerCopy = sWarpTimerTarget;
|
|
BackupCameraData();
|
|
SaveOnePointDemoData();
|
|
SaveOverlayStaticData();
|
|
SaveMiscCodeData();
|
|
|
|
}
|
|
|
|
void SaveState::Load(void) {
|
|
std::unique_lock<std::mutex> Lock(audio.mutex);
|
|
memcpy(gSystemHeap, &info->sysHeapCopy, SYSTEM_HEAP_SIZE);
|
|
memcpy(gAudioHeap, &info->audioHeapCopy, AUDIO_HEAP_SIZE);
|
|
|
|
memcpy(&gAudioContext, &info->audioContextCopy, sizeof(AudioContext));
|
|
memcpy(D_8016E750, &info->unk_D_8016E750Copy, sizeof(info->unk_D_8016E750Copy));
|
|
LoadSeqScriptState();
|
|
|
|
memcpy(&gSaveContext, &info->saveContextCopy, sizeof(gSaveContext));
|
|
memcpy(gGameInfo, &info->gameInfoCopy, sizeof(*gGameInfo));
|
|
memcpy(&sLightsBuffer, &info->lightBufferCopy, sizeof(sLightsBuffer));
|
|
memcpy(sMatrixStack, &info->mtxStackCopy, sizeof(MtxF) * 20);
|
|
memcpy(sCurrentMatrix, &info->currentMtxCopy, sizeof(MtxF));
|
|
sWarpTimerTarget = info->blueWarpTimerCopy;
|
|
|
|
memcpy(gActiveSounds, info->gActiveSoundsCopy, sizeof(gActiveSounds));
|
|
memcpy(gSoundBankMuted, &info->gSoundBankMutedCopy, sizeof(info->gSoundBankMutedCopy));
|
|
D_801333F0 = info->D_801333F0_copy;
|
|
gAudioSfxSwapOff = info->gAudioSfxSwapOff_copy;
|
|
|
|
memcpy(gAudioSfxSwapSource, &info->gAudioSfxSwapSource_copy,
|
|
sizeof(info->gAudioSfxSwapSource_copy));
|
|
memcpy(gAudioSfxSwapTarget, &info->gAudioSfxSwapTarget_copy,
|
|
sizeof(info->gAudioSfxSwapTarget_copy));
|
|
memcpy(gAudioSfxSwapMode, &info->gAudioSfxSwapMode_copy,
|
|
sizeof(info->gAudioSfxSwapMode_copy));
|
|
|
|
//Various static data
|
|
D_801755D0 = info->D_801755D0_copy;
|
|
LoadCameraData();
|
|
LoadOnePointDemoData();
|
|
LoadOverlayStaticData();
|
|
LoadMiscCodeData();
|
|
|
|
}
|