Versioned saves (#423)

* v1

* Cleanup

* Cleanup

* cleanup

* Organization

* Fixes

* Fix typos

* fixup merge

* use gLanguages

* Restore n64dd

* Fix bad merge

* Set ddflag
This commit is contained in:
Rozelette 2022-06-20 12:41:43 -05:00 committed by GitHub
parent 73ff7ef3da
commit b4eebbbcd6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 23579 additions and 892 deletions

View File

@ -1322,18 +1322,9 @@ void SkinMatrix_SetTranslateRotateZYX(MtxF* dest, s16 rotX, s16 rotY, s16 rotZ,
f32 translateZ); f32 translateZ);
Mtx* SkinMatrix_MtxFToNewMtx(GraphicsContext* gfxCtx, MtxF* src); Mtx* SkinMatrix_MtxFToNewMtx(GraphicsContext* gfxCtx, MtxF* src);
void SkinMatrix_SetRotateAxis(MtxF* mf, s16 angle, f32 axisX, f32 axisY, f32 axisZ); void SkinMatrix_SetRotateAxis(MtxF* mf, s16 angle, f32 axisX, f32 axisY, f32 axisZ);
void Sram_InitNewSave(void); void Sram_OpenSave();
void Sram_InitDebugSave(void); void Sram_InitSave(FileChooseContext* fileChoose);
void Sram_OpenSave(SramContext* sramCtx); void Sram_InitSram(GameState* gameState);
void Sram_WriteSave(SramContext* sramCtx);
void Sram_VerifyAndLoadAllSaves(FileChooseContext* fileChoose, SramContext* sramCtx);
void Sram_InitSave(FileChooseContext* fileChoose, SramContext* sramCtx);
void Sram_EraseSave(FileChooseContext* fileChoose, SramContext* sramCtx);
void Sram_CopySave(FileChooseContext* fileChoose, SramContext* sramCtx);
void Sram_WriteSramHeader(SramContext* sramCtx);
void Sram_InitSram(GameState* gameState, SramContext* sramCtx);
void Sram_Alloc(GameState* gameState, SramContext* sramCtx);
void Sram_Init(GlobalContext* globalCtx, SramContext* sramCtx);
void SsSram_ReadWrite(uintptr_t addr, void* dramAddr, size_t size, s32 direction); void SsSram_ReadWrite(uintptr_t addr, void* dramAddr, size_t size, s32 direction);
void func_800A9F30(PadMgr*, s32); void func_800A9F30(PadMgr*, s32);
void func_800A9F6C(f32, u8, u8, u8); void func_800A9F6C(f32, u8, u8, u8);

View File

@ -1072,10 +1072,6 @@ typedef struct {
/* 0x01 */ u8 room; /* 0x01 */ u8 room;
} EntranceEntry; } EntranceEntry;
typedef struct {
/* 0x00 */ u8* readBuff;
} SramContext; // size = 0x4
#define SRAM_SIZE 0x8000 #define SRAM_SIZE 0x8000
#define SRAM_HEADER_SIZE 0x10 #define SRAM_HEADER_SIZE 0x10
@ -1120,7 +1116,6 @@ typedef struct {
/* 0x0000 */ GameState state; /* 0x0000 */ GameState state;
/* 0x00A4 */ u8* staticSegment; /* 0x00A4 */ u8* staticSegment;
/* 0x00A8 */ View view; /* 0x00A8 */ View view;
/* 0x01D0 */ SramContext sramCtx;
/* 0x01D4 */ u16 unk_1D4; // not used in mq dbg (some sort of timer that doesn't seem to affect anything) /* 0x01D4 */ u16 unk_1D4; // not used in mq dbg (some sort of timer that doesn't seem to affect anything)
/* 0x01D6 */ s16 coverAlpha; /* 0x01D6 */ s16 coverAlpha;
/* 0x01D8 */ s16 addAlpha; // not used in mq dbg /* 0x01D8 */ s16 addAlpha; // not used in mq dbg
@ -1206,7 +1201,6 @@ typedef struct GlobalContext {
/* 0x01C24 */ ActorContext actorCtx; /* 0x01C24 */ ActorContext actorCtx;
/* 0x01D64 */ CutsceneContext csCtx; // "demo_play" /* 0x01D64 */ CutsceneContext csCtx; // "demo_play"
/* 0x01DB4 */ SoundSource soundSources[16]; /* 0x01DB4 */ SoundSource soundSources[16];
/* 0x01F74 */ SramContext sramCtx;
/* 0x01F78 */ SkyboxContext skyboxCtx; /* 0x01F78 */ SkyboxContext skyboxCtx;
/* 0x020D8 */ MessageContext msgCtx; // "message" /* 0x020D8 */ MessageContext msgCtx; // "message"
/* 0x104F0 */ InterfaceContext interfaceCtx; // "parameter" /* 0x104F0 */ InterfaceContext interfaceCtx; // "parameter"
@ -1280,7 +1274,6 @@ typedef struct {
/* 0x000AC */ u8* parameterSegment; /* 0x000AC */ u8* parameterSegment;
/* 0x000B0 */ char unk_B0[0x8]; /* 0x000B0 */ char unk_B0[0x8];
/* 0x000B8 */ View view; /* 0x000B8 */ View view;
/* 0x001E0 */ SramContext sramCtx;
/* 0x001E4 */ char unk_1E4[0x4]; /* 0x001E4 */ char unk_1E4[0x4];
/* 0x001E8 */ SkyboxContext skyboxCtx; /* 0x001E8 */ SkyboxContext skyboxCtx;
/* 0x00348 */ MessageContext msgCtx; /* 0x00348 */ MessageContext msgCtx;
@ -1291,13 +1284,6 @@ typedef struct {
/* 0x1C9EC */ Vtx* keyboardVtx; /* 0x1C9EC */ Vtx* keyboardVtx;
/* 0x1C9F0 */ Vtx* nameEntryVtx; /* 0x1C9F0 */ Vtx* nameEntryVtx;
/* 0x1C9F4 */ u8 n64ddFlag; /* 0x1C9F4 */ u8 n64ddFlag;
/* 0x1C9F6 */ u16 deaths[3];
/* 0x1C9FC */ u8 fileNames[3][8];
/* 0x1CA14 */ u16 healthCapacities[3];
/* 0x1CA1C */ u32 questItems[3];
/* 0x1CA28 */ s16 n64ddFlags[3];
/* 0x1CA2E */ s8 defense[3];
/* 0x1CA32 */ u16 health[3];
/* 0x1CA38 */ s16 buttonIndex; /* 0x1CA38 */ s16 buttonIndex;
/* 0x1CA3A */ s16 confirmButtonIndex; // 0: yes, 1: quit /* 0x1CA3A */ s16 confirmButtonIndex; // 0: yes, 1: quit
/* 0x1CA3C */ s16 menuMode; /* 0x1CA3C */ s16 menuMode;

View File

@ -68,7 +68,6 @@ typedef struct {
/* 0x0010 */ s32 nightFlag; /* 0x0010 */ s32 nightFlag;
/* 0x0014 */ s32 totalDays; /* 0x0014 */ s32 totalDays;
/* 0x0018 */ s32 bgsDayCount; // increments with totalDays, can be cleared with `Environment_ClearBgsDayCount` /* 0x0018 */ s32 bgsDayCount; // increments with totalDays, can be cleared with `Environment_ClearBgsDayCount`
/* 0x001C */ char newf[6]; // string "ZELDAZ". start of `info` substruct, originally called "information"
/* 0x0022 */ u16 deaths; /* 0x0022 */ u16 deaths;
/* 0x0024 */ char playerName[8]; /* 0x0024 */ char playerName[8];
/* 0x002C */ s16 n64ddFlag; /* 0x002C */ s16 n64ddFlag;
@ -80,7 +79,6 @@ typedef struct {
/* 0x0036 */ u16 swordHealth; /* 0x0036 */ u16 swordHealth;
/* 0x0038 */ u16 naviTimer; /* 0x0038 */ u16 naviTimer;
/* 0x003A */ u8 magicAcquired; /* 0x003A */ u8 magicAcquired;
/* 0x003B */ char unk_3B[0x01];
/* 0x003C */ u8 doubleMagic; /* 0x003C */ u8 doubleMagic;
/* 0x003D */ u8 doubleDefense; /* 0x003D */ u8 doubleDefense;
/* 0x003E */ u8 bgsFlag; /* 0x003E */ u8 bgsFlag;
@ -88,30 +86,23 @@ typedef struct {
/* 0x0040 */ ItemEquips childEquips; /* 0x0040 */ ItemEquips childEquips;
/* 0x004A */ ItemEquips adultEquips; /* 0x004A */ ItemEquips adultEquips;
/* 0x0054 */ u32 unk_54; // this may be incorrect, currently used for alignement /* 0x0054 */ u32 unk_54; // this may be incorrect, currently used for alignement
/* 0x0058 */ char unk_58[0x0E];
/* 0x0066 */ s16 savedSceneNum; /* 0x0066 */ s16 savedSceneNum;
/* 0x0068 */ ItemEquips equips; /* 0x0068 */ ItemEquips equips;
/* 0x0074 */ Inventory inventory; /* 0x0074 */ Inventory inventory;
/* 0x00D4 */ SavedSceneFlags sceneFlags[124]; /* 0x00D4 */ SavedSceneFlags sceneFlags[124];
/* 0x0E64 */ FaroresWindData fw; /* 0x0E64 */ FaroresWindData fw;
/* 0x0E8C */ char unk_E8C[0x10];
/* 0x0E9C */ s32 gsFlags[6]; /* 0x0E9C */ s32 gsFlags[6];
/* 0x0EB4 */ char unk_EB4[0x4];
/* 0x0EB8 */ s32 highScores[7]; /* 0x0EB8 */ s32 highScores[7];
/* 0x0ED4 */ u16 eventChkInf[14]; // "event_chk_inf" /* 0x0ED4 */ u16 eventChkInf[14]; // "event_chk_inf"
/* 0x0EF0 */ u16 itemGetInf[4]; // "item_get_inf" /* 0x0EF0 */ u16 itemGetInf[4]; // "item_get_inf"
/* 0x0EF8 */ u16 infTable[30]; // "inf_table" /* 0x0EF8 */ u16 infTable[30]; // "inf_table"
/* 0x0F34 */ char unk_F34[0x04];
/* 0x0F38 */ u32 worldMapAreaData; // "area_arrival" /* 0x0F38 */ u32 worldMapAreaData; // "area_arrival"
/* 0x0F3C */ char unk_F3C[0x4];
/* 0x0F40 */ u8 scarecrowCustomSongSet; /* 0x0F40 */ u8 scarecrowCustomSongSet;
/* 0x0F41 */ u8 scarecrowCustomSong[0x360]; /* 0x0F41 */ u8 scarecrowCustomSong[0x360];
/* 0x12A1 */ char unk_12A1[0x24];
/* 0x12C5 */ u8 scarecrowSpawnSongSet; /* 0x12C5 */ u8 scarecrowSpawnSongSet;
/* 0x12C6 */ u8 scarecrowSpawnSong[0x80]; /* 0x12C6 */ u8 scarecrowSpawnSong[0x80];
/* 0x1346 */ char unk_1346[0x02]; /* 0x1346 */ char unk_1346[0x02];
/* 0x1348 */ HorseData horseData; /* 0x1348 */ HorseData horseData;
/* 0x1352 */ u16 checksum; // "check_sum"
/* 0x1354 */ s32 fileNum; // "file_no" /* 0x1354 */ s32 fileNum; // "file_no"
/* 0x1358 */ char unk_1358[0x0004]; /* 0x1358 */ char unk_1358[0x0004];
/* 0x135C */ s32 gameMode; /* 0x135C */ s32 gameMode;
@ -120,13 +111,11 @@ typedef struct {
/* 0x1368 */ RespawnData respawn[3]; // "restart_data" /* 0x1368 */ RespawnData respawn[3]; // "restart_data"
/* 0x13BC */ f32 entranceSpeed; /* 0x13BC */ f32 entranceSpeed;
/* 0x13C0 */ u16 entranceSound; /* 0x13C0 */ u16 entranceSound;
/* 0x13C2 */ char unk_13C2[0x0001];
/* 0x13C3 */ u8 unk_13C3; /* 0x13C3 */ u8 unk_13C3;
/* 0x13C4 */ s16 dogParams; /* 0x13C4 */ s16 dogParams;
/* 0x13C6 */ u8 textTriggerFlags; /* 0x13C6 */ u8 textTriggerFlags;
/* 0x13C7 */ u8 showTitleCard; /* 0x13C7 */ u8 showTitleCard;
/* 0x13C8 */ s16 nayrusLoveTimer; /* 0x13C8 */ s16 nayrusLoveTimer;
/* 0x13CA */ char unk_13CA[0x0002];
/* 0x13CC */ s16 rupeeAccumulator; /* 0x13CC */ s16 rupeeAccumulator;
/* 0x13CE */ s16 timer1State; /* 0x13CE */ s16 timer1State;
/* 0x13D0 */ s16 timer1Value; /* 0x13D0 */ s16 timer1Value;
@ -134,7 +123,6 @@ typedef struct {
/* 0x13D4 */ s16 timer2Value; /* 0x13D4 */ s16 timer2Value;
/* 0x13D6 */ s16 timerX[2]; /* 0x13D6 */ s16 timerX[2];
/* 0x13DA */ s16 timerY[2]; /* 0x13DA */ s16 timerY[2];
/* 0x13DE */ char unk_13DE[0x0002];
/* 0x13E0 */ u8 seqId; /* 0x13E0 */ u8 seqId;
/* 0x13E1 */ u8 natureAmbienceId; /* 0x13E1 */ u8 natureAmbienceId;
/* 0x13E2 */ u8 buttonStatus[5]; /* 0x13E2 */ u8 buttonStatus[5];
@ -152,14 +140,11 @@ typedef struct {
/* 0x1402 */ u16 mapIndex; // intended for maps/minimaps but commonly used as the dungeon index /* 0x1402 */ u16 mapIndex; // intended for maps/minimaps but commonly used as the dungeon index
/* 0x1404 */ u16 minigameState; /* 0x1404 */ u16 minigameState;
/* 0x1406 */ u16 minigameScore; // "yabusame_total" /* 0x1406 */ u16 minigameScore; // "yabusame_total"
/* 0x1408 */ char unk_1408[0x0001];
/* 0x1409 */ u8 language; // NTSC 0: Japanese; 1: English | PAL 0: English; 1: German; 2: French /* 0x1409 */ u8 language; // NTSC 0: Japanese; 1: English | PAL 0: English; 1: German; 2: French
/* 0x140A */ u8 audioSetting; /* 0x140A */ u8 audioSetting;
/* 0x140B */ char unk_140B[0x0001];
/* 0x140C */ u8 zTargetSetting; // 0: Switch; 1: Hold /* 0x140C */ u8 zTargetSetting; // 0: Switch; 1: Hold
/* 0x140E */ u16 forcedSeqId; // immediately start playing the sequence if set /* 0x140E */ u16 forcedSeqId; // immediately start playing the sequence if set
/* 0x1410 */ u8 unk_1410; // transition related /* 0x1410 */ u8 unk_1410; // transition related
/* 0x1411 */ char unk_1411[0x0001];
/* 0x1412 */ u16 nextCutsceneIndex; /* 0x1412 */ u16 nextCutsceneIndex;
/* 0x1414 */ u8 cutsceneTrigger; /* 0x1414 */ u8 cutsceneTrigger;
/* 0x1415 */ u8 chamberCutsceneNum; /* 0x1415 */ u8 chamberCutsceneNum;
@ -169,7 +154,6 @@ typedef struct {
/* 0x141A */ u16 skyboxTime; /* 0x141A */ u16 skyboxTime;
/* 0x141C */ u8 dogIsLost; /* 0x141C */ u8 dogIsLost;
/* 0x141D */ u8 nextTransition; /* 0x141D */ u8 nextTransition;
/* 0x141E */ char unk_141E[0x0002];
/* 0x1420 */ s16 worldMapArea; /* 0x1420 */ s16 worldMapArea;
/* 0x1422 */ s16 sunsSongState; // controls the effects of suns song /* 0x1422 */ s16 sunsSongState; // controls the effects of suns song
/* 0x1424 */ s16 healthAccumulator; /* 0x1424 */ s16 healthAccumulator;

View File

@ -186,6 +186,7 @@
<ClCompile Include="soh\GbiWrap.cpp" /> <ClCompile Include="soh\GbiWrap.cpp" />
<ClCompile Include="soh\gu_pc.c" /> <ClCompile Include="soh\gu_pc.c" />
<ClCompile Include="soh\OTRGlobals.cpp" /> <ClCompile Include="soh\OTRGlobals.cpp" />
<ClCompile Include="soh\SaveManager.cpp" />
<ClCompile Include="soh\stubs.c" /> <ClCompile Include="soh\stubs.c" />
<ClCompile Include="soh\util.cpp" /> <ClCompile Include="soh\util.cpp" />
<ClCompile Include="soh\z_message_OTR.cpp" /> <ClCompile Include="soh\z_message_OTR.cpp" />
@ -935,8 +936,10 @@
<ClInclude Include="soh\Enhancements\debugger\debugSaveEditor.h" /> <ClInclude Include="soh\Enhancements\debugger\debugSaveEditor.h" />
<ClInclude Include="soh\Enhancements\debugger\ImGuiHelpers.h" /> <ClInclude Include="soh\Enhancements\debugger\ImGuiHelpers.h" />
<ClInclude Include="soh\gameconsole.h" /> <ClInclude Include="soh\gameconsole.h" />
<ClInclude Include="soh\Lib\nlohmann\json.hpp" />
<ClInclude Include="soh\OTRAudio.h" /> <ClInclude Include="soh\OTRAudio.h" />
<ClInclude Include="soh\OTRGlobals.h" /> <ClInclude Include="soh\OTRGlobals.h" />
<ClInclude Include="soh\SaveManager.h" />
<ClInclude Include="soh\util.h" /> <ClInclude Include="soh\util.h" />
<ClInclude Include="src\overlays\actors\ovl_Arms_Hook\z_arms_hook.h" /> <ClInclude Include="src\overlays\actors\ovl_Arms_Hook\z_arms_hook.h" />
<ClInclude Include="src\overlays\actors\ovl_Arrow_Fire\z_arrow_fire.h" /> <ClInclude Include="src\overlays\actors\ovl_Arrow_Fire\z_arrow_fire.h" />

View File

@ -85,6 +85,9 @@
<Filter Include="Source Files\soh\Lib"> <Filter Include="Source Files\soh\Lib">
<UniqueIdentifier>{dbcf07c4-80b1-4c88-ac54-2bbdd8f53ee4}</UniqueIdentifier> <UniqueIdentifier>{dbcf07c4-80b1-4c88-ac54-2bbdd8f53ee4}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Source Files\soh\Lib\nlohmann">
<UniqueIdentifier>{9c880c8e-492b-48f6-b230-1fd269ea74b1}</UniqueIdentifier>
</Filter>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="src\boot\assert.c"> <ClCompile Include="src\boot\assert.c">
@ -2202,6 +2205,9 @@
<ClCompile Include="soh\Enhancements\savestates.cpp"> <ClCompile Include="soh\Enhancements\savestates.cpp">
<Filter>Source Files\soh\Enhancements</Filter> <Filter>Source Files\soh\Enhancements</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="soh\SaveManager.cpp">
<Filter>Source Files\soh</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="src\overlays\actors\ovl_kaleido_scope\z_kaleido_scope.h"> <ClInclude Include="src\overlays\actors\ovl_kaleido_scope\z_kaleido_scope.h">
@ -3770,6 +3776,12 @@
<ClInclude Include="soh\OTRAudio.h"> <ClInclude Include="soh\OTRAudio.h">
<Filter>Source Files\soh</Filter> <Filter>Source Files\soh</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="soh\Lib\nlohmann\json.hpp">
<Filter>Source Files\soh\Lib\nlohmann</Filter>
</ClInclude>
<ClInclude Include="soh\SaveManager.h">
<Filter>Source Files\soh</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Image Include="SHIPOFHARKINIAN.ico" /> <Image Include="SHIPOFHARKINIAN.ico" />

View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2013-2022 Niels Lohmann
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

22091
soh/soh/Lib/nlohmann/json.hpp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -39,6 +39,7 @@
#include <Audio.h> #include <Audio.h>
OTRGlobals* OTRGlobals::Instance; OTRGlobals* OTRGlobals::Instance;
SaveManager* SaveManager::Instance;
OTRGlobals::OTRGlobals() { OTRGlobals::OTRGlobals() {
@ -70,6 +71,7 @@ extern "C" void OTRAudio_Init()
extern "C" void InitOTR() { extern "C" void InitOTR() {
OTRGlobals::Instance = new OTRGlobals(); OTRGlobals::Instance = new OTRGlobals();
SaveManager::Instance = new SaveManager();
auto t = OTRGlobals::Instance->context->GetResourceManager()->LoadFile("version"); auto t = OTRGlobals::Instance->context->GetResourceManager()->LoadFile("version");
if (!t->bHasLoadError) if (!t->bHasLoadError)

View File

@ -4,6 +4,7 @@
#pragma once #pragma once
#include "GlobalCtx2.h" #include "GlobalCtx2.h"
#include "SaveManager.h"
#ifdef __cplusplus #ifdef __cplusplus
#include "Enhancements/savestates.h" #include "Enhancements/savestates.h"

1217
soh/soh/SaveManager.cpp Normal file

File diff suppressed because it is too large Load Diff

149
soh/soh/SaveManager.h Normal file
View File

@ -0,0 +1,149 @@
#pragma once
#include <ultra64/gbi.h>
typedef struct {
u8 valid;
u16 deaths;
char playerName[8];
u16 healthCapacity;
u32 questItems;
s8 defense;
u16 health;
u8 n64ddFlag;
} SaveFileMetaInfo;
#ifdef __cplusplus
#include <map>
#include <string>
#include <tuple>
#include <functional>
#include <vector>
#include <filesystem>
#include "Lib/nlohmann/json.hpp"
class SaveManager {
public:
static SaveManager* Instance;
using InitFunc = void(*)(bool isDebug);
using LoadFunc = void(*)();
using SaveFunc = void(*)();
using PostFunc = void(*)(int version);
SaveManager();
void Init();
void InitFile(bool isDebug);
void SaveFile(int fileNum);
void SaveGlobal();
void LoadFile(int fileNum);
// Adds a function that is called when we are intializing a save, including when we are loading a save.
void AddInitFunction(InitFunc func);
// Adds a function to handling loading a section
void AddLoadFunction(const std::string& name, int version, LoadFunc func);
// Adds a function that is called when saving. This should only be called once for each function, the version is filled in automatically.
void AddSaveFunction(const std::string& name, int version, SaveFunc func);
// Adds a function to be called after loading is complete. This is to handle any cleanup required from loading old versions.
void AddPostFunction(const std::string& name, PostFunc func);
void CopyZeldaFile(int from, int to);
void DeleteZeldaFile(int fileNum);
// Use a name of "" to save to an array. You must be in a SaveArray callback.
template<typename T>
void SaveData(const std::string& name, const T& data) {
if (name == "") {
assert((*currentJsonContext).is_array());
(*currentJsonContext).push_back(data);
} else {
(*currentJsonContext)[name.c_str()] = data;
}
}
// In the SaveArrayFunc func, the name must be "" to save to the array.
using SaveArrayFunc = std::function<void(size_t)>;
void SaveArray(const std::string& name, const size_t size, SaveArrayFunc func);
using SaveStructFunc = std::function<void()>;
void SaveStruct(const std::string& name, SaveStructFunc func);
// Use a name of "" to load from an array. You must be in a LoadArray callback.
template<typename T> void LoadData(const std::string& name, T& data, const T& defaultValue = T{}) {
if (name == "") {
if (currentJsonArrayContext == currentJsonContext->end()) {
// This array member is past the data in the json file. Therefore, default construct it
data = defaultValue;
} else {
currentJsonArrayContext.value().get_to(data);
}
} else if (!currentJsonContext->contains(name.c_str())) {
data = defaultValue;
} else {
(*currentJsonContext)[name.c_str()].get_to(data);
}
}
// In the LoadArrayFunc func, the name must be "" to load from the array.
using LoadArrayFunc = std::function<void(size_t)>;
void LoadArray(const std::string& name, const size_t size, LoadArrayFunc func);
using LoadStructFunc = std::function<void()>;
void LoadStruct(const std::string& name, LoadStructFunc func);
static const int MaxFiles = 3;
std::array<SaveFileMetaInfo, MaxFiles> fileMetaInfo;
private:
std::filesystem::path GetFileName(int fileNum);
void ConvertFromUnversioned();
void CreateDefaultGlobal();
void InitMeta(int slotNum);
static void InitFileImpl(bool isDebug);
static void InitFileNormal();
static void InitFileDebug();
static void LoadBaseVersion1();
static void SaveBase();
std::vector<InitFunc> initFuncs;
using SectionLoadHandler = std::map<int, LoadFunc>;
std::map<std::string, SectionLoadHandler> sectionLoadHandlers;
using SectionSaveHandler = std::pair<int, SaveFunc>;
std::map<std::string, SectionSaveHandler> sectionSaveHandlers;
std::map<std::string, PostFunc> postHandlers;
nlohmann::json* currentJsonContext = nullptr;
nlohmann::json::iterator currentJsonArrayContext;
};
#else
// TODO feature parity to the C++ interface. We need Save_AddInitFunction and Save_AddPostFunction at least
typedef void (*Save_LoadFunc)(void);
typedef void (*Save_SaveFunc)(void);
void Save_Init(void);
void Save_InitFile(int isDebug);
void Save_SaveFile(void);
void Save_SaveGlobal(void);
void Save_LoadGlobal(void);
void Save_AddLoadFunction(char* name, int version, Save_LoadFunc func);
void Save_AddSaveFunction(char* name, int version, Save_SaveFunc func);
SaveFileMetaInfo* Save_GetSaveMetaInfo(int fileNum);
void Save_CopyFile(int from, int to);
void Save_DeleteFile(int fileNum);
#endif

View File

@ -2,13 +2,9 @@
#include <string.h> #include <string.h>
SaveContext gSaveContext; SaveContext gSaveContext;
u32 D_8015FA88;
u32 D_8015FA8C;
void SaveContext_Init(void) { void SaveContext_Init(void) {
memset(&gSaveContext, 0, sizeof(gSaveContext)); memset(&gSaveContext, 0, sizeof(gSaveContext));
D_8015FA88 = 0;
D_8015FA8C = 0;
gSaveContext.seqId = (u8)NA_BGM_DISABLED; gSaveContext.seqId = (u8)NA_BGM_DISABLED;
gSaveContext.natureAmbienceId = NATURE_ID_DISABLED; gSaveContext.natureAmbienceId = NATURE_ID_DISABLED;
gSaveContext.forcedSeqId = NA_BGM_GENERAL_SFX; gSaveContext.forcedSeqId = NA_BGM_GENERAL_SFX;

View File

@ -240,7 +240,6 @@ void Gameplay_Init(GameState* thisx) {
globalCtx->cameraPtrs[MAIN_CAM]->uid = 0; globalCtx->cameraPtrs[MAIN_CAM]->uid = 0;
globalCtx->activeCamera = MAIN_CAM; globalCtx->activeCamera = MAIN_CAM;
func_8005AC48(&globalCtx->mainCamera, 0xFF); func_8005AC48(&globalCtx->mainCamera, 0xFF);
Sram_Init(globalCtx, &globalCtx->sramCtx);
func_80112098(globalCtx); func_80112098(globalCtx);
Message_Init(globalCtx); Message_Init(globalCtx);
GameOver_Init(globalCtx); GameOver_Init(globalCtx);

View File

@ -3,242 +3,14 @@
#include <string.h> #include <string.h>
// these are the main substructs of save context.
// we are going to hold off on splitting save context until later on,
// so these temporary structs will live here for now.
typedef struct {
/* 0x00 */ char newf[6]; // string "ZELDAZ"
/* 0x06 */ s16 deaths;
/* 0x08 */ char playerName[8];
/* 0x10 */ s16 n64ddFlag;
/* 0x12 */ s16 healthCapacity; // "max_life"
/* 0x14 */ s16 health; // "now_life"
/* 0x16 */ s8 magicLevel;
/* 0x17 */ s8 magic;
/* 0x18 */ s16 rupees;
/* 0x1A */ u16 swordHealth;
/* 0x1C */ u16 naviTimer;
/* 0x1E */ u8 magicAcquired;
/* 0x1F */ u8 unk_1F;
/* 0x20 */ u8 doubleMagic;
/* 0x21 */ u8 doubleDefense;
/* 0x22 */ u8 bgsFlag;
/* 0x23 */ u8 ocarinaGameRoundNum;
/* 0x24 */ ItemEquips childEquips;
/* 0x2E */ ItemEquips adultEquips;
/* 0x38 */ u32 unk_38; // this may be incorrect, currently used for alignement
/* 0x3C */ char unk_3C[0x0E];
/* 0x4A */ s16 savedSceneNum;
} SavePlayerData; // size = 0x4C
typedef struct {
/* 0x0000 */ SavePlayerData playerData; // "S_Private" substruct name
/* 0x004C */ ItemEquips equips;
/* 0x0058 */ Inventory inventory;
/* 0x00B8 */ SavedSceneFlags sceneFlags[124];
/* 0x0E48 */ FaroresWindData fw;
/* 0x0E70 */ char unk_E70[0x10];
/* 0x0E80 */ s32 gsFlags[6];
/* 0x0E98 */ char unk_E98[0x10];
/* 0x0EA8 */ s32 horseRaceRecord;
/* 0x0EAC */ char unk_EAC[0x0C];
/* 0x0EB8 */ u16 eventChkInf[14]; // "event_chk_inf"
/* 0x0ED4 */ u16 itemGetInf[4]; // "item_get_inf"
/* 0x0EDC */ u16 infTable[30]; // "inf_table"
/* 0x0F18 */ char unk_F18[0x04];
/* 0x0F1C */ u32 worldMapAreaData; // "area_arrival"
/* 0x0F20 */ char unk_F20[0x4];
/* 0x0F24 */ u8 scarecrowCustomSongSet;
/* 0x0F25 */ u8 scarecrowCustomSong[0x360];
/* 0x1285 */ char unk_1285[0x24];
/* 0x12A9 */ u8 scarecrowSpawnSongSet;
/* 0x12AA */ u8 scarecrowSpawnSong[0x80];
/* 0x132A */ char unk_132A[0x02];
/* 0x132C */ HorseData horseData;
/* 0x1336 */ u16 checksum; // "check_sum"
} SaveInfo; // size = 0x1338
typedef struct {
/* 0x00 */ s32 entranceIndex;
/* 0x04 */ s32 linkAge; // 0: Adult; 1: Child
/* 0x08 */ s32 cutsceneIndex;
/* 0x0C */ u16 dayTime; // "zelda_time"
/* 0x10 */ s32 nightFlag;
/* 0x14 */ s32 totalDays;
/* 0x18 */ s32 unk_18; // increments with totalDays, gets reset by goron for bgs and one other use
/* 0x1C */ SaveInfo info; // "information"
} Save; // size = 0x1354
#define SAVE_PLAYER_DATA (*((SavePlayerData*)&gSaveContext.newf))
#define SAVE_INFO (*((SaveInfo*)&gSaveContext.newf))
#define SLOT_SIZE (sizeof(SaveContext) + 0x28)
#define CHECKSUM_SIZE (sizeof(Save) / 2)
#define DEATHS OFFSETOF(SaveContext, deaths)
#define NAME OFFSETOF(SaveContext, playerName)
#define N64DD OFFSETOF(SaveContext, n64ddFlag)
#define HEALTH_CAP OFFSETOF(SaveContext, healthCapacity)
#define QUEST OFFSETOF(SaveContext, inventory.questItems)
#define DEFENSE OFFSETOF(SaveContext, inventory.defenseHearts)
#define HEALTH OFFSETOF(SaveContext, health)
#define SLOT_OFFSET(index) (SRAM_HEADER_SIZE + 0x10 + (index * SLOT_SIZE))
u16 gSramSlotOffsets[] = {
SLOT_OFFSET(0),
SLOT_OFFSET(1),
SLOT_OFFSET(2),
// the latter three saves are backup saves for the former saves
SLOT_OFFSET(3),
SLOT_OFFSET(4),
SLOT_OFFSET(5),
};
static u8 sZeldaMagic[] = { '\0', '\0', '\0', '\x98', '\x09', '\x10', '\x21', 'Z', 'E', 'L', 'D', 'A' };
static SavePlayerData sNewSavePlayerData = {
{ '\0', '\0', '\0', '\0', '\0', '\0' }, // newf
0, // deaths
{ 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E }, // playerName
0, // n64ddFlag
0x30, // healthCapacity
0x30, // defense
0, // magicLevel
0x30, // magic
0, // rupees
0, // swordHealth
0, // naviTimer
0, // magicAcquired
0, // unk_1F
0, // doubleMagic
0, // doubleDefense
0, // bgsFlag
0, // ocarinaGameRoundNum
{
{ ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE }, // buttonItems
{ SLOT_NONE, SLOT_NONE, SLOT_NONE }, // cButtonSlots
0, // equipment
}, // childEquips
{
{ ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE }, // buttonItems
{ SLOT_NONE, SLOT_NONE, SLOT_NONE }, // cButtonSlots
0, // equipment
}, // adultEquips
0, // unk_38
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // unk_3C
0x34, // savedSceneNum
};
static ItemEquips sNewSaveEquips = {
{ ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE }, // buttonItems
{ SLOT_NONE, SLOT_NONE, SLOT_NONE }, // cButtonSlots
0x1100, // equipment
};
static Inventory sNewSaveInventory = {
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, // items
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // ammo
0x1100, // equipment
0, // upgrades
0, // questItems
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // dungeonItems
{
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
}, // dungeonKeys
0, // defenseHearts
0, // gsTokens
};
static u16 sNewSaveChecksum = 0;
/** /**
* Initialize new save. * Initialize new save.
* This save has an empty inventory with 3 hearts and single magic. * This save has an empty inventory with 3 hearts and single magic.
*/ */
void Sram_InitNewSave(void) { void Sram_InitNewSave(void) {
SaveContext* temp = &gSaveContext; Save_InitFile(false);
memset(&SAVE_INFO, 0, sizeof(SaveInfo));
gSaveContext.totalDays = 0;
gSaveContext.bgsDayCount = 0;
SAVE_PLAYER_DATA = sNewSavePlayerData;
gSaveContext.equips = sNewSaveEquips;
gSaveContext.inventory = sNewSaveInventory;
temp->checksum = sNewSaveChecksum;
gSaveContext.horseData.scene = SCENE_SPOT00;
gSaveContext.horseData.pos.x = -1840;
gSaveContext.horseData.pos.y = 72;
gSaveContext.horseData.pos.z = 5497;
gSaveContext.horseData.angle = -0x6AD9;
gSaveContext.magicLevel = 0;
gSaveContext.infTable[29] = 1;
gSaveContext.sceneFlags[5].swch = 0x40000000;
} }
static SavePlayerData sDebugSavePlayerData = {
{ 'Z', 'E', 'L', 'D', 'A', 'Z' }, // newf
0, // deaths
{ 0x15, 0x12, 0x17, 0x14, 0x3E, 0x3E, 0x3E, 0x3E }, // playerName ( "LINK" )
0, // n64ddFlag
0xE0, // healthCapacity
0xE0, // health
0, // magicLevel
0x30, // magic
150, // rupees
8, // swordHealth
0, // naviTimer
1, // magicAcquired
0, // unk_1F
0, // doubleMagic
0, // doubleDefense
0, // bgsFlag
0, // ocarinaGameRoundNum
{
{ ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE }, // buttonItems
{ SLOT_NONE, SLOT_NONE, SLOT_NONE }, // cButtonSlots
0, // equipment
}, // childEquips
{
{ ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE }, // buttonItems
{ SLOT_NONE, SLOT_NONE, SLOT_NONE }, // cButtonSlots
0, // equipment
}, // adultEquips
0, // unk_38
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // unk_3C
0x51, // savedSceneNum
};
static ItemEquips sDebugSaveEquips = {
{ ITEM_SWORD_MASTER, ITEM_BOW, ITEM_BOMB, ITEM_OCARINA_FAIRY }, // buttonItems
{ SLOT_BOW, SLOT_BOMB, SLOT_OCARINA }, // cButtonSlots
0x1122, // equipment
};
static Inventory sDebugSaveInventory = {
{
ITEM_STICK, ITEM_NUT, ITEM_BOMB, ITEM_BOW, ITEM_ARROW_FIRE, ITEM_DINS_FIRE,
ITEM_SLINGSHOT, ITEM_OCARINA_FAIRY, ITEM_BOMBCHU, ITEM_HOOKSHOT, ITEM_ARROW_ICE, ITEM_FARORES_WIND,
ITEM_BOOMERANG, ITEM_LENS, ITEM_BEAN, ITEM_HAMMER, ITEM_ARROW_LIGHT, ITEM_NAYRUS_LOVE,
ITEM_BOTTLE, ITEM_POTION_RED, ITEM_POTION_GREEN, ITEM_POTION_BLUE, ITEM_POCKET_EGG, ITEM_WEIRD_EGG,
}, // items
{ 50, 50, 10, 30, 1, 1, 30, 1, 50, 1, 1, 1, 1, 1, 1, 1 }, // ammo
0x7777, // equipment
0x125249, // upgrades
0x1E3FFFF, // questItems
{ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // dungeonItems
{ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 }, // dungeonKeys
0, // defenseHearts
0, // gsTokens
};
static u16 sDebugSaveChecksum = 0;
/** /**
* Initialize debug save. This is also used on the Title Screen * Initialize debug save. This is also used on the Title Screen
* This save has a mostly full inventory with 10 hearts and single magic. * This save has a mostly full inventory with 10 hearts and single magic.
@ -249,40 +21,7 @@ static u16 sDebugSaveChecksum = 0;
* and set water level in Water Temple to lowest level. * and set water level in Water Temple to lowest level.
*/ */
void Sram_InitDebugSave(void) { void Sram_InitDebugSave(void) {
SaveContext* temp = &gSaveContext; Save_InitFile(true);
memset(&SAVE_INFO, 0, sizeof(SaveInfo));
gSaveContext.totalDays = 0;
gSaveContext.bgsDayCount = 0;
SAVE_PLAYER_DATA = sDebugSavePlayerData;
gSaveContext.equips = sDebugSaveEquips;
gSaveContext.inventory = sDebugSaveInventory;
temp->checksum = sDebugSaveChecksum;
gSaveContext.horseData.scene = SCENE_SPOT00;
gSaveContext.horseData.pos.x = -1840;
gSaveContext.horseData.pos.y = 72;
gSaveContext.horseData.pos.z = 5497;
gSaveContext.horseData.angle = -0x6AD9;
gSaveContext.infTable[0] |= 0x5009;
gSaveContext.eventChkInf[0] |= 0x123F;
gSaveContext.eventChkInf[8] |= 1;
gSaveContext.eventChkInf[12] |= 0x10;
if (LINK_AGE_IN_YEARS == YEARS_CHILD) {
gSaveContext.equips.buttonItems[0] = ITEM_SWORD_KOKIRI;
Inventory_ChangeEquipment(EQUIP_SWORD, 1);
if (gSaveContext.fileNum == 0xFF) {
gSaveContext.equips.buttonItems[1] = ITEM_SLINGSHOT;
gSaveContext.equips.cButtonSlots[0] = SLOT_SLINGSHOT;
Inventory_ChangeEquipment(EQUIP_SHIELD, 1);
}
}
gSaveContext.entranceIndex = 0xCD;
gSaveContext.magicLevel = 0;
gSaveContext.sceneFlags[5].swch = 0x40000000;
} }
/** /**
@ -295,7 +34,7 @@ void Sram_InitDebugSave(void) {
* - Give and equip master sword if player is adult and doesnt have kokiri sword (bug?) * - Give and equip master sword if player is adult and doesnt have kokiri sword (bug?)
* - Revert any trade items that spoil * - Revert any trade items that spoil
*/ */
void Sram_OpenSave(SramContext* sramCtx) { void Sram_OpenSave() {
static s16 dungeonEntrances[] = { static s16 dungeonEntrances[] = {
0x0000, 0x0004, 0x0028, 0x0169, 0x0165, 0x0010, 0x0082, 0x0037, 0x0000, 0x0004, 0x0028, 0x0169, 0x0165, 0x0010, 0x0082, 0x0037,
0x0098, 0x0088, 0x041B, 0x0008, 0x0486, 0x0467, 0x0179, 0x056C, 0x0098, 0x0088, 0x041B, 0x0008, 0x0486, 0x0467, 0x0179, 0x056C,
@ -304,15 +43,7 @@ void Sram_OpenSave(SramContext* sramCtx) {
u16 j; u16 j;
u8* ptr; u8* ptr;
osSyncPrintf("個人File作成\n"); // "Create personal file" Save_LoadFile();
i = gSramSlotOffsets[gSaveContext.fileNum];
osSyncPrintf("ぽいんと=%x(%d)\n", i, gSaveContext.fileNum); // "Point="
memcpy(&gSaveContext, sramCtx->readBuff + i, sizeof(Save));
osSyncPrintf(VT_FGCOL(YELLOW));
osSyncPrintf("SCENE_DATA_ID = %d SceneNo = %d\n", gSaveContext.savedSceneNum,
((void)0, gSaveContext.entranceIndex));
switch (gSaveContext.savedSceneNum) { switch (gSaveContext.savedSceneNum) {
case SCENE_YDAN: case SCENE_YDAN:
@ -446,232 +177,7 @@ void Sram_OpenSave(SramContext* sramCtx) {
gSaveContext.magicLevel = 0; gSaveContext.magicLevel = 0;
} }
/** void Sram_InitSave(FileChooseContext* fileChooseCtx) {
* Write the contents of the Save Context to a main and backup slot in SRAM.
* Note: The whole Save Context is written even though only the `save` substruct is read back later
*/
void Sram_WriteSave(SramContext* sramCtx) {
u16 offset;
u16 checksum;
u16 j;
u16* ptr;
gSaveContext.checksum = 0;
ptr = (u16*)&gSaveContext;
checksum = 0;
j = 0;
for (offset = 0; offset < CHECKSUM_SIZE; offset++) {
if (++j == 0x20) {
j = 0;
}
checksum += *ptr++;
}
gSaveContext.checksum = checksum;
ptr = (u16*)&gSaveContext;
checksum = 0;
for (offset = 0; offset < CHECKSUM_SIZE; offset++) {
if (++j == 0x20) {
j = 0;
}
checksum += *ptr++;
}
offset = gSramSlotOffsets[gSaveContext.fileNum];
SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000) + offset, &gSaveContext, SLOT_SIZE, OS_WRITE);
ptr = (u16*)&gSaveContext;
checksum = 0;
for (offset = 0; offset < CHECKSUM_SIZE; offset++) {
if (++j == 0x20) {
j = 0;
}
checksum += *ptr++;
}
offset = gSramSlotOffsets[gSaveContext.fileNum + 3];
SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000) + offset, &gSaveContext, SLOT_SIZE, OS_WRITE);
}
/**
* For all 3 slots, verify that the checksum is correct. If corrupted, attempt to load a backup save.
* If backup is also corrupted, default to a new save (or debug save for slot 0 on debug rom).
*
* After verifying all 3 saves, pass relevant data to File Select to be displayed.
*/
void Sram_VerifyAndLoadAllSaves(FileChooseContext* fileChooseCtx, SramContext* sramCtx) {
u16 i;
u16 newChecksum;
u16 slotNum;
u16 offset;
u16 j;
u16 oldChecksum;
u16* ptr;
u16 dayTime;
osSyncPrintf(" START─LOAD\n");
memset(sramCtx->readBuff,0, SRAM_SIZE);
SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000), sramCtx->readBuff, SRAM_SIZE, OS_READ);
dayTime = ((void)0, gSaveContext.dayTime);
for (slotNum = 0; slotNum < 3; slotNum++) {
offset = gSramSlotOffsets[slotNum];
osSyncPrintf("ぽいんと=%x(%d) SAVE_MAX=%d\n", offset, gSaveContext.fileNum, sizeof(Save));
memcpy(&gSaveContext, sramCtx->readBuff + offset, sizeof(Save));
oldChecksum = gSaveContext.checksum;
gSaveContext.checksum = 0;
ptr = (u16*)&gSaveContext;
osSyncPrintf("\n %d \n", slotNum);
for (i = newChecksum = j = 0; i < CHECKSUM_SIZE; i++, offset += 2) {
newChecksum += *ptr++;
}
// "SAVE checksum calculation"
osSyncPrintf("\nSAVEチェックサム計算 j=%x mmm=%x ", newChecksum, oldChecksum);
if (newChecksum != oldChecksum) {
// checksum didnt match, try backup save
osSyncPrintf(" %x(%d)\n", gSramSlotOffsets[slotNum], slotNum);
offset = gSramSlotOffsets[slotNum + 3];
memcpy(&gSaveContext, sramCtx->readBuff + offset, sizeof(Save));
oldChecksum = gSaveContext.checksum;
gSaveContext.checksum = 0;
ptr = (u16*)&gSaveContext;
osSyncPrintf("================= BACK─UP ========================\n");
for (i = newChecksum = j = 0; i < CHECKSUM_SIZE; i++, offset += 2) {
newChecksum += *ptr++;
}
// "(B) SAVE checksum calculation"
osSyncPrintf("\n(B)SAVEチェックサム計算 j=%x mmm=%x ", newChecksum, oldChecksum);
if (newChecksum != oldChecksum) {
// backup save didnt work, make new save
osSyncPrintf(" %x(%d+3)\n", gSramSlotOffsets[slotNum + 3], slotNum);
memset(&gSaveContext.entranceIndex, 0, sizeof(s32));
memset(&gSaveContext.linkAge, 0, sizeof(s32));
memset(&gSaveContext.cutsceneIndex, 0, sizeof(s32));
// note that gSaveContext.dayTime is not actually the sizeof(s32)
memset(&gSaveContext.dayTime, 0, sizeof(s32));
memset(&gSaveContext.nightFlag, 0, sizeof(s32));
memset(&gSaveContext.totalDays, 0, sizeof(s32));
memset(&gSaveContext.bgsDayCount, 0, sizeof(s32));
if (!slotNum && CVar_GetS32("gDebugEnabled", 0)) {
Sram_InitDebugSave();
gSaveContext.newf[0] = 'Z';
gSaveContext.newf[1] = 'E';
gSaveContext.newf[2] = 'L';
gSaveContext.newf[3] = 'D';
gSaveContext.newf[4] = 'A';
gSaveContext.newf[5] = 'Z';
osSyncPrintf("newf=%x,%x,%x,%x,%x,%x\n", gSaveContext.newf[0], gSaveContext.newf[1],
gSaveContext.newf[2], gSaveContext.newf[3], gSaveContext.newf[4],
gSaveContext.newf[5]);
} else {
Sram_InitNewSave();
}
ptr = (u16*)&gSaveContext;
osSyncPrintf("\n--------------------------------------------------------------\n");
for (i = newChecksum = j = 0; i < CHECKSUM_SIZE; i++) {
osSyncPrintf("%x ", *ptr);
if (++j == 0x20) {
osSyncPrintf("\n");
j = 0;
}
newChecksum += *ptr++;
}
gSaveContext.checksum = newChecksum;
osSyncPrintf("\nCheck_Sum=%x(%x)\n", gSaveContext.checksum, newChecksum);
i = gSramSlotOffsets[slotNum + 3];
SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000) + i, &gSaveContext, SLOT_SIZE, OS_WRITE);
osSyncPrintf("????#%x,%x,%x,%x,%x,%x\n", gSaveContext.newf[0], gSaveContext.newf[1],
gSaveContext.newf[2], gSaveContext.newf[3], gSaveContext.newf[4], gSaveContext.newf[5]);
osSyncPrintf("\nぽいんと=%x(%d+3) check_sum=%x(%x)\n", i, slotNum, gSaveContext.checksum,
newChecksum);
}
i = gSramSlotOffsets[slotNum];
SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000) + i, &gSaveContext, SLOT_SIZE, OS_WRITE);
osSyncPrintf("ぽいんと=%x(%d) check_sum=%x(%x)\n", i, slotNum, gSaveContext.checksum, newChecksum);
} else {
osSyncPrintf("\nSAVEデータ \n"); // "SAVE data OK! ! ! !"
}
}
memset(sramCtx->readBuff,0, SRAM_SIZE);
SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000), sramCtx->readBuff, SRAM_SIZE, OS_READ);
gSaveContext.dayTime = dayTime;
osSyncPrintf("SAVECT=%x, NAME=%x, LIFE=%x, ITEM=%x, 64DD=%x, HEART=%x\n", DEATHS, NAME, HEALTH_CAP, QUEST, N64DD,
DEFENSE);
memcpy(&fileChooseCtx->deaths[0], sramCtx->readBuff + SLOT_OFFSET(0) + DEATHS, sizeof(fileChooseCtx->deaths[0]));
memcpy(&fileChooseCtx->deaths[1], sramCtx->readBuff + SLOT_OFFSET(1) + DEATHS, sizeof(fileChooseCtx->deaths[0]));
memcpy(&fileChooseCtx->deaths[2], sramCtx->readBuff + SLOT_OFFSET(2) + DEATHS, sizeof(fileChooseCtx->deaths[0]));
memcpy(&fileChooseCtx->fileNames[0], sramCtx->readBuff + SLOT_OFFSET(0) + NAME,
sizeof(fileChooseCtx->fileNames[0]));
memcpy(&fileChooseCtx->fileNames[1], sramCtx->readBuff + SLOT_OFFSET(1) + NAME,
sizeof(fileChooseCtx->fileNames[0]));
memcpy(&fileChooseCtx->fileNames[2], sramCtx->readBuff + SLOT_OFFSET(2) + NAME,
sizeof(fileChooseCtx->fileNames[0]));
memcpy(&fileChooseCtx->healthCapacities[0], sramCtx->readBuff + SLOT_OFFSET(0) + HEALTH_CAP,
sizeof(fileChooseCtx->healthCapacities[0]));
memcpy(&fileChooseCtx->healthCapacities[1], sramCtx->readBuff + SLOT_OFFSET(1) + HEALTH_CAP,
sizeof(fileChooseCtx->healthCapacities[0]));
memcpy(&fileChooseCtx->healthCapacities[2], sramCtx->readBuff + SLOT_OFFSET(2) + HEALTH_CAP,
sizeof(fileChooseCtx->healthCapacities[0]));
memcpy(&fileChooseCtx->questItems[0], sramCtx->readBuff + SLOT_OFFSET(0) + QUEST,
sizeof(fileChooseCtx->questItems[0]));
memcpy(&fileChooseCtx->questItems[1], sramCtx->readBuff + SLOT_OFFSET(1) + QUEST,
sizeof(fileChooseCtx->questItems[0]));
memcpy(&fileChooseCtx->questItems[2], sramCtx->readBuff + SLOT_OFFSET(2) + QUEST,
sizeof(fileChooseCtx->questItems[0]));
memcpy(&fileChooseCtx->n64ddFlags[0], sramCtx->readBuff + SLOT_OFFSET(0) + N64DD,
sizeof(fileChooseCtx->n64ddFlags[0]));
memcpy(&fileChooseCtx->n64ddFlags[1], sramCtx->readBuff + SLOT_OFFSET(1) + N64DD,
sizeof(fileChooseCtx->n64ddFlags[0]));
memcpy(&fileChooseCtx->n64ddFlags[2], sramCtx->readBuff + SLOT_OFFSET(2) + N64DD,
sizeof(fileChooseCtx->n64ddFlags[0]));
memcpy(&fileChooseCtx->defense[0], sramCtx->readBuff + SLOT_OFFSET(0) + DEFENSE,
sizeof(fileChooseCtx->defense[0]));
memcpy(&fileChooseCtx->defense[1], sramCtx->readBuff + SLOT_OFFSET(1) + DEFENSE,
sizeof(fileChooseCtx->defense[0]));
memcpy(&fileChooseCtx->defense[2], sramCtx->readBuff + SLOT_OFFSET(2) + DEFENSE,
sizeof(fileChooseCtx->defense[0]));
memcpy(&fileChooseCtx->health[0], sramCtx->readBuff + SLOT_OFFSET(0) + HEALTH, sizeof(fileChooseCtx->health[0]));
memcpy(&fileChooseCtx->health[1], sramCtx->readBuff + SLOT_OFFSET(1) + HEALTH, sizeof(fileChooseCtx->health[0]));
memcpy(&fileChooseCtx->health[2], sramCtx->readBuff + SLOT_OFFSET(2) + HEALTH, sizeof(fileChooseCtx->health[0]));
osSyncPrintf("f_64dd=%d, %d, %d\n", fileChooseCtx->n64ddFlags[0], fileChooseCtx->n64ddFlags[1],
fileChooseCtx->n64ddFlags[2]);
osSyncPrintf("heart_status=%d, %d, %d\n", fileChooseCtx->defense[0], fileChooseCtx->defense[1],
fileChooseCtx->defense[2]);
osSyncPrintf("now_life=%d, %d, %d\n", fileChooseCtx->health[0], fileChooseCtx->health[1], fileChooseCtx->health[2]);
}
void Sram_InitSave(FileChooseContext* fileChooseCtx, SramContext* sramCtx) {
u16 offset; u16 offset;
u16 j; u16 j;
u16* ptr; u16* ptr;
@ -693,189 +199,14 @@ void Sram_InitSave(FileChooseContext* fileChooseCtx, SramContext* sramCtx) {
} }
for (offset = 0; offset < 8; offset++) { for (offset = 0; offset < 8; offset++) {
gSaveContext.playerName[offset] = fileChooseCtx->fileNames[fileChooseCtx->buttonIndex][offset]; gSaveContext.playerName[offset] = Save_GetSaveMetaInfo(fileChooseCtx->buttonIndex)->playerName[offset];
} }
gSaveContext.newf[0] = 'Z'; Save_SaveFile();
gSaveContext.newf[1] = 'E';
gSaveContext.newf[2] = 'L';
gSaveContext.newf[3] = 'D';
gSaveContext.newf[4] = 'A';
gSaveContext.newf[5] = 'Z';
gSaveContext.n64ddFlag = fileChooseCtx->n64ddFlag;
osSyncPrintf("64DDフラグ=%d\n", fileChooseCtx->n64ddFlag);
osSyncPrintf("newf=%x,%x,%x,%x,%x,%x\n", gSaveContext.newf[0], gSaveContext.newf[1], gSaveContext.newf[2],
gSaveContext.newf[3], gSaveContext.newf[4], gSaveContext.newf[5]);
osSyncPrintf("\n$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n");
ptr = (u16*)&gSaveContext;
j = 0;
checksum = 0;
for (offset = 0; offset < CHECKSUM_SIZE; offset++) {
osSyncPrintf("%x ", *ptr);
checksum += *ptr++;
if (++j == 0x20) {
osSyncPrintf("\n");
j = 0;
}
} }
gSaveContext.checksum = checksum; void Sram_InitSram(GameState* gameState) {
osSyncPrintf("\nチェックサム=%x\n", gSaveContext.checksum); // "Checksum = %x" Save_Init();
offset = gSramSlotOffsets[gSaveContext.fileNum];
osSyncPrintf("I=%x no=%d\n", offset, gSaveContext.fileNum);
memcpy(sramCtx->readBuff + offset, &gSaveContext, sizeof(Save));
offset = gSramSlotOffsets[gSaveContext.fileNum + 3];
osSyncPrintf("I=%x no=%d\n", offset, gSaveContext.fileNum + 3);
memcpy(sramCtx->readBuff + offset, &gSaveContext, sizeof(Save));
SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000), sramCtx->readBuff, SRAM_SIZE, OS_WRITE);
osSyncPrintf("SAVE終了\n"); // "SAVE end"
osSyncPrintf("z_common_data.file_no = %d\n", gSaveContext.fileNum);
osSyncPrintf("SAVECT=%x, NAME=%x, LIFE=%x, ITEM=%x, SAVE_64DD=%x\n", DEATHS, NAME, HEALTH_CAP, QUEST, N64DD);
j = gSramSlotOffsets[gSaveContext.fileNum];
memcpy(&fileChooseCtx->deaths[gSaveContext.fileNum], sramCtx->readBuff + j + DEATHS,
sizeof(fileChooseCtx->deaths[0]));
memcpy(&fileChooseCtx->fileNames[gSaveContext.fileNum], sramCtx->readBuff + j + NAME,
sizeof(fileChooseCtx->fileNames[0]));
memcpy(&fileChooseCtx->healthCapacities[gSaveContext.fileNum], sramCtx->readBuff + j + HEALTH_CAP,
sizeof(fileChooseCtx->healthCapacities[0]));
memcpy(&fileChooseCtx->questItems[gSaveContext.fileNum], sramCtx->readBuff + j + QUEST,
sizeof(fileChooseCtx->questItems[0]));
memcpy(&fileChooseCtx->n64ddFlags[gSaveContext.fileNum], sramCtx->readBuff + j + N64DD,
sizeof(fileChooseCtx->n64ddFlags[0]));
memcpy(&fileChooseCtx->defense[gSaveContext.fileNum], sramCtx->readBuff + j + DEFENSE,
sizeof(fileChooseCtx->defense[0]));
memcpy(&fileChooseCtx->health[gSaveContext.fileNum], sramCtx->readBuff + j + HEALTH,
sizeof(fileChooseCtx->health[0]));
osSyncPrintf("f_64dd[%d]=%d\n", gSaveContext.fileNum, fileChooseCtx->n64ddFlags[gSaveContext.fileNum]);
osSyncPrintf("heart_status[%d]=%d\n", gSaveContext.fileNum, fileChooseCtx->defense[gSaveContext.fileNum]);
osSyncPrintf("now_life[%d]=%d\n", gSaveContext.fileNum, fileChooseCtx->health[gSaveContext.fileNum]);
}
void Sram_EraseSave(FileChooseContext* fileChooseCtx, SramContext* sramCtx) {
s32 offset;
Sram_InitNewSave();
offset = gSramSlotOffsets[fileChooseCtx->selectedFileIndex];
memcpy(sramCtx->readBuff + offset, &gSaveContext, sizeof(Save));
SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000) + offset, &gSaveContext, SLOT_SIZE, OS_WRITE);
memcpy(&fileChooseCtx->n64ddFlags[fileChooseCtx->selectedFileIndex], sramCtx->readBuff + offset + N64DD,
sizeof(fileChooseCtx->n64ddFlags[0]));
offset = gSramSlotOffsets[fileChooseCtx->selectedFileIndex + 3];
memcpy(sramCtx->readBuff + offset, &gSaveContext, sizeof(Save));
SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000) + offset, &gSaveContext, SLOT_SIZE, OS_WRITE);
osSyncPrintf("CLEAR終了\n");
}
void Sram_CopySave(FileChooseContext* fileChooseCtx, SramContext* sramCtx) {
s32 offset;
osSyncPrintf("=%d(%x) =%d(%x)\n", fileChooseCtx->selectedFileIndex,
gSramSlotOffsets[fileChooseCtx->selectedFileIndex], fileChooseCtx->copyDestFileIndex,
gSramSlotOffsets[fileChooseCtx->copyDestFileIndex]);
offset = gSramSlotOffsets[fileChooseCtx->selectedFileIndex];
memcpy(&gSaveContext, sramCtx->readBuff + offset, sizeof(Save));
offset = gSramSlotOffsets[fileChooseCtx->copyDestFileIndex];
memcpy(sramCtx->readBuff + offset, &gSaveContext, sizeof(Save));
offset = gSramSlotOffsets[fileChooseCtx->copyDestFileIndex + 3];
memcpy(sramCtx->readBuff + offset, &gSaveContext, sizeof(Save));
SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000), sramCtx->readBuff, SRAM_SIZE, OS_WRITE);
offset = gSramSlotOffsets[fileChooseCtx->copyDestFileIndex];
memcpy(&fileChooseCtx->deaths[fileChooseCtx->copyDestFileIndex], sramCtx->readBuff + offset + DEATHS,
sizeof(fileChooseCtx->deaths[0]));
memcpy(&fileChooseCtx->fileNames[fileChooseCtx->copyDestFileIndex], sramCtx->readBuff + offset + NAME,
sizeof(fileChooseCtx->fileNames[0]));
memcpy(&fileChooseCtx->healthCapacities[fileChooseCtx->copyDestFileIndex], sramCtx->readBuff + offset + HEALTH_CAP,
sizeof(fileChooseCtx->healthCapacities[0]));
memcpy(&fileChooseCtx->questItems[fileChooseCtx->copyDestFileIndex], sramCtx->readBuff + offset + QUEST,
sizeof(fileChooseCtx->questItems[0]));
memcpy(&fileChooseCtx->n64ddFlags[fileChooseCtx->copyDestFileIndex], sramCtx->readBuff + offset + N64DD,
sizeof(fileChooseCtx->n64ddFlags[0]));
memcpy(&fileChooseCtx->defense[fileChooseCtx->copyDestFileIndex], sramCtx->readBuff + offset + DEFENSE,
sizeof(fileChooseCtx->defense[0]));
memcpy(&fileChooseCtx->health[fileChooseCtx->copyDestFileIndex], (sramCtx->readBuff + offset) + HEALTH,
sizeof(fileChooseCtx->health[0]));
osSyncPrintf("f_64dd[%d]=%d\n", gSaveContext.fileNum, fileChooseCtx->n64ddFlags[gSaveContext.fileNum]);
osSyncPrintf("heart_status[%d]=%d\n", gSaveContext.fileNum, fileChooseCtx->defense[gSaveContext.fileNum]);
osSyncPrintf("COPY終了\n"); // "Copy end"
}
/**
* Write the first 16 bytes of the read buffer to the SRAM header
*/
void Sram_WriteSramHeader(SramContext* sramCtx) {
SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000), sramCtx->readBuff, SRAM_HEADER_SIZE, OS_WRITE);
}
void Sram_InitSram(GameState* gameState, SramContext* sramCtx) {
u16 i;
osSyncPrintf("sram_initialize( Game *game, Sram *sram )\n");
SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000), sramCtx->readBuff, SRAM_SIZE, OS_READ);
for (i = 0; i < ARRAY_COUNTU(sZeldaMagic) - 3; i++) {
if (sZeldaMagic[i + SRAM_HEADER_MAGIC] != sramCtx->readBuff[i + SRAM_HEADER_MAGIC]) {
osSyncPrintf("SRAM破壊!!!!!!\n"); // "SRAM destruction! ! ! ! ! !"
gSaveContext.language = CVar_GetS32("gLanguages", 0);
memcpy(sramCtx->readBuff, sZeldaMagic, sizeof(sZeldaMagic));
sramCtx->readBuff[SRAM_HEADER_LANGUAGE] = gSaveContext.language;
Sram_WriteSramHeader(sramCtx);
}
}
gSaveContext.audioSetting = sramCtx->readBuff[SRAM_HEADER_SOUND] & 3;
gSaveContext.zTargetSetting = sramCtx->readBuff[SRAM_HEADER_ZTARGET] & 1;
gSaveContext.language = CVar_GetS32("gLanguages", 0);
if (gSaveContext.language >= LANGUAGE_MAX) {
gSaveContext.language = LANGUAGE_ENG;
sramCtx->readBuff[SRAM_HEADER_LANGUAGE] = gSaveContext.language;
Sram_WriteSramHeader(sramCtx);
}
if (CHECK_BTN_ANY(gameState->input[2].cur.button, BTN_DRIGHT)) {
memset(sramCtx->readBuff, 0,SRAM_SIZE);
for (i = 0; i < CHECKSUM_SIZE; i++) {
sramCtx->readBuff[i] = i;
}
SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000), sramCtx->readBuff, SRAM_SIZE, OS_WRITE);
osSyncPrintf("SRAM破壊!!!!!!\n"); // "SRAM destruction! ! ! ! ! !"
}
// "GOOD! GOOD! Size = %d + %d = %d"
osSyncPrintf(" サイズ=%d + %d %d\n", sizeof(SaveInfo), 4, sizeof(SaveInfo) + 4);
osSyncPrintf(VT_FGCOL(BLUE));
osSyncPrintf("Na_SetSoundOutputMode = %d\n", gSaveContext.audioSetting);
osSyncPrintf("Na_SetSoundOutputMode = %d\n", gSaveContext.audioSetting);
osSyncPrintf("Na_SetSoundOutputMode = %d\n", gSaveContext.audioSetting);
osSyncPrintf(VT_RST);
func_800F6700(gSaveContext.audioSetting); func_800F6700(gSaveContext.audioSetting);
} }
void Sram_Alloc(GameState* gameState, SramContext* sramCtx) {
sramCtx->readBuff = GameState_Alloc(gameState, SRAM_SIZE, "../z_sram.c", 1294);
ASSERT(sramCtx->readBuff != NULL, "sram->read_buff != NULL", "../z_sram.c", 1295);
}
void Sram_Init(GlobalContext* globalCtx, SramContext* sramCtx) {
}

View File

@ -5,17 +5,6 @@
#include "global.h" #include "global.h"
#include "vt.h" #include "vt.h"
#define GET_NEWF(sramCtx, slotNum, index) (sramCtx->readBuff[gSramSlotOffsets[slotNum] + OFFSETOF(SaveContext, newf[index])])
#define SLOT_OCCUPIED(sramCtx, slotNum) \
((GET_NEWF(sramCtx, slotNum, 0) == 'Z') || \
(GET_NEWF(sramCtx, slotNum, 1) == 'E') || \
(GET_NEWF(sramCtx, slotNum, 2) == 'L') || \
(GET_NEWF(sramCtx, slotNum, 3) == 'D') || \
(GET_NEWF(sramCtx, slotNum, 4) == 'A') || \
(GET_NEWF(sramCtx, slotNum, 5) == 'Z'))
// Init mode: Initial setup as the file select is starting up, fades and slides in various menu elements // Init mode: Initial setup as the file select is starting up, fades and slides in various menu elements
// Config mode: Handles the bulk of the file select, various configuration tasks like picking a file, copy/erase, and the options menu // Config mode: Handles the bulk of the file select, various configuration tasks like picking a file, copy/erase, and the options menu
// Select mode: Displays the selected file with various details about it, and allows the player to confirm and open it // Select mode: Displays the selected file with various details about it, and allows the player to confirm and open it

View File

@ -64,9 +64,6 @@ void FileChoose_InitModeUpdate(GameState* thisx) {
this->menuMode = FS_MENU_MODE_CONFIG; this->menuMode = FS_MENU_MODE_CONFIG;
this->configMode = CM_FADE_IN_START; this->configMode = CM_FADE_IN_START;
this->nextTitleLabel = FS_TITLE_OPEN_FILE; this->nextTitleLabel = FS_TITLE_OPEN_FILE;
osSyncPrintf(" Start─Load 》》》》》 ");
Sram_VerifyAndLoadAllSaves(this, &this->sramCtx);
osSyncPrintf("終了!!!\n");
} }
} }
@ -80,7 +77,6 @@ void FileChoose_InitModeDraw(GameState* thisx) {
*/ */
void FileChoose_FadeInMenuElements(GameState* thisx) { void FileChoose_FadeInMenuElements(GameState* thisx) {
FileChooseContext* this = (FileChooseContext*)thisx; FileChooseContext* this = (FileChooseContext*)thisx;
SramContext* sramCtx = &this->sramCtx;
s16 i; s16 i;
this->titleAlpha[0] += VREG(1); this->titleAlpha[0] += VREG(1);
@ -89,7 +85,7 @@ void FileChoose_FadeInMenuElements(GameState* thisx) {
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
this->fileButtonAlpha[i] = this->windowAlpha; this->fileButtonAlpha[i] = this->windowAlpha;
if (SLOT_OCCUPIED(sramCtx, i)) { if (Save_GetSaveMetaInfo(i)->valid) {
this->nameBoxAlpha[i] = this->nameAlpha[i] = this->windowAlpha; this->nameBoxAlpha[i] = this->nameAlpha[i] = this->windowAlpha;
this->connectorAlpha[i] += VREG(1); this->connectorAlpha[i] += VREG(1);
if (this->connectorAlpha[i] >= 255) { if (this->connectorAlpha[i] >= 255) {
@ -176,18 +172,12 @@ void FileChoose_FinishFadeIn(GameState* thisx) {
void FileChoose_UpdateMainMenu(GameState* thisx) { void FileChoose_UpdateMainMenu(GameState* thisx) {
static u8 emptyName[] = { 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E }; static u8 emptyName[] = { 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E };
FileChooseContext* this = (FileChooseContext*)thisx; FileChooseContext* this = (FileChooseContext*)thisx;
SramContext* sramCtx = &this->sramCtx;
Input* input = &this->state.input[0]; Input* input = &this->state.input[0];
bool dpad = CVar_GetS32("gDpadPauseName", 0); bool dpad = CVar_GetS32("gDpadPauseName", 0);
if (CHECK_BTN_ALL(input->press.button, BTN_START) || CHECK_BTN_ALL(input->press.button, BTN_A)) { if (CHECK_BTN_ALL(input->press.button, BTN_START) || CHECK_BTN_ALL(input->press.button, BTN_A)) {
if (this->buttonIndex <= FS_BTN_MAIN_FILE_3) { if (this->buttonIndex <= FS_BTN_MAIN_FILE_3) {
osSyncPrintf("REGCK_ALL[%x]=%x,%x,%x,%x,%x,%x\n", this->buttonIndex, if (!Save_GetSaveMetaInfo(this->buttonIndex)->valid) {
GET_NEWF(sramCtx, this->buttonIndex, 0), GET_NEWF(sramCtx, this->buttonIndex, 1),
GET_NEWF(sramCtx, this->buttonIndex, 2), GET_NEWF(sramCtx, this->buttonIndex, 3),
GET_NEWF(sramCtx, this->buttonIndex, 4), GET_NEWF(sramCtx, this->buttonIndex, 5));
if (!SLOT_OCCUPIED(sramCtx, this->buttonIndex)) {
Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
this->configMode = CM_ROTATE_TO_NAME_ENTRY; this->configMode = CM_ROTATE_TO_NAME_ENTRY;
this->kbdButton = FS_KBD_BTN_NONE; this->kbdButton = FS_KBD_BTN_NONE;
@ -199,16 +189,14 @@ void FileChoose_UpdateMainMenu(GameState* thisx) {
this->newFileNameCharCount = 0; this->newFileNameCharCount = 0;
this->nameEntryBoxPosX = 120; this->nameEntryBoxPosX = 120;
this->nameEntryBoxAlpha = 0; this->nameEntryBoxAlpha = 0;
memcpy(&this->fileNames[this->buttonIndex][0], &emptyName, 8); memcpy(Save_GetSaveMetaInfo(this->buttonIndex)->playerName, &emptyName, 8);
} else if (this->n64ddFlags[this->buttonIndex] == this->n64ddFlag) { } else {
Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
this->actionTimer = 8; this->actionTimer = 8;
this->selectMode = SM_FADE_MAIN_TO_SELECT; this->selectMode = SM_FADE_MAIN_TO_SELECT;
this->selectedFileIndex = this->buttonIndex; this->selectedFileIndex = this->buttonIndex;
this->menuMode = FS_MENU_MODE_SELECT; this->menuMode = FS_MENU_MODE_SELECT;
this->nextTitleLabel = FS_TITLE_OPEN_FILE; this->nextTitleLabel = FS_TITLE_OPEN_FILE;
} else if (!this->n64ddFlags[this->buttonIndex]) {
Audio_PlaySoundGeneral(NA_SE_SY_FSEL_ERROR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
} }
} else { } else {
if (this->warningLabel == FS_WARNING_NONE) { if (this->warningLabel == FS_WARNING_NONE) {
@ -254,11 +242,12 @@ void FileChoose_UpdateMainMenu(GameState* thisx) {
} }
if (this->buttonIndex == FS_BTN_MAIN_COPY) { if (this->buttonIndex == FS_BTN_MAIN_COPY) {
if (!SLOT_OCCUPIED(sramCtx, 0) && !SLOT_OCCUPIED(sramCtx, 1) && !SLOT_OCCUPIED(sramCtx, 2)) { if (!Save_GetSaveMetaInfo(0)->valid && !Save_GetSaveMetaInfo(1)->valid && !Save_GetSaveMetaInfo(2)->valid) {
this->warningButtonIndex = this->buttonIndex; this->warningButtonIndex = this->buttonIndex;
this->warningLabel = FS_WARNING_NO_FILE_COPY; this->warningLabel = FS_WARNING_NO_FILE_COPY;
this->emptyFileTextAlpha = 255; this->emptyFileTextAlpha = 255;
} else if (SLOT_OCCUPIED(sramCtx, 0) && SLOT_OCCUPIED(sramCtx, 1) && SLOT_OCCUPIED(sramCtx, 2)) { } else if (Save_GetSaveMetaInfo(0)->valid && Save_GetSaveMetaInfo(1)->valid &&
Save_GetSaveMetaInfo(2)->valid) {
this->warningButtonIndex = this->buttonIndex; this->warningButtonIndex = this->buttonIndex;
this->warningLabel = FS_WARNING_NO_EMPTY_FILES; this->warningLabel = FS_WARNING_NO_EMPTY_FILES;
this->emptyFileTextAlpha = 255; this->emptyFileTextAlpha = 255;
@ -266,7 +255,7 @@ void FileChoose_UpdateMainMenu(GameState* thisx) {
this->warningLabel = FS_WARNING_NONE; this->warningLabel = FS_WARNING_NONE;
} }
} else if (this->buttonIndex == FS_BTN_MAIN_ERASE) { } else if (this->buttonIndex == FS_BTN_MAIN_ERASE) {
if (!SLOT_OCCUPIED(sramCtx, 0) && !SLOT_OCCUPIED(sramCtx, 1) && !SLOT_OCCUPIED(sramCtx, 2)) { if (!Save_GetSaveMetaInfo(0)->valid && !Save_GetSaveMetaInfo(1)->valid && !Save_GetSaveMetaInfo(2)->valid) {
this->warningButtonIndex = this->buttonIndex; this->warningButtonIndex = this->buttonIndex;
this->warningLabel = FS_WARNING_NO_FILE_ERASE; this->warningLabel = FS_WARNING_NO_FILE_ERASE;
this->emptyFileTextAlpha = 255; this->emptyFileTextAlpha = 255;
@ -379,48 +368,6 @@ void FileChoose_PulsateCursor(GameState* thisx) {
static s16 cursorAlphaTargets[] = { 70, 200 }; static s16 cursorAlphaTargets[] = { 70, 200 };
FileChooseContext* this = (FileChooseContext*)thisx; FileChooseContext* this = (FileChooseContext*)thisx;
s16 alphaStep; s16 alphaStep;
SramContext* sramCtx = &this->sramCtx;
Input* debugInput = &this->state.input[2];
if (CHECK_BTN_ALL(debugInput->press.button, BTN_DLEFT)) {
sramCtx->readBuff[SRAM_HEADER_LANGUAGE] = gSaveContext.language = LANGUAGE_ENG;
*((u8*)0x80000002) = LANGUAGE_ENG;
SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000), sramCtx->readBuff, 3, OS_WRITE);
osSyncPrintf("1:read_buff[]=%x, %x, %x, %x\n", sramCtx->readBuff[SRAM_HEADER_SOUND],
sramCtx->readBuff[SRAM_HEADER_ZTARGET], sramCtx->readBuff[SRAM_HEADER_LANGUAGE],
sramCtx->readBuff[SRAM_HEADER_MAGIC]);
SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000), sramCtx->readBuff, SRAM_SIZE, OS_READ);
osSyncPrintf("read_buff[]=%x, %x, %x, %x\n", sramCtx->readBuff[SRAM_HEADER_SOUND],
sramCtx->readBuff[SRAM_HEADER_ZTARGET], sramCtx->readBuff[SRAM_HEADER_LANGUAGE],
sramCtx->readBuff[SRAM_HEADER_MAGIC]);
} else if (CHECK_BTN_ALL(debugInput->press.button, BTN_DUP)) {
sramCtx->readBuff[SRAM_HEADER_LANGUAGE] = gSaveContext.language = LANGUAGE_GER;
*((u8*)0x80000002) = LANGUAGE_GER;
SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000), sramCtx->readBuff, 3, OS_WRITE);
osSyncPrintf("1:read_buff[]=%x, %x, %x, %x\n", sramCtx->readBuff[SRAM_HEADER_SOUND],
sramCtx->readBuff[SRAM_HEADER_ZTARGET], sramCtx->readBuff[SRAM_HEADER_LANGUAGE],
sramCtx->readBuff[SRAM_HEADER_MAGIC]);
SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000), sramCtx->readBuff, SRAM_SIZE, OS_READ);
osSyncPrintf("read_buff[]=%x, %x, %x, %x\n", sramCtx->readBuff[SRAM_HEADER_SOUND],
sramCtx->readBuff[SRAM_HEADER_ZTARGET], sramCtx->readBuff[SRAM_HEADER_LANGUAGE],
sramCtx->readBuff[SRAM_HEADER_MAGIC]);
} else if (CHECK_BTN_ALL(debugInput->press.button, BTN_DRIGHT)) {
sramCtx->readBuff[SRAM_HEADER_LANGUAGE] = gSaveContext.language = LANGUAGE_FRA;
*((u8*)0x80000002) = LANGUAGE_FRA;
SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000), sramCtx->readBuff, 3, OS_WRITE);
osSyncPrintf("1:read_buff[]=%x, %x, %x, %x\n", sramCtx->readBuff[SRAM_HEADER_SOUND],
sramCtx->readBuff[SRAM_HEADER_ZTARGET], sramCtx->readBuff[SRAM_HEADER_LANGUAGE],
sramCtx->readBuff[SRAM_HEADER_MAGIC]);
SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000), sramCtx->readBuff, SRAM_SIZE, OS_READ);
osSyncPrintf("read_buff[]=%x, %x, %x, %x\n", sramCtx->readBuff[SRAM_HEADER_SOUND],
sramCtx->readBuff[SRAM_HEADER_ZTARGET], sramCtx->readBuff[SRAM_HEADER_LANGUAGE],
sramCtx->readBuff[SRAM_HEADER_MAGIC]);
}
alphaStep = ABS(this->highlightColor[3] - cursorAlphaTargets[this->highlightPulseDir]) / XREG(35); alphaStep = ABS(this->highlightColor[3] - cursorAlphaTargets[this->highlightPulseDir]) / XREG(35);
@ -510,7 +457,6 @@ void FileChoose_SetWindowContentVtx(GameState* thisx) {
s16 phi_a1; s16 phi_a1;
s16 phi_ra; s16 phi_ra;
s16 temp_t1; s16 temp_t1;
SramContext* sramCtx = &this->sramCtx;
this->windowContentVtx = Graph_Alloc(this->state.gfxCtx, 0x288 * sizeof(Vtx)); this->windowContentVtx = Graph_Alloc(this->state.gfxCtx, 0x288 * sizeof(Vtx));
@ -648,7 +594,7 @@ void FileChoose_SetWindowContentVtx(GameState* thisx) {
phi_ra = 0x2C; phi_ra = 0x2C;
for (phi_t5 = 0; phi_t5 < 3; phi_t5++, phi_ra -= WREG(38)) { for (phi_t5 = 0; phi_t5 < 3; phi_t5++, phi_ra -= WREG(38)) {
if (SLOT_OCCUPIED(sramCtx, phi_t5)) { if (Save_GetSaveMetaInfo(phi_t5)->valid) {
phi_t0 = this->windowPosX - WREG(39); phi_t0 = this->windowPosX - WREG(39);
if ((this->configMode == 0xF) && (phi_t5 == this->copyDestFileIndex)) { if ((this->configMode == 0xF) && (phi_t5 == this->copyDestFileIndex)) {
@ -822,8 +768,9 @@ void FileChoose_DrawFileInfo(GameState* thisx, s16 fileIndex, s16 isActive) {
sNamePrimColors[isActive][2], this->nameAlpha[fileIndex]); sNamePrimColors[isActive][2], this->nameAlpha[fileIndex]);
for (i = 0, vtxOffset = 0; vtxOffset < 0x20; i++, vtxOffset += 4) { for (i = 0, vtxOffset = 0; vtxOffset < 0x20; i++, vtxOffset += 4) {
FileChoose_DrawCharacter(this->state.gfxCtx, FileChoose_DrawCharacter(
sp54->fontBuf + this->fileNames[fileIndex][i] * FONT_CHAR_TEX_SIZE, vtxOffset); this->state.gfxCtx, sp54->fontBuf + Save_GetSaveMetaInfo(fileIndex)->playerName[i] * FONT_CHAR_TEX_SIZE,
vtxOffset);
} }
} }
@ -834,7 +781,8 @@ void FileChoose_DrawFileInfo(GameState* thisx, s16 fileIndex, s16 isActive) {
gDPSetPrimColor(POLY_OPA_DISP++, 0x00, 0x00, 255, 255, 255, this->fileInfoAlpha[fileIndex]); gDPSetPrimColor(POLY_OPA_DISP++, 0x00, 0x00, 255, 255, 255, this->fileInfoAlpha[fileIndex]);
gSPVertex(POLY_OPA_DISP++, &this->windowContentVtx[D_8081284C[fileIndex]] + 0x24, 12, 0); gSPVertex(POLY_OPA_DISP++, &this->windowContentVtx[D_8081284C[fileIndex]] + 0x24, 12, 0);
FileChoose_SplitNumber(this->deaths[fileIndex], &deathCountSplit[0], &deathCountSplit[1], &deathCountSplit[2]); FileChoose_SplitNumber(Save_GetSaveMetaInfo(fileIndex)->deaths, &deathCountSplit[0], &deathCountSplit[1],
&deathCountSplit[2]);
// draw death count // draw death count
for (i = 0, vtxOffset = 0; i < 3; i++, vtxOffset += 4) { for (i = 0, vtxOffset = 0; i < 3; i++, vtxOffset += 4) {
@ -844,7 +792,7 @@ void FileChoose_DrawFileInfo(GameState* thisx, s16 fileIndex, s16 isActive) {
gDPPipeSync(POLY_OPA_DISP++); gDPPipeSync(POLY_OPA_DISP++);
heartType = (this->defense[fileIndex] == 0) ? 0 : 1; heartType = (Save_GetSaveMetaInfo(fileIndex)->defense == 0) ? 0 : 1;
gDPPipeSync(POLY_OPA_DISP++); gDPPipeSync(POLY_OPA_DISP++);
gDPSetCombineLERP(POLY_OPA_DISP++, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0, gDPSetCombineLERP(POLY_OPA_DISP++, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0,
@ -854,7 +802,7 @@ void FileChoose_DrawFileInfo(GameState* thisx, s16 fileIndex, s16 isActive) {
gDPSetEnvColor(POLY_OPA_DISP++, sHeartEnvColors[heartType][0], sHeartEnvColors[heartType][1], gDPSetEnvColor(POLY_OPA_DISP++, sHeartEnvColors[heartType][0], sHeartEnvColors[heartType][1],
sHeartEnvColors[heartType][2], 255); sHeartEnvColors[heartType][2], 255);
i = this->healthCapacities[fileIndex] / 0x10; i = Save_GetSaveMetaInfo(fileIndex)->healthCapacity / 0x10;
// draw hearts // draw hearts
for (vtxOffset = 0, j = 0; j < i; j++, vtxOffset += 4) { for (vtxOffset = 0, j = 0; j < i; j++, vtxOffset += 4) {
@ -867,7 +815,7 @@ void FileChoose_DrawFileInfo(GameState* thisx, s16 fileIndex, s16 isActive) {
// draw quest items // draw quest items
for (vtxOffset = 0, j = 0; j < 9; j++, vtxOffset += 4) { for (vtxOffset = 0, j = 0; j < 9; j++, vtxOffset += 4) {
if (this->questItems[fileIndex] & gBitFlags[sQuestItemFlags[j]]) { if (Save_GetSaveMetaInfo(fileIndex)->questItems & gBitFlags[sQuestItemFlags[j]]) {
gSPVertex(POLY_OPA_DISP++, &this->windowContentVtx[D_8081284C[fileIndex] + vtxOffset] + 0x80, 4, 0); gSPVertex(POLY_OPA_DISP++, &this->windowContentVtx[D_8081284C[fileIndex] + vtxOffset] + 0x80, 4, 0);
gDPPipeSync(POLY_OPA_DISP++); gDPPipeSync(POLY_OPA_DISP++);
gDPSetPrimColor(POLY_OPA_DISP++, 0x00, 0x00, sQuestItemRed[j], sQuestItemGreen[j], sQuestItemBlue[j], gDPSetPrimColor(POLY_OPA_DISP++, 0x00, 0x00, sQuestItemRed[j], sQuestItemGreen[j], sQuestItemBlue[j],
@ -998,7 +946,7 @@ void FileChoose_DrawWindowContents(GameState* thisx) {
// draw file button // draw file button
gSPVertex(POLY_OPA_DISP++, &this->windowContentVtx[temp], 20, 0); gSPVertex(POLY_OPA_DISP++, &this->windowContentVtx[temp], 20, 0);
isActive = ((this->n64ddFlag == this->n64ddFlags[i]) || (this->nameBoxAlpha[i] == 0)) ? 0 : 1; isActive = ((this->n64ddFlag == Save_GetSaveMetaInfo(i)->n64ddFlag) || (this->nameBoxAlpha[i] == 0)) ? 0 : 1;
if (CVar_GetS32("gHudColors", 1) == 2) { if (CVar_GetS32("gHudColors", 1) == 2) {
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, CVar_GetS32("gCCFileChoosePrimR", 100), CVar_GetS32("gCCFileChoosePrimG", 150), gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, CVar_GetS32("gCCFileChoosePrimR", 100), CVar_GetS32("gCCFileChoosePrimG", 150),
@ -1007,13 +955,13 @@ void FileChoose_DrawWindowContents(GameState* thisx) {
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, sWindowContentColors[isActive][0], sWindowContentColors[isActive][1], gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, sWindowContentColors[isActive][0], sWindowContentColors[isActive][1],
sWindowContentColors[isActive][2], this->fileButtonAlpha[i]); sWindowContentColors[isActive][2], this->fileButtonAlpha[i]);
} }
gDPLoadTextureBlock(POLY_OPA_DISP++, sFileButtonTextures[gSaveContext.language][i], G_IM_FMT_IA, G_IM_SIZ_16b, gDPLoadTextureBlock(POLY_OPA_DISP++, sFileButtonTextures[gSaveContext.language][i], G_IM_FMT_IA, G_IM_SIZ_16b,
64, 16, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, 64, 16, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK,
G_TX_NOLOD, G_TX_NOLOD); G_TX_NOLOD, G_TX_NOLOD);
gSP1Quadrangle(POLY_OPA_DISP++, 0, 2, 3, 1, 0); gSP1Quadrangle(POLY_OPA_DISP++, 0, 2, 3, 1, 0);
// draw file name box // draw file name box
if (CVar_GetS32("gHudColors", 1) == 2) { if (CVar_GetS32("gHudColors", 1) == 2) {
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, CVar_GetS32("gCCFileChoosePrimR", 100), CVar_GetS32("gCCFileChoosePrimG", 150), gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, CVar_GetS32("gCCFileChoosePrimR", 100), CVar_GetS32("gCCFileChoosePrimG", 150),
CVar_GetS32("gCCFileChoosePrimB", 255), this->nameBoxAlpha[i]); CVar_GetS32("gCCFileChoosePrimB", 255), this->nameBoxAlpha[i]);
@ -1021,14 +969,14 @@ void FileChoose_DrawWindowContents(GameState* thisx) {
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, sWindowContentColors[isActive][0], sWindowContentColors[isActive][1], gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, sWindowContentColors[isActive][0], sWindowContentColors[isActive][1],
sWindowContentColors[isActive][2], this->nameBoxAlpha[i]); sWindowContentColors[isActive][2], this->nameBoxAlpha[i]);
} }
gDPLoadTextureBlock(POLY_OPA_DISP++, gFileSelNameBoxTex, G_IM_FMT_IA, G_IM_SIZ_16b, 108, 16, 0, gDPLoadTextureBlock(POLY_OPA_DISP++, gFileSelNameBoxTex, G_IM_FMT_IA, G_IM_SIZ_16b, 108, 16, 0,
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD,
G_TX_NOLOD); G_TX_NOLOD);
gSP1Quadrangle(POLY_OPA_DISP++, 4, 6, 7, 5, 0); gSP1Quadrangle(POLY_OPA_DISP++, 4, 6, 7, 5, 0);
// draw disk label for 64DD // draw disk label for 64DD
if (this->n64ddFlags[i]) { if (Save_GetSaveMetaInfo(i)->n64ddFlag) {
if (CVar_GetS32("gHudColors", 1) == 2) { if (CVar_GetS32("gHudColors", 1) == 2) {
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, CVar_GetS32("gCCFileChoosePrimR", 0), gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, CVar_GetS32("gCCFileChoosePrimR", 0),
CVar_GetS32("gCCFileChoosePrimG", 200), CVar_GetS32("gCCFileChoosePrimB", 255), CVar_GetS32("gCCFileChoosePrimG", 200), CVar_GetS32("gCCFileChoosePrimB", 255),
@ -1045,10 +993,10 @@ void FileChoose_DrawWindowContents(GameState* thisx) {
} }
// draw connectors // draw connectors
if (CVar_GetS32("gHudColors", 1) == 2) { if (CVar_GetS32("gHudColors", 1) == 2) {
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, CVar_GetS32("gCCFileChoosePrimR", 100), CVar_GetS32("gCCFileChoosePrimG", 150), gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, CVar_GetS32("gCCFileChoosePrimR", 100),
CVar_GetS32("gCCFileChoosePrimB", 255), this->connectorAlpha[i]); CVar_GetS32("gCCFileChoosePrimG", 150), CVar_GetS32("gCCFileChoosePrimB", 255),
this->connectorAlpha[i]);
} else { } else {
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, sWindowContentColors[isActive][0], sWindowContentColors[isActive][1], gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, sWindowContentColors[isActive][0], sWindowContentColors[isActive][1],
sWindowContentColors[isActive][2], this->connectorAlpha[i]); sWindowContentColors[isActive][2], this->connectorAlpha[i]);
@ -1058,14 +1006,14 @@ void FileChoose_DrawWindowContents(GameState* thisx) {
G_TX_NOLOD); G_TX_NOLOD);
gSP1Quadrangle(POLY_OPA_DISP++, 12, 14, 15, 13, 0); gSP1Quadrangle(POLY_OPA_DISP++, 12, 14, 15, 13, 0);
if (this->n64ddFlags[i]) { if (Save_GetSaveMetaInfo(i)->n64ddFlag) {
gSP1Quadrangle(POLY_OPA_DISP++, 16, 18, 19, 17, 0); gSP1Quadrangle(POLY_OPA_DISP++, 16, 18, 19, 17, 0);
} }
} }
// draw file info // draw file info
for (fileIndex = 0; fileIndex < 3; fileIndex++) { for (fileIndex = 0; fileIndex < 3; fileIndex++) {
isActive = ((this->n64ddFlag == this->n64ddFlags[fileIndex]) || (this->nameBoxAlpha[fileIndex] == 0)) ? 0 : 1; isActive = ((this->n64ddFlag == Save_GetSaveMetaInfo(fileIndex)->n64ddFlag) || (this->nameBoxAlpha[fileIndex] == 0)) ? 0 : 1;
FileChoose_DrawFileInfo(&this->state, fileIndex, isActive); FileChoose_DrawFileInfo(&this->state, fileIndex, isActive);
} }
@ -1315,7 +1263,6 @@ void FileChoose_ConfigModeDraw(GameState* thisx) {
*/ */
void FileChoose_FadeMainToSelect(GameState* thisx) { void FileChoose_FadeMainToSelect(GameState* thisx) {
FileChooseContext* this = (FileChooseContext*)thisx; FileChooseContext* this = (FileChooseContext*)thisx;
SramContext* sramCtx = &this->sramCtx;
s16 i; s16 i;
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
@ -1324,7 +1271,7 @@ void FileChoose_FadeMainToSelect(GameState* thisx) {
this->actionButtonAlpha[FS_BTN_ACTION_COPY] = this->actionButtonAlpha[FS_BTN_ACTION_ERASE] = this->actionButtonAlpha[FS_BTN_ACTION_COPY] = this->actionButtonAlpha[FS_BTN_ACTION_ERASE] =
this->optionButtonAlpha = this->fileButtonAlpha[i]; this->optionButtonAlpha = this->fileButtonAlpha[i];
if (SLOT_OCCUPIED(sramCtx, i)) { if (Save_GetSaveMetaInfo(i)->valid) {
this->nameAlpha[i] = this->nameBoxAlpha[i] = this->fileButtonAlpha[i]; this->nameAlpha[i] = this->nameBoxAlpha[i] = this->fileButtonAlpha[i];
this->connectorAlpha[i] -= 31; this->connectorAlpha[i] -= 31;
} }
@ -1445,7 +1392,6 @@ void FileChoose_FadeOutFileInfo(GameState* thisx) {
*/ */
void FileChoose_MoveSelectedFileToSlot(GameState* thisx) { void FileChoose_MoveSelectedFileToSlot(GameState* thisx) {
FileChooseContext* this = (FileChooseContext*)thisx; FileChooseContext* this = (FileChooseContext*)thisx;
SramContext* sramCtx = &this->sramCtx;
s16 yStep; s16 yStep;
s16 i; s16 i;
@ -1467,7 +1413,7 @@ void FileChoose_MoveSelectedFileToSlot(GameState* thisx) {
this->actionButtonAlpha[FS_BTN_ACTION_COPY] = this->actionButtonAlpha[FS_BTN_ACTION_ERASE] = this->actionButtonAlpha[FS_BTN_ACTION_COPY] = this->actionButtonAlpha[FS_BTN_ACTION_ERASE] =
this->optionButtonAlpha = this->fileButtonAlpha[i]; this->optionButtonAlpha = this->fileButtonAlpha[i];
if (SLOT_OCCUPIED(sramCtx, i)) { if (Save_GetSaveMetaInfo(i)->valid) {
this->nameBoxAlpha[i] = this->nameAlpha[i] = this->fileButtonAlpha[i]; this->nameBoxAlpha[i] = this->nameAlpha[i] = this->fileButtonAlpha[i];
this->connectorAlpha[i] += 31; this->connectorAlpha[i] += 31;
} }
@ -1518,14 +1464,14 @@ void FileChoose_LoadGame(GameState* thisx) {
if (this->buttonIndex == FS_BTN_SELECT_FILE_1 && CVar_GetS32("gDebugEnabled", 0)) { if (this->buttonIndex == FS_BTN_SELECT_FILE_1 && CVar_GetS32("gDebugEnabled", 0)) {
Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
gSaveContext.fileNum = this->buttonIndex; gSaveContext.fileNum = this->buttonIndex;
Sram_OpenSave(&this->sramCtx); Sram_OpenSave();
gSaveContext.gameMode = 0; gSaveContext.gameMode = 0;
SET_NEXT_GAMESTATE(&this->state, Select_Init, SelectContext); SET_NEXT_GAMESTATE(&this->state, Select_Init, SelectContext);
this->state.running = false; this->state.running = false;
} else { } else {
Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
gSaveContext.fileNum = this->buttonIndex; gSaveContext.fileNum = this->buttonIndex;
Sram_OpenSave(&this->sramCtx); Sram_OpenSave();
gSaveContext.gameMode = 0; gSaveContext.gameMode = 0;
SET_NEXT_GAMESTATE(&this->state, Gameplay_Init, GlobalContext); SET_NEXT_GAMESTATE(&this->state, Gameplay_Init, GlobalContext);
this->state.running = false; this->state.running = false;
@ -1840,9 +1786,6 @@ void FileChoose_Main(GameState* thisx) {
void FileChoose_InitContext(GameState* thisx) { void FileChoose_InitContext(GameState* thisx) {
FileChooseContext* this = (FileChooseContext*)thisx; FileChooseContext* this = (FileChooseContext*)thisx;
EnvironmentContext* envCtx = &this->envCtx; EnvironmentContext* envCtx = &this->envCtx;
SramContext* sramCtx = &this->sramCtx;
Sram_Alloc(&this->state, sramCtx);
ZREG(7) = 32; ZREG(7) = 32;
ZREG(8) = 22; ZREG(8) = 22;
@ -1995,17 +1938,6 @@ void FileChoose_InitContext(GameState* thisx) {
gSaveContext.buttonStatus[0] = gSaveContext.buttonStatus[1] = gSaveContext.buttonStatus[2] = gSaveContext.buttonStatus[0] = gSaveContext.buttonStatus[1] = gSaveContext.buttonStatus[2] =
gSaveContext.buttonStatus[3] = gSaveContext.buttonStatus[4] = BTN_ENABLED; gSaveContext.buttonStatus[3] = gSaveContext.buttonStatus[4] = BTN_ENABLED;
this->n64ddFlags[0] = this->n64ddFlags[1] = this->n64ddFlags[2] = this->defense[0] = this->defense[1] =
this->defense[2] = 0;
SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000), sramCtx->readBuff, SRAM_SIZE, OS_READ);
gSaveContext.language = sramCtx->readBuff[SRAM_HEADER_LANGUAGE];
if (gSaveContext.language >= LANGUAGE_MAX) {
sramCtx->readBuff[SRAM_HEADER_LANGUAGE] = gSaveContext.language = LANGUAGE_ENG;
}
} }
void FileChoose_Destroy(GameState* thisx) { void FileChoose_Destroy(GameState* thisx) {

View File

@ -60,7 +60,6 @@ void FileChoose_SetupCopySource(GameState* thisx) {
*/ */
void FileChoose_SelectCopySource(GameState* thisx) { void FileChoose_SelectCopySource(GameState* thisx) {
FileChooseContext* this = (FileChooseContext*)thisx; FileChooseContext* this = (FileChooseContext*)thisx;
SramContext* sramCtx = &this->sramCtx;
Input* input = &this->state.input[0]; Input* input = &this->state.input[0];
bool dpad = CVar_GetS32("gDpadPauseName", 0); bool dpad = CVar_GetS32("gDpadPauseName", 0);
@ -73,7 +72,7 @@ void FileChoose_SelectCopySource(GameState* thisx) {
this->warningLabel = FS_WARNING_NONE; this->warningLabel = FS_WARNING_NONE;
Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CLOSE, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CLOSE, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
} else if (CHECK_BTN_ANY(input->press.button, BTN_A | BTN_START)) { } else if (CHECK_BTN_ANY(input->press.button, BTN_A | BTN_START)) {
if (SLOT_OCCUPIED(sramCtx, this->buttonIndex)) { if (Save_GetSaveMetaInfo(this->buttonIndex)->valid) {
this->actionTimer = 8; this->actionTimer = 8;
this->selectedFileIndex = this->buttonIndex; this->selectedFileIndex = this->buttonIndex;
this->configMode = CM_SETUP_COPY_DEST_1; this->configMode = CM_SETUP_COPY_DEST_1;
@ -102,7 +101,7 @@ void FileChoose_SelectCopySource(GameState* thisx) {
} }
if (this->buttonIndex != FS_BTN_COPY_QUIT) { if (this->buttonIndex != FS_BTN_COPY_QUIT) {
if (!SLOT_OCCUPIED(sramCtx, this->buttonIndex)) { if (!Save_GetSaveMetaInfo(this->buttonIndex)->valid) {
this->warningLabel = FS_WARNING_FILE_EMPTY; this->warningLabel = FS_WARNING_FILE_EMPTY;
this->warningButtonIndex = this->buttonIndex; this->warningButtonIndex = this->buttonIndex;
this->emptyFileTextAlpha = 255; this->emptyFileTextAlpha = 255;
@ -173,7 +172,6 @@ void FileChoose_SetupCopyDest2(GameState* thisx) {
*/ */
void FileChoose_SelectCopyDest(GameState* thisx) { void FileChoose_SelectCopyDest(GameState* thisx) {
FileChooseContext* this = (FileChooseContext*)thisx; FileChooseContext* this = (FileChooseContext*)thisx;
SramContext* sramCtx = &this->sramCtx;
Input* input = &this->state.input[0]; Input* input = &this->state.input[0];
bool dpad = CVar_GetS32("gDpadPauseName", 0); bool dpad = CVar_GetS32("gDpadPauseName", 0);
@ -185,7 +183,7 @@ void FileChoose_SelectCopyDest(GameState* thisx) {
this->configMode = CM_EXIT_TO_COPY_SOURCE_1; this->configMode = CM_EXIT_TO_COPY_SOURCE_1;
Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CLOSE, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CLOSE, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
} else if (CHECK_BTN_ANY(input->press.button, BTN_A | BTN_START)) { } else if (CHECK_BTN_ANY(input->press.button, BTN_A | BTN_START)) {
if (!SLOT_OCCUPIED(sramCtx, this->buttonIndex)) { if (!Save_GetSaveMetaInfo(this->buttonIndex)->valid) {
this->copyDestFileIndex = this->buttonIndex; this->copyDestFileIndex = this->buttonIndex;
this->nextTitleLabel = FS_TITLE_COPY_CONFIRM; this->nextTitleLabel = FS_TITLE_COPY_CONFIRM;
this->actionTimer = 8; this->actionTimer = 8;
@ -227,7 +225,7 @@ void FileChoose_SelectCopyDest(GameState* thisx) {
} }
if (this->buttonIndex != FS_BTN_COPY_QUIT) { if (this->buttonIndex != FS_BTN_COPY_QUIT) {
if (SLOT_OCCUPIED(sramCtx, this->buttonIndex)) { if (Save_GetSaveMetaInfo(this->buttonIndex)->valid) {
this->warningLabel = FS_WARNING_FILE_IN_USE; this->warningLabel = FS_WARNING_FILE_IN_USE;
this->warningButtonIndex = this->buttonIndex; this->warningButtonIndex = this->buttonIndex;
this->emptyFileTextAlpha = 255; this->emptyFileTextAlpha = 255;
@ -264,7 +262,6 @@ void FileChoose_ExitToCopySource1(GameState* thisx) {
*/ */
void FileChoose_ExitToCopySource2(GameState* thisx) { void FileChoose_ExitToCopySource2(GameState* thisx) {
FileChooseContext* this = (FileChooseContext*)thisx; FileChooseContext* this = (FileChooseContext*)thisx;
SramContext* sramCtx = &this->sramCtx;
s16 i; s16 i;
s16 yStep; s16 yStep;
@ -298,7 +295,6 @@ void FileChoose_ExitToCopySource2(GameState* thisx) {
void FileChoose_SetupCopyConfirm1(GameState* thisx) { void FileChoose_SetupCopyConfirm1(GameState* thisx) {
static s16 D_808124A4[] = { -56, -40, -24, 0 }; static s16 D_808124A4[] = { -56, -40, -24, 0 };
FileChooseContext* this = (FileChooseContext*)thisx; FileChooseContext* this = (FileChooseContext*)thisx;
SramContext* sramCtx = &this->sramCtx;
s16 i; s16 i;
s16 yStep; s16 yStep;
@ -309,7 +305,7 @@ void FileChoose_SetupCopyConfirm1(GameState* thisx) {
if ((i != this->copyDestFileIndex) && (i != this->selectedFileIndex)) { if ((i != this->copyDestFileIndex) && (i != this->selectedFileIndex)) {
this->fileButtonAlpha[i] -= 25; this->fileButtonAlpha[i] -= 25;
if (SLOT_OCCUPIED(sramCtx, i)) { if (Save_GetSaveMetaInfo(i)->valid) {
this->connectorAlpha[i] -= 31; this->connectorAlpha[i] -= 31;
this->nameBoxAlpha[i] = this->nameAlpha[i] = this->fileButtonAlpha[i]; this->nameBoxAlpha[i] = this->nameAlpha[i] = this->fileButtonAlpha[i];
} }
@ -359,7 +355,6 @@ void FileChoose_SetupCopyConfirm2(GameState* thisx) {
*/ */
void FileChoose_CopyConfirm(GameState* thisx) { void FileChoose_CopyConfirm(GameState* thisx) {
FileChooseContext* this = (FileChooseContext*)thisx; FileChooseContext* this = (FileChooseContext*)thisx;
SramContext* sramCtx = &this->sramCtx;
Input* input = &this->state.input[0]; Input* input = &this->state.input[0];
u16 dayTime; u16 dayTime;
bool dpad = CVar_GetS32("gDpadPauseName", 0); bool dpad = CVar_GetS32("gDpadPauseName", 0);
@ -372,7 +367,7 @@ void FileChoose_CopyConfirm(GameState* thisx) {
Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CLOSE, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CLOSE, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
} else if (CHECK_BTN_ANY(input->press.button, BTN_A | BTN_START)) { } else if (CHECK_BTN_ANY(input->press.button, BTN_A | BTN_START)) {
dayTime = gSaveContext.dayTime; dayTime = gSaveContext.dayTime;
Sram_CopySave(this, sramCtx); Save_CopyFile(this->selectedFileIndex, this->copyDestFileIndex);
gSaveContext.dayTime = dayTime; gSaveContext.dayTime = dayTime;
this->fileInfoAlpha[this->copyDestFileIndex] = this->nameAlpha[this->copyDestFileIndex] = 0; this->fileInfoAlpha[this->copyDestFileIndex] = this->nameAlpha[this->copyDestFileIndex] = 0;
this->nextTitleLabel = FS_TITLE_COPY_COMPLETE; this->nextTitleLabel = FS_TITLE_COPY_COMPLETE;
@ -392,7 +387,6 @@ void FileChoose_CopyConfirm(GameState* thisx) {
*/ */
void FileChoose_ReturnToCopyDest(GameState* thisx) { void FileChoose_ReturnToCopyDest(GameState* thisx) {
FileChooseContext* this = (FileChooseContext*)thisx; FileChooseContext* this = (FileChooseContext*)thisx;
SramContext* sramCtx = &this->sramCtx;
s16 i; s16 i;
s16 yStep; s16 yStep;
@ -404,7 +398,7 @@ void FileChoose_ReturnToCopyDest(GameState* thisx) {
if ((i != this->copyDestFileIndex) && (i != this->selectedFileIndex)) { if ((i != this->copyDestFileIndex) && (i != this->selectedFileIndex)) {
this->fileButtonAlpha[i] += 25; this->fileButtonAlpha[i] += 25;
if (SLOT_OCCUPIED(sramCtx, i)) { if (Save_GetSaveMetaInfo(i)->valid) {
this->nameBoxAlpha[i] = this->nameAlpha[i] = this->fileButtonAlpha[i]; this->nameBoxAlpha[i] = this->nameAlpha[i] = this->fileButtonAlpha[i];
this->connectorAlpha[i] += 31; this->connectorAlpha[i] += 31;
} }
@ -535,7 +529,6 @@ void FileChoose_CopyAnim4(GameState* thisx) {
*/ */
void FileChoose_CopyAnim5(GameState* thisx) { void FileChoose_CopyAnim5(GameState* thisx) {
FileChooseContext* this = (FileChooseContext*)thisx; FileChooseContext* this = (FileChooseContext*)thisx;
SramContext* sramCtx = &this->sramCtx;
s16 i; s16 i;
s16 yStep; s16 yStep;
@ -553,7 +546,7 @@ void FileChoose_CopyAnim5(GameState* thisx) {
if (i != this->buttonIndex) { if (i != this->buttonIndex) {
this->fileButtonAlpha[i] += 25; this->fileButtonAlpha[i] += 25;
if (SLOT_OCCUPIED(sramCtx, i)) { if (Save_GetSaveMetaInfo(i)->valid) {
this->nameBoxAlpha[i] = this->nameAlpha[i] = this->fileButtonAlpha[i]; this->nameBoxAlpha[i] = this->nameAlpha[i] = this->fileButtonAlpha[i];
this->connectorAlpha[i] += 31; this->connectorAlpha[i] += 31;
} }
@ -572,7 +565,7 @@ void FileChoose_CopyAnim5(GameState* thisx) {
this->fileButtonAlpha[i] = 200; this->fileButtonAlpha[i] = 200;
this->nameBoxAlpha[i] = this->nameAlpha[i] = this->connectorAlpha[i]; this->nameBoxAlpha[i] = this->nameAlpha[i] = this->connectorAlpha[i];
if (SLOT_OCCUPIED(sramCtx, i)) { if (Save_GetSaveMetaInfo(i)->valid) {
this->connectorAlpha[i] = 255; this->connectorAlpha[i] = 255;
this->nameBoxAlpha[i] = this->nameAlpha[i] = this->fileButtonAlpha[i]; this->nameBoxAlpha[i] = this->nameAlpha[i] = this->fileButtonAlpha[i];
} }
@ -681,7 +674,6 @@ void FileChoose_SetupEraseSelect(GameState* thisx) {
*/ */
void FileChoose_EraseSelect(GameState* thisx) { void FileChoose_EraseSelect(GameState* thisx) {
FileChooseContext* this = (FileChooseContext*)thisx; FileChooseContext* this = (FileChooseContext*)thisx;
SramContext* sramCtx = &this->sramCtx;
Input* input = &this->state.input[0]; Input* input = &this->state.input[0];
bool dpad = CVar_GetS32("gDpadPauseName", 0); bool dpad = CVar_GetS32("gDpadPauseName", 0);
@ -694,7 +686,7 @@ void FileChoose_EraseSelect(GameState* thisx) {
this->warningLabel = FS_WARNING_NONE; this->warningLabel = FS_WARNING_NONE;
Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CLOSE, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CLOSE, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
} else if (CHECK_BTN_ANY(input->press.button, BTN_A | BTN_START)) { } else if (CHECK_BTN_ANY(input->press.button, BTN_A | BTN_START)) {
if (SLOT_OCCUPIED(sramCtx, this->buttonIndex)) { if (Save_GetSaveMetaInfo(this->buttonIndex)->valid) {
this->actionTimer = 8; this->actionTimer = 8;
this->selectedFileIndex = this->buttonIndex; this->selectedFileIndex = this->buttonIndex;
this->configMode = CM_SETUP_ERASE_CONFIRM_1; this->configMode = CM_SETUP_ERASE_CONFIRM_1;
@ -721,7 +713,7 @@ void FileChoose_EraseSelect(GameState* thisx) {
} }
if (this->buttonIndex != FS_BTN_ERASE_QUIT) { if (this->buttonIndex != FS_BTN_ERASE_QUIT) {
if (!SLOT_OCCUPIED(sramCtx, this->buttonIndex)) { if (!Save_GetSaveMetaInfo(this->buttonIndex)->valid) {
this->warningLabel = FS_WARNING_FILE_EMPTY; this->warningLabel = FS_WARNING_FILE_EMPTY;
this->warningButtonIndex = this->buttonIndex; this->warningButtonIndex = this->buttonIndex;
this->emptyFileTextAlpha = 255; this->emptyFileTextAlpha = 255;
@ -741,7 +733,6 @@ void FileChoose_EraseSelect(GameState* thisx) {
void FileChoose_SetupEraseConfirm1(GameState* thisx) { void FileChoose_SetupEraseConfirm1(GameState* thisx) {
static s16 D_808124AC[] = { 0, 16, 32 }; static s16 D_808124AC[] = { 0, 16, 32 };
FileChooseContext* this = (FileChooseContext*)thisx; FileChooseContext* this = (FileChooseContext*)thisx;
SramContext* sramCtx = &this->sramCtx;
s16 i; s16 i;
s16 yStep; s16 yStep;
@ -749,7 +740,7 @@ void FileChoose_SetupEraseConfirm1(GameState* thisx) {
if (i != this->buttonIndex) { if (i != this->buttonIndex) {
this->fileButtonAlpha[i] -= 25; this->fileButtonAlpha[i] -= 25;
if (SLOT_OCCUPIED(sramCtx, i)) { if (Save_GetSaveMetaInfo(i)->valid) {
this->connectorAlpha[i] -= 31; this->connectorAlpha[i] -= 31;
this->nameBoxAlpha[i] = this->nameAlpha[i] = this->fileButtonAlpha[i]; this->nameBoxAlpha[i] = this->nameAlpha[i] = this->fileButtonAlpha[i];
} }
@ -775,7 +766,7 @@ void FileChoose_SetupEraseConfirm1(GameState* thisx) {
if (i != this->buttonIndex) { if (i != this->buttonIndex) {
this->fileButtonAlpha[i] = 0; this->fileButtonAlpha[i] = 0;
if (SLOT_OCCUPIED(sramCtx, i)) { if (Save_GetSaveMetaInfo(i)->valid) {
this->connectorAlpha[i] = 0; this->connectorAlpha[i] = 0;
this->nameBoxAlpha[i] = this->nameAlpha[i] = this->fileButtonAlpha[i] = 0; this->nameBoxAlpha[i] = this->nameAlpha[i] = this->fileButtonAlpha[i] = 0;
} }
@ -831,7 +822,7 @@ void FileChoose_EraseConfirm(GameState* thisx) {
this->actionTimer = 8; this->actionTimer = 8;
Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CLOSE, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CLOSE, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
} else if (CHECK_BTN_ANY(input->press.button, BTN_A | BTN_START)) { } else if (CHECK_BTN_ANY(input->press.button, BTN_A | BTN_START)) {
this->n64ddFlags[this->selectedFileIndex] = this->connectorAlpha[this->selectedFileIndex] = 0; Save_GetSaveMetaInfo(this->selectedFileIndex)->n64ddFlag = this->connectorAlpha[this->selectedFileIndex] = 0;
Audio_PlaySoundGeneral(NA_SE_EV_DIAMOND_SWITCH, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); Audio_PlaySoundGeneral(NA_SE_EV_DIAMOND_SWITCH, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
this->actionTimer = 8; this->actionTimer = 8;
this->configMode = CM_ERASE_ANIM_1; this->configMode = CM_ERASE_ANIM_1;
@ -869,7 +860,6 @@ void FileChoose_ExitToEraseSelect1(GameState* thisx) {
*/ */
void FileChoose_ExitToEraseSelect2(GameState* thisx) { void FileChoose_ExitToEraseSelect2(GameState* thisx) {
FileChooseContext* this = (FileChooseContext*)thisx; FileChooseContext* this = (FileChooseContext*)thisx;
SramContext* sramCtx = &this->sramCtx;
s16 i; s16 i;
s16 yStep; s16 yStep;
@ -885,7 +875,7 @@ void FileChoose_ExitToEraseSelect2(GameState* thisx) {
if (i != this->buttonIndex) { if (i != this->buttonIndex) {
this->fileButtonAlpha[i] += 25; this->fileButtonAlpha[i] += 25;
if (SLOT_OCCUPIED(sramCtx, i)) { if (Save_GetSaveMetaInfo(i)->valid) {
this->nameBoxAlpha[i] = this->nameAlpha[i] = this->fileButtonAlpha[i]; this->nameBoxAlpha[i] = this->nameAlpha[i] = this->fileButtonAlpha[i];
this->connectorAlpha[i] += 31; this->connectorAlpha[i] += 31;
} }
@ -915,7 +905,6 @@ void FileChoose_ExitToEraseSelect2(GameState* thisx) {
void FileChoose_EraseAnim1(GameState* thisx) { void FileChoose_EraseAnim1(GameState* thisx) {
static s16 D_80813800; static s16 D_80813800;
FileChooseContext* this = (FileChooseContext*)thisx; FileChooseContext* this = (FileChooseContext*)thisx;
SramContext* sramCtx = &this->sramCtx;
if (sEraseDelayTimer == 0) { if (sEraseDelayTimer == 0) {
if (this->actionTimer == 8) { if (this->actionTimer == 8) {
@ -935,7 +924,7 @@ void FileChoose_EraseAnim1(GameState* thisx) {
D_80813800 += 2; D_80813800 += 2;
if (this->actionTimer == 0) { if (this->actionTimer == 0) {
Sram_EraseSave(this, sramCtx); Save_DeleteFile(this->selectedFileIndex);
this->titleLabel = this->nextTitleLabel; this->titleLabel = this->nextTitleLabel;
this->titleAlpha[0] = 255; this->titleAlpha[0] = 255;
this->titleAlpha[1] = this->connectorAlpha[this->selectedFileIndex] = 0; this->titleAlpha[1] = this->connectorAlpha[this->selectedFileIndex] = 0;
@ -981,7 +970,6 @@ void FileChoose_EraseAnim2(GameState* thisx) {
*/ */
void FileChoose_EraseAnim3(GameState* thisx) { void FileChoose_EraseAnim3(GameState* thisx) {
FileChooseContext* this = (FileChooseContext*)thisx; FileChooseContext* this = (FileChooseContext*)thisx;
SramContext* sramCtx = &this->sramCtx;
s16 i; s16 i;
s16 yStep; s16 yStep;
@ -998,7 +986,7 @@ void FileChoose_EraseAnim3(GameState* thisx) {
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
this->fileButtonAlpha[i] += 25; this->fileButtonAlpha[i] += 25;
if (SLOT_OCCUPIED(sramCtx, i)) { if (Save_GetSaveMetaInfo(i)->valid) {
this->nameBoxAlpha[i] = this->nameAlpha[i] = this->fileButtonAlpha[i]; this->nameBoxAlpha[i] = this->nameAlpha[i] = this->fileButtonAlpha[i];
this->connectorAlpha[i] += 31; this->connectorAlpha[i] += 31;
} }

View File

@ -113,6 +113,7 @@ void FileChoose_SetNameEntryVtx(GameState* thisx) {
s16 phi_t1; s16 phi_t1;
u8 temp; u8 temp;
s16 phi_v0; s16 phi_v0;
char* filename = Save_GetSaveMetaInfo(this->buttonIndex)->playerName;
if (1) {} if (1) {}
if (1) {} if (1) {}
@ -152,7 +153,7 @@ void FileChoose_SetNameEntryVtx(GameState* thisx) {
for (phi_s0 = 0, phi_t1 = 0; phi_t1 < 44; phi_t1 += 4, phi_s0++) { for (phi_s0 = 0, phi_t1 = 0; phi_t1 < 44; phi_t1 += 4, phi_s0++) {
if ((phi_s0 > 0) && (phi_s0 < 9)) { if ((phi_s0 > 0) && (phi_s0 < 9)) {
temp = this->fileNames[this->buttonIndex][phi_s0 - 1]; temp = filename[phi_s0 - 1];
this->nameEntryVtx[phi_t1].v.ob[0] = this->nameEntryVtx[phi_t1 + 2].v.ob[0] = this->nameEntryVtx[phi_t1].v.ob[0] = this->nameEntryVtx[phi_t1 + 2].v.ob[0] =
D_808125EC[phi_s0] + this->nameEntryBoxPosX + D_808124C0[temp]; D_808125EC[phi_s0] + this->nameEntryBoxPosX + D_808124C0[temp];
@ -223,8 +224,7 @@ void FileChoose_SetNameEntryVtx(GameState* thisx) {
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, this->nameEntryBoxAlpha); gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, this->nameEntryBoxAlpha);
for (phi_v0 = 0, phi_s0 = 0; phi_s0 < 0x20; phi_s0 += 4, phi_v0++) { for (phi_v0 = 0, phi_s0 = 0; phi_s0 < 0x20; phi_s0 += 4, phi_v0++) {
FileChoose_DrawCharacter(this->state.gfxCtx, FileChoose_DrawCharacter(this->state.gfxCtx, font->fontBuf + filename[phi_v0] * FONT_CHAR_TEX_SIZE,
font->fontBuf + this->fileNames[this->buttonIndex][phi_v0] * FONT_CHAR_TEX_SIZE,
phi_s0); phi_s0);
} }
@ -281,6 +281,7 @@ void FileChoose_DrawNameEntry(GameState* thisx) {
s16 tmp; s16 tmp;
u16 dayTime; u16 dayTime;
s16 validName; s16 validName;
char* filename = Save_GetSaveMetaInfo(this->buttonIndex)->playerName;
OPEN_DISPS(this->state.gfxCtx, "../z_file_nameset_PAL.c", 368); OPEN_DISPS(this->state.gfxCtx, "../z_file_nameset_PAL.c", 368);
@ -375,12 +376,12 @@ void FileChoose_DrawNameEntry(GameState* thisx) {
this->kbdY = 5; this->kbdY = 5;
this->kbdX = 4; this->kbdX = 4;
} else if (CHECK_BTN_ALL(input->press.button, BTN_B)) { } else if (CHECK_BTN_ALL(input->press.button, BTN_B)) {
if ((this->newFileNameCharCount == 7) && (this->fileNames[this->buttonIndex][7] != 0x3E)) { if ((this->newFileNameCharCount == 7) && (filename[7] != 0x3E)) {
for (i = this->newFileNameCharCount; i < 7; i++) { for (i = this->newFileNameCharCount; i < 7; i++) {
this->fileNames[this->buttonIndex][i] = this->fileNames[this->buttonIndex][i + 1]; filename[i] = filename[i + 1];
} }
this->fileNames[this->buttonIndex][i] = 0x3E; filename[i] = 0x3E;
Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_S, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_S, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
} else { } else {
this->newFileNameCharCount--; this->newFileNameCharCount--;
@ -390,10 +391,10 @@ void FileChoose_DrawNameEntry(GameState* thisx) {
this->configMode = CM_NAME_ENTRY_TO_MAIN; this->configMode = CM_NAME_ENTRY_TO_MAIN;
} else { } else {
for (i = this->newFileNameCharCount; i < 7; i++) { for (i = this->newFileNameCharCount; i < 7; i++) {
this->fileNames[this->buttonIndex][i] = this->fileNames[this->buttonIndex][i + 1]; filename[i] = filename[i + 1];
} }
this->fileNames[this->buttonIndex][i] = 0x3E; filename[i] = 0x3E;
Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_S, &D_801333D4, 4, &D_801333E0, &D_801333E0, Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_S, &D_801333D4, 4, &D_801333E0, &D_801333E0,
&D_801333E8); &D_801333E8);
} }
@ -411,7 +412,7 @@ void FileChoose_DrawNameEntry(GameState* thisx) {
if (CHECK_BTN_ALL(input->press.button, BTN_A)) { if (CHECK_BTN_ALL(input->press.button, BTN_A)) {
Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_S, &D_801333D4, 4, &D_801333E0, &D_801333E0, Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_S, &D_801333D4, 4, &D_801333E0, &D_801333E0,
&D_801333E8); &D_801333E8);
this->fileNames[this->buttonIndex][this->newFileNameCharCount] = D_808123F0[this->charIndex]; filename[this->newFileNameCharCount] = D_808123F0[this->charIndex];
this->newFileNameCharCount++; this->newFileNameCharCount++;
if (this->newFileNameCharCount > 7) { if (this->newFileNameCharCount > 7) {
@ -420,12 +421,12 @@ void FileChoose_DrawNameEntry(GameState* thisx) {
} }
} else if (CHECK_BTN_ALL(input->press.button, BTN_A) && (this->charPage != this->kbdButton)) { } else if (CHECK_BTN_ALL(input->press.button, BTN_A) && (this->charPage != this->kbdButton)) {
if (this->kbdButton == FS_KBD_BTN_BACKSPACE) { if (this->kbdButton == FS_KBD_BTN_BACKSPACE) {
if ((this->newFileNameCharCount == 7) && (this->fileNames[this->buttonIndex][7] != 0x3E)) { if ((this->newFileNameCharCount == 7) && (filename[7] != 0x3E)) {
for (i = this->newFileNameCharCount; i < 7; i++) { for (i = this->newFileNameCharCount; i < 7; i++) {
this->fileNames[this->buttonIndex][i] = this->fileNames[this->buttonIndex][i + 1]; filename[i] = filename[i + 1];
} }
this->fileNames[this->buttonIndex][i] = 0x3E; filename[i] = 0x3E;
Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_S, &D_801333D4, 4, &D_801333E0, &D_801333E0, Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_S, &D_801333D4, 4, &D_801333E0, &D_801333E0,
&D_801333E8); &D_801333E8);
} else { } else {
@ -436,10 +437,10 @@ void FileChoose_DrawNameEntry(GameState* thisx) {
} }
for (i = this->newFileNameCharCount; i < 7; i++) { for (i = this->newFileNameCharCount; i < 7; i++) {
this->fileNames[this->buttonIndex][i] = this->fileNames[this->buttonIndex][i + 1]; filename[i] = filename[i + 1];
} }
this->fileNames[this->buttonIndex][i] = 0x3E; filename[i] = 0x3E;
Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_S, &D_801333D4, 4, &D_801333E0, &D_801333E0, Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_S, &D_801333D4, 4, &D_801333E0, &D_801333E0,
&D_801333E8); &D_801333E8);
} }
@ -447,7 +448,7 @@ void FileChoose_DrawNameEntry(GameState* thisx) {
validName = false; validName = false;
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
if (this->fileNames[this->buttonIndex][i] != 0x3E) { if (filename[i] != 0x3E) {
validName = true; validName = true;
break; break;
} }
@ -458,7 +459,7 @@ void FileChoose_DrawNameEntry(GameState* thisx) {
&D_801333E8); &D_801333E8);
gSaveContext.fileNum = this->buttonIndex; gSaveContext.fileNum = this->buttonIndex;
dayTime = ((void)0, gSaveContext.dayTime); dayTime = ((void)0, gSaveContext.dayTime);
Sram_InitSave(this, &this->sramCtx); Sram_InitSave(this);
gSaveContext.dayTime = dayTime; gSaveContext.dayTime = dayTime;
this->configMode = CM_NAME_ENTRY_TO_MAIN; this->configMode = CM_NAME_ENTRY_TO_MAIN;
this->nameBoxAlpha[this->buttonIndex] = this->nameAlpha[this->buttonIndex] = 200; this->nameBoxAlpha[this->buttonIndex] = this->nameAlpha[this->buttonIndex] = 200;
@ -676,20 +677,15 @@ static u8 sSelectedSetting;
*/ */
void FileChoose_UpdateOptionsMenu(GameState* thisx) { void FileChoose_UpdateOptionsMenu(GameState* thisx) {
FileChooseContext* this = (FileChooseContext*)thisx; FileChooseContext* this = (FileChooseContext*)thisx;
SramContext* sramCtx = &this->sramCtx;
Input* input = &this->state.input[0]; Input* input = &this->state.input[0];
bool dpad = CVar_GetS32("gDpadPauseName", 0); bool dpad = CVar_GetS32("gDpadPauseName", 0);
if (CHECK_BTN_ALL(input->press.button, BTN_B)) { if (CHECK_BTN_ALL(input->press.button, BTN_B)) {
Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
this->configMode = CM_OPTIONS_TO_MAIN; this->configMode = CM_OPTIONS_TO_MAIN;
sramCtx->readBuff[0] = gSaveContext.audioSetting;
sramCtx->readBuff[1] = gSaveContext.zTargetSetting;
osSyncPrintf(""); osSyncPrintf("");
Sram_WriteSramHeader(sramCtx); Save_SaveGlobal();
osSyncPrintf(VT_FGCOL(YELLOW)); osSyncPrintf(VT_FGCOL(YELLOW));
osSyncPrintf("sram->read_buff[2] = J_N = %x\n", sramCtx->readBuff[2]);
osSyncPrintf("sram->read_buff[2] = J_N = %x\n", &sramCtx->readBuff[2]);
osSyncPrintf("Na_SetSoundOutputMode = %d\n", gSaveContext.audioSetting); osSyncPrintf("Na_SetSoundOutputMode = %d\n", gSaveContext.audioSetting);
osSyncPrintf("Na_SetSoundOutputMode = %d\n", gSaveContext.audioSetting); osSyncPrintf("Na_SetSoundOutputMode = %d\n", gSaveContext.audioSetting);
osSyncPrintf("Na_SetSoundOutputMode = %d\n", gSaveContext.audioSetting); osSyncPrintf("Na_SetSoundOutputMode = %d\n", gSaveContext.audioSetting);

View File

@ -224,7 +224,7 @@ void Title_Main(GameState* thisx) {
if (CVar_GetS32("gSkipLogoTitle",0)!=0) { if (CVar_GetS32("gSkipLogoTitle",0)!=0) {
gSaveContext.language = CVar_GetS32("gLanguages", 0); gSaveContext.language = CVar_GetS32("gLanguages", 0);
Sram_InitSram(&this->state, &this->sramCtx); Sram_InitSram(&this->state);
s16 selectedfile = CVar_GetS32("gSaveFileID", 0); s16 selectedfile = CVar_GetS32("gSaveFileID", 0);
if (selectedfile == 4) { if (selectedfile == 4) {
selectedfile = 0xFF; selectedfile = 0xFF;
@ -242,13 +242,13 @@ void Title_Main(GameState* thisx) {
} }
if (selectedfile == 0xFF) { if (selectedfile == 0xFF) {
gSaveContext.fileNum = selectedfile; gSaveContext.fileNum = selectedfile;
Sram_OpenSave(&this->sramCtx); Sram_OpenSave();
gSaveContext.gameMode = 0; gSaveContext.gameMode = 0;
this->state.running = false; this->state.running = false;
SET_NEXT_GAMESTATE(&this->state, Select_Init, SelectContext); SET_NEXT_GAMESTATE(&this->state, Select_Init, SelectContext);
} else { } else {
gSaveContext.fileNum = selectedfile; gSaveContext.fileNum = selectedfile;
Sram_OpenSave(&this->sramCtx); Sram_OpenSave();
gSaveContext.gameMode = 0; gSaveContext.gameMode = 0;
this->state.running = false; this->state.running = false;
//return; //return;
@ -322,7 +322,7 @@ void Title_Main(GameState* thisx) {
void Title_Destroy(GameState* thisx) { void Title_Destroy(GameState* thisx) {
TitleContext* this = (TitleContext*)thisx; TitleContext* this = (TitleContext*)thisx;
Sram_InitSram(&this->state, &this->sramCtx); Sram_InitSram(&this->state);
} }
void Title_Init(GameState* thisx) { void Title_Init(GameState* thisx) {
@ -346,7 +346,6 @@ void Title_Init(GameState* thisx) {
this->state.destroy = Title_Destroy; this->state.destroy = Title_Destroy;
this->exit = false; this->exit = false;
gSaveContext.fileNum = 0xFF; gSaveContext.fileNum = 0xFF;
Sram_Alloc(&this->state, &this->sramCtx);
this->ult = 0; this->ult = 0;
this->unk_1D4 = 0x14; this->unk_1D4 = 0x14;
this->coverAlpha = 255; this->coverAlpha = 255;

View File

@ -3779,7 +3779,7 @@ void KaleidoScope_Update(GlobalContext* globalCtx)
&D_801333E8); &D_801333E8);
Gameplay_SaveSceneFlags(globalCtx); Gameplay_SaveSceneFlags(globalCtx);
gSaveContext.savedSceneNum = globalCtx->sceneNum; gSaveContext.savedSceneNum = globalCtx->sceneNum;
Sram_WriteSave(&globalCtx->sramCtx); Save_SaveFile();
pauseCtx->unk_1EC = 4; pauseCtx->unk_1EC = 4;
D_8082B25C = 3; D_8082B25C = 3;
} }
@ -4019,7 +4019,7 @@ void KaleidoScope_Update(GlobalContext* globalCtx)
pauseCtx->promptChoice = 0; pauseCtx->promptChoice = 0;
Gameplay_SaveSceneFlags(globalCtx); Gameplay_SaveSceneFlags(globalCtx);
gSaveContext.savedSceneNum = globalCtx->sceneNum; gSaveContext.savedSceneNum = globalCtx->sceneNum;
Sram_WriteSave(&globalCtx->sramCtx); Save_SaveFile();
pauseCtx->state = 0xF; pauseCtx->state = 0xF;
D_8082B25C = 3; D_8082B25C = 3;
} }