diff --git a/assets/xml/misc/title_static.xml b/assets/xml/misc/title_static.xml
new file mode 100644
index 0000000000..5e6cea55f7
--- /dev/null
+++ b/assets/xml/misc/title_static.xml
@@ -0,0 +1,126 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/xml/overlays/ovl_file_choose.xml b/assets/xml/overlays/ovl_file_choose.xml
new file mode 100644
index 0000000000..cac6f3d9dc
--- /dev/null
+++ b/assets/xml/overlays/ovl_file_choose.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/include/functions.h b/include/functions.h
index ccf1877e01..7d64745f69 100644
--- a/include/functions.h
+++ b/include/functions.h
@@ -2218,7 +2218,8 @@ s32 SysFlashrom_IsBusy(void);
s32 SysFlashrom_AwaitResult(void);
void SysFlashrom_WriteDataSync(void* addr, u32 pageNum, u32 pageCount);
-s32 func_80185F90(u32 param_1);
+s32 func_80185F90(u32 arg0);
+
u32 osFlashGetAddr(u32 pageNum);
OSPiHandle* osFlashReInit(u8 latency, u8 pulse, u8 pageSize, u8 relDuration, u32 start);
void osFlashChange(u32 flashNum);
diff --git a/include/z64.h b/include/z64.h
index b5597f58cf..a83001a010 100644
--- a/include/z64.h
+++ b/include/z64.h
@@ -273,45 +273,45 @@ typedef struct {
/* 0x00 */ u16 unk_0;
/* 0x02 */ u16 sceneTimeSpeed;
/* 0x04 */ Vec3f sunPos;
- /* 0x10 */ u8 unk_10;
- /* 0x11 */ u8 unk_11;
+ /* 0x10 */ u8 skybox1Index;
+ /* 0x11 */ u8 skybox2Index;
/* 0x12 */ u8 unk_12;
- /* 0x13 */ u8 unk_13;
+ /* 0x13 */ u8 skyboxBlend;
/* 0x14 */ u8 unk_14;
/* 0x15 */ u8 skyboxDisabled;
/* 0x16 */ u8 sunMoonDisabled;
- /* 0x17 */ u8 unk_17;
- /* 0x18 */ u8 unk_18;
- /* 0x19 */ u8 unk_19;
- /* 0x1A */ u16 unk_1A;
+ /* 0x17 */ u8 skyboxConfig;
+ /* 0x18 */ u8 changeSkyboxNextConfig;
+ /* 0x19 */ u8 changeSkyboxState;
+ /* 0x1A */ u16 changeSkyboxTimer;
/* 0x1C */ u16 unk_1C;
- /* 0x1E */ u8 unk_1E;
- /* 0x1F */ u8 unk_1F;
- /* 0x20 */ u8 unk_20;
- /* 0x21 */ u8 unk_21;
- /* 0x22 */ u16 unk_22;
- /* 0x24 */ u16 unk_24;
+ /* 0x1E */ u8 lightMode;
+ /* 0x1F */ u8 lightConfig;
+ /* 0x20 */ u8 changeLightNextConfig;
+ /* 0x21 */ u8 changeLightEnabled;
+ /* 0x22 */ u16 changeLightTimer;
+ /* 0x24 */ u16 changeDuration;
/* 0x26 */ u8 unk_26;
/* 0x28 */ LightInfo dirLight1; // sun 1
/* 0x36 */ LightInfo unk_36; // sun 2
- /* 0x44 */ s8 unk_44;
- /* 0x48 */ DmaRequest unk_48;
- /* 0x68 */ OSMesgQueue unk_68;
- /* 0x80 */ OSMesg unk_80;
- /* 0x84 */ f32 unk_84;
- /* 0x88 */ f32 unk_88;
+ /* 0x44 */ s8 skyboxDmaState;
+ /* 0x48 */ DmaRequest dmaRequest;
+ /* 0x68 */ OSMesgQueue loadQueue;
+ /* 0x80 */ OSMesg loadMsg;
+ /* 0x84 */ f32 glareAlpha;
+ /* 0x88 */ f32 lensFlareAlphaScale;
/* 0x8C */ EnvLightSettings lightSettings;
/* 0xA8 */ f32 unk_A8;
/* 0xAC */ Vec3s windDir;
/* 0xB4 */ f32 windSpeed;
/* 0xB8 */ u8 numLightSettings;
/* 0xBC */ LightSettings* lightSettingsList;
- /* 0xC0 */ u8 unk_C0;
- /* 0xC1 */ u8 unk_C1;
- /* 0xC2 */ u8 unk_C2;
+ /* 0xC0 */ u8 lightBlendEnabled;
+ /* 0xC1 */ u8 lightSetting;
+ /* 0xC2 */ u8 prevLightSetting;
/* 0xC3 */ u8 lightSettingOverride;
/* 0xC4 */ LightSettings unk_C4;
- /* 0xDA */ u16 unk_DA;
+ /* 0xDA */ u16 lightBlendRateOverride;
/* 0xDC */ f32 lightBlend;
/* 0xE0 */ u8 unk_E0;
/* 0xE1 */ u8 unk_E1;
diff --git a/include/z64save.h b/include/z64save.h
index fdb99fea04..cea6ffa46c 100644
--- a/include/z64save.h
+++ b/include/z64save.h
@@ -10,6 +10,13 @@ struct GameState;
struct PlayState;
struct FileSelectState;
+typedef enum {
+ /* 0 */ SAVE_AUDIO_STEREO,
+ /* 1 */ SAVE_AUDIO_MONO,
+ /* 2 */ SAVE_AUDIO_HEADSET,
+ /* 3 */ SAVE_AUDIO_SURROUND
+} AudioOption;
+
// TODO: properly name DOWN, RETURN and TOP
typedef enum RespawnMode {
/* 0 */ RESPAWN_MODE_DOWN, // "RESTART_MODE_DOWN"
@@ -157,13 +164,13 @@ typedef enum {
#define PICTO_PHOTO_COMPRESSED_SIZE (PICTO_PHOTO_SIZE * 5 / 8)
typedef struct SramContext {
- /* 0x00 */ u8* readBuff;
- /* 0x04 */ u8 *saveBuf;
+ /* 0x00 */ u8* noFlashSaveBuf; // Never allocated memory
+ /* 0x04 */ u8* saveBuf;
/* 0x08 */ char unk_08[4];
/* 0x0C */ s16 status;
/* 0x10 */ u32 curPage;
/* 0x14 */ u32 numPages;
- /* 0x18 */ OSTime unk_18;
+ /* 0x18 */ OSTime startWriteOsTime;
/* 0x20 */ s16 unk_20;
/* 0x22 */ s16 unk_22;
/* 0x24 */ s16 unk_24;
@@ -226,14 +233,14 @@ typedef struct CycleSceneFlags {
typedef struct SaveOptions {
/* 0x0 */ u16 optionId; // "option_id"
/* 0x2 */ u8 language; // "j_n"
- /* 0x3 */ s8 audioSetting; // "s_sound"
+ /* 0x3 */ u8 audioSetting; // "s_sound"
/* 0x4 */ u8 languageSetting; // "language"
/* 0x5 */ u8 zTargetSetting; // "z_attention", 0: Switch; 1: Hold
} SaveOptions; // size = 0x6
typedef struct SavePlayerData {
/* 0x00 */ char newf[6]; // "newf" Will always be "ZELDA3 for a valid save
- /* 0x06 */ u16 deaths; // "savect"
+ /* 0x06 */ u16 threeDayResetCount; // "savect"
/* 0x08 */ char playerName[8]; // "player_name"
/* 0x10 */ s16 healthCapacity; // "max_life"
/* 0x12 */ s16 health; // "now_life"
@@ -337,11 +344,11 @@ typedef struct SaveContext {
/* 0x3DB4 */ f32 entranceSpeed; // "player_wipe_speedF"
/* 0x3DB8 */ u16 entranceSound; // "player_wipe_door_SE"
/* 0x3DBA */ u8 unk_3DBA; // "player_wipe_item"
- /* 0x3DBB */ u8 unk_3DBB; // "next_walk"
+ /* 0x3DBB */ u8 retainWeatherMode; // "next_walk"
/* 0x3DBC */ s16 dogParams; // OoT leftover. "dog_flag"
/* 0x3DBE */ u8 envHazardTextTriggerFlags; // "guide_status"
/* 0x3DBF */ u8 showTitleCard; // "name_display"
- /* 0x3DC0 */ s16 unk_3DC0; // "shield_magic_timer"
+ /* 0x3DC0 */ s16 nayrusLoveTimer; // remnant of OoT, "shield_magic_timer"
/* 0x3DC2 */ u8 unk_3DC2; // "pad1"
/* 0x3DC8 */ OSTime postmanTimerStopOsTime; // The osTime when the timer stops for the postman minigame. "get_time"
/* 0x3DD0 */ u8 timerStates[TIMER_ID_MAX]; // See the `TimerState` enum. "event_fg"
@@ -374,13 +381,13 @@ typedef struct SaveContext {
/* 0x3F3A */ u16 minigameScore; // "yabusame_total"
/* 0x3F3C */ u16 minigameHiddenScore; // "yabusame_out_ct"
/* 0x3F3E */ u8 unk_3F3E; // "no_save"
- /* 0x3F3F */ u8 unk_3F3F; // "flash_flag"
+ /* 0x3F3F */ u8 flashSaveAvailable; // "flash_flag"
/* 0x3F40 */ SaveOptions options;
- /* 0x3F46 */ u16 unk_3F46; // "NottoriBgm"
+ /* 0x3F46 */ u16 forcedSeqId; // "NottoriBgm"
/* 0x3F48 */ u8 cutsceneTransitionControl; // "fade_go"
/* 0x3F4A */ u16 nextCutsceneIndex; // "next_daytime"
/* 0x3F4C */ u8 cutsceneTrigger; // "doukidemo"
- /* 0x3F4D */ u8 unk_3F4D; // "Kenjya_no"
+ /* 0x3F4D */ u8 chamberCutsceneNum; // remnant of OoT "Kenjya_no"
/* 0x3F4E */ u16 nextDayTime; // "next_zelda_time"
/* 0x3F50 */ u8 transFadeDuration; // "fade_speed"
/* 0x3F51 */ u8 transWipeSpeed; // "wipe_speed" transition related
@@ -1575,28 +1582,28 @@ void Sram_InitDebugSave(void);
void Sram_ResetSaveFromMoonCrash(SramContext* sramCtx);
void Sram_OpenSave(struct FileSelectState* fileSelect, SramContext* sramCtx);
void func_8014546C(SramContext* sramCtx);
-void func_801457CC(struct FileSelectState* fileSelect, SramContext* sramCtx);
-void func_80146580(struct FileSelectState* fileSelect2, SramContext* sramCtx, s32 fileNum);
-void func_80146628(struct FileSelectState* fileSelect2, SramContext* sramCtx);
+void func_801457CC(struct GameState* gameState, SramContext* sramCtx);
+void Sram_EraseSave(struct FileSelectState* fileSelect2, SramContext* sramCtx, s32 fileNum);
+void Sram_CopySave(struct FileSelectState* fileSelect2, SramContext* sramCtx);
void Sram_InitSave(struct FileSelectState* fileSelect2, SramContext* sramCtx);
-void func_80146DF8(SramContext* sramCtx);
+void Sram_WriteSaveOptionsToBuffer(SramContext* sramCtx);
void Sram_InitSram(struct GameState* gameState, SramContext* sramCtx);
void Sram_Alloc(struct GameState* gameState, SramContext* sramCtx);
void Sram_SaveSpecialEnterClockTown(struct PlayState* play);
void Sram_SaveSpecialNewDay(struct PlayState* play);
-void func_80147008(SramContext* sramCtx, u32 curPage, u32 numPages);
-void func_80147020(SramContext* sramCtx);
-void func_80147068(SramContext* sramCtx);
-void func_80147138(SramContext* sramCtx, s32 curPage, s32 numPages);
-void func_80147150(SramContext* sramCtx);
-void func_80147198(SramContext* sramCtx);
+void Sram_SetFlashPagesDefault(SramContext* sramCtx, u32 curPage, u32 numPages);
+void Sram_StartWriteToFlashDefault(SramContext* sramCtx);
+void Sram_UpdateWriteToFlashDefault(SramContext* sramCtx);
+void Sram_SetFlashPagesOwlSave(SramContext* sramCtx, s32 curPage, s32 numPages);
+void Sram_StartWriteToFlashOwlSave(SramContext* sramCtx);
+void Sram_UpdateWriteToFlashOwlSave(SramContext* sramCtx);
-extern s32 D_801C6798[];
+extern u32 gSramSlotOffsets[];
extern u8 gAmmoItems[];
-extern s32 D_801C67C8[];
-extern s32 D_801C67F0[];
-extern s32 D_801C6818[];
-extern s32 D_801C6840[];
-extern s32 D_801C6850[];
+extern s32 gFlashSaveStartPages[];
+extern s32 gFlashSaveNumPages[];
+extern s32 gFlashSpecialSaveNumPages[];
+extern s32 gFlashOwlSaveStartPages[];
+extern s32 gFlashOwlSaveNumPages[];
#endif
diff --git a/include/z64scene.h b/include/z64scene.h
index 7f48d87402..5505f08e31 100644
--- a/include/z64scene.h
+++ b/include/z64scene.h
@@ -130,8 +130,8 @@ typedef struct {
/* 0x1 */ u8 data1;
/* 0x2 */ UNK_TYPE1 pad2[2];
/* 0x4 */ u8 skyboxId;
- /* 0x5 */ u8 unk5;
- /* 0x6 */ u8 unk6;
+ /* 0x5 */ u8 skyboxConfig;
+ /* 0x6 */ u8 envLightMode;
} SCmdSkyboxSettings; // size = 0x7
typedef struct {
@@ -719,6 +719,8 @@ typedef enum {
*/
#define ENTRANCE(scene, spawn) ((((ENTR_SCENE_##scene) & 0x7F) << 9) | (((spawn) & 0x1F) << 4))
+#define ENTR_LOAD_OPENING -1
+
/*
* Entrances used in cutscene destination. Includes scene layer that's immediately applied to `nextCutsceneIndex` and removed.
* See `CutsceneScriptEntry.nextEntrance`
diff --git a/spec b/spec
index 601a46f403..a3cde9e587 100644
--- a/spec
+++ b/spec
@@ -664,12 +664,15 @@ endseg
beginseg
name "ovl_file_choose"
compress
+ include "build/src/overlays/gamestates/ovl_file_choose/z_file_nameset_data.o"
+ include "build/src/overlays/gamestates/ovl_file_choose/z_file_copy_erase.o"
include "build/src/overlays/gamestates/ovl_file_choose/z_file_nameset_NES.o"
- include "build/src/overlays/gamestates/ovl_file_choose/z_file_choose_80807940.o"
include "build/src/overlays/gamestates/ovl_file_choose/z_file_choose_NES.o"
- include "build/data/ovl_file_choose/ovl_file_choose.data.o"
- include "build/data/ovl_file_choose/ovl_file_choose.bss.o"
- include "build/data/ovl_file_choose/ovl_file_choose.reloc.o"
+ #ifdef NON_MATCHING
+ include "build/src/overlays/gamestates/ovl_file_choose/ovl_file_choose_reloc.o"
+ #else
+ include "build/data/ovl_file_choose/ovl_file_choose.reloc.o"
+ #endif
endseg
beginseg
@@ -8824,7 +8827,8 @@ beginseg
name "title_static"
compress
romalign 0x1000
- include "build/baserom/title_static.o"
+ include "build/assets/misc/title_static/title_static.o"
+ number 1
endseg
beginseg
diff --git a/src/code/graph.c b/src/code/graph.c
index bf9067b698..2e104234e2 100644
--- a/src/code/graph.c
+++ b/src/code/graph.c
@@ -2,7 +2,7 @@
#include "buffers.h"
#include "system_malloc.h"
#include "overlays/gamestates/ovl_daytelop/z_daytelop.h"
-#include "overlays/gamestates/ovl_file_choose/z_file_choose.h"
+#include "overlays/gamestates/ovl_file_choose/z_file_select.h"
#include "overlays/gamestates/ovl_opening/z_opening.h"
#include "overlays/gamestates/ovl_select/z_select.h"
#include "overlays/gamestates/ovl_title/z_title.h"
diff --git a/src/code/z_common_data.c b/src/code/z_common_data.c
index 0e682231f4..46dfe189ef 100644
--- a/src/code/z_common_data.c
+++ b/src/code/z_common_data.c
@@ -8,10 +8,10 @@ void SaveContext_Init(void) {
gSaveContext.save.playerForm = 0;
gSaveContext.seqId = (u8)NA_BGM_DISABLED;
gSaveContext.ambienceId = AMBIENCE_ID_DISABLED;
- gSaveContext.unk_3F46 = NA_BGM_GENERAL_SFX;
+ gSaveContext.forcedSeqId = NA_BGM_GENERAL_SFX;
gSaveContext.nextCutsceneIndex = 0xFFEF;
gSaveContext.cutsceneTrigger = 0;
- gSaveContext.unk_3F4D = 0;
+ gSaveContext.chamberCutsceneNum = 0;
gSaveContext.nextDayTime = 0xFFFF;
gSaveContext.skyboxTime = 0;
gSaveContext.dogIsLost = true;
@@ -19,6 +19,6 @@ void SaveContext_Init(void) {
gSaveContext.prevHudVisibility = HUD_VISIBILITY_ALL;
gSaveContext.options.language = 1;
- gSaveContext.options.audioSetting = 0;
+ gSaveContext.options.audioSetting = SAVE_AUDIO_STEREO;
gSaveContext.options.zTargetSetting = 0;
}
diff --git a/src/code/z_demo.c b/src/code/z_demo.c
index 733ec4bc13..00ee877e93 100644
--- a/src/code/z_demo.c
+++ b/src/code/z_demo.c
@@ -171,15 +171,15 @@ void CutsceneCmd_Misc(PlayState* play, CutsceneContext* csCtx, CsCmdMisc* cmd) {
case CS_MISC_CLOUDY_SKY:
if (isFirstFrame) {
- play->envCtx.unk_19 = 1;
- play->envCtx.unk_17 = 1;
- play->envCtx.unk_18 = 0;
- play->envCtx.unk_1A = 0x3C;
- play->envCtx.unk_21 = 1;
- play->envCtx.unk_1F = 0;
- play->envCtx.unk_20 = 1;
- play->envCtx.unk_24 = 0x3C;
- play->envCtx.unk_22 = play->envCtx.unk_24;
+ play->envCtx.changeSkyboxState = 1;
+ play->envCtx.skyboxConfig = 1;
+ play->envCtx.changeSkyboxNextConfig = 0;
+ play->envCtx.changeSkyboxTimer = 60;
+ play->envCtx.changeLightEnabled = true;
+ play->envCtx.lightConfig = 0;
+ play->envCtx.changeLightNextConfig = 1;
+ play->envCtx.changeDuration = 60;
+ play->envCtx.changeLightTimer = play->envCtx.changeDuration;
}
break;
@@ -327,8 +327,7 @@ void CutsceneCmd_Misc(PlayState* play, CutsceneContext* csCtx, CsCmdMisc* cmd) {
case CS_MISC_MOON_CRASH_SKYBOX:
if (isFirstFrame) {
- // skyboxConfig
- play->envCtx.unk_17 = 0xD;
+ play->envCtx.skyboxConfig = 0xD;
}
break;
diff --git a/src/code/z_game_dlftbls.c b/src/code/z_game_dlftbls.c
index 1b82705f56..7336b01f6f 100644
--- a/src/code/z_game_dlftbls.c
+++ b/src/code/z_game_dlftbls.c
@@ -1,6 +1,6 @@
#include "global.h"
#include "overlays/gamestates/ovl_daytelop/z_daytelop.h"
-#include "overlays/gamestates/ovl_file_choose/z_file_choose.h"
+#include "overlays/gamestates/ovl_file_choose/z_file_select.h"
#include "overlays/gamestates/ovl_opening/z_opening.h"
#include "overlays/gamestates/ovl_select/z_select.h"
#include "overlays/gamestates/ovl_title/z_title.h"
diff --git a/src/code/z_game_over.c b/src/code/z_game_over.c
index d0e5e45f22..c3c6819be6 100644
--- a/src/code/z_game_over.c
+++ b/src/code/z_game_over.c
@@ -49,7 +49,7 @@ void GameOver_Update(PlayState* play) {
}
}
- gSaveContext.unk_3DC0 = 2000;
+ gSaveContext.nayrusLoveTimer = 2000;
gSaveContext.save.saveInfo.playerData.tatlTimer = 0;
gSaveContext.seqId = (u8)NA_BGM_DISABLED;
gSaveContext.ambienceId = AMBIENCE_ID_DISABLED;
diff --git a/src/code/z_lifemeter.c b/src/code/z_lifemeter.c
index c9bea16694..7226a6719d 100644
--- a/src/code/z_lifemeter.c
+++ b/src/code/z_lifemeter.c
@@ -16,14 +16,14 @@ s16 sBeatingHeartsDDEnv[3];
s16 sHeartsDDPrim[2][3];
s16 sHeartsDDEnv[2][3];
-TexturePtr sHeartTextures[] = {
+static TexturePtr sHeartTextures[] = {
gHeartFullTex, gHeartQuarterTex, gHeartQuarterTex, gHeartQuarterTex,
gHeartQuarterTex, gHeartQuarterTex, gHeartHalfTex, gHeartHalfTex,
gHeartHalfTex, gHeartHalfTex, gHeartHalfTex, gHeartThreeQuarterTex,
gHeartThreeQuarterTex, gHeartThreeQuarterTex, gHeartThreeQuarterTex, gHeartThreeQuarterTex,
};
-TexturePtr sHeartDDTextures[] = {
+static TexturePtr sHeartDDTextures[] = {
gDefenseHeartFullTex, gDefenseHeartQuarterTex, gDefenseHeartQuarterTex,
gDefenseHeartQuarterTex, gDefenseHeartQuarterTex, gDefenseHeartQuarterTex,
gDefenseHeartHalfTex, gDefenseHeartHalfTex, gDefenseHeartHalfTex,
diff --git a/src/code/z_parameter.c b/src/code/z_parameter.c
index 9672b8804c..f8f28f4b8d 100644
--- a/src/code/z_parameter.c
+++ b/src/code/z_parameter.c
@@ -147,7 +147,7 @@ s16 D_801BF97C = 255;
f32 D_801BF980 = 1.0f;
s32 D_801BF984 = 0;
-Gfx sScreenFillSetupDL[] = {
+static Gfx sScreenFillSetupDL[] = {
gsDPPipeSync(),
gsSPClearGeometryMode(G_ZBUFFER | G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN |
G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH),
diff --git a/src/code/z_play.c b/src/code/z_play.c
index dade44cf6f..dd9b6c561c 100644
--- a/src/code/z_play.c
+++ b/src/code/z_play.c
@@ -7,7 +7,7 @@
#include "z64view.h"
#include "overlays/gamestates/ovl_daytelop/z_daytelop.h"
#include "overlays/gamestates/ovl_opening/z_opening.h"
-#include "overlays/gamestates/ovl_file_choose/z_file_choose.h"
+#include "overlays/gamestates/ovl_file_choose/z_file_select.h"
#include "overlays/kaleido_scope/ovl_kaleido_scope/z_kaleido_scope.h"
s32 gDbgCamEnabled = false;
@@ -1036,9 +1036,9 @@ void Play_UpdateMain(PlayState* this) {
if (this->sramCtx.status != 0) {
if (gSaveContext.save.isOwlSave) {
- func_80147198(&this->sramCtx);
+ Sram_UpdateWriteToFlashOwlSave(&this->sramCtx);
} else {
- func_80147068(&this->sramCtx);
+ Sram_UpdateWriteToFlashDefault(&this->sramCtx);
}
}
}
@@ -1272,8 +1272,8 @@ void Play_DrawMain(PlayState* this) {
if ((this->skyboxId != SKYBOX_NONE) && !this->envCtx.skyboxDisabled) {
if ((this->skyboxId == SKYBOX_NORMAL_SKY) || (this->skyboxId == SKYBOX_3)) {
Environment_UpdateSkybox(this->skyboxId, &this->envCtx, &this->skyboxCtx);
- Skybox_Draw(&this->skyboxCtx, gfxCtx, this->skyboxId, this->envCtx.unk_13, this->view.eye.x,
- this->view.eye.y, this->view.eye.z);
+ Skybox_Draw(&this->skyboxCtx, gfxCtx, this->skyboxId, this->envCtx.skyboxBlend,
+ this->view.eye.x, this->view.eye.y, this->view.eye.z);
} else if (!this->skyboxCtx.skyboxShouldDraw) {
Skybox_Draw(&this->skyboxCtx, gfxCtx, this->skyboxId, 0, this->view.eye.x, this->view.eye.y,
this->view.eye.z);
@@ -2217,7 +2217,7 @@ void Play_Init(GameState* thisx) {
if (((gSaveContext.gameMode != GAMEMODE_NORMAL) && (gSaveContext.gameMode != GAMEMODE_TITLE_SCREEN)) ||
(gSaveContext.save.cutsceneIndex >= 0xFFF0)) {
- gSaveContext.unk_3DC0 = 0;
+ gSaveContext.nayrusLoveTimer = 0;
Magic_Reset(this);
gSaveContext.sceneLayer = (gSaveContext.save.cutsceneIndex & 0xF) + 1;
diff --git a/src/code/z_scene.c b/src/code/z_scene.c
index 623db6b24b..368b4509e2 100644
--- a/src/code/z_scene.c
+++ b/src/code/z_scene.c
@@ -365,8 +365,8 @@ void Scene_LoadAreaTextures(PlayState* play, s32 fileIndex) {
// SceneTableEntry Header Command 0x11: Skybox Settings
void Scene_CommandSkyboxSettings(PlayState* play, SceneCmd* cmd) {
play->skyboxId = cmd->skyboxSettings.skyboxId & 3;
- play->envCtx.unk_17 = play->envCtx.unk_18 = cmd->skyboxSettings.unk5;
- play->envCtx.unk_1E = cmd->skyboxSettings.unk6;
+ play->envCtx.skyboxConfig = play->envCtx.changeSkyboxNextConfig = cmd->skyboxSettings.skyboxConfig;
+ play->envCtx.lightMode = cmd->skyboxSettings.envLightMode;
Scene_LoadAreaTextures(play, cmd->skyboxSettings.data1);
}
diff --git a/src/code/z_sram_NES.c b/src/code/z_sram_NES.c
index f47a8e2010..21bfaf7efa 100644
--- a/src/code/z_sram_NES.c
+++ b/src/code/z_sram_NES.c
@@ -1,9 +1,9 @@
#include "prevent_bss_reordering.h"
#include "global.h"
#include "z64horse.h"
-#include "overlays/gamestates/ovl_file_choose/z_file_choose.h"
+#include "overlays/gamestates/ovl_file_choose/z_file_select.h"
-void func_80146EBC(SramContext* sramCtx, s32 curPage, s32 numPages);
+void Sram_SyncWriteToFlash(SramContext* sramCtx, s32 curPage, s32 numPages);
void func_80147314(SramContext* sramCtx, s32 fileNum);
void func_80147414(SramContext* sramCtx, s32 fileNum, s32 arg2);
@@ -140,9 +140,21 @@ u16 D_801C66D0[ARRAY_COUNT(gSaveContext.save.saveInfo.weekEventReg)] = {
/* 99 */ 0,
};
+// Unused remnant values from OoT. Not the correct sizes in MM.
+#define OOT_SAVECONTEXT_SIZE 0x1428
+#define OOT_SLOT_SIZE (OOT_SAVECONTEXT_SIZE + 0x28)
+#define OOT_SRAM_HEADER_SIZE 0x10
+#define OOT_SLOT_OFFSET(index) (OOT_SRAM_HEADER_SIZE + 0x10 + (index * OOT_SLOT_SIZE))
+
// used in other files
-s32 D_801C6798[] = {
- 0x00000020, 0x00001470, 0x000028C0, 0x00003D10, 0x00005160, 0x000065B0,
+u32 gSramSlotOffsets[] = {
+ OOT_SLOT_OFFSET(0),
+ OOT_SLOT_OFFSET(1),
+ OOT_SLOT_OFFSET(2),
+ // the latter three saves are backup saves for the former saves (in OoT)
+ OOT_SLOT_OFFSET(3),
+ OOT_SLOT_OFFSET(4),
+ OOT_SLOT_OFFSET(5),
};
u8 gAmmoItems[] = {
@@ -172,28 +184,89 @@ u8 gAmmoItems[] = {
ITEM_NONE, // SLOT_BOTTLE_6
};
-s32 D_801C67C8[] = { 0, 0x40, 0x80, 0xC0, 0x100, 0x180, 0x200, 0x280, 0x300, 0x380 };
-
-s32 D_801C67F0[] = { 0x40, 0x40, 0x40, 0x40, 0x80, 0x80, 0x80, 0x80, 1, 1 };
-
-s32 D_801C6818[] = { 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 1, 1 };
-
-s32 D_801C6840[] = { 0x100, 0x180, 0x200, 0x280 };
-
-s32 D_801C6850[] = { 0x80, 0x80, 0x80, 0x80, 0x300, 0x380, 1, 1 };
-
-s32 D_801C6870[] = {
- sizeof(Save),
- sizeof(Save),
- sizeof(Save),
- sizeof(Save),
- offsetof(SaveContext, fileNum),
- offsetof(SaveContext, fileNum),
- offsetof(SaveContext, fileNum),
- offsetof(SaveContext, fileNum),
+// Stores flash start page number
+s32 gFlashSaveStartPages[] = {
+ 0, // File 1 New Cycle Save
+ 0x40, // File 1 New Cycle Save Backup
+ 0x80, // File 2 New Cycle Save
+ 0xC0, // File 2 New Cycle Save Backup
+ 0x100, // File 1 Owl Save
+ 0x180, // File 1 Owl Save Backup
+ 0x200, // File 2 Owl Save
+ 0x280, // File 2 Owl Save Backup
+ 0x300, // Sram Header (SaveOptions)
+ 0x380, // Sram Header Backup (SaveOptions)
};
-u8 D_801C6890[8] = { 1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80 };
+// Flash rom number of pages
+s32 gFlashSaveNumPages[] = {
+ 0x40, // File 1 New Cycle Save
+ 0x40, // File 1 New Cycle Save Backup
+ 0x40, // File 2 New Cycle Save
+ 0x40, // File 2 New Cycle Save Backup
+ 0x80, // File 1 Owl Save
+ 0x80, // File 1 Owl Save Backup
+ 0x80, // File 2 Owl Save
+ 0x80, // File 2 Owl Save Backup
+ 1, // Sram Header (SaveOptions)
+ 1, // Sram Header Backup (SaveOptions)
+};
+
+// Flash rom number of pages on very first time Player enters South Clock Town from the Clock Tower
+s32 gFlashSpecialSaveNumPages[] = {
+ 0x80, // File 1 New Cycle Save
+ 0x80, // File 1 New Cycle Save Backup
+ 0x80, // File 2 New Cycle Save
+ 0x80, // File 2 New Cycle Save Backup
+ 0x80, // File 1 Owl Save
+ 0x80, // File 1 Owl Save Backup
+ 0x80, // File 2 Owl Save
+ 0x80, // File 2 Owl Save Backup
+ 1, // Sram Header (SaveOptions)
+ 1, // Sram Header Backup (SaveOptions)
+};
+
+// Owl Save flash rom start page number
+s32 gFlashOwlSaveStartPages[] = {
+ 0x100, // File 1 Owl Save
+ 0x180, // File 1 Owl Save Backup
+ 0x200, // File 2 Owl Save
+ 0x280, // File 2 Owl Save Backup
+};
+
+// Owl Save flash rom number of pages
+s32 gFlashOwlSaveNumPages[] = {
+ 0x80, // File 1 Owl Save
+ 0x80, // File 1 Owl Save Backup
+ 0x80, // File 2 Owl Save
+ 0x80, // File 2 Owl Save Backup
+};
+
+// Save Options Sram Header flash rom start page number
+s32 gFlashOptionsSaveStartPages[] = {
+ 0x300, // Sram Header (SaveOptions)
+ 0x380, // Sram Header Backup (SaveOptions)
+};
+
+// Save Options Sram Header flash rom number of pages
+s32 gFlashOptionsSaveNumPages[] = {
+ 1, // Sram Header (SaveOptions)
+ 1, // Sram Header Backup (SaveOptions)
+};
+
+// Flash rom actual size needed
+s32 gFlashSaveSizes[] = {
+ sizeof(Save), // size = 0x100C - File 1 New Cycle Save
+ sizeof(Save), // size = 0x100C - File 1 New Cycle Save Backup
+ sizeof(Save), // size = 0x100C - File 2 New Cycle Save
+ sizeof(Save), // size = 0x100C - File 2 New Cycle Save Backup
+ offsetof(SaveContext, fileNum), // size = 0x3CA0 - File 1 Owl Save
+ offsetof(SaveContext, fileNum), // size = 0x3CA0 - File 1 Owl Save Backup
+ offsetof(SaveContext, fileNum), // size = 0x3CA0 - File 2 Owl Save
+ offsetof(SaveContext, fileNum), // size = 0x3CA0 - File 2 Owl Save Backup
+};
+
+u8 D_801C6890[8] = { 1 << 0, 1 << 1, 1 << 2, 1 << 3, 1 << 4, 1 << 5, 1 << 6, 1 << 7 };
u16 D_801F6AF0;
u8 D_801F6AF2;
@@ -245,9 +318,9 @@ void Sram_SaveEndOfCycle(PlayState* play) {
gSaveContext.save.day = 0;
gSaveContext.save.time = CLOCK_TIME(6, 0) - 1;
- gSaveContext.save.saveInfo.playerData.deaths++;
- if (gSaveContext.save.saveInfo.playerData.deaths > 999) {
- gSaveContext.save.saveInfo.playerData.deaths = 999;
+ gSaveContext.save.saveInfo.playerData.threeDayResetCount++;
+ if (gSaveContext.save.saveInfo.playerData.threeDayResetCount > 999) {
+ gSaveContext.save.saveInfo.playerData.threeDayResetCount = 999;
}
sceneId = Play_GetOriginalSceneId(play->sceneId);
@@ -577,7 +650,7 @@ void Sram_GenerateRandomSaveFields(void) {
SavePlayerData sSaveDefaultPlayerData = {
{ '\0', '\0', '\0', '\0', '\0', '\0' }, // newf
- 0, // deaths
+ 0, // threeDayResetCount
{ 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E }, // playerName " "
0x30, // healthCapacity
0x30, // health
@@ -678,7 +751,7 @@ void Sram_InitNewSave(void) {
SavePlayerData sSaveDebugPlayerData = {
{ 'Z', 'E', 'L', 'D', 'A', '3' }, // newf
- 0x0000, // deaths
+ 0, // threeDayResetCount
{ 0x15, 0x12, 0x17, 0x14, 0x3E, 0x3E, 0x3E, 0x3E }, // playerName "LINK "
0x80, // healthCapacity
0x80, // health
@@ -775,7 +848,18 @@ Inventory sSaveDebugInventory = {
(1 << QUEST_SONG_SOARING) | (1 << QUEST_SONG_STORMS) | (1 << QUEST_BOMBERS_NOTEBOOK) |
(1 << QUEST_SONG_LULLABY_INTRO),
// dungeonItems
- { 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 },
+ {
+ (1 << DUNGEON_BOSS_KEY) | (1 << DUNGEON_COMPASS) | (1 << DUNGEON_MAP),
+ (1 << DUNGEON_BOSS_KEY) | (1 << DUNGEON_COMPASS) | (1 << DUNGEON_MAP),
+ (1 << DUNGEON_BOSS_KEY) | (1 << DUNGEON_COMPASS) | (1 << DUNGEON_MAP),
+ (1 << DUNGEON_BOSS_KEY) | (1 << DUNGEON_COMPASS) | (1 << DUNGEON_MAP),
+ (1 << DUNGEON_BOSS_KEY) | (1 << DUNGEON_COMPASS) | (1 << DUNGEON_MAP),
+ (1 << DUNGEON_BOSS_KEY) | (1 << DUNGEON_COMPASS) | (1 << DUNGEON_MAP),
+ (1 << DUNGEON_BOSS_KEY) | (1 << DUNGEON_COMPASS) | (1 << DUNGEON_MAP),
+ (1 << DUNGEON_BOSS_KEY) | (1 << DUNGEON_COMPASS) | (1 << DUNGEON_MAP),
+ (1 << DUNGEON_BOSS_KEY) | (1 << DUNGEON_COMPASS) | (1 << DUNGEON_MAP),
+ (1 << DUNGEON_BOSS_KEY) | (1 << DUNGEON_COMPASS) | (1 << DUNGEON_MAP),
+ },
// dungeonKeys
{ 8, 8, 8, 8, 8, 8, 8, 8, 8 },
// defenseHearts
@@ -851,15 +935,15 @@ void Sram_ResetSaveFromMoonCrash(SramContext* sramCtx) {
bzero(sramCtx->saveBuf, SAVE_BUFFER_SIZE);
- if (SysFlashrom_ReadData(sramCtx->saveBuf, D_801C67C8[gSaveContext.fileNum * 2],
- D_801C67F0[gSaveContext.fileNum * 2]) != 0) {
- SysFlashrom_ReadData(sramCtx->saveBuf, D_801C67C8[gSaveContext.fileNum * 2 + 1],
- D_801C67F0[gSaveContext.fileNum * 2 + 1]);
+ if (SysFlashrom_ReadData(sramCtx->saveBuf, gFlashSaveStartPages[gSaveContext.fileNum * 2],
+ gFlashSaveNumPages[gSaveContext.fileNum * 2]) != 0) {
+ SysFlashrom_ReadData(sramCtx->saveBuf, gFlashSaveStartPages[gSaveContext.fileNum * 2 + 1],
+ gFlashSaveNumPages[gSaveContext.fileNum * 2 + 1]);
}
Lib_MemCpy(&gSaveContext.save, sramCtx->saveBuf, sizeof(Save));
if (CHECK_NEWF(gSaveContext.save.saveInfo.playerData.newf)) {
- SysFlashrom_ReadData(sramCtx->saveBuf, D_801C67C8[gSaveContext.fileNum * 2 + 1],
- D_801C67F0[gSaveContext.fileNum * 2 + 1]);
+ SysFlashrom_ReadData(sramCtx->saveBuf, gFlashSaveStartPages[gSaveContext.fileNum * 2 + 1],
+ gFlashSaveNumPages[gSaveContext.fileNum * 2 + 1]);
Lib_MemCpy(&gSaveContext, sramCtx->saveBuf, sizeof(Save));
}
gSaveContext.save.cutsceneIndex = cutsceneIndex;
@@ -907,32 +991,34 @@ void Sram_OpenSave(FileSelectState* fileSelect, SramContext* sramCtx) {
s32 pad1;
s32 fileNum;
- if (gSaveContext.unk_3F3F) {
+ if (gSaveContext.flashSaveAvailable) {
bzero(sramCtx->saveBuf, SAVE_BUFFER_SIZE);
if (gSaveContext.fileNum == 0xFF) {
- SysFlashrom_ReadData(sramCtx->saveBuf, D_801C67C8[0], D_801C67F0[0]);
- } else if (fileSelect->unk_2446A[gSaveContext.fileNum] != 0) {
+ SysFlashrom_ReadData(sramCtx->saveBuf, gFlashSaveStartPages[0], gFlashSaveNumPages[0]);
+ } else if (fileSelect->isOwlSave[gSaveContext.fileNum + 2]) {
phi_t1 = gSaveContext.fileNum + 2;
phi_t1 *= 2;
- if (SysFlashrom_ReadData(sramCtx->saveBuf, D_801C67C8[phi_t1], D_801C67F0[phi_t1]) != 0) {
- SysFlashrom_ReadData(sramCtx->saveBuf, D_801C67C8[phi_t1 + 1], D_801C67F0[phi_t1 + 1]);
+ if (SysFlashrom_ReadData(sramCtx->saveBuf, gFlashSaveStartPages[phi_t1], gFlashSaveNumPages[phi_t1]) != 0) {
+ SysFlashrom_ReadData(sramCtx->saveBuf, gFlashSaveStartPages[phi_t1 + 1],
+ gFlashSaveNumPages[phi_t1 + 1]);
}
} else {
phi_t1 = gSaveContext.fileNum;
phi_t1 *= 2;
- if (SysFlashrom_ReadData(sramCtx->saveBuf, D_801C67C8[phi_t1], D_801C67F0[phi_t1]) != 0) {
- SysFlashrom_ReadData(sramCtx->saveBuf, D_801C67C8[phi_t1 + 1], D_801C67F0[phi_t1 + 1]);
+ if (SysFlashrom_ReadData(sramCtx->saveBuf, gFlashSaveStartPages[phi_t1], gFlashSaveNumPages[phi_t1]) != 0) {
+ SysFlashrom_ReadData(sramCtx->saveBuf, gFlashSaveStartPages[phi_t1 + 1],
+ gFlashSaveNumPages[phi_t1 + 1]);
}
}
- Lib_MemCpy(&gSaveContext, sramCtx->saveBuf, D_801C6870[phi_t1]);
+ Lib_MemCpy(&gSaveContext, sramCtx->saveBuf, gFlashSaveSizes[phi_t1]);
if (CHECK_NEWF(gSaveContext.save.saveInfo.playerData.newf)) {
- SysFlashrom_ReadData(sramCtx->saveBuf, D_801C67C8[phi_t1 + 1], D_801C67F0[phi_t1 + 1]);
- Lib_MemCpy(&gSaveContext, sramCtx->saveBuf, D_801C6870[phi_t1]);
+ SysFlashrom_ReadData(sramCtx->saveBuf, gFlashSaveStartPages[phi_t1 + 1], gFlashSaveNumPages[phi_t1 + 1]);
+ Lib_MemCpy(&gSaveContext, sramCtx->saveBuf, gFlashSaveSizes[phi_t1]);
}
}
@@ -963,7 +1049,7 @@ void Sram_OpenSave(FileSelectState* fileSelect, SramContext* sramCtx) {
if (gSaveContext.save.isFirstCycle) {
gSaveContext.save.entrance = ENTRANCE(SOUTH_CLOCK_TOWN, 0);
gSaveContext.save.day = 0;
- gSaveContext.save.time = 0x3FFF;
+ gSaveContext.save.time = CLOCK_TIME(6, 0) - 1;
} else {
gSaveContext.save.entrance = ENTRANCE(CUTSCENE, 0);
gSaveContext.nextCutsceneIndex = 0;
@@ -1028,7 +1114,7 @@ void func_8014546C(SramContext* sramCtx) {
gSaveContext.save.saveInfo.checksum = 0;
gSaveContext.save.saveInfo.checksum = Sram_CalcChecksum(&gSaveContext.save, sizeof(Save));
- if (gSaveContext.unk_3F3F) {
+ if (gSaveContext.flashSaveAvailable) {
Lib_MemCpy(sramCtx->saveBuf, &gSaveContext, sizeof(Save));
Lib_MemCpy(&sramCtx->saveBuf[0x2000], &gSaveContext.save, sizeof(Save));
}
@@ -1051,7 +1137,7 @@ void func_80145698(SramContext* sramCtx) {
gSaveContext.save.saveInfo.checksum = 0;
gSaveContext.save.saveInfo.checksum = Sram_CalcChecksum(&gSaveContext.save, sizeof(Save));
- if (gSaveContext.unk_3F3F) {
+ if (gSaveContext.flashSaveAvailable) {
Lib_MemCpy(sramCtx->saveBuf, &gSaveContext, sizeof(Save));
Lib_MemCpy(&sramCtx->saveBuf[0x2000], &gSaveContext.save, sizeof(Save));
}
@@ -1059,31 +1145,21 @@ void func_80145698(SramContext* sramCtx) {
// Verifies save and use backup if corrupted?
#ifdef NON_EQUIVALENT
-void func_801457CC(FileSelectState* fileSelect2, SramContext* sramCtx) {
- FileSelectState* fileSelect = fileSelect2;
+void func_801457CC(GameState* gameState, SramContext* sramCtx) {
+ FileSelectState* fileSelect = (FileSelectState*)gameState;
u16 sp7A;
- // u16 sp78;
+ u16 oldCheckSum; // s2
u16 sp76;
- // u16 sp74;
- u16 sp6E; //!
- // s32 sp68;
- // u16 sp66;
- u16 phi_s2; //!
- u16 sp64;
- // s32 sp60;
- // s32 sp5C;
- // s32 sp58;
- // u32 new_var;
- u16 phi_s2_3;
- // s16 fakevar;
+ u16 sp64; // sp74?
+ u16 phi_s2;
+ u16 phi_s7;
+ u16 sp6E;
+ u16 newCheckSum; // v0
+ u16 phi_a0; // maskCount
- u16 temp_s2;
- u16 temp_v0_2;
- u16 phi_a0; // maskCount
-
- if (gSaveContext.unk_3F3F) {
+ if (gSaveContext.flashSaveAvailable) {
D_801F6AF0 = gSaveContext.save.time;
- D_801F6AF2 = gSaveContext.unk_3F3F;
+ D_801F6AF2 = gSaveContext.flashSaveAvailable;
sp64 = 0;
for (sp76 = 0; sp76 < 5; sp76++, sp64 += 2) {
@@ -1091,40 +1167,65 @@ void func_801457CC(FileSelectState* fileSelect2, SramContext* sramCtx) {
phi_s2 = false;
sp6E = 0;
- if (SysFlashrom_ReadData(sramCtx->saveBuf, D_801C67C8[sp64], D_801C67F0[sp64])) {
+ // read main save from flash
+ if (SysFlashrom_ReadData(sramCtx->saveBuf, gFlashSaveStartPages[sp64], gFlashSaveNumPages[sp64]) != 0) {
+ // main save didn't work
sp6E = 1;
- if (SysFlashrom_ReadData(sramCtx->saveBuf, D_801C67C8[sp64 + 1], D_801C67F0[sp64 + 1])) {
+ // read backup save from flash
+ if (SysFlashrom_ReadData(sramCtx->saveBuf, gFlashSaveStartPages[sp64 + 1],
+ gFlashSaveNumPages[sp64 + 1]) != 0) {
+ // backup save didn't work
phi_s2 = true;
}
}
if (sp76 < 2) {
- fileSelect->unk_24468[sp76] = 0;
+ // Non-owl save
+ // sp76 = 0: main save
+ // sp76 = 1: backup save
+
+ fileSelect->isOwlSave[sp76] = 0;
if (phi_s2) {
+ // both main save and backup save failed
bzero(sramCtx->saveBuf, SAVE_BUFFER_SIZE);
- Lib_MemCpy(&gSaveContext, sramCtx->saveBuf, D_801C6870[sp64]);
+ Lib_MemCpy(&gSaveContext, sramCtx->saveBuf, gFlashSaveSizes[sp64]);
} else {
- // Lib_MemCpy(&gSaveContext, sramCtx->saveBuf, D_801C6870[sp64]);
- Lib_MemCpy(&gSaveContext, sramCtx->saveBuf, D_801C6870[sp64]);
- temp_s2 = gSaveContext.save.saveInfo.checksum;
+ Lib_MemCpy(&gSaveContext, sramCtx->saveBuf, gFlashSaveSizes[sp64]);
+
+ // test checksum of main save
+ oldCheckSum = gSaveContext.save.saveInfo.checksum;
gSaveContext.save.saveInfo.checksum = 0;
- temp_v0_2 = Sram_CalcChecksum(&gSaveContext, D_801C6870[sp64]);
- gSaveContext.save.saveInfo.checksum = temp_s2;
+ newCheckSum = Sram_CalcChecksum(&gSaveContext, gFlashSaveSizes[sp64]);
+ gSaveContext.save.saveInfo.checksum = oldCheckSum;
- if (CHECK_NEWF(gSaveContext.save.saveInfo.playerData.newf) || (temp_s2 != temp_v0_2)) {
+ if (CHECK_NEWF(gSaveContext.save.saveInfo.playerData.newf) || (oldCheckSum != newCheckSum)) {
+ // checksum didnt match, try backup save
sp6E = 1;
- if (CHECK_NEWF2(gSaveContext.save.saveInfo.playerData.newf)) {}
- phi_s2 = false;
- if (SysFlashrom_ReadData(sramCtx->saveBuf, D_801C67C8[sp64 + 1], D_801C67F0[sp64 + 1])) {
+ if ((gSaveContext.save.saveInfo.playerData.newf[0] == 'Z') &&
+ (gSaveContext.save.saveInfo.playerData.newf[1] == 'E')) {
+ phi_s2 = false;
+ }
+
+ // phi_s2 = false;
+
+ // read backup save from flash
+ if (SysFlashrom_ReadData(sramCtx->saveBuf, gFlashSaveStartPages[sp64 + 1],
+ gFlashSaveNumPages[sp64 + 1]) != 0) {
+ // backup save didn't work
phi_s2 = true;
}
- Lib_MemCpy(&gSaveContext, sramCtx->saveBuf, D_801C6870[sp64]);
- temp_s2 = gSaveContext.save.saveInfo.checksum;
+ Lib_MemCpy(&gSaveContext, sramCtx->saveBuf, gFlashSaveSizes[sp64]);
+
+ // test checksum of backup save
+ oldCheckSum = gSaveContext.save.saveInfo.checksum;
gSaveContext.save.saveInfo.checksum = 0;
+
+ //! FAKE: (s32)sp64
if (phi_s2 || CHECK_NEWF(gSaveContext.save.saveInfo.playerData.newf) ||
- (temp_s2 != Sram_CalcChecksum(&gSaveContext, D_801C6870[sp64]))) {
+ (oldCheckSum != Sram_CalcChecksum(&gSaveContext, gFlashSaveSizes[(s32)sp64]))) {
+ // backup save didn't work
bzero(sramCtx->saveBuf, SAVE_BUFFER_SIZE);
Lib_MemCpy(&gSaveContext.save, sramCtx->saveBuf, sizeof(Save));
sp6E = 999;
@@ -1133,29 +1234,30 @@ void func_801457CC(FileSelectState* fileSelect2, SramContext* sramCtx) {
}
gSaveContext.save.saveInfo.checksum = 0;
+ // FAKE: Needed?
gSaveContext.save.saveInfo.checksum =
- Sram_CalcChecksum(&gSaveContext, D_801C6870[sp64 & 0xFFFFFFFF]); // TODO: Needed?
+ Sram_CalcChecksum(&gSaveContext, gFlashSaveSizes[sp64 & 0xFFFFFFFF]);
for (sp7A = 0; sp7A < ARRAY_COUNT(gSaveContext.save.saveInfo.playerData.newf); sp7A++) {
fileSelect->newf[sp76][sp7A] = gSaveContext.save.saveInfo.playerData.newf[sp7A];
}
if (!CHECK_NEWF(fileSelect->newf[sp76])) {
- fileSelect->unk_2440C[sp76] = gSaveContext.save.saveInfo.playerData.deaths;
+ fileSelect->threeDayResetCount[sp76] = gSaveContext.save.saveInfo.playerData.threeDayResetCount;
for (sp7A = 0; sp7A < ARRAY_COUNT(gSaveContext.save.saveInfo.playerData.playerName); sp7A++) {
- fileSelect->unk_24414[sp76][sp7A] = gSaveContext.save.saveInfo.playerData.playerName[sp7A];
+ fileSelect->fileNames[sp76][sp7A] = gSaveContext.save.saveInfo.playerData.playerName[sp7A];
}
fileSelect->healthCapacity[sp76] = gSaveContext.save.saveInfo.playerData.healthCapacity;
fileSelect->health[sp76] = gSaveContext.save.saveInfo.playerData.health;
- fileSelect->unk_24454[sp76] = gSaveContext.save.saveInfo.inventory.defenseHearts;
- fileSelect->unk_24444[sp76] = gSaveContext.save.saveInfo.inventory.questItems;
- fileSelect->unk_24458[sp76] = gSaveContext.save.time;
- fileSelect->unk_24460[sp76] = gSaveContext.save.day;
- fileSelect->unk_24468[sp76] = gSaveContext.save.isOwlSave;
+ fileSelect->defenseHearts[sp76] = gSaveContext.save.saveInfo.inventory.defenseHearts;
+ fileSelect->questItems[sp76] = gSaveContext.save.saveInfo.inventory.questItems;
+ fileSelect->time[sp76] = gSaveContext.save.time;
+ fileSelect->day[sp76] = gSaveContext.save.day;
+ fileSelect->isOwlSave[sp76] = gSaveContext.save.isOwlSave;
fileSelect->rupees[sp76] = gSaveContext.save.saveInfo.playerData.rupees;
- fileSelect->unk_24474[sp76] = CUR_UPG_VALUE(4);
+ fileSelect->walletUpgrades[sp76] = CUR_UPG_VALUE(UPG_WALLET);
for (sp7A = 0, phi_a0 = 0; sp7A < 24; sp7A++) {
if (gSaveContext.save.saveInfo.inventory.items[sp7A + 24] != 0xFF) {
@@ -1168,90 +1270,106 @@ void func_801457CC(FileSelectState* fileSelect2, SramContext* sramCtx) {
}
if (sp6E == 1) {
+ // backup save
Lib_MemCpy(&sramCtx->saveBuf[0x2000], &gSaveContext.save, sizeof(Save));
- func_80146EBC(sramCtx, D_801C67C8[sp64], D_801C6818[sp64]);
- } else if (sp6E == 0) { // TODO: == 0?
- temp_s2 = gSaveContext.save.saveInfo.checksum;
- if (SysFlashrom_ReadData(sramCtx->saveBuf, D_801C67C8[sp64 + 1], D_801C67F0[sp64 + 1])) {
- phi_s2_3 = 1;
+ Sram_SyncWriteToFlash(sramCtx, gFlashSaveStartPages[sp64], gFlashSpecialSaveNumPages[sp64]);
+ } else if (!sp6E) {
+ // main save
+ phi_s7 = gSaveContext.save.saveInfo.checksum;
+
+ if (SysFlashrom_ReadData(sramCtx->saveBuf, gFlashSaveStartPages[sp64 + 1],
+ gFlashSaveNumPages[sp64 + 1]) != 0) {
+ oldCheckSum = 1;
} else {
Lib_MemCpy(&gSaveContext.save, sramCtx->saveBuf, sizeof(Save));
- phi_s2_3 = gSaveContext.save.saveInfo.checksum;
+ oldCheckSum = gSaveContext.save.saveInfo.checksum;
gSaveContext.save.saveInfo.checksum = 0;
sp7A = Sram_CalcChecksum(&gSaveContext.save, sizeof(Save));
}
- if (CHECK_NEWF(gSaveContext.save.saveInfo.playerData.newf) || (phi_s2_3 != sp7A) ||
- (phi_s2_3 != temp_s2)) {
- SysFlashrom_ReadData(sramCtx->saveBuf, D_801C67C8[sp64], D_801C67F0[sp64]);
+ if (CHECK_NEWF(gSaveContext.save.saveInfo.playerData.newf) || (oldCheckSum != sp7A) ||
+ (oldCheckSum != phi_s7)) {
+ SysFlashrom_ReadData(sramCtx->saveBuf, gFlashSaveStartPages[sp64], gFlashSaveNumPages[sp64]);
Lib_MemCpy(&gSaveContext.save, sramCtx->saveBuf, sizeof(Save));
Lib_MemCpy(&sramCtx->saveBuf[0x2000], &gSaveContext.save, sizeof(Save));
- func_80146EBC(sramCtx, D_801C67C8[sp64], D_801C6818[sp64]);
+ Sram_SyncWriteToFlash(sramCtx, gFlashSaveStartPages[sp64], gFlashSpecialSaveNumPages[sp64]);
}
}
} else if (sp76 < 4) {
- fileSelect->unk_24468[sp76] = 0;
+ // Owl Save:
+ // sp76 = 3: main owl save
+ // sp76 = 4: backup owl save
+ fileSelect->isOwlSave[sp76] = 0;
- if (!CHECK_NEWF(fileSelect->newf2[(s32)sp76])) { // TODO: Needed?
+ if (!CHECK_NEWF(fileSelect->newf[sp76 - 2])) {
if (phi_s2) {
+ // both main save and backup save failed
bzero(sramCtx->saveBuf, SAVE_BUFFER_SIZE);
- Lib_MemCpy(&gSaveContext, sramCtx->saveBuf,
- D_801C6870[sp64]); // TODO: Needed?
+ Lib_MemCpy(&gSaveContext, sramCtx->saveBuf, gFlashSaveSizes[sp64]);
} else {
- Lib_MemCpy(&gSaveContext, sramCtx->saveBuf, D_801C6870[sp64]);
- temp_s2 = gSaveContext.save.saveInfo.checksum;
+ Lib_MemCpy(&gSaveContext, sramCtx->saveBuf, gFlashSaveSizes[sp64]);
+ oldCheckSum = gSaveContext.save.saveInfo.checksum;
+ // test checksum of main save
gSaveContext.save.saveInfo.checksum = 0;
- temp_v0_2 = Sram_CalcChecksum(&gSaveContext, D_801C6870[sp64]);
- gSaveContext.save.saveInfo.checksum = temp_s2;
- if (CHECK_NEWF(gSaveContext.save.saveInfo.playerData.newf) || (temp_s2 != temp_v0_2)) {
+ newCheckSum = Sram_CalcChecksum(&gSaveContext, gFlashSaveSizes[sp64]);
+ gSaveContext.save.saveInfo.checksum = oldCheckSum;
+
+ if (CHECK_NEWF(gSaveContext.save.saveInfo.playerData.newf) || (oldCheckSum != newCheckSum)) {
+ // checksum didnt match, try backup save
sp6E = 1;
if ((gSaveContext.save.saveInfo.playerData.newf[0] == 'Z') &&
(gSaveContext.save.saveInfo.playerData.newf[1] == 'E')) {
phi_s2 = false;
}
- if (SysFlashrom_ReadData(sramCtx->saveBuf, D_801C67C8[sp64 + 1], D_801C67F0[sp64 + 1])) {
+ // read backup save from flash
+ if (SysFlashrom_ReadData(sramCtx->saveBuf, gFlashSaveStartPages[sp64 + 1],
+ gFlashSaveNumPages[sp64 + 1])) {
+ // backup save didn't work
phi_s2 = true;
}
- Lib_MemCpy(&gSaveContext, sramCtx->saveBuf, D_801C6870[sp64]);
- temp_s2 = gSaveContext.save.saveInfo.checksum;
+ Lib_MemCpy(&gSaveContext, sramCtx->saveBuf, gFlashSaveSizes[sp64]);
+
+ // test checksum of backup save
+ oldCheckSum = gSaveContext.save.saveInfo.checksum;
gSaveContext.save.saveInfo.checksum = 0;
+
if (phi_s2 || CHECK_NEWF(gSaveContext.save.saveInfo.playerData.newf) ||
- (temp_s2 != Sram_CalcChecksum(&gSaveContext, D_801C6870[sp64]))) {
+ (oldCheckSum != Sram_CalcChecksum(&gSaveContext, gFlashSaveSizes[sp64]))) {
bzero(sramCtx->saveBuf, SAVE_BUFFER_SIZE);
- Lib_MemCpy(&gSaveContext, sramCtx->saveBuf, D_801C6870[sp64]);
+ Lib_MemCpy(&gSaveContext, sramCtx->saveBuf, gFlashSaveSizes[sp64]);
sp6E = 999;
}
}
}
gSaveContext.save.saveInfo.checksum = 0;
+ // FAKE: Needed?
gSaveContext.save.saveInfo.checksum =
- Sram_CalcChecksum(&gSaveContext, D_801C6870[sp64 & 0xFFFFFFFF]); // TODO: Needed?
+ Sram_CalcChecksum(&gSaveContext, gFlashSaveSizes[sp64 & 0xFFFFFFFF]);
for (sp7A = 0; sp7A < ARRAY_COUNT(gSaveContext.save.saveInfo.playerData.newf); sp7A++) {
fileSelect->newf[sp76][sp7A] = gSaveContext.save.saveInfo.playerData.newf[sp7A];
}
if (!CHECK_NEWF(fileSelect->newf[sp76])) {
- fileSelect->unk_2440C[sp76] = gSaveContext.save.saveInfo.playerData.deaths;
+ fileSelect->threeDayResetCount[sp76] = gSaveContext.save.saveInfo.playerData.threeDayResetCount;
for (sp7A = 0; sp7A < ARRAY_COUNT(gSaveContext.save.saveInfo.playerData.playerName); sp7A++) {
- phi_s2 += 0; // TODO: Needed?
- fileSelect->unk_24414[sp76][sp7A] = gSaveContext.save.saveInfo.playerData.playerName[sp7A];
+ fileSelect->fileNames[sp76][sp7A] = gSaveContext.save.saveInfo.playerData.playerName[sp7A];
}
fileSelect->healthCapacity[sp76] = gSaveContext.save.saveInfo.playerData.healthCapacity;
fileSelect->health[sp76] = gSaveContext.save.saveInfo.playerData.health;
- fileSelect->unk_24454[sp76] = gSaveContext.save.saveInfo.inventory.defenseHearts;
- fileSelect->unk_24444[sp76] = gSaveContext.save.saveInfo.inventory.questItems;
- fileSelect->unk_24458[sp76] = gSaveContext.save.time;
- fileSelect->unk_24460[sp76] = gSaveContext.save.day;
- fileSelect->unk_24468[sp76] = gSaveContext.save.isOwlSave;
+ fileSelect->defenseHearts[sp76] = gSaveContext.save.saveInfo.inventory.defenseHearts;
+ fileSelect->questItems[sp76] = gSaveContext.save.saveInfo.inventory.questItems;
+ fileSelect->time[sp76] = gSaveContext.save.time;
+ fileSelect->day[sp76] = gSaveContext.save.day;
+ fileSelect->isOwlSave[sp76] = gSaveContext.save.isOwlSave;
fileSelect->rupees[sp76] = gSaveContext.save.saveInfo.playerData.rupees;
- fileSelect->unk_24474[sp76] = CUR_UPG_VALUE(4);
+ fileSelect->walletUpgrades[sp76] = CUR_UPG_VALUE(UPG_WALLET);
for (sp7A = 0, phi_a0 = 0; sp7A < 24; sp7A++) {
if (gSaveContext.save.saveInfo.inventory.items[sp7A + 24] != 0xFF) {
@@ -1264,39 +1382,44 @@ void func_801457CC(FileSelectState* fileSelect2, SramContext* sramCtx) {
}
if (sp6E == 1) {
- func_80146EBC(sramCtx, D_801C67C8[sp64], D_801C67F0[sp64]);
- func_80146EBC(sramCtx, D_801C67C8[sp64 + 1], D_801C67F0[sp64 + 1]);
- } else if (!sp6E) { // TODO: == 0?
- temp_s2 = gSaveContext.save.saveInfo.checksum;
- if (SysFlashrom_ReadData(sramCtx->saveBuf, D_801C67C8[sp64 + 1], D_801C67F0[sp64 + 1])) {
- phi_s2_3 = 1;
+ // backup save
+ Sram_SyncWriteToFlash(sramCtx, gFlashSaveStartPages[sp64], gFlashSaveNumPages[sp64]);
+ Sram_SyncWriteToFlash(sramCtx, gFlashSaveStartPages[sp64 + 1], gFlashSaveNumPages[sp64 + 1]);
+ } else if (!sp6E) {
+ // main save
+ phi_s7 = gSaveContext.save.saveInfo.checksum;
+
+ if (SysFlashrom_ReadData(sramCtx->saveBuf, gFlashSaveStartPages[sp64 + 1],
+ gFlashSaveNumPages[sp64 + 1])) {
+ oldCheckSum = 1;
} else {
- Lib_MemCpy(&gSaveContext, sramCtx->saveBuf, D_801C6870[sp64]);
- phi_s2_3 = gSaveContext.save.saveInfo.checksum;
+ Lib_MemCpy(&gSaveContext, sramCtx->saveBuf, gFlashSaveSizes[sp64]);
+ oldCheckSum = gSaveContext.save.saveInfo.checksum;
gSaveContext.save.saveInfo.checksum = 0;
- // phi_s2_3 = gSaveContext.save.saveInfo.checksum;
- sp7A = Sram_CalcChecksum(&gSaveContext, D_801C6870[sp64]);
+ sp7A = Sram_CalcChecksum(&gSaveContext, gFlashSaveSizes[sp64]);
}
- if (CHECK_NEWF(gSaveContext.save.saveInfo.playerData.newf) || (phi_s2_3 != sp7A) ||
- (phi_s2_3 != temp_s2)) {
- SysFlashrom_ReadData(sramCtx->saveBuf, D_801C67C8[sp64], D_801C67F0[sp64]);
- Lib_MemCpy(&gSaveContext, sramCtx->saveBuf, D_801C6870[sp64]);
- func_80146EBC(sramCtx, D_801C67C8[sp64], D_801C67F0[sp64]);
- func_80146EBC(sramCtx, D_801C67C8[sp64 + 1], D_801C67F0[sp64 + 1]);
+ if (CHECK_NEWF(gSaveContext.save.saveInfo.playerData.newf) || (oldCheckSum != sp7A) ||
+ (oldCheckSum != phi_s7)) {
+ SysFlashrom_ReadData(sramCtx->saveBuf, gFlashSaveStartPages[sp64],
+ gFlashSaveNumPages[sp64]);
+ Lib_MemCpy(&gSaveContext, sramCtx->saveBuf, gFlashSaveSizes[sp64]);
+ Sram_SyncWriteToFlash(sramCtx, gFlashSaveStartPages[sp64], gFlashSaveNumPages[sp64]);
+ Sram_SyncWriteToFlash(sramCtx, gFlashSaveStartPages[sp64 + 1],
+ gFlashSaveNumPages[sp64 + 1]);
}
}
} else {
bzero(sramCtx->saveBuf, SAVE_BUFFER_SIZE);
- Lib_MemCpy(&gSaveContext, sramCtx->saveBuf, D_801C6870[sp64]);
- func_80146EBC(sramCtx, D_801C67C8[sp64], D_801C67F0[sp64]);
- func_80146EBC(sramCtx, D_801C67C8[sp64 + 1], D_801C67F0[sp64 + 1]);
+ Lib_MemCpy(&gSaveContext, sramCtx->saveBuf, gFlashSaveSizes[sp64]);
+ Sram_SyncWriteToFlash(sramCtx, gFlashSaveStartPages[sp64], gFlashSaveNumPages[sp64]);
+ Sram_SyncWriteToFlash(sramCtx, gFlashSaveStartPages[sp64 + 1], gFlashSaveNumPages[sp64 + 1]);
}
} else {
if (phi_s2) {
gSaveContext.options.optionId = 0xA51D;
gSaveContext.options.language = 1;
- gSaveContext.options.audioSetting = 0;
+ gSaveContext.options.audioSetting = SAVE_AUDIO_STEREO;
gSaveContext.options.languageSetting = 0;
gSaveContext.options.zTargetSetting = 0;
} else {
@@ -1304,7 +1427,7 @@ void func_801457CC(FileSelectState* fileSelect2, SramContext* sramCtx) {
if (gSaveContext.options.optionId != 0xA51D) {
gSaveContext.options.optionId = 0xA51D;
gSaveContext.options.language = 1;
- gSaveContext.options.audioSetting = 0;
+ gSaveContext.options.audioSetting = SAVE_AUDIO_STEREO;
gSaveContext.options.languageSetting = 0;
gSaveContext.options.zTargetSetting = 0;
}
@@ -1314,7 +1437,7 @@ void func_801457CC(FileSelectState* fileSelect2, SramContext* sramCtx) {
}
gSaveContext.save.time = D_801F6AF0;
- gSaveContext.unk_3F3F = D_801F6AF2;
+ gSaveContext.flashSaveAvailable = D_801F6AF2;
}
gSaveContext.options.language = 1;
@@ -1323,50 +1446,52 @@ void func_801457CC(FileSelectState* fileSelect2, SramContext* sramCtx) {
#pragma GLOBAL_ASM("asm/non_matchings/code/z_sram_NES/func_801457CC.s")
#endif
-void func_80146580(FileSelectState* fileSelect2, SramContext* sramCtx, s32 fileNum) {
+void Sram_EraseSave(FileSelectState* fileSelect2, SramContext* sramCtx, s32 fileNum) {
FileSelectState* fileSelect = fileSelect2;
s32 pad;
- if (gSaveContext.unk_3F3F) {
- if (fileSelect->unk_2446A[fileNum]) {
+ if (gSaveContext.flashSaveAvailable) {
+ if (fileSelect->isOwlSave[fileNum + 2]) {
func_80147314(sramCtx, fileNum);
- fileSelect->unk_2446A[fileNum] = 0;
+ fileSelect->isOwlSave[fileNum + 2] = false;
}
bzero(sramCtx->saveBuf, SAVE_BUFFER_SIZE);
Lib_MemCpy(&gSaveContext, sramCtx->saveBuf, sizeof(Save));
}
gSaveContext.save.time = D_801F6AF0;
- gSaveContext.unk_3F3F = D_801F6AF2;
+ gSaveContext.flashSaveAvailable = D_801F6AF2;
}
#ifdef NON_MATCHING
// v0/v1
-void func_80146628(FileSelectState* fileSelect2, SramContext* sramCtx) {
+void Sram_CopySave(FileSelectState* fileSelect2, SramContext* sramCtx) {
FileSelectState* fileSelect = fileSelect2;
u16 i;
s16 maskCount;
- if (gSaveContext.unk_3F3F) {
- if (fileSelect->unk_2446A[fileSelect->unk_2448E]) {
- func_80147414(sramCtx, fileSelect->unk_2448E, fileSelect->fileNum);
- fileSelect->unk_24410[fileSelect->fileNum] = gSaveContext.save.saveInfo.playerData.deaths;
+ if (gSaveContext.flashSaveAvailable) {
+ if (fileSelect->isOwlSave[fileSelect->selectedFileIndex + 2]) {
+ func_80147414(sramCtx, fileSelect->selectedFileIndex, fileSelect->copyDestFileIndex);
+ fileSelect->threeDayResetCount[fileSelect->copyDestFileIndex + 2] =
+ gSaveContext.save.saveInfo.playerData.threeDayResetCount;
for (i = 0; i < ARRAY_COUNT(gSaveContext.save.saveInfo.playerData.playerName); i++) {
- fileSelect->unk_24424[fileSelect->fileNum][i] = gSaveContext.save.saveInfo.playerData.playerName[i];
+ fileSelect->fileNames[fileSelect->copyDestFileIndex + 2][i] =
+ gSaveContext.save.saveInfo.playerData.playerName[i];
}
- fileSelect->unk_24438[fileSelect->fileNum] = gSaveContext.save.saveInfo.playerData.healthCapacity;
- fileSelect->unk_24440[fileSelect->fileNum] = gSaveContext.save.saveInfo.playerData.health;
- fileSelect->unk_24456[fileSelect->fileNum] = gSaveContext.save.saveInfo.inventory.defenseHearts;
- fileSelect->unk_2444C[fileSelect->fileNum] = gSaveContext.save.saveInfo.inventory.questItems;
- fileSelect->unk_2445C[fileSelect->fileNum] = gSaveContext.save.time;
- fileSelect->unk_24464[fileSelect->fileNum] = gSaveContext.save.day;
- fileSelect->unk_2446A[fileSelect->fileNum] = gSaveContext.save.isOwlSave;
- fileSelect->unk_24470[fileSelect->fileNum] = gSaveContext.save.saveInfo.playerData.rupees;
- // = CUR_UPG_VALUE(UPG_WALLET);
- fileSelect->unk_24476[fileSelect->fileNum] =
- (gSaveContext.save.saveInfo.inventory.upgrades & gUpgradeMasks[4]) >> gUpgradeShifts[4];
+ fileSelect->healthCapacity[fileSelect->copyDestFileIndex + 2] =
+ gSaveContext.save.saveInfo.playerData.healthCapacity;
+ fileSelect->health[fileSelect->copyDestFileIndex + 2] = gSaveContext.save.saveInfo.playerData.health;
+ fileSelect->defenseHearts[fileSelect->copyDestFileIndex + 2] =
+ gSaveContext.save.saveInfo.inventory.defenseHearts;
+ fileSelect->questItems[fileSelect->copyDestFileIndex + 2] = gSaveContext.save.saveInfo.inventory.questItems;
+ fileSelect->time[fileSelect->copyDestFileIndex + 2] = gSaveContext.save.time;
+ fileSelect->day[fileSelect->copyDestFileIndex + 2] = gSaveContext.save.day;
+ fileSelect->isOwlSave[fileSelect->copyDestFileIndex + 2] = gSaveContext.save.isOwlSave;
+ fileSelect->rupees[fileSelect->copyDestFileIndex + 2] = gSaveContext.save.saveInfo.playerData.rupees;
+ fileSelect->walletUpgrades[fileSelect->copyDestFileIndex + 2] = CUR_UPG_VALUE(UPG_WALLET);
for (i = 0, maskCount = 0; i < 24; i++) {
if (gSaveContext.save.saveInfo.inventory.items[i + 24] != ITEM_NONE) {
@@ -1374,42 +1499,42 @@ void func_80146628(FileSelectState* fileSelect2, SramContext* sramCtx) {
}
}
- fileSelect->unk_2447A[fileSelect->fileNum] = maskCount;
- fileSelect->unk_2447E[fileSelect->fileNum] =
- (gSaveContext.save.saveInfo.inventory.questItems & 0xF0000000) >> 0x1C;
+ fileSelect->maskCount[fileSelect->copyDestFileIndex + 2] = maskCount;
+ fileSelect->heartPieceCount[fileSelect->copyDestFileIndex + 2] = GET_QUEST_HEART_PIECE_COUNT;
}
// clear buffer
bzero(sramCtx->saveBuf, SAVE_BUFFER_SIZE);
// read to buffer
- SysFlashrom_ReadData(sramCtx->saveBuf, D_801C67C8[fileSelect->unk_2448E * 2],
- D_801C67F0[fileSelect->unk_2448E * 2]);
-
+ SysFlashrom_ReadData(&sramCtx->saveBuf[0], gFlashSaveStartPages[fileSelect->selectedFileIndex * 2],
+ gFlashSaveNumPages[fileSelect->selectedFileIndex * 2]);
if (1) {}
- SysFlashrom_ReadData(&sramCtx->saveBuf[0x2000], D_801C67C8[fileSelect->unk_2448E * 2 + 1],
- D_801C67F0[fileSelect->unk_2448E * 2 + 1]);
+
+ SysFlashrom_ReadData(&sramCtx->saveBuf[0x2000], gFlashSaveStartPages[fileSelect->selectedFileIndex * 2 + 1],
+ gFlashSaveNumPages[fileSelect->selectedFileIndex * 2 + 1]);
if (1) {}
// copy buffer to save context
Lib_MemCpy(&gSaveContext.save, sramCtx->saveBuf, sizeof(Save));
- fileSelect->unk_2440C[fileSelect->fileNum] = gSaveContext.save.saveInfo.playerData.deaths;
+ fileSelect->threeDayResetCount[fileSelect->copyDestFileIndex] =
+ gSaveContext.save.saveInfo.playerData.threeDayResetCount;
for (i = 0; i < ARRAY_COUNT(gSaveContext.save.saveInfo.playerData.playerName); i++) {
- fileSelect->unk_24414[fileSelect->fileNum][i] = gSaveContext.save.saveInfo.playerData.playerName[i];
+ fileSelect->fileNames[fileSelect->copyDestFileIndex][i] =
+ gSaveContext.save.saveInfo.playerData.playerName[i];
}
- fileSelect->healthCapacity[fileSelect->fileNum] = gSaveContext.save.saveInfo.playerData.healthCapacity;
- fileSelect->health[fileSelect->fileNum] = gSaveContext.save.saveInfo.playerData.health;
- fileSelect->unk_24454[fileSelect->fileNum] = gSaveContext.save.saveInfo.inventory.defenseHearts;
- fileSelect->unk_24444[fileSelect->fileNum] = gSaveContext.save.saveInfo.inventory.questItems;
- fileSelect->unk_24458[fileSelect->fileNum] = gSaveContext.save.time;
- fileSelect->unk_24460[fileSelect->fileNum] = gSaveContext.save.day;
- fileSelect->unk_24468[fileSelect->fileNum] = gSaveContext.save.isOwlSave;
- fileSelect->rupees[fileSelect->fileNum] = gSaveContext.save.saveInfo.playerData.rupees;
- // = CUR_UPG_VALUE(UPG_WALLET);
- fileSelect->unk_24474[fileSelect->fileNum] =
- (gSaveContext.save.saveInfo.inventory.upgrades & gUpgradeMasks[4]) >> gUpgradeShifts[4];
+ fileSelect->healthCapacity[fileSelect->copyDestFileIndex] =
+ gSaveContext.save.saveInfo.playerData.healthCapacity;
+ fileSelect->health[fileSelect->copyDestFileIndex] = gSaveContext.save.saveInfo.playerData.health;
+ fileSelect->defenseHearts[fileSelect->copyDestFileIndex] = gSaveContext.save.saveInfo.inventory.defenseHearts;
+ fileSelect->questItems[fileSelect->copyDestFileIndex] = gSaveContext.save.saveInfo.inventory.questItems;
+ fileSelect->time[fileSelect->copyDestFileIndex] = gSaveContext.save.time;
+ fileSelect->day[fileSelect->copyDestFileIndex] = gSaveContext.save.day;
+ fileSelect->isOwlSave[fileSelect->copyDestFileIndex] = gSaveContext.save.isOwlSave;
+ fileSelect->rupees[fileSelect->copyDestFileIndex] = gSaveContext.save.saveInfo.playerData.rupees;
+ fileSelect->walletUpgrades[fileSelect->copyDestFileIndex] = CUR_UPG_VALUE(UPG_WALLET);
for (i = 0, maskCount = 0; i < 24; i++) {
if (gSaveContext.save.saveInfo.inventory.items[i + 24] != ITEM_NONE) {
@@ -1417,16 +1542,15 @@ void func_80146628(FileSelectState* fileSelect2, SramContext* sramCtx) {
}
}
- fileSelect->maskCount[fileSelect->fileNum] = maskCount;
- fileSelect->heartPieceCount[fileSelect->fileNum] =
- (gSaveContext.save.saveInfo.inventory.questItems & 0xF0000000) >> 0x1C;
+ fileSelect->maskCount[fileSelect->copyDestFileIndex] = maskCount;
+ fileSelect->heartPieceCount[fileSelect->copyDestFileIndex] = GET_QUEST_HEART_PIECE_COUNT;
}
gSaveContext.save.time = D_801F6AF0;
- gSaveContext.unk_3F3F = D_801F6AF2;
+ gSaveContext.flashSaveAvailable = D_801F6AF2;
}
#else
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_sram_NES/func_80146628.s")
+#pragma GLOBAL_ASM("asm/non_matchings/code/z_sram_NES/Sram_CopySave.s")
#endif
void Sram_InitSave(FileSelectState* fileSelect2, SramContext* sramCtx) {
@@ -1435,15 +1559,15 @@ void Sram_InitSave(FileSelectState* fileSelect2, SramContext* sramCtx) {
FileSelectState* fileSelect = fileSelect2;
s16 maskCount;
- if (gSaveContext.unk_3F3F) {
+ if (gSaveContext.flashSaveAvailable) {
Sram_InitNewSave();
- if (fileSelect->unk_24480 == 0) {
+ if (fileSelect->buttonIndex == 0) {
gSaveContext.save.cutsceneIndex = 0xFFF0;
}
for (phi_v0 = 0; phi_v0 < ARRAY_COUNT(gSaveContext.save.saveInfo.playerData.playerName); phi_v0++) {
gSaveContext.save.saveInfo.playerData.playerName[phi_v0] =
- fileSelect->unk_24414[fileSelect->unk_24480][phi_v0];
+ fileSelect->fileNames[fileSelect->buttonIndex][phi_v0];
}
gSaveContext.save.saveInfo.playerData.newf[0] = 'Z';
@@ -1459,24 +1583,25 @@ void Sram_InitSave(FileSelectState* fileSelect2, SramContext* sramCtx) {
Lib_MemCpy(&sramCtx->saveBuf[0x2000], &gSaveContext.save, sizeof(Save));
for (i = 0; i < ARRAY_COUNT(gSaveContext.save.saveInfo.playerData.newf); i++) {
- fileSelect->newf[fileSelect->unk_24480][i] = gSaveContext.save.saveInfo.playerData.newf[i];
+ fileSelect->newf[fileSelect->buttonIndex][i] = gSaveContext.save.saveInfo.playerData.newf[i];
}
- fileSelect->unk_2440C[fileSelect->unk_24480] = gSaveContext.save.saveInfo.playerData.deaths;
+ fileSelect->threeDayResetCount[fileSelect->buttonIndex] =
+ gSaveContext.save.saveInfo.playerData.threeDayResetCount;
for (i = 0; i < ARRAY_COUNT(gSaveContext.save.saveInfo.playerData.playerName); i++) {
- fileSelect->unk_24414[fileSelect->unk_24480][i] = gSaveContext.save.saveInfo.playerData.playerName[i];
+ fileSelect->fileNames[fileSelect->buttonIndex][i] = gSaveContext.save.saveInfo.playerData.playerName[i];
}
- fileSelect->healthCapacity[fileSelect->unk_24480] = gSaveContext.save.saveInfo.playerData.healthCapacity;
- fileSelect->health[fileSelect->unk_24480] = gSaveContext.save.saveInfo.playerData.health;
- fileSelect->unk_24454[fileSelect->unk_24480] = gSaveContext.save.saveInfo.inventory.defenseHearts;
- fileSelect->unk_24444[fileSelect->unk_24480] = gSaveContext.save.saveInfo.inventory.questItems;
- fileSelect->unk_24458[fileSelect->unk_24480] = gSaveContext.save.time;
- fileSelect->unk_24460[fileSelect->unk_24480] = gSaveContext.save.day;
- fileSelect->unk_24468[fileSelect->unk_24480] = gSaveContext.save.isOwlSave;
- fileSelect->rupees[fileSelect->unk_24480] = gSaveContext.save.saveInfo.playerData.rupees;
- fileSelect->unk_24474[fileSelect->unk_24480] = CUR_UPG_VALUE(UPG_WALLET);
+ fileSelect->healthCapacity[fileSelect->buttonIndex] = gSaveContext.save.saveInfo.playerData.healthCapacity;
+ fileSelect->health[fileSelect->buttonIndex] = gSaveContext.save.saveInfo.playerData.health;
+ fileSelect->defenseHearts[fileSelect->buttonIndex] = gSaveContext.save.saveInfo.inventory.defenseHearts;
+ fileSelect->questItems[fileSelect->buttonIndex] = gSaveContext.save.saveInfo.inventory.questItems;
+ fileSelect->time[fileSelect->buttonIndex] = gSaveContext.save.time;
+ fileSelect->day[fileSelect->buttonIndex] = gSaveContext.save.day;
+ fileSelect->isOwlSave[fileSelect->buttonIndex] = gSaveContext.save.isOwlSave;
+ fileSelect->rupees[fileSelect->buttonIndex] = gSaveContext.save.saveInfo.playerData.rupees;
+ fileSelect->walletUpgrades[fileSelect->buttonIndex] = CUR_UPG_VALUE(UPG_WALLET);
for (i = 0, maskCount = 0; i < 24; i++) {
if (gSaveContext.save.saveInfo.inventory.items[i + 24] != ITEM_NONE) {
@@ -1484,17 +1609,19 @@ void Sram_InitSave(FileSelectState* fileSelect2, SramContext* sramCtx) {
}
}
- fileSelect->maskCount[fileSelect->unk_24480] = maskCount;
- fileSelect->heartPieceCount[fileSelect->unk_24480] =
- (gSaveContext.save.saveInfo.inventory.questItems & 0xF0000000) >> 0x1C;
+ fileSelect->maskCount[fileSelect->buttonIndex] = maskCount;
+ fileSelect->heartPieceCount[fileSelect->buttonIndex] = GET_QUEST_HEART_PIECE_COUNT;
}
gSaveContext.save.time = D_801F6AF0;
- gSaveContext.unk_3F3F = D_801F6AF2;
+ gSaveContext.flashSaveAvailable = D_801F6AF2;
}
-void func_80146DF8(SramContext* sramCtx) {
- if (gSaveContext.unk_3F3F) {
+/**
+ * Write the SaveOptions of SaveContext to the save buffer
+ */
+void Sram_WriteSaveOptionsToBuffer(SramContext* sramCtx) {
+ if (gSaveContext.flashSaveAvailable) {
// TODO: macros for languages
gSaveContext.options.language = 1;
Lib_MemCpy(sramCtx->saveBuf, &gSaveContext.options, sizeof(SaveOptions));
@@ -1508,7 +1635,7 @@ void Sram_InitSram(GameState* gameState, SramContext* sramCtx) {
}
void Sram_Alloc(GameState* gameState, SramContext* sramCtx) {
- if (gSaveContext.unk_3F3F) {
+ if (gSaveContext.flashSaveAvailable) {
sramCtx->saveBuf = THA_AllocTailAlign16(&gameState->heap, SAVE_BUFFER_SIZE);
sramCtx->status = 0;
}
@@ -1517,7 +1644,7 @@ void Sram_Alloc(GameState* gameState, SramContext* sramCtx) {
/**
* Synchronous flash write
*/
-void func_80146EBC(SramContext* sramCtx, s32 curPage, s32 numPages) {
+void Sram_SyncWriteToFlash(SramContext* sramCtx, s32 curPage, s32 numPages) {
sramCtx->curPage = curPage;
sramCtx->numPages = numPages;
SysFlashrom_WriteDataSync(sramCtx->saveBuf, curPage, numPages);
@@ -1533,8 +1660,8 @@ void Sram_SaveSpecialEnterClockTown(PlayState* play) {
gSaveContext.save.isFirstCycle = true;
gSaveContext.save.isOwlSave = false;
func_80145698(sramCtx);
- SysFlashrom_WriteDataSync(sramCtx->saveBuf, D_801C67C8[gSaveContext.fileNum * 2],
- D_801C6818[gSaveContext.fileNum * 2]);
+ SysFlashrom_WriteDataSync(sramCtx->saveBuf, gFlashSaveStartPages[gSaveContext.fileNum * 2],
+ gFlashSpecialSaveNumPages[gSaveContext.fileNum * 2]);
}
/**
@@ -1555,25 +1682,25 @@ void Sram_SaveSpecialNewDay(PlayState* play) {
gSaveContext.save.day = day;
gSaveContext.save.time = time;
gSaveContext.save.cutsceneIndex = cutsceneIndex;
- SysFlashrom_WriteDataSync(play->sramCtx.saveBuf, D_801C67C8[gSaveContext.fileNum * 2],
- D_801C67F0[gSaveContext.fileNum * 2]);
+ SysFlashrom_WriteDataSync(play->sramCtx.saveBuf, gFlashSaveStartPages[gSaveContext.fileNum * 2],
+ gFlashSaveNumPages[gSaveContext.fileNum * 2]);
}
-void func_80147008(SramContext* sramCtx, u32 curPage, u32 numPages) {
+void Sram_SetFlashPagesDefault(SramContext* sramCtx, u32 curPage, u32 numPages) {
sramCtx->curPage = curPage;
sramCtx->numPages = numPages;
sramCtx->status = 1;
}
-void func_80147020(SramContext* sramCtx) {
+void Sram_StartWriteToFlashDefault(SramContext* sramCtx) {
// async flash write
SysFlashrom_WriteDataAsync(sramCtx->saveBuf, sramCtx->curPage, sramCtx->numPages);
- sramCtx->unk_18 = osGetTime();
+ sramCtx->startWriteOsTime = osGetTime();
sramCtx->status = 2;
}
-void func_80147068(SramContext* sramCtx) {
+void Sram_UpdateWriteToFlashDefault(SramContext* sramCtx) {
if (sramCtx->status == 2) {
if (SysFlashrom_IsBusy() != 0) { // if task running
if (SysFlashrom_AwaitResult() == 0) { // wait for task done
@@ -1584,25 +1711,26 @@ void func_80147068(SramContext* sramCtx) {
sramCtx->status = 4;
}
}
- } else if (OSTIME_TO_TIMER(osGetTime() - sramCtx->unk_18) >= SECONDS_TO_TIMER(2)) {
+ } else if (OSTIME_TO_TIMER(osGetTime() - sramCtx->startWriteOsTime) >= SECONDS_TO_TIMER(2)) {
+ // Finished status is hardcoded to 2 seconds instead of when the task finishes
sramCtx->status = 0;
}
}
-void func_80147138(SramContext* sramCtx, s32 curPage, s32 numPages) {
+void Sram_SetFlashPagesOwlSave(SramContext* sramCtx, s32 curPage, s32 numPages) {
sramCtx->curPage = curPage;
sramCtx->numPages = numPages;
sramCtx->status = 6;
}
-void func_80147150(SramContext* sramCtx) {
+void Sram_StartWriteToFlashOwlSave(SramContext* sramCtx) {
SysFlashrom_WriteDataAsync(sramCtx->saveBuf, sramCtx->curPage, sramCtx->numPages);
- sramCtx->unk_18 = osGetTime();
+ sramCtx->startWriteOsTime = osGetTime();
sramCtx->status = 7;
}
-void func_80147198(SramContext* sramCtx) {
+void Sram_UpdateWriteToFlashOwlSave(SramContext* sramCtx) {
if (sramCtx->status == 7) {
if (SysFlashrom_IsBusy() != 0) { // Is task running
if (SysFlashrom_AwaitResult() == 0) { // Wait for task done
@@ -1621,7 +1749,8 @@ void func_80147198(SramContext* sramCtx) {
sramCtx->status = 4;
}
}
- } else if (OSTIME_TO_TIMER(osGetTime() - sramCtx->unk_18) >= SECONDS_TO_TIMER(2)) {
+ } else if (OSTIME_TO_TIMER(osGetTime() - sramCtx->startWriteOsTime) >= SECONDS_TO_TIMER(2)) {
+ // Finished status is hardcoded to 2 seconds instead of when the task finishes
sramCtx->status = 0;
bzero(sramCtx->saveBuf, SAVE_BUFFER_SIZE);
gSaveContext.save.isOwlSave = false;
@@ -1648,8 +1777,9 @@ void func_80147314(SramContext* sramCtx, s32 fileNum) {
gSaveContext.save.saveInfo.checksum = Sram_CalcChecksum(&gSaveContext, offsetof(SaveContext, fileNum));
Lib_MemCpy(sramCtx->saveBuf, &gSaveContext, offsetof(SaveContext, fileNum));
- func_80146EBC(sramCtx, D_801C6840[fileNum * 2], D_801C6850[fileNum * 2]);
- func_80146EBC(sramCtx, D_801C6840[fileNum * 2 + 1], D_801C6850[fileNum * 2]);
+ Sram_SyncWriteToFlash(sramCtx, gFlashOwlSaveStartPages[fileNum * 2], gFlashOwlSaveNumPages[fileNum * 2]);
+ //! Note: should be `gFlashOwlSaveNumPages[fileNum * 2 + 1]`?
+ Sram_SyncWriteToFlash(sramCtx, gFlashOwlSaveStartPages[fileNum * 2 + 1], gFlashOwlSaveNumPages[fileNum * 2]);
gSaveContext.save.isOwlSave = true;
@@ -1661,6 +1791,7 @@ void func_80147314(SramContext* sramCtx, s32 fileNum) {
gSaveContext.save.saveInfo.playerData.newf[5] = '3';
}
+// Used by `Sram_CopySave` with `isOwlSave` set
void func_80147414(SramContext* sramCtx, s32 fileNum, s32 arg2) {
s32 pad;
@@ -1668,16 +1799,18 @@ void func_80147414(SramContext* sramCtx, s32 fileNum, s32 arg2) {
bzero(sramCtx->saveBuf, SAVE_BUFFER_SIZE);
// Read save file
- if (SysFlashrom_ReadData(sramCtx->saveBuf, D_801C6840[fileNum * 2], D_801C6850[fileNum * 2]) != 0) {
+ if (SysFlashrom_ReadData(sramCtx->saveBuf, gFlashOwlSaveStartPages[fileNum * 2],
+ gFlashOwlSaveNumPages[fileNum * 2]) != 0) {
// If failed, read backup save file
- SysFlashrom_ReadData(sramCtx->saveBuf, D_801C6840[fileNum * 2 + 1], D_801C6850[fileNum * 2 + 1]);
+ SysFlashrom_ReadData(sramCtx->saveBuf, gFlashOwlSaveStartPages[fileNum * 2 + 1],
+ gFlashOwlSaveNumPages[fileNum * 2 + 1]);
}
// Copy buffer to save context
Lib_MemCpy(&gSaveContext, sramCtx->saveBuf, offsetof(SaveContext, fileNum));
- func_80146EBC(sramCtx, D_801C6840[arg2 * 2], D_801C6850[arg2 * 2]);
- func_80146EBC(sramCtx, D_801C6840[arg2 * 2 + 1], D_801C6850[arg2 * 2]);
+ Sram_SyncWriteToFlash(sramCtx, gFlashOwlSaveStartPages[arg2 * 2], gFlashOwlSaveNumPages[arg2 * 2]);
+ Sram_SyncWriteToFlash(sramCtx, gFlashOwlSaveStartPages[arg2 * 2 + 1], gFlashOwlSaveNumPages[arg2 * 2]);
}
void Sram_nop8014750C(UNK_TYPE4 arg0) {
diff --git a/src/code/z_vr_box.c b/src/code/z_vr_box.c
index 911e3e7577..dd0785d94a 100644
--- a/src/code/z_vr_box.c
+++ b/src/code/z_vr_box.c
@@ -239,7 +239,7 @@ void func_80143324(PlayState* play, SkyboxContext* skyboxCtx, s16 skyboxId) {
case SKYBOX_NORMAL_SKY:
osCreateMesgQueue(&skyboxCtx->loadQueue, &skyboxCtx->loadMsg, 1);
- if (play->envCtx.unk_10 == 0) {
+ if (play->envCtx.skybox1Index == 0) {
// Send a DMA request for the clear sky texture
size = SEGMENT_ROM_SIZE(d2_fine_static);
@@ -256,7 +256,7 @@ void func_80143324(PlayState* play, SkyboxContext* skyboxCtx, s16 skyboxId) {
osRecvMesg(&skyboxCtx->loadQueue, NULL, OS_MESG_BLOCK);
osCreateMesgQueue(&skyboxCtx->loadQueue, &skyboxCtx->loadMsg, 1);
- if (play->envCtx.unk_11 == 0) {
+ if (play->envCtx.skybox2Index == 0) {
// Send a DMA request for the clear sky texture
size = SEGMENT_ROM_SIZE(d2_fine_static);
diff --git a/src/overlays/actors/ovl_Dm_Char01/z_dm_char01.c b/src/overlays/actors/ovl_Dm_Char01/z_dm_char01.c
index 767d4c8274..33c6eed8ff 100644
--- a/src/overlays/actors/ovl_Dm_Char01/z_dm_char01.c
+++ b/src/overlays/actors/ovl_Dm_Char01/z_dm_char01.c
@@ -74,8 +74,8 @@ void DmChar01_Init(Actor* thisx, PlayState* play) {
}
if (gSaveContext.sceneLayer == 0) {
- play->envCtx.unk_1F = 5;
- play->envCtx.unk_20 = 5;
+ play->envCtx.lightConfig = 5;
+ play->envCtx.changeLightNextConfig = 5;
}
this->unk_348 = 255.0f;
diff --git a/src/overlays/actors/ovl_Dm_Stk/z_dm_stk.c b/src/overlays/actors/ovl_Dm_Stk/z_dm_stk.c
index 36415d7dbc..01a5b8c822 100644
--- a/src/overlays/actors/ovl_Dm_Stk/z_dm_stk.c
+++ b/src/overlays/actors/ovl_Dm_Stk/z_dm_stk.c
@@ -1129,8 +1129,8 @@ void DmStk_Init(Actor* thisx, PlayState* play) {
Actor_SetScale(&this->actor, 0.01f);
if ((play->sceneId == SCENE_00KEIKOKU) && (gSaveContext.sceneLayer == 3) && (play->csCtx.scriptIndex > 0)) {
- play->envCtx.unk_17 = 15;
- play->envCtx.unk_18 = 15;
+ play->envCtx.skyboxConfig = 15;
+ play->envCtx.changeSkyboxNextConfig = 15;
}
}
@@ -1826,8 +1826,8 @@ void DmStk_Update(Actor* thisx, PlayState* play) {
}
if ((play->sceneId == SCENE_00KEIKOKU) && (gSaveContext.sceneLayer == 3) && (play->csCtx.scriptIndex > 0)) {
- play->envCtx.unk_17 = 15;
- play->envCtx.unk_18 = 15;
+ play->envCtx.skyboxConfig = 15;
+ play->envCtx.changeSkyboxNextConfig = 15;
}
}
diff --git a/src/overlays/actors/ovl_En_Holl/z_en_holl.c b/src/overlays/actors/ovl_En_Holl/z_en_holl.c
index 9b196c2fcd..ed3fe65b95 100644
--- a/src/overlays/actors/ovl_En_Holl/z_en_holl.c
+++ b/src/overlays/actors/ovl_En_Holl/z_en_holl.c
@@ -191,7 +191,7 @@ void EnHoll_VisibleIdle(EnHoll* this, PlayState* play) {
}
} else if (this->type == EN_HOLL_TYPE_SCENE_CHANGER) {
play->nextEntrance = play->setupExitList[EN_HOLL_GET_EXIT_LIST_INDEX(&this->actor)];
- gSaveContext.unk_3DBB = 1;
+ gSaveContext.retainWeatherMode = true;
Scene_SetExitFade(play);
play->transitionTrigger = TRANS_TRIGGER_START;
play->unk_1878C(play);
diff --git a/src/overlays/actors/ovl_En_Viewer/z_en_viewer.c b/src/overlays/actors/ovl_En_Viewer/z_en_viewer.c
index 34551dac90..79bee615aa 100644
--- a/src/overlays/actors/ovl_En_Viewer/z_en_viewer.c
+++ b/src/overlays/actors/ovl_En_Viewer/z_en_viewer.c
@@ -78,8 +78,8 @@ void func_8089F014(EnViewer* this, PlayState* play, f32 arg2) {
}
play->envCtx.lightSettingOverride = 0;
play->envCtx.unk_E0 = 2;
- play->envCtx.unk_C1 = this->actor.world.rot.x;
- play->envCtx.unk_C2 = this->actor.world.rot.z;
+ play->envCtx.lightSetting = this->actor.world.rot.x;
+ play->envCtx.prevLightSetting = this->actor.world.rot.z;
play->envCtx.lightBlend = arg2;
}
@@ -94,7 +94,7 @@ void func_8089F0A0(EnViewer* this, PlayState* play) {
func_800FAAB4(
play, SurfaceType_GetLightSettingIndex(&play->colCtx, player->actor.floorPoly, player->actor.floorBgId));
play->envCtx.lightBlend = 1.0f;
- play->envCtx.unk_C2 = play->envCtx.unk_C1;
+ play->envCtx.prevLightSetting = play->envCtx.lightSetting;
}
}
diff --git a/src/overlays/actors/ovl_En_Weather_Tag/z_en_weather_tag.c b/src/overlays/actors/ovl_En_Weather_Tag/z_en_weather_tag.c
index 10be4ec3c6..84f6219158 100644
--- a/src/overlays/actors/ovl_En_Weather_Tag/z_en_weather_tag.c
+++ b/src/overlays/actors/ovl_En_Weather_Tag/z_en_weather_tag.c
@@ -99,8 +99,8 @@ void EnWeatherTag_Init(Actor* thisx, PlayState* play) {
case WEATHERTAG_TYPE_UNK5:
func_800BC154(play, &play->actorCtx, &this->actor, 7);
play->skyboxId = SKYBOX_3;
- play->envCtx.unk_1F = 5;
- play->envCtx.unk_20 = 5;
+ play->envCtx.lightConfig = 5;
+ play->envCtx.changeLightNextConfig = 5;
D_801F4E74 = 1.0f;
EnWeatherTag_SetupAction(this, func_80966BF4);
break;
@@ -124,25 +124,26 @@ void EnWeatherTag_Init(Actor* thisx, PlayState* play) {
// matches but unused params is suspicious
// called WeatherTag_CheckEnableWeatherEffect in OOT, that's where "weatherMode" came from
-u8 func_80966608(EnWeatherTag* this, PlayState* play, UNK_TYPE a3, UNK_TYPE a4, u8 new1F, u8 new20, u16 new24,
- u8 weatherMode) {
+u8 func_80966608(EnWeatherTag* this, PlayState* play, UNK_TYPE a3, UNK_TYPE a4, u8 lightConfig,
+ u8 changeLightNextConfig, u16 changeDuration, u8 weatherMode) {
Player* player = GET_PLAYER(play);
u8 returnVal = 0;
if (WEATHER_TAG_RANGE100(&this->actor) > Actor_WorldDistXZToActor(&player->actor, &this->actor)) {
- if (play->envCtx.unk_1F == play->envCtx.unk_20) {
+ if (play->envCtx.lightConfig == play->envCtx.changeLightNextConfig) {
D_801BDBB8 = 1;
- if (!(play->envCtx.unk_1E == 0) || ((play->envCtx.unk_1F != 1) && (play->envCtx.unk_21 == 0))) {
+ if (!(play->envCtx.lightMode == 0) ||
+ ((play->envCtx.lightConfig != 1) && !play->envCtx.changeLightEnabled)) {
D_801BDBB8 = 0;
if (gWeatherMode != weatherMode) {
gWeatherMode = weatherMode;
- play->envCtx.unk_21 = 1;
- play->envCtx.unk_1F = new1F;
- play->envCtx.unk_20 = new20;
- D_801BDBB4 = new20;
- play->envCtx.unk_24 = new24;
- play->envCtx.unk_22 = play->envCtx.unk_24;
+ play->envCtx.changeLightEnabled = true;
+ play->envCtx.lightConfig = lightConfig;
+ play->envCtx.changeLightNextConfig = changeLightNextConfig;
+ D_801BDBB4 = changeLightNextConfig;
+ play->envCtx.changeDuration = changeDuration;
+ play->envCtx.changeLightTimer = play->envCtx.changeDuration;
}
returnVal = 1;
}
@@ -153,23 +154,25 @@ u8 func_80966608(EnWeatherTag* this, PlayState* play, UNK_TYPE a3, UNK_TYPE a4,
// again with the unused parameters
// called WeatherTag_CheckRestoreWeather in OOT
-u8 func_80966758(EnWeatherTag* this, PlayState* play, UNK_TYPE a3, UNK_TYPE a4, u8 new1F, u8 new20, u16 new24) {
+u8 func_80966758(EnWeatherTag* this, PlayState* play, UNK_TYPE a3, UNK_TYPE a4, u8 lightConfig,
+ u8 changeLightNextConfig, u16 changeDuration) {
Player* player = GET_PLAYER(play);
u8 returnVal = 0;
if (WEATHER_TAG_RANGE100(&this->actor) < Actor_WorldDistXZToActor(&player->actor, &this->actor)) {
- if (play->envCtx.unk_1F == play->envCtx.unk_20) {
+ if (play->envCtx.lightConfig == play->envCtx.changeLightNextConfig) {
D_801BDBB8 = 1;
- if (!(play->envCtx.unk_1E == 0) || ((play->envCtx.unk_1F != 1) && (play->envCtx.unk_21 == 0))) {
+ if (!(play->envCtx.lightMode == 0) ||
+ ((play->envCtx.lightConfig != 1) && !play->envCtx.changeLightEnabled)) {
D_801BDBB8 = 0;
gWeatherMode = 0;
- play->envCtx.unk_21 = 1;
- play->envCtx.unk_1F = new1F;
- play->envCtx.unk_20 = new20;
- D_801BDBB4 = new20;
- play->envCtx.unk_24 = new24;
- play->envCtx.unk_22 = play->envCtx.unk_24;
+ play->envCtx.changeLightEnabled = true;
+ play->envCtx.lightConfig = lightConfig;
+ play->envCtx.changeLightNextConfig = changeLightNextConfig;
+ D_801BDBB4 = changeLightNextConfig;
+ play->envCtx.changeDuration = changeDuration;
+ play->envCtx.changeLightTimer = play->envCtx.changeDuration;
returnVal = 1;
}
}
@@ -240,7 +243,7 @@ void EnWeatherTag_Die(EnWeatherTag* this, PlayState* play) {
// poisoned swamp: placed behind the water fall from ikana
// this tag stops spawning after STT cleared?
void func_80966B08(EnWeatherTag* this, PlayState* play) {
- if (func_80966608(this, play, 0, 0, play->envCtx.unk_1F, 5, 100, 2) || (gWeatherMode == 2)) {
+ if (func_80966608(this, play, 0, 0, play->envCtx.lightConfig, 5, 100, 2) || (gWeatherMode == 2)) {
play->skyboxId = SKYBOX_3;
EnWeatherTag_SetupAction(this, func_80966D20);
} else if (D_801F4E74 <= 0.01f) {
@@ -253,7 +256,7 @@ void func_80966B08(EnWeatherTag* this, PlayState* play) {
// WEATHERTAG_TYPE_UNK5: only one in ikana canyon, corner of cliff right outside of stone tower entrance
// because it uses cutsecnes.. is this the clear ikana cutcsene?
void func_80966BF4(EnWeatherTag* this, PlayState* play) {
- u8 newUnk20;
+ u8 changeLightNextConfig;
CsCmdActorCue* cue;
if (Cutscene_IsCueInChannel(play, CS_CMD_ACTOR_CUE_567)) {
@@ -263,25 +266,25 @@ void func_80966BF4(EnWeatherTag* this, PlayState* play) {
case 0:
case 1:
default:
-
- newUnk20 = 0;
+ changeLightNextConfig = 0;
break;
+
case 2:
- newUnk20 = 3;
+ changeLightNextConfig = 3;
break;
case 3:
- newUnk20 = 4;
+ changeLightNextConfig = 4;
break;
}
Math_SmoothStepToF(&D_801F4E74, 0.0f, 0.2f, 0.02f, 0.001f);
- if (play->envCtx.unk_20 != newUnk20) {
- play->envCtx.unk_21 = 1;
- play->envCtx.unk_20 = newUnk20;
- play->envCtx.unk_24 = 100;
- play->envCtx.unk_22 = play->envCtx.unk_24;
+ if (play->envCtx.changeLightNextConfig != changeLightNextConfig) {
+ play->envCtx.changeLightEnabled = true;
+ play->envCtx.changeLightNextConfig = changeLightNextConfig;
+ play->envCtx.changeDuration = 100;
+ play->envCtx.changeLightTimer = play->envCtx.changeDuration;
}
}
}
diff --git a/src/overlays/actors/ovl_Obj_Grass/z_obj_grass.c b/src/overlays/actors/ovl_Obj_Grass/z_obj_grass.c
index 6431a558bb..a17f853df3 100644
--- a/src/overlays/actors/ovl_Obj_Grass/z_obj_grass.c
+++ b/src/overlays/actors/ovl_Obj_Grass/z_obj_grass.c
@@ -4,6 +4,7 @@
* Description: "Master" instance of grass for unit spawned by Obj_Grass_Unit
*/
+#include "prevent_bss_reordering.h"
#include "z_obj_grass.h"
#include "overlays/actors/ovl_Obj_Grass_Carry/z_obj_grass_carry.h"
#include "objects/gameplay_keep/gameplay_keep.h"
diff --git a/src/overlays/actors/ovl_player_actor/z_player.c b/src/overlays/actors/ovl_player_actor/z_player.c
index 5da69099e4..41cf34318f 100644
--- a/src/overlays/actors/ovl_player_actor/z_player.c
+++ b/src/overlays/actors/ovl_player_actor/z_player.c
@@ -5734,7 +5734,7 @@ void func_808354A4(PlayState* play, s32 arg1, s32 arg2) {
gSaveContext.respawnFlag = -2;
}
- gSaveContext.unk_3DBB = 1;
+ gSaveContext.retainWeatherMode = 1;
Scene_SetExitFade(play);
}
@@ -16454,7 +16454,7 @@ void func_8085269C(Player* this, PlayState* play) {
(play->msgCtx.ocarinaMode == 0x18) || (play->msgCtx.ocarinaMode == 0x19)) {
if (play->msgCtx.ocarinaMode == 0x16) {
if (!func_8082DA90(play)) {
- if (gSaveContext.save.saveInfo.playerData.deaths == 1) {
+ if (gSaveContext.save.saveInfo.playerData.threeDayResetCount == 1) {
play->nextEntrance = ENTRANCE(CUTSCENE, 1);
} else {
play->nextEntrance = ENTRANCE(CUTSCENE, 0);
diff --git a/src/overlays/gamestates/ovl_file_choose/z_file_choose.h b/src/overlays/gamestates/ovl_file_choose/z_file_choose.h
deleted file mode 100644
index f3231ec56b..0000000000
--- a/src/overlays/gamestates/ovl_file_choose/z_file_choose.h
+++ /dev/null
@@ -1,115 +0,0 @@
-#ifndef Z64_FILE_CHOOSE_H
-#define Z64_FILE_CHOOSE_H
-
-#include "global.h"
-
-void FileSelect_Init(GameState* thisx);
-void FileSelect_Destroy(GameState* thisx);
-
-typedef struct FileSelectState {
- /* 0x00000 */ GameState state;
- /* 0x000A4 */ Vtx* unk_A4;
- /* 0x000A8 */ u8* staticSegment;
- /* 0x000AC */ u8* parameterSegment;
- /* 0x000B0 */ u8* titleSegment;
- /* 0x000B8 */ View view;
- /* 0x00220 */ SramContext sramCtx;
- /* 0x00248 */ SkyboxContext skyboxCtx;
- /* 0x00470 */ MessageContext msgCtx;
- /* 0x12550 */ Font font;
- /* 0x242E0 */ EnvironmentContext envCtx;
- /* 0x243E0 */ Vtx* unk_243E0;
- /* 0x243E4 */ Vtx* unk_243E4;
- /* 0x243E8 */ u8 newf2[2][6];
- /* 0x243F4 */ u8 newf[2][6];
- /* 0x24400 */ UNK_TYPE1 unk_24400[0xC];
- /* 0x2440C */ u16 unk_2440C[2];
- /* 0x24410 */ u16 unk_24410[2];
- /* 0x24414 */ u8 unk_24414[2][8]; // playername
- /* 0x24424 */ u8 unk_24424[2][8]; // playername
- /* 0x24434 */ s16 healthCapacity[2];
- /* 0x24438 */ u16 unk_24438[2];
- /* 0x2443C */ s16 health[2];
- /* 0x24440 */ u16 unk_24440[2];
- /* 0x24444 */ u32 unk_24444[2];
- /* 0x2444C */ u32 unk_2444C[2];
- /* 0x24454 */ s8 unk_24454[2];
- /* 0x24456 */ u8 unk_24456[2];
- /* 0x24458 */ u16 unk_24458[2];
- /* 0x2445C */ u16 unk_2445C[2];
- /* 0x24460 */ s16 unk_24460[2];
- /* 0x24464 */ s16 unk_24464[2];
- /* 0x24468 */ u8 unk_24468[2];
- /* 0x2446A */ u8 unk_2446A[2];
- /* 0x2446C */ s16 rupees[2];
- /* 0x24470 */ s16 unk_24470[2];
- /* 0x24474 */ s8 unk_24474[2];
- /* 0x24476 */ s8 unk_24476[2];
- /* 0x24478 */ s8 maskCount[2];
- /* 0x2447A */ s8 unk_2447A[2];
- /* 0x2447C */ s8 heartPieceCount[2];
- /* 0x2447E */ s8 unk_2447E[2];
- /* 0x24480 */ s16 unk_24480;
- /* 0x24482 */ s16 unk_24482;
- /* 0x24484 */ s16 unk_24484;
- /* 0x24486 */ s16 unk_24486;
- /* 0x24488 */ s16 unk_24488;
- /* 0x2448A */ s16 unk_2448A;
- /* 0x2448C */ s16 unk_2448C;
- /* 0x2448E */ s16 unk_2448E;
- /* 0x24490 */ s16 unk_24490;
- /* 0x24492 */ s16 unk_24492[3];
- /* 0x24498 */ s16 unk_24498;
- /* 0x2449A */ s16 unk_2449A[6];
- /* 0x244A6 */ s16 fileNum;
- /* 0x244A8 */ s16 unk_244A8;
- /* 0x244AA */ s16 unk_244AA;
- /* 0x244AC */ s16 unk_244AC;
- /* 0x244AE */ s16 unk_244AE;
- /* 0x244B0 */ s16 unk_244B0[3];
- /* 0x244B6 */ s16 unk_244B6[2];
- /* 0x244BA */ s16 unk_244BA;
- /* 0x244BC */ s16 unk_244BC[3];
- /* 0x244C2 */ s16 unk_244C2[3];
- /* 0x244C8 */ s16 unk_244C8[3];
- /* 0x244CE */ s16 unk_244CE[3];
- /* 0x244D4 */ s16 unk_244D4[3];
- /* 0x244DA */ s16 unk_244DA[4];
- /* 0x244E2 */ s16 unk_244E2;
- /* 0x244E4 */ s16 unk_244E4;
- /* 0x244E6 */ s16 unk_244E6;
- /* 0x244E8 */ s16 unk_244E8;
- /* 0x244EA */ s16 unk_244EA[4];
- /* 0x244F2 */ s16 unk_244F2;
- /* 0x244F4 */ s16 unk_244F4;
- /* 0x244F6 */ s16 unk_244F6[2];
- /* 0x244FA */ s16 unk_244FA;
- /* 0x244FC */ s16 unk_244FC;
- /* 0x244FE */ s16 unk_244FE;
- /* 0x24500 */ s16 unk_24500;
- /* 0x24502 */ s16 unk_24502;
- /* 0x24504 */ s16 unk_24504;
- /* 0x24506 */ s16 unk_24506;
- /* 0x24508 */ s16 unk_24508;
- /* 0x2450A */ s16 unk_2450A;
- /* 0x2450C */ f32 unk_2450C;
- /* 0x24510 */ s16 unk_24510;
- /* 0x24512 */ s16 unk_24512;
- /* 0x24514 */ s16 unk_24514;
- /* 0x24516 */ s16 unk_24516;
- /* 0x24518 */ s16 unk_24518;
- /* 0x2451A */ s16 unk_2451A;
- /* 0x2451C */ s16 unk_2451C;
- /* 0x2451E */ s16 unk_2451E[5];
- /* 0x24528 */ s16 unk_24528;
- /* 0x2452A */ s16 unk_2452A;
- /* 0x2452C */ s16 unk_2452C[4];
- /* 0x24534 */ s16 unk_24534[4];
- /* 0x2453C */ s16 unk_2453C[4];
- /* 0x24544 */ s16 unk_24544[4];
- /* 0x2454C */ s16 unk_2454C;
- /* 0x2454E */ s16 unk_2454E;
- /* 0x24550 */ s16 unk_24550;
-} FileSelectState; // size = 0x24558
-
-#endif
diff --git a/src/overlays/gamestates/ovl_file_choose/z_file_choose_80807940.c b/src/overlays/gamestates/ovl_file_choose/z_file_choose_80807940.c
deleted file mode 100644
index 2e0e9a0d44..0000000000
--- a/src/overlays/gamestates/ovl_file_choose/z_file_choose_80807940.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * File: z_file_choose_80807940.c
- * Overlay: ovl_file_choose
- * Description:
- */
-
-#include "z_file_choose.h"
-#include "z64rumble.h"
-
-extern UNK_TYPE D_01002800;
-extern UNK_TYPE D_01007980;
-extern UNK_TYPE D_0102A6B0;
-extern UNK_TYPE D_0102B170;
-extern UNK_TYPE D_010310F0;
-extern UNK_TYPE D_010311F0;
-
-// there are uses of D_0E000000.fillRect (appearing as D_0E0002E0) in this file
-extern GfxMasterList D_0E000000;
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_80807940.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_80807A78.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_80807C58.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_80808214.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_80808D30.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_80808F1C.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_80809DF0.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_80809EA0.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_8080A3CC.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_8080A418.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_8080A4A0.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_8080A6BC.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_8080A708.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_8080BBFC.s")
diff --git a/src/overlays/gamestates/ovl_file_choose/z_file_choose_NES.c b/src/overlays/gamestates/ovl_file_choose/z_file_choose_NES.c
index da9144e7c6..0cc43ad501 100644
--- a/src/overlays/gamestates/ovl_file_choose/z_file_choose_NES.c
+++ b/src/overlays/gamestates/ovl_file_choose/z_file_choose_NES.c
@@ -4,96 +4,2545 @@
* Description:
*/
-#include "z_file_choose.h"
+#include "z_file_select.h"
+#include "overlays/gamestates/ovl_opening/z_opening.h"
#include "z64rumble.h"
+#include "z64save.h"
#include "z64shrink_window.h"
#include "z64view.h"
+#include "interface/parameter_static/parameter_static.h"
+#include "misc/title_static/title_static.h"
-extern UNK_TYPE D_01002800;
-extern UNK_TYPE D_01007980;
-extern UNK_TYPE D_0102A6B0;
-extern UNK_TYPE D_0102B170;
-extern UNK_TYPE D_010310F0;
-extern UNK_TYPE D_010311F0;
+s32 D_808144F10 = 100;
+f32 D_808144F14 = 8.0f;
+f32 D_808144F18 = 100.0f;
+s32 D_808144F1C = 0;
-// there are uses of D_0E000000.fillRect (appearing as D_0E0002E0) in this file
-extern GfxMasterList D_0E000000;
+static Gfx sScreenFillSetupDL[] = {
+ gsDPPipeSync(),
+ gsSPClearGeometryMode(G_ZBUFFER | G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN |
+ G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH),
+ gsDPSetOtherMode(G_AD_DISABLE | G_CD_MAGICSQ | G_CK_NONE | G_TC_FILT | G_TF_BILERP | G_TT_NONE | G_TL_TILE |
+ G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_1PRIMITIVE,
+ G_AC_NONE | G_ZS_PIXEL | G_RM_CLD_SURF | G_RM_CLD_SURF2),
+ gsDPSetCombineMode(G_CC_PRIMITIVE, G_CC_PRIMITIVE),
+ gsSPEndDisplayList(),
+};
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_8080BC20.s")
+s16 sFileInfoBoxPartWidths[] = {
+ 36, 36, 36, 36, 24, 28, 28,
+};
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/FileSelect_nop8080bc44.s")
+s16 sWindowContentColors[] = { 100, 150, 255 };
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/FileSelect_nop8080BC4C.s")
+s16 sFileSelectSkyboxRotation = 0;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_8080BC58.s")
+s16 sWalletFirstDigit[] = {
+ 1, // tens (Default Wallet)
+ 0, // hundreds (Adult Wallet)
+ 0, // hundreds (Giant Wallet)
+};
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_8080BDAC.s")
+void FileSelect_IncrementConfigMode(FileSelectState* this) {
+ this->configMode++;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/FileSelect_RenderView.s")
+void FileSelect_Noop1(void) {
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_8080BE60.s")
+void FileSelect_Noop2(FileSelectState* this) {
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_8080C040.s")
+void FileSelect_InitModeUpdate(GameState* thisx) {
+ FileSelectState* this = (FileSelectState*)thisx;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_8080C228.s")
+ if (this->configMode == CM_FADE_IN_START) {
+ if (gSaveContext.options.optionId != 0xA51D) { // Magic number?
+ this->configMode++;
+ } else {
+ this->menuMode = FS_MENU_MODE_CONFIG;
+ this->configMode = CM_FADE_IN_START;
+ this->titleLabel = FS_TITLE_SELECT_FILE;
+ this->nextTitleLabel = FS_TITLE_OPEN_FILE;
+ }
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_8080C29C.s")
+ if (this->configMode == CM_FADE_IN_END) {
+ this->screenFillAlpha -= 40;
+ if (this->screenFillAlpha <= 0) {
+ this->screenFillAlpha = 0;
+ this->configMode++; // CM_MAIN_MENU
+ }
+ } else if (this->configMode == CM_MAIN_MENU) {
+ FileSelect_IncrementConfigMode(this); // CM_SETUP_COPY_SOURCE
+ } else {
+ this->screenFillAlpha += 40;
+ if (this->screenFillAlpha >= 255) {
+ this->screenFillAlpha = 255;
+ this->menuMode = FS_MENU_MODE_CONFIG;
+ this->configMode = CM_FADE_IN_START;
+ this->titleLabel = FS_TITLE_SELECT_FILE;
+ this->nextTitleLabel = FS_TITLE_OPEN_FILE;
+ }
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_8080C324.s")
+void FileSelect_InitModeDraw(GameState* thisx) {
+ FileSelectState* this = (FileSelectState*)thisx;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_8080C3A8.s")
+ Gfx_SetupDL39_Opa(this->state.gfxCtx);
+ FileSelect_Noop2(this);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_8080D164.s")
+void FileSelect_SetView(FileSelectState* this, f32 eyeX, f32 eyeY, f32 eyeZ) {
+ Vec3f eye;
+ Vec3f lookAt;
+ Vec3f up;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_8080D170.s")
+ eye.x = eyeX;
+ eye.y = eyeY;
+ eye.z = eyeZ;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_8080D1BC.s")
+ lookAt.x = lookAt.y = lookAt.z = 0.0f;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_8080D220.s")
+ up.x = up.z = 0.0f;
+ up.y = 1.0f;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_8080D284.s")
+ View_LookAt(&this->view, &eye, &lookAt, &up);
+ View_Apply(&this->view, VIEW_ALL | VIEW_FORCE_VIEWING | VIEW_FORCE_VIEWPORT | VIEW_FORCE_PROJECTION_PERSPECTIVE);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_8080D2EC.s")
+Gfx* FileSelect_DrawTexQuadIA8(Gfx* gfx, TexturePtr texture, s16 width, s16 height, s16 point) {
+ gDPLoadTextureBlock(gfx++, texture, G_IM_FMT_IA, G_IM_SIZ_8b, width, height, 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);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_8080D3D0.s")
+ gSP1Quadrangle(gfx++, point, point + 2, point + 3, point + 1, 0);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_8080D40C.s")
+ return gfx;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_8080D6D4.s")
+/**
+ * Fade in the menu window and title label.
+ * If a file is occupied fade in the name, name box, and connector.
+ * Fade in the copy erase and options button according to the window alpha.
+ */
+void FileSelect_FadeInMenuElements(FileSelectState* this) {
+ SramContext* sramCtx = &this->sramCtx;
+ s16 i;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_8080F25C.s")
+ this->titleAlpha[FS_TITLE_CUR] += 20;
+ this->windowAlpha += 16;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_808108DC.s")
+ for (i = 0; i < 3; i++) {
+ this->fileButtonAlpha[i] = this->windowAlpha;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_80811CB8.s")
+ if (!gSaveContext.flashSaveAvailable) {
+ if (NO_FLASH_SLOT_OCCUPIED(sramCtx, i)) {
+ this->nameBoxAlpha[i] = this->nameAlpha[i] = this->windowAlpha;
+ this->connectorAlpha[i] += 20;
+ if (this->connectorAlpha[i] >= 255) {
+ this->connectorAlpha[i] = 255;
+ }
+ }
+ } else if (SLOT_OCCUPIED(this, i)) {
+ this->nameBoxAlpha[i] = this->nameAlpha[i] = this->windowAlpha;
+ this->connectorAlpha[i] += 20;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_80812460.s")
+ if (this->connectorAlpha[i] >= 255) {
+ this->connectorAlpha[i] = 255;
+ }
+ }
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_80812668.s")
+ this->actionButtonAlpha[FS_BTN_ACTION_COPY] = this->actionButtonAlpha[FS_BTN_ACTION_ERASE] =
+ this->optionButtonAlpha = this->windowAlpha;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_80812760.s")
+/**
+ * Converts a numerical value to hundreds-tens-ones digits
+ */
+void FileSelect_SplitNumber(u16 value, u16* hundreds, u16* tens, u16* ones) {
+ *hundreds = 0;
+ *tens = 0;
+ *ones = value;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_80812840.s")
+ do {
+ if ((*ones - 100) < 0) {
+ break;
+ }
+ (*hundreds)++;
+ *ones -= 100;
+ } while (true);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_80812980.s")
+ do {
+ if ((*ones - 10) < 0) {
+ break;
+ }
+ (*tens)++;
+ *ones -= 10;
+ } while (true);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_80812A6C.s")
+// Start of Config Mode Update Functions
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_80812D44.s")
+/**
+ * Reduce the alpha of the black screen fill to create a fade in effect.
+ * Additionally, slide the window from the right to the center of the screen.
+ * Update function for `CM_FADE_IN_START`
+ */
+void FileSelect_StartFadeIn(GameState* thisx) {
+ FileSelectState* this = (FileSelectState*)thisx;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_80812D94.s")
+ FileSelect_FadeInMenuElements(this);
+ this->screenFillAlpha -= 40;
+ this->windowPosX -= 20;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_80812E94.s")
+ if (this->windowPosX <= -94) {
+ this->windowPosX = -94;
+ this->configMode = CM_FADE_IN_END;
+ this->screenFillAlpha = 0;
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_80812ED0.s")
+/**
+ * Finish fading in the remaining menu elements.
+ * Fade in the controls text at the bottom of the screen.
+ * Update function for `CM_FADE_IN_END`
+ */
+void FileSelect_FinishFadeIn(GameState* thisx) {
+ FileSelectState* this = (FileSelectState*)thisx;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/FileSelect_UpdateAndDrawSkybox.s")
+ this->controlsAlpha += 20;
+ FileSelect_FadeInMenuElements(this);
-void FileSelect_Main(GameState* thisx);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/FileSelect_Main.s")
+ if (this->titleAlpha[FS_TITLE_CUR] >= 255) {
+ this->titleAlpha[FS_TITLE_CUR] = 255;
+ this->controlsAlpha = 255;
+ this->windowAlpha = 200;
+ this->configMode = CM_MAIN_MENU;
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_80813908.s")
+u8 sEmptyName[] = { 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E };
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/FileSelect_Destroy.s")
+/**
+ * Update the cursor and wait for the player to select a button to change menus accordingly.
+ * If an empty file is selected, enter the name entry config mode.
+ * If an occupied file is selected, enter the `Select` menu mode.
+ * If copy, erase, or options is selected, set config mode accordingly.
+ * Lastly, set any warning labels if appropriate.
+ * Update function for `CM_MAIN_MENU`
+ */
+void FileSelect_UpdateMainMenu(GameState* thisx) {
+ FileSelectState* this = (FileSelectState*)thisx;
+ SramContext* sramCtx = &this->sramCtx;
+ Input* input = CONTROLLER1(&this->state);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/FileSelect_Init.s")
+ 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 (!gSaveContext.flashSaveAvailable) {
+ if (!NO_FLASH_SLOT_OCCUPIED(sramCtx, this->buttonIndex)) {
+ play_sound(NA_SE_SY_FSEL_DECIDE_L);
+ this->configMode = CM_ROTATE_TO_NAME_ENTRY;
+ this->kbdButton = FS_KBD_BTN_NONE;
+ this->charPage = FS_CHAR_PAGE_HIRA;
+ if (gSaveContext.options.language != 0) {
+ this->charPage = FS_CHAR_PAGE_ENG;
+ }
+ this->kbdX = 0;
+ this->kbdY = 0;
+ this->charIndex = 0;
+ this->charBgAlpha = 0;
+ this->newFileNameCharCount = 0;
+ this->nameEntryBoxPosX = 120;
+ this->nameEntryBoxAlpha = 0;
+ Lib_MemCpy(&this->fileNames[this->buttonIndex], &sEmptyName, ARRAY_COUNT(sEmptyName));
+ } else {
+ play_sound(NA_SE_SY_FSEL_DECIDE_L);
+ this->actionTimer = 4;
+ this->selectMode = SM_FADE_MAIN_TO_SELECT;
+ this->selectedFileIndex = this->buttonIndex;
+ this->menuMode = FS_MENU_MODE_SELECT;
+ this->nextTitleLabel = FS_TITLE_OPEN_FILE;
+ }
+ } else if (!SLOT_OCCUPIED(this, this->buttonIndex)) {
+ play_sound(NA_SE_SY_FSEL_DECIDE_L);
+ this->configMode = CM_ROTATE_TO_NAME_ENTRY;
+ this->kbdButton = FS_KBD_BTN_NONE;
+ this->charPage = FS_CHAR_PAGE_HIRA;
+ if (gSaveContext.options.language != 0) {
+ this->charPage = FS_CHAR_PAGE_ENG;
+ }
+ this->kbdX = 0;
+ this->kbdY = 0;
+ this->charIndex = 0;
+ this->charBgAlpha = 0;
+ this->newFileNameCharCount = 0;
+ this->nameEntryBoxPosX = 120;
+ this->nameEntryBoxAlpha = 0;
+ Lib_MemCpy(&this->fileNames[this->buttonIndex], &sEmptyName, ARRAY_COUNT(sEmptyName));
+ } else {
+ play_sound(NA_SE_SY_FSEL_DECIDE_L);
+ this->actionTimer = 4;
+ this->selectMode = SM_FADE_MAIN_TO_SELECT;
+ this->selectedFileIndex = this->buttonIndex;
+ this->menuMode = FS_MENU_MODE_SELECT;
+ this->nextTitleLabel = FS_TITLE_OPEN_FILE;
+ }
+ } else if (this->warningLabel == FS_WARNING_NONE) {
+ play_sound(NA_SE_SY_FSEL_DECIDE_L);
+ this->prevConfigMode = this->configMode;
+
+ if (this->buttonIndex == FS_BTN_MAIN_COPY) {
+ this->configMode = CM_SETUP_COPY_SOURCE;
+ this->nextTitleLabel = FS_TITLE_COPY_FROM;
+ } else if (this->buttonIndex == FS_BTN_MAIN_ERASE) {
+ this->configMode = CM_SETUP_ERASE_SELECT;
+ this->nextTitleLabel = FS_TITLE_ERASE_FILE;
+ } else {
+ this->configMode = CM_MAIN_TO_OPTIONS;
+ this->kbdButton = FS_KBD_BTN_HIRA;
+ this->kbdX = 0;
+ this->kbdY = 0;
+ this->charBgAlpha = 0;
+ this->newFileNameCharCount = 0;
+ this->nameEntryBoxPosX = 120;
+ }
+ this->actionTimer = 4;
+ } else {
+ play_sound(NA_SE_SY_FSEL_ERROR);
+ }
+ } else if (CHECK_BTN_ALL(input->press.button, BTN_B)) {
+ gSaveContext.gameMode = GAMEMODE_TITLE_SCREEN;
+ STOP_GAMESTATE(&this->state);
+ SET_NEXT_GAMESTATE(&this->state, TitleSetup_Init, sizeof(TitleSetupState));
+ } else {
+ if (ABS_ALT(this->stickAdjY) > 30) {
+ play_sound(NA_SE_SY_FSEL_CURSOR);
+ if (this->stickAdjY > 30) {
+ this->buttonIndex--;
+ if (this->buttonIndex == FS_BTN_MAIN_FILE_3) {
+ this->buttonIndex = FS_BTN_MAIN_FILE_2;
+ }
+ if (this->buttonIndex < FS_BTN_MAIN_FILE_1) {
+ this->buttonIndex = FS_BTN_MAIN_OPTIONS;
+ }
+ } else {
+ this->buttonIndex++;
+ if (this->buttonIndex == FS_BTN_MAIN_FILE_3) {
+ this->buttonIndex = FS_BTN_MAIN_COPY;
+ }
+ if (this->buttonIndex > FS_BTN_MAIN_OPTIONS) {
+ this->buttonIndex = FS_BTN_MAIN_FILE_1;
+ }
+ }
+ }
+
+ if (this->buttonIndex == FS_BTN_MAIN_COPY) {
+ if (!gSaveContext.flashSaveAvailable) {
+ if (!NO_FLASH_SLOT_OCCUPIED(sramCtx, 0) && !NO_FLASH_SLOT_OCCUPIED(sramCtx, 1) &&
+ !NO_FLASH_SLOT_OCCUPIED(sramCtx, 2)) {
+ this->warningButtonIndex = this->buttonIndex;
+ this->warningLabel = FS_WARNING_NO_FILE_COPY;
+ this->emptyFileTextAlpha = 255;
+ } else if (NO_FLASH_SLOT_OCCUPIED(sramCtx, 0) && NO_FLASH_SLOT_OCCUPIED(sramCtx, 1) &&
+ NO_FLASH_SLOT_OCCUPIED(sramCtx, 2)) {
+ this->warningButtonIndex = this->buttonIndex;
+ this->warningLabel = FS_WARNING_NO_EMPTY_FILES;
+ this->emptyFileTextAlpha = 255;
+ } else {
+ this->warningLabel = FS_WARNING_NONE;
+ }
+ } else {
+ if (!SLOT_OCCUPIED(this, 0) && !SLOT_OCCUPIED(this, 1) && !SLOT_OCCUPIED(this, 2)) {
+ this->warningButtonIndex = this->buttonIndex;
+ this->warningLabel = FS_WARNING_NO_FILE_COPY;
+ this->emptyFileTextAlpha = 255;
+ } else if (SLOT_OCCUPIED(this, 0) && SLOT_OCCUPIED(this, 1) && SLOT_OCCUPIED(this, 2)) {
+ this->warningButtonIndex = this->buttonIndex;
+ this->warningLabel = FS_WARNING_NO_EMPTY_FILES;
+ this->emptyFileTextAlpha = 255;
+ } else {
+ this->warningLabel = FS_WARNING_NONE;
+ }
+ }
+ } else if (this->buttonIndex == FS_BTN_MAIN_ERASE) {
+ if (!gSaveContext.flashSaveAvailable) {
+ if (!NO_FLASH_SLOT_OCCUPIED(sramCtx, 0) && !NO_FLASH_SLOT_OCCUPIED(sramCtx, 1) &&
+ !NO_FLASH_SLOT_OCCUPIED(sramCtx, 2)) {
+ this->warningButtonIndex = this->buttonIndex;
+ this->warningLabel = FS_WARNING_NO_FILE_ERASE;
+ this->emptyFileTextAlpha = 255;
+ } else {
+ this->warningLabel = FS_WARNING_NONE;
+ }
+ } else {
+ if (!SLOT_OCCUPIED(this, 0) && !SLOT_OCCUPIED(this, 1) && !SLOT_OCCUPIED(this, 2)) {
+ this->warningButtonIndex = this->buttonIndex;
+ this->warningLabel = FS_WARNING_NO_FILE_ERASE;
+ this->emptyFileTextAlpha = 255;
+ } else {
+ this->warningLabel = FS_WARNING_NONE;
+ }
+ }
+ } else {
+ this->warningLabel = FS_WARNING_NONE;
+ }
+ }
+}
+
+/**
+ * Update function for `CM_UNUSED_31`
+ */
+void FileSelect_UnusedCM31(GameState* thisx) {
+}
+
+/**
+ * Delay the next config mode from running until `D_80814564` reaches 254.
+ * Because the timer increments by 2, the delay is 127 frames (assuming the value was not changed by reg editor).
+ * Unused in the final game, was possibly used for debugging.
+ * Update function for `CM_UNUSED_DELAY`
+ */
+void FileSelect_UnusedCMDelay(GameState* thisx) {
+ static s16 D_80814564 = 0;
+ FileSelectState* this = (FileSelectState*)thisx;
+
+ D_80814564 += 2;
+
+ if (D_80814564 == 254) {
+ this->configMode = this->nextConfigMode;
+ D_80814564 = 0;
+ }
+}
+
+/**
+ * Rotate the window from the main menu to the name entry menu.
+ * Update function for `CM_ROTATE_TO_NAME_ENTRY`
+ */
+void FileSelect_RotateToNameEntry(GameState* thisx) {
+ FileSelectState* this = (FileSelectState*)thisx;
+
+ this->windowRot += 50.0f;
+
+ if (this->windowRot >= 314.0f) {
+ this->windowRot = 314.0f;
+ this->configMode = CM_START_NAME_ENTRY;
+ }
+}
+
+/**
+ * Rotate the window from the main menu to the options menu.
+ * Update function for `CM_MAIN_TO_OPTIONS`
+ */
+void FileSelect_RotateToOptions(GameState* thisx) {
+ FileSelectState* this = (FileSelectState*)thisx;
+
+ this->windowRot += 50.0f;
+
+ if (this->windowRot >= 314.0f) {
+ this->windowRot = 314.0f;
+ this->configMode = CM_START_OPTIONS;
+ }
+}
+
+/**
+ * Rotate the window from the options menu to the main menu.
+ * Update function for `CM_NAME_ENTRY_TO_MAIN` and `CM_OPTIONS_TO_MAIN`
+ */
+void FileSelect_RotateToMain(GameState* thisx) {
+ FileSelectState* this = (FileSelectState*)thisx;
+
+ this->windowRot += 50.0f;
+
+ if (this->windowRot >= 628.0f) {
+ this->windowRot = 0.0f;
+ this->configMode = CM_MAIN_MENU;
+ }
+}
+
+void (*sConfigModeUpdateFuncs[])(GameState*) = {
+ // Main Menu
+ FileSelect_StartFadeIn, // CM_FADE_IN_START
+ FileSelect_FinishFadeIn, // CM_FADE_IN_END
+ FileSelect_UpdateMainMenu, // CM_MAIN_MENU
+ // Copy File
+ FileSelect_SetupCopySource, // CM_SETUP_COPY_SOURCE
+ FileSelect_SelectCopySource, // CM_SELECT_COPY_SOURCE
+ FileSelect_SetupCopyDest1, // CM_SETUP_COPY_DEST_1
+ FileSelect_SetupCopyDest2, // CM_SETUP_COPY_DEST_2
+ FileSelect_SelectCopyDest, // CM_SELECT_COPY_DEST
+ FileSelect_ExitToCopySource1, // CM_EXIT_TO_COPY_SOURCE_1
+ FileSelect_ExitToCopySource2, // CM_EXIT_TO_COPY_SOURCE_2
+ FileSelect_SetupCopyConfirm1, // CM_SETUP_COPY_CONFIRM_1
+ FileSelect_SetupCopyConfirm2, // CM_SETUP_COPY_CONFIRM_2
+ FileSelect_CopyConfirm, // CM_COPY_CONFIRM
+ FileSelect_CopyWaitForFlashSave, // CM_COPY_WAIT_FOR_FLASH_SAVE
+ FileSelect_ReturnToCopyDest, // CM_RETURN_TO_COPY_DEST
+ FileSelect_CopyAnim1, // CM_COPY_ANIM_1
+ FileSelect_CopyAnim2, // CM_COPY_ANIM_2
+ FileSelect_CopyAnim3, // CM_COPY_ANIM_3
+ FileSelect_CopyAnim4, // CM_COPY_ANIM_4
+ FileSelect_CopyAnim5, // CM_COPY_ANIM_5
+ FileSelect_ExitCopyToMain, // CM_COPY_RETURN_MAIN
+ // Erase File
+ FileSelect_SetupEraseSelect, // CM_SETUP_ERASE_SELECT
+ FileSelect_EraseSelect, // CM_ERASE_SELECT
+ FileSelect_SetupEraseConfirm1, // CM_SETUP_ERASE_CONFIRM_1
+ FileSelect_SetupEraseConfirm2, // CM_SETUP_ERASE_CONFIRM_2
+ FileSelect_EraseConfirm, // CM_ERASE_CONFIRM
+ FileSelect_ExitToEraseSelect1, // CM_EXIT_TO_ERASE_SELECT_1
+ FileSelect_ExitToEraseSelect2, // CM_EXIT_TO_ERASE_SELECT_2
+ FileSelect_EraseAnim1, // CM_ERASE_ANIM_1
+ FileSelect_EraseWaitForFlashSave, // CM_ERASE_WAIT_FOR_FLASH_SAVE
+ FileSelect_EraseAnim2, // CM_ERASE_ANIM_2
+ FileSelect_EraseAnim3, // CM_ERASE_ANIM_3
+ FileSelect_ExitEraseToMain, // CM_EXIT_ERASE_TO_MAIN
+ FileSelect_UnusedCM31, // CM_UNUSED_31
+ // New File Name Entry
+ FileSelect_RotateToNameEntry, // CM_ROTATE_TO_NAME_ENTRY
+ FileSelect_StartNameEntry, // CM_START_NAME_ENTRY
+ FileSelect_UpdateKeyboardCursor, // CM_NAME_ENTRY
+ FileSelect_NameEntryWaitForFlashSave, // CM_NAME_ENTRY_WAIT_FOR_FLASH_SAVE
+ FileSelect_RotateToMain, // CM_NAME_ENTRY_TO_MAIN
+ // Options
+ FileSelect_RotateToOptions, // CM_MAIN_TO_OPTIONS
+ FileSelect_StartOptions, // CM_START_OPTIONS
+ FileSelect_UpdateOptionsMenu, // CM_OPTIONS_MENU
+ FileSelect_OptionsWaitForFlashSave, // CM_OPTIONS_WAIT_FOR_FLASH_SAVE
+ FileSelect_RotateToMain, // CM_OPTIONS_TO_MAIN
+ // Possible Debug
+ FileSelect_UnusedCMDelay, // CM_UNUSED_DELAY
+};
+
+s16 sCursorAlphaTargets[] = { 70, 200 };
+
+/**
+ * Updates the alpha of the cursor to make it pulsate.
+ */
+void FileSelect_PulsateCursor(GameState* thisx) {
+ FileSelectState* this = (FileSelectState*)thisx;
+ s32 alphaStep =
+ ABS_ALT(this->highlightColor[3] - sCursorAlphaTargets[this->highlightPulseDir]) / this->highlightTimer;
+
+ if (this->highlightColor[3] >= sCursorAlphaTargets[this->highlightPulseDir]) {
+ this->highlightColor[3] -= alphaStep;
+ } else {
+ this->highlightColor[3] += alphaStep;
+ }
+
+ this->highlightTimer--;
+
+ if (this->highlightTimer == 0) {
+ this->highlightColor[3] = sCursorAlphaTargets[this->highlightPulseDir];
+ this->highlightTimer = 20;
+ this->highlightPulseDir ^= 1;
+ }
+}
+
+void FileSelect_ConfigModeUpdate(GameState* thisx) {
+ FileSelectState* this = (FileSelectState*)thisx;
+
+ sConfigModeUpdateFuncs[this->configMode](&this->state);
+}
+
+void FileSelect_SetWindowVtx(GameState* thisx) {
+ FileSelectState* this = (FileSelectState*)thisx;
+ s16 i;
+ s16 j;
+ s16 x;
+ s32 tmp;
+ s32 tmp2;
+ s32 tmp3;
+
+ this->windowVtx = GRAPH_ALLOC(this->state.gfxCtx, 80 * sizeof(Vtx));
+ tmp = this->windowPosX - 90;
+
+ for (x = 0, i = 0; i < 4; i++) {
+ tmp += 0x40;
+ tmp2 = (i == 3) ? 0x30 : 0x40;
+
+ for (j = 0, tmp3 = 0x50; j < 5; j++, x += 4, tmp3 -= 0x20) {
+ this->windowVtx[x].v.ob[0] = this->windowVtx[x + 2].v.ob[0] = tmp;
+
+ this->windowVtx[x + 1].v.ob[0] = this->windowVtx[x + 3].v.ob[0] = tmp2 + tmp;
+
+ this->windowVtx[x].v.ob[1] = this->windowVtx[x + 1].v.ob[1] = tmp3;
+
+ this->windowVtx[x + 2].v.ob[1] = this->windowVtx[x + 3].v.ob[1] = tmp3 - 0x20;
+
+ this->windowVtx[x].v.ob[2] = this->windowVtx[x + 1].v.ob[2] = this->windowVtx[x + 2].v.ob[2] =
+ this->windowVtx[x + 3].v.ob[2] = 0;
+
+ this->windowVtx[x].v.flag = this->windowVtx[x + 1].v.flag = this->windowVtx[x + 2].v.flag =
+ this->windowVtx[x + 3].v.flag = 0;
+
+ this->windowVtx[x].v.tc[0] = this->windowVtx[x].v.tc[1] = this->windowVtx[x + 1].v.tc[1] =
+ this->windowVtx[x + 2].v.tc[0] = 0;
+
+ this->windowVtx[x + 1].v.tc[0] = this->windowVtx[x + 3].v.tc[0] = tmp2 << 5;
+
+ this->windowVtx[x + 2].v.tc[1] = this->windowVtx[x + 3].v.tc[1] = 32 << 5;
+
+ this->windowVtx[x].v.cn[0] = this->windowVtx[x + 2].v.cn[0] = this->windowVtx[x].v.cn[1] =
+ this->windowVtx[x + 2].v.cn[1] = this->windowVtx[x].v.cn[2] = this->windowVtx[x + 2].v.cn[2] =
+ this->windowVtx[x + 1].v.cn[0] = this->windowVtx[x + 3].v.cn[0] = this->windowVtx[x + 1].v.cn[1] =
+ this->windowVtx[x + 3].v.cn[1] = this->windowVtx[x + 1].v.cn[2] =
+ this->windowVtx[x + 3].v.cn[2] = this->windowVtx[x].v.cn[3] =
+ this->windowVtx[x + 2].v.cn[3] = this->windowVtx[x + 1].v.cn[3] =
+ this->windowVtx[x + 3].v.cn[3] = 255;
+ }
+ }
+}
+
+s16 D_80814620[] = { 8, 8, 8, 0 };
+s16 D_80814628[] = { 12, 12, 12, 0 };
+s16 D_80814630[] = { 12, 12, 12, 0 };
+s16 D_80814638[] = {
+ 88, 104, 120, 940, 944, 948,
+};
+s16 D_80814644[] = { 88, 104, 120, 944 };
+s16 D_8081464C[] = { 940, 944 };
+s16 D_80814650[] = { 940, 944 };
+
+/*
+ * fileSelect->windowContentVtx[0] -> Title Label (4)
+ *
+ * fileSelect->windowContentVtx[4] -> File 1 InfoBox (28)
+ * fileSelect->windowContentVtx[32] -> File 2 InfoBox (28)
+ * fileSelect->windowContentVtx[60] -> File 3 InfoBox (28)
+ *
+ * ** FILE 1 **
+ *
+ * fileSelect->windowContentVtx[88] -> File Button
+ * fileSelect->windowContentVtx[92] -> File Name Box
+ * fileSelect->windowContentVtx[96] -> Connectors
+ * fileSelect->windowContentVtx[100] -> Blank Button (Owl Save)
+ *
+ * ** FILE 2 **
+ *
+ * fileSelect->windowContentVtx[104] -> Repeat of File 1 above
+ *
+ * ** FILE 3 **
+ *
+ * fileSelect->windowContentVtx[120] -> Repeat of File 1 above
+ *
+ * ** FILE 1 Info **
+ *
+ * fileSelect->windowContentVtx[136] -> File Name (32)
+ * fileSelect->windowContentVtx[168] -> File Name Shadow (32)
+ * fileSelect->windowContentVtx[200] -> Rupee Digits (12)
+ * fileSelect->windowContentVtx[212] -> Rupee Digits Shadow (12)
+ * fileSelect->windowContentVtx[224] -> Mask Count (8)
+ * fileSelect->windowContentVtx[232] -> Mask Count Shadow (8)
+ * fileSelect->windowContentVtx[240] -> Hearts (80)
+ * fileSelect->windowContentVtx[320] -> Remains (16)
+ * fileSelect->windowContentVtx[336] -> Rupee Icon (4)
+ * fileSelect->windowContentVtx[340] -> Heart Piece Count (4)
+ * fileSelect->windowContentVtx[344] -> Mask Text (8)
+ * fileSelect->windowContentVtx[352] -> Owl Save Icon (4)
+ * fileSelect->windowContentVtx[356] -> Day Text (8)
+ * fileSelect->windowContentVtx[364] -> Time Digits (20)
+ * fileSelect->windowContentVtx[384] -> Time Digits Shadow (20)
+ *
+ * ** FILE 2 Info **
+ *
+ * fileSelect->windowContentVtx[404] -> Repeat of File 1 above
+ *
+ * ** FILE 3 Info **
+ *
+ * fileSelect->windowContentVtx[672] -> Repeat of File 1 above
+ *
+ * fileSelect->windowContentVtx[940] -> Action buttons (copy/erase/yes/quit)
+ * fileSelect->windowContentVtx[944] -> Action buttons (copy/erase/yes/quit)
+ * fileSelect->windowContentVtx[948] -> Option Button
+ * fileSelect->windowContentVtx[952] -> Highlight over currently selected button
+ * fileSelect->windowContentVtx[956] -> Warning labels
+ */
+
+#ifdef NON_MATCHING
+// regalloc at the beginning is fixed by removing FAKE: labelled code
+void FileSelect_SetWindowContentVtx(GameState* thisx) {
+ FileSelectState* this = (FileSelectState*)thisx;
+ u16 vtxId;
+ s16 j;
+ s16 index;
+ s16 spAC;
+ s16 i; // a3
+ u16 spA4[3];
+ u16* ptr;
+ s32 posY; // sp9C
+ s32 relPosY; // sp98
+ s32 tempPosY;
+ s32 posX; // s1
+ s32 temp_t5;
+
+ this->windowContentVtx = GRAPH_ALLOC(this->state.gfxCtx, 960 * sizeof(Vtx));
+
+ // Initialize all windowContentVtx
+ for (vtxId = 0; vtxId < 960; vtxId += 4) {
+ // x-coord (left)
+ this->windowContentVtx[vtxId + 0].v.ob[0] = this->windowContentVtx[vtxId + 2].v.ob[0] = 0x12C;
+ // x-coord (right)
+ this->windowContentVtx[vtxId + 1].v.ob[0] = this->windowContentVtx[vtxId + 3].v.ob[0] =
+ this->windowContentVtx[vtxId + 0].v.ob[0] + 16;
+
+ // y-coord (top)
+ this->windowContentVtx[vtxId + 0].v.ob[1] = this->windowContentVtx[vtxId + 1].v.ob[1] = 0;
+ // y-coord (bottom)
+ this->windowContentVtx[vtxId + 2].v.ob[1] = this->windowContentVtx[vtxId + 3].v.ob[1] =
+ this->windowContentVtx[vtxId + 0].v.ob[1] - 16;
+
+ // z-coordinate
+ this->windowContentVtx[vtxId + 0].v.ob[2] = this->windowContentVtx[vtxId + 1].v.ob[2] =
+ this->windowContentVtx[vtxId + 2].v.ob[2] = this->windowContentVtx[vtxId + 3].v.ob[2] = 0;
+
+ //! FAKE:
+ if (index && index && index) {}
+
+ // flag
+ this->windowContentVtx[vtxId + 0].v.flag = this->windowContentVtx[vtxId + 1].v.flag =
+ this->windowContentVtx[vtxId + 2].v.flag = this->windowContentVtx[vtxId + 3].v.flag = 0;
+
+ // texture coordinates
+ this->windowContentVtx[vtxId + 0].v.tc[0] = this->windowContentVtx[vtxId + 0].v.tc[1] =
+ this->windowContentVtx[vtxId + 1].v.tc[1] = this->windowContentVtx[vtxId + 2].v.tc[0] = 0;
+ this->windowContentVtx[vtxId + 1].v.tc[0] = this->windowContentVtx[vtxId + 2].v.tc[1] =
+ this->windowContentVtx[vtxId + 3].v.tc[0] = this->windowContentVtx[vtxId + 3].v.tc[1] = 0x200;
+
+ // alpha
+ this->windowContentVtx[vtxId + 0].v.cn[0] = this->windowContentVtx[vtxId + 1].v.cn[0] =
+ this->windowContentVtx[vtxId + 2].v.cn[0] = this->windowContentVtx[vtxId + 3].v.cn[0] =
+ this->windowContentVtx[vtxId + 0].v.cn[1] = this->windowContentVtx[vtxId + 1].v.cn[1] =
+ this->windowContentVtx[vtxId + 2].v.cn[1] = this->windowContentVtx[vtxId + 3].v.cn[1] =
+ this->windowContentVtx[vtxId + 0].v.cn[2] = this->windowContentVtx[vtxId + 1].v.cn[2] =
+ this->windowContentVtx[vtxId + 2].v.cn[2] = this->windowContentVtx[vtxId + 3].v.cn[2] =
+ this->windowContentVtx[vtxId + 0].v.cn[3] = this->windowContentVtx[vtxId + 1].v.cn[3] =
+ this->windowContentVtx[vtxId + 2].v.cn[3] =
+ this->windowContentVtx[vtxId + 3].v.cn[3] = 255;
+ }
+
+ /** Title Label **/
+
+ // x-coord (left)
+ this->windowContentVtx[0].v.ob[0] = this->windowContentVtx[2].v.ob[0] = this->windowPosX;
+ // x-coord (right)
+ this->windowContentVtx[1].v.ob[0] = this->windowContentVtx[3].v.ob[0] = this->windowContentVtx[0].v.ob[0] + 0x80;
+ // y-coord (top)
+ this->windowContentVtx[0].v.ob[1] = this->windowContentVtx[1].v.ob[1] = 0x48;
+ // y-coord (bottom)
+ this->windowContentVtx[2].v.ob[1] = this->windowContentVtx[3].v.ob[1] = this->windowContentVtx[0].v.ob[1] - 0x10;
+ // texture coordinates
+ this->windowContentVtx[1].v.tc[0] = this->windowContentVtx[3].v.tc[0] = 0x1000;
+
+ /** File InfoBox **/
+
+ // Loop through 3 files
+ for (vtxId = 4, i = 0; i < 3; i++) {
+ posX = this->windowPosX - 6;
+
+ // Loop through 7 textures
+ for (j = 0; j < 7; j++, vtxId += 4) {
+ // x-coord (left)
+ this->windowContentVtx[vtxId + 0].v.ob[0] = this->windowContentVtx[vtxId + 2].v.ob[0] = posX;
+ // x-coord (right)
+ this->windowContentVtx[vtxId + 1].v.ob[0] = this->windowContentVtx[vtxId + 3].v.ob[0] =
+ this->windowContentVtx[vtxId + 0].v.ob[0] + sFileInfoBoxPartWidths[j];
+
+ // y-coord(top)
+ this->windowContentVtx[vtxId + 0].v.ob[1] = this->windowContentVtx[vtxId + 1].v.ob[1] =
+ this->fileNamesY[i] + 0x2C;
+ // y-coord (bottom)
+ this->windowContentVtx[vtxId + 2].v.ob[1] = this->windowContentVtx[vtxId + 3].v.ob[1] =
+ this->windowContentVtx[vtxId + 0].v.ob[1] - 0x38;
+
+ // texture coordinates
+ this->windowContentVtx[vtxId + 1].v.tc[0] = this->windowContentVtx[vtxId + 3].v.tc[0] =
+ sFileInfoBoxPartWidths[j] << 5;
+ this->windowContentVtx[vtxId + 2].v.tc[1] = this->windowContentVtx[vtxId + 3].v.tc[1] = 0x700;
+
+ // Update X position
+ posX += sFileInfoBoxPartWidths[j];
+ }
+ }
+
+ // File Buttons
+
+ posX = this->windowPosX - 6;
+ posY = 44;
+
+ // Loop through 3 files
+ for (j = 0; j < 3; j++, vtxId += 16, posY -= 0x10) {
+
+ /* File Button */
+
+ // x-coord (left)
+ this->windowContentVtx[vtxId + 0].v.ob[0] = this->windowContentVtx[vtxId + 2].v.ob[0] = posX;
+ // x-coord (right)
+ this->windowContentVtx[vtxId + 1].v.ob[0] = this->windowContentVtx[vtxId + 3].v.ob[0] =
+ this->windowContentVtx[vtxId + 0].v.ob[0] + 0x40;
+
+ // y-coord(top)
+ this->windowContentVtx[vtxId + 0].v.ob[1] = this->windowContentVtx[vtxId + 1].v.ob[1] =
+ this->buttonYOffsets[j] + posY;
+ // y-coord (bottom)
+ this->windowContentVtx[vtxId + 2].v.ob[1] = this->windowContentVtx[vtxId + 3].v.ob[1] =
+ this->windowContentVtx[vtxId + 0].v.ob[1] - 0x10;
+
+ // texture coordinates
+ this->windowContentVtx[vtxId + 1].v.tc[0] = this->windowContentVtx[vtxId + 3].v.tc[0] = 0x800;
+
+ /* File Name Box */
+
+ // x-coord (left)
+ this->windowContentVtx[vtxId + 4].v.ob[0] = this->windowContentVtx[vtxId + 6].v.ob[0] = posX + 0x40;
+ // x-coord (right)
+ this->windowContentVtx[vtxId + 5].v.ob[0] = this->windowContentVtx[vtxId + 7].v.ob[0] =
+ this->windowContentVtx[vtxId + 4].v.ob[0] + 0x6C;
+
+ // y-coord(top)
+ this->windowContentVtx[vtxId + 4].v.ob[1] = this->windowContentVtx[vtxId + 5].v.ob[1] =
+ this->buttonYOffsets[j] + posY;
+ // y-coord (bottom)
+ this->windowContentVtx[vtxId + 6].v.ob[1] = this->windowContentVtx[vtxId + 7].v.ob[1] =
+ this->windowContentVtx[vtxId + 4].v.ob[1] - 0x10;
+
+ // texture coordinates
+ this->windowContentVtx[vtxId + 5].v.tc[0] = this->windowContentVtx[vtxId + 7].v.tc[0] = 0xD80;
+
+ /* Connectors */
+
+ // x-coord (left)
+ this->windowContentVtx[vtxId + 8].v.ob[0] = this->windowContentVtx[vtxId + 10].v.ob[0] = posX + 0x34;
+ // x-coord (right)
+ this->windowContentVtx[vtxId + 9].v.ob[0] = this->windowContentVtx[vtxId + 11].v.ob[0] =
+ this->windowContentVtx[vtxId + 8].v.ob[0] + 0x18;
+
+ // y-coord(top)
+ this->windowContentVtx[vtxId + 8].v.ob[1] = this->windowContentVtx[vtxId + 9].v.ob[1] =
+ this->buttonYOffsets[j] + posY;
+ // y-coord (bottom)
+ this->windowContentVtx[vtxId + 10].v.ob[1] = this->windowContentVtx[vtxId + 11].v.ob[1] =
+ this->windowContentVtx[vtxId + 8].v.ob[1] - 0x10;
+
+ // texture coordinates
+ this->windowContentVtx[vtxId + 9].v.tc[0] = this->windowContentVtx[vtxId + 11].v.tc[0] = 0x300;
+
+ /* Blank Button (Owl Save) */
+
+ // x-coord (left)
+ this->windowContentVtx[vtxId + 12].v.ob[0] = this->windowContentVtx[vtxId + 14].v.ob[0] = posX + 0xA9;
+ // x-coord (right)
+ this->windowContentVtx[vtxId + 13].v.ob[0] = this->windowContentVtx[vtxId + 15].v.ob[0] =
+ this->windowContentVtx[vtxId + 12].v.ob[0] + 0x34;
+
+ // y-coord(top)
+ this->windowContentVtx[vtxId + 12].v.ob[1] = this->windowContentVtx[vtxId + 13].v.ob[1] =
+ this->buttonYOffsets[j] + posY;
+ // y-coord (bottom)
+ this->windowContentVtx[vtxId + 14].v.ob[1] = this->windowContentVtx[vtxId + 15].v.ob[1] =
+ this->windowContentVtx[vtxId + 12].v.ob[1] - 0x10;
+
+ // texture coordinates
+ this->windowContentVtx[vtxId + 13].v.tc[0] = this->windowContentVtx[vtxId + 15].v.tc[0] = 0x680;
+ }
+
+ posY = 44;
+
+ // Loop through 3 files
+ for (j = 0; j < 3; j++, posY -= 16) {
+ if (!gSaveContext.flashSaveAvailable) {
+ // Should skip vtxId
+ // vtxId += 268;
+ continue;
+ }
+
+ // Account for owl-save offset
+
+ spAC = j;
+ if (this->isOwlSave[j + 2]) {
+ spAC = j + 2;
+ }
+
+ /* File name */
+
+ posX = this->windowPosX - 6;
+
+ if ((this->configMode == 0x10) && (j == this->copyDestFileIndex)) {
+ relPosY = this->fileNamesY[j] + 0x2C;
+ } else if (((this->configMode == 0x11) || (this->configMode == 0x12)) && (j == this->copyDestFileIndex)) {
+ relPosY = this->buttonYOffsets[j] + posY;
+ } else {
+ relPosY = posY + this->buttonYOffsets[j] + this->fileNamesY[j];
+ }
+
+ tempPosY = relPosY - 2;
+
+ // Loop through 8 characters of file name
+ for (i = 0; i < 8; i++, vtxId += 4) {
+
+ index = this->fileNames[j][i];
+
+ /* File Name */
+
+ // x-coord (left)
+ this->windowContentVtx[vtxId + 0].v.ob[0] = this->windowContentVtx[vtxId + 2].v.ob[0] =
+ D_80814280[index] + posX + 0x4E;
+ // x-coord (right)
+ this->windowContentVtx[vtxId + 1].v.ob[0] = this->windowContentVtx[vtxId + 3].v.ob[0] =
+ this->windowContentVtx[vtxId + 0].v.ob[0] + 0xB;
+
+ // y-coord(top)
+ this->windowContentVtx[vtxId + 0].v.ob[1] = this->windowContentVtx[vtxId + 1].v.ob[1] = tempPosY;
+ // y-coord (bottom)
+ this->windowContentVtx[vtxId + 2].v.ob[1] = this->windowContentVtx[vtxId + 3].v.ob[1] =
+ this->windowContentVtx[vtxId + 0].v.ob[1] - 0xC;
+
+ /* File Name Shadow */
+
+ // x-coord (left)
+ this->windowContentVtx[vtxId + 32].v.ob[0] = this->windowContentVtx[vtxId + 34].v.ob[0] =
+ D_80814280[index] + posX + 0x4F;
+ // x-coord (right)
+ this->windowContentVtx[vtxId + 33].v.ob[0] = this->windowContentVtx[vtxId + 35].v.ob[0] =
+ this->windowContentVtx[vtxId + 32].v.ob[0] + 0xB;
+
+ // y-coord(top)
+ this->windowContentVtx[vtxId + 32].v.ob[1] = this->windowContentVtx[vtxId + 33].v.ob[1] = tempPosY - 1;
+ // y-coord (bottom)
+ this->windowContentVtx[vtxId + 34].v.ob[1] = this->windowContentVtx[vtxId + 35].v.ob[1] =
+ this->windowContentVtx[vtxId + 32].v.ob[1] - 0xC;
+
+ // Update X position
+ posX += 10;
+ }
+ // Account for the shadow
+ vtxId += 32;
+
+ /* Rupee Digits */
+
+ posX = this->windowPosX + 14;
+ tempPosY = relPosY - 0x18;
+
+ FileSelect_SplitNumber(this->rupees[spAC], &spA4[0], &spA4[1], &spA4[2]);
+
+ index = sWalletFirstDigit[this->walletUpgrades[spAC]];
+
+ ptr = &spA4[index];
+
+ for (i = 0; i < 3; i++, vtxId += 4, ptr++) {
+
+ /* Rupee Digits */
+
+ // x-coord (left)
+ this->windowContentVtx[vtxId + 0].v.ob[0] = this->windowContentVtx[vtxId + 2].v.ob[0] =
+ D_80814280[*ptr] + posX;
+ // x-coord (right)
+ this->windowContentVtx[vtxId + 1].v.ob[0] = this->windowContentVtx[vtxId + 3].v.ob[0] =
+ this->windowContentVtx[vtxId + 0].v.ob[0] + D_80814628[i];
+
+ // y-coord(top)
+ this->windowContentVtx[vtxId + 0].v.ob[1] = this->windowContentVtx[vtxId + 1].v.ob[1] = tempPosY;
+ // y-coord (bottom)
+ this->windowContentVtx[vtxId + 2].v.ob[1] = this->windowContentVtx[vtxId + 3].v.ob[1] =
+ this->windowContentVtx[vtxId + 0].v.ob[1] - D_80814630[i];
+
+ /* Rupee Digits Shadow */
+
+ // x-coord (left)
+ this->windowContentVtx[vtxId + 12].v.ob[0] = this->windowContentVtx[vtxId + 14].v.ob[0] =
+ this->windowContentVtx[vtxId + 0].v.ob[0] + 1;
+ // x-coord (right)
+ this->windowContentVtx[vtxId + 13].v.ob[0] = this->windowContentVtx[vtxId + 15].v.ob[0] =
+ this->windowContentVtx[vtxId + 12].v.ob[0] + D_80814628[i];
+
+ // y-coord(top)
+ this->windowContentVtx[vtxId + 12].v.ob[1] = this->windowContentVtx[vtxId + 13].v.ob[1] = tempPosY - 1;
+ // y-coord (bottom)
+ this->windowContentVtx[vtxId + 14].v.ob[1] = this->windowContentVtx[vtxId + 15].v.ob[1] =
+ this->windowContentVtx[vtxId + 12].v.ob[1] - D_80814630[i];
+
+ // Update X position
+ posX += D_80814620[i];
+ }
+
+ // Account for the shadow
+ vtxId += 12;
+
+ /* Mask Count */
+
+ posX = this->windowPosX + 42;
+ tempPosY = relPosY - 0x2A;
+
+ FileSelect_SplitNumber(this->maskCount[spAC], &spA4[0], &spA4[1], &spA4[2]);
+
+ for (i = 1; i < 3; i++, vtxId += 4) {
+
+ /* Mask Count */
+
+ // x-coord (left)
+ this->windowContentVtx[vtxId + 0].v.ob[0] = this->windowContentVtx[vtxId + 2].v.ob[0] =
+ D_80814280[spA4[i]] + posX;
+ // x-coord (right)
+ this->windowContentVtx[vtxId + 1].v.ob[0] = this->windowContentVtx[vtxId + 3].v.ob[0] =
+ this->windowContentVtx[vtxId + 0].v.ob[0] + D_80814628[i];
+
+ // y-coord(top)
+ this->windowContentVtx[vtxId + 0].v.ob[1] = this->windowContentVtx[vtxId + 1].v.ob[1] = tempPosY;
+ // y-coord (bottom)
+ this->windowContentVtx[vtxId + 2].v.ob[1] = this->windowContentVtx[vtxId + 3].v.ob[1] =
+ this->windowContentVtx[vtxId + 0].v.ob[1] - D_80814630[i];
+
+ /* Mask Count Shadow */
+
+ // x-coord (left)
+ this->windowContentVtx[vtxId + 8].v.ob[0] = this->windowContentVtx[vtxId + 10].v.ob[0] =
+ this->windowContentVtx[vtxId + 0].v.ob[0] + 1;
+ // x-coord (right)
+ this->windowContentVtx[vtxId + 9].v.ob[0] = this->windowContentVtx[vtxId + 11].v.ob[0] =
+ this->windowContentVtx[vtxId + 8].v.ob[0] + D_80814628[i];
+
+ // y-coord(top)
+ this->windowContentVtx[vtxId + 8].v.ob[1] = this->windowContentVtx[vtxId + 9].v.ob[1] = tempPosY - 1;
+ // y-coord (bottom)
+ this->windowContentVtx[vtxId + 10].v.ob[1] = this->windowContentVtx[vtxId + 11].v.ob[1] =
+ this->windowContentVtx[vtxId + 8].v.ob[1] - D_80814630[i];
+
+ // Update X position
+ posX += D_80814620[i];
+ }
+
+ // Account for the shadow
+ vtxId += 8;
+
+ /* Hearts */
+
+ posX = this->windowPosX + 63;
+ tempPosY = relPosY - 0x10;
+
+ // Loop through 20 hearts
+ for (i = 0; i < 20; i++, vtxId += 4, posX += 9) {
+ // x-coord (left)
+ this->windowContentVtx[vtxId + 0].v.ob[0] = this->windowContentVtx[vtxId + 2].v.ob[0] = posX;
+ // x-coord (right)
+ this->windowContentVtx[vtxId + 1].v.ob[0] = this->windowContentVtx[vtxId + 3].v.ob[0] =
+ this->windowContentVtx[vtxId + 0].v.ob[0] + 0xA;
+
+ // y-coord(top)
+ this->windowContentVtx[vtxId + 0].v.ob[1] = this->windowContentVtx[vtxId + 1].v.ob[1] = tempPosY;
+ // y-coord (bottom)
+ this->windowContentVtx[vtxId + 2].v.ob[1] = this->windowContentVtx[vtxId + 3].v.ob[1] =
+ this->windowContentVtx[vtxId + 0].v.ob[1] - 0xA;
+
+ // New row of hearts next iteration
+ if (i == 9) {
+ posX = this->windowPosX + (63 - 9);
+ tempPosY -= 8;
+ }
+ }
+
+ /* Quest Remains */
+
+ posX = this->windowPosX + 64;
+ tempPosY = relPosY - 0x20;
+
+ // Loop through 4 Remains
+ for (i = 0; i < 4; i++, vtxId += 4, posX += 0x18) {
+ // x-coord (left)
+ this->windowContentVtx[vtxId + 0].v.ob[0] = this->windowContentVtx[vtxId + 2].v.ob[0] = posX;
+ // x-coord (right)
+ this->windowContentVtx[vtxId + 1].v.ob[0] = this->windowContentVtx[vtxId + 3].v.ob[0] =
+ this->windowContentVtx[vtxId + 0].v.ob[0] + 0x14;
+
+ // y-coord(top)
+ this->windowContentVtx[vtxId + 0].v.ob[1] = this->windowContentVtx[vtxId + 1].v.ob[1] = tempPosY;
+ // y-coord (bottom)
+ this->windowContentVtx[vtxId + 2].v.ob[1] = this->windowContentVtx[vtxId + 3].v.ob[1] =
+ this->windowContentVtx[vtxId + 0].v.ob[1] - 0x14;
+
+ // texture coordinates
+ this->windowContentVtx[vtxId + 1].v.tc[0] = this->windowContentVtx[vtxId + 2].v.tc[1] =
+ this->windowContentVtx[vtxId + 3].v.tc[0] = this->windowContentVtx[vtxId + 3].v.tc[1] = 0x400;
+ }
+
+ /* Rupee Icon */
+
+ // posX = this->windowPosX - 1;
+ tempPosY = relPosY - 0x15;
+
+ // x-coord (left)
+ this->windowContentVtx[vtxId + 0].v.ob[0] = this->windowContentVtx[vtxId + 2].v.ob[0] = this->windowPosX - 1;
+ // x-coord (right)
+ this->windowContentVtx[vtxId + 1].v.ob[0] = this->windowContentVtx[vtxId + 3].v.ob[0] =
+ this->windowContentVtx[vtxId + 0].v.ob[0] + 0x10;
+
+ // y-coord(top)
+ this->windowContentVtx[vtxId + 0].v.ob[1] = this->windowContentVtx[vtxId + 1].v.ob[1] = tempPosY;
+ // y-coord (bottom)
+ this->windowContentVtx[vtxId + 2].v.ob[1] = this->windowContentVtx[vtxId + 3].v.ob[1] =
+ this->windowContentVtx[vtxId + 0].v.ob[1] - 0x10;
+
+ // texture coordinates
+ this->windowContentVtx[vtxId + 1].v.tc[0] = this->windowContentVtx[vtxId + 3].v.tc[0] = 0x200;
+ this->windowContentVtx[vtxId + 2].v.tc[1] = this->windowContentVtx[vtxId + 3].v.tc[1] = 0x200;
+
+ vtxId += 4;
+
+ /* Heart Piece Count */
+
+ // posX = this->windowPosX + 0x27;
+ tempPosY = relPosY - 0x15;
+
+ // x-coord (left)
+ this->windowContentVtx[vtxId + 0].v.ob[0] = this->windowContentVtx[vtxId + 2].v.ob[0] = this->windowPosX + 0x27;
+ // x-coord (right)
+ this->windowContentVtx[vtxId + 1].v.ob[0] = this->windowContentVtx[vtxId + 3].v.ob[0] =
+ this->windowContentVtx[vtxId + 0].v.ob[0] + 0x18;
+
+ // y-coord(top)
+ this->windowContentVtx[vtxId + 0].v.ob[1] = this->windowContentVtx[vtxId + 1].v.ob[1] = tempPosY;
+ // y-coord (bottom)
+ this->windowContentVtx[vtxId + 2].v.ob[1] = this->windowContentVtx[vtxId + 3].v.ob[1] =
+ this->windowContentVtx[vtxId + 0].v.ob[1] - 0x10;
+
+ // texture coordinates
+ this->windowContentVtx[vtxId + 1].v.tc[0] = this->windowContentVtx[vtxId + 3].v.tc[0] = 0x300;
+ this->windowContentVtx[vtxId + 2].v.tc[1] = this->windowContentVtx[vtxId + 3].v.tc[1] = 0x200;
+
+ vtxId += 4;
+
+ /* Mask Text */
+
+ // posX = this->windowPosX - 10;
+ tempPosY = relPosY - 0x27;
+
+ this->windowContentVtx[vtxId + 0].v.ob[0] = this->windowContentVtx[vtxId + 2].v.ob[0] = this->windowPosX - 10;
+
+ this->windowContentVtx[vtxId + 1].v.ob[0] = this->windowContentVtx[vtxId + 3].v.ob[0] =
+ this->windowContentVtx[vtxId + 0].v.ob[0] + 0x40;
+
+ this->windowContentVtx[vtxId + 0].v.ob[1] = this->windowContentVtx[vtxId + 1].v.ob[1] = tempPosY;
+
+ this->windowContentVtx[vtxId + 2].v.ob[1] = this->windowContentVtx[vtxId + 3].v.ob[1] =
+ this->windowContentVtx[vtxId + 0].v.ob[1] - 0x10;
+
+ this->windowContentVtx[vtxId + 1].v.tc[0] = this->windowContentVtx[vtxId + 3].v.tc[0] = 0x800;
+ this->windowContentVtx[vtxId + 2].v.tc[1] = this->windowContentVtx[vtxId + 3].v.tc[1] = 0x200;
+
+ this->windowContentVtx[vtxId + 4].v.ob[0] = this->windowContentVtx[vtxId + 6].v.ob[0] =
+ this->windowContentVtx[vtxId + 0].v.ob[0] + 1;
+
+ this->windowContentVtx[vtxId + 5].v.ob[0] = this->windowContentVtx[vtxId + 7].v.ob[0] =
+ this->windowContentVtx[vtxId + 4].v.ob[0] + 0x40;
+
+ this->windowContentVtx[vtxId + 4].v.ob[1] = this->windowContentVtx[vtxId + 5].v.ob[1] = tempPosY - 1;
+
+ this->windowContentVtx[vtxId + 6].v.ob[1] = this->windowContentVtx[vtxId + 7].v.ob[1] =
+ this->windowContentVtx[vtxId + 4].v.ob[1] - 0x10;
+
+ this->windowContentVtx[vtxId + 5].v.tc[0] = this->windowContentVtx[vtxId + 7].v.tc[0] = 0x800;
+ this->windowContentVtx[vtxId + 6].v.tc[1] = this->windowContentVtx[vtxId + 7].v.tc[1] = 0x200;
+
+ vtxId += 8;
+
+ /* Owl Save Icon */
+
+ posX = this->windowPosX + 0xA3;
+
+ if ((this->configMode == 0x10) && (j == this->copyDestFileIndex)) {
+ tempPosY = this->fileNamesY[j] + 0x2C;
+ } else if (((this->configMode == 0x11) || (this->configMode == 0x12)) && (j == this->copyDestFileIndex)) {
+ tempPosY = this->buttonYOffsets[j] + posY;
+ } else {
+ tempPosY = posY + this->buttonYOffsets[j] + this->fileNamesY[j];
+ }
+
+ this->windowContentVtx[vtxId + 0].v.ob[0] = this->windowContentVtx[vtxId + 2].v.ob[0] = posX + 0xE;
+
+ this->windowContentVtx[vtxId + 1].v.ob[0] = this->windowContentVtx[vtxId + 3].v.ob[0] =
+ this->windowContentVtx[vtxId + 0].v.ob[0] + 0x18;
+
+ this->windowContentVtx[vtxId + 0].v.ob[1] = this->windowContentVtx[vtxId + 1].v.ob[1] = tempPosY - 2;
+
+ this->windowContentVtx[vtxId + 2].v.ob[1] = this->windowContentVtx[vtxId + 3].v.ob[1] =
+ this->windowContentVtx[vtxId + 0].v.ob[1] - 0xC;
+
+ this->windowContentVtx[vtxId + 1].v.tc[0] = this->windowContentVtx[vtxId + 3].v.tc[0] = 0x300;
+ this->windowContentVtx[vtxId + 2].v.tc[1] = this->windowContentVtx[vtxId + 3].v.tc[1] = 0x180;
+
+ vtxId += 4;
+
+ /* Day Text */
+
+ for (i = 0; i < 2; i++, vtxId += 4) {
+
+ this->windowContentVtx[vtxId + 0].v.ob[0] = this->windowContentVtx[vtxId + 2].v.ob[0] = 2 + posX + i;
+
+ this->windowContentVtx[vtxId + 1].v.ob[0] = this->windowContentVtx[vtxId + 3].v.ob[0] =
+ this->windowContentVtx[vtxId + 0].v.ob[0] + 0x30;
+
+ this->windowContentVtx[vtxId + 0].v.ob[1] = this->windowContentVtx[vtxId + 1].v.ob[1] = tempPosY - i - 0x12;
+
+ this->windowContentVtx[vtxId + 2].v.ob[1] = this->windowContentVtx[vtxId + 3].v.ob[1] =
+ this->windowContentVtx[vtxId + 0].v.ob[1] - 0x18;
+
+ this->windowContentVtx[vtxId + 1].v.tc[0] = this->windowContentVtx[vtxId + 3].v.tc[0] = 0x600;
+
+ this->windowContentVtx[vtxId + 2].v.tc[1] = this->windowContentVtx[vtxId + 3].v.tc[1] = 0x300;
+ }
+
+ /* Time Digits */
+
+ posX += 6;
+ temp_t5 = vtxId;
+
+ for (i = 0; i < 5; i++, vtxId += 4, posX += 8) {
+
+ this->windowContentVtx[vtxId + 0].v.ob[0] = this->windowContentVtx[vtxId + 2].v.ob[0] = posX;
+
+ this->windowContentVtx[vtxId + 1].v.ob[0] = this->windowContentVtx[vtxId + 3].v.ob[0] =
+ this->windowContentVtx[vtxId + 0].v.ob[0] + 0xC;
+
+ this->windowContentVtx[vtxId + 0].v.ob[1] = this->windowContentVtx[vtxId + 1].v.ob[1] = tempPosY - 0x2A;
+
+ this->windowContentVtx[vtxId + 2].v.ob[1] = this->windowContentVtx[vtxId + 3].v.ob[1] =
+ this->windowContentVtx[vtxId + 0].v.ob[1] - 0xC;
+
+ this->windowContentVtx[vtxId + 0x14].v.ob[0] = this->windowContentVtx[vtxId + 0x16].v.ob[0] = posX + 1;
+
+ this->windowContentVtx[vtxId + 0x15].v.ob[0] = this->windowContentVtx[vtxId + 0x17].v.ob[0] =
+ this->windowContentVtx[vtxId + 0x14].v.ob[0] + 0xC;
+
+ this->windowContentVtx[vtxId + 0x14].v.ob[1] = this->windowContentVtx[vtxId + 0x15].v.ob[1] =
+ tempPosY - 0x2B;
+
+ this->windowContentVtx[vtxId + 0x16].v.ob[1] = this->windowContentVtx[vtxId + 0x17].v.ob[1] =
+ this->windowContentVtx[vtxId + 0x14].v.ob[1] - 0xC;
+ }
+
+ // Adjust the colon to the right
+ this->windowContentVtx[temp_t5 + 8].v.ob[0] = this->windowContentVtx[temp_t5 + 10].v.ob[0] =
+ this->windowContentVtx[temp_t5 + 8].v.ob[0] + 3;
+
+ this->windowContentVtx[temp_t5 + 9].v.ob[0] = this->windowContentVtx[temp_t5 + 11].v.ob[0] =
+ this->windowContentVtx[temp_t5 + 8].v.ob[0] + 0xC;
+
+ this->windowContentVtx[temp_t5 + 0x1C].v.ob[0] = this->windowContentVtx[temp_t5 + 0x1E].v.ob[0] =
+ this->windowContentVtx[temp_t5 + 8].v.ob[0] + 1;
+
+ this->windowContentVtx[temp_t5 + 0x1D].v.ob[0] = this->windowContentVtx[temp_t5 + 0x1F].v.ob[0] =
+ this->windowContentVtx[temp_t5 + 0x1C].v.ob[0] + 0xC;
+
+ vtxId += 20;
+ }
+
+ posX = this->windowPosX - 6;
+ posY = -0xC;
+
+ for (j = 0; j < 2; j++, vtxId += 4, posY -= 0x10) {
+
+ this->windowContentVtx[vtxId + 0].v.ob[0] = this->windowContentVtx[vtxId + 2].v.ob[0] = posX;
+
+ this->windowContentVtx[vtxId + 1].v.ob[0] = this->windowContentVtx[vtxId + 3].v.ob[0] =
+ this->windowContentVtx[vtxId + 0].v.ob[0] + 0x40;
+
+ this->windowContentVtx[vtxId + 0].v.ob[1] = this->windowContentVtx[vtxId + 1].v.ob[1] =
+ this->buttonYOffsets[j + 3] + posY;
+
+ this->windowContentVtx[vtxId + 2].v.ob[1] = this->windowContentVtx[vtxId + 3].v.ob[1] =
+ this->windowContentVtx[vtxId + 0].v.ob[1] - 0x10;
+
+ this->windowContentVtx[vtxId + 1].v.tc[0] = this->windowContentVtx[vtxId + 3].v.tc[0] = 0x800;
+ }
+
+ this->windowContentVtx[vtxId + 0].v.ob[0] = this->windowContentVtx[vtxId + 2].v.ob[0] = posX;
+
+ this->windowContentVtx[vtxId + 1].v.ob[0] = this->windowContentVtx[vtxId + 3].v.ob[0] =
+ this->windowContentVtx[vtxId + 0].v.ob[0] + 0x40;
+
+ this->windowContentVtx[vtxId + 0].v.ob[1] = this->windowContentVtx[vtxId + 1].v.ob[1] =
+ this->buttonYOffsets[5] - 0x34;
+
+ this->windowContentVtx[vtxId + 2].v.ob[1] = this->windowContentVtx[vtxId + 3].v.ob[1] =
+ this->windowContentVtx[vtxId + 0].v.ob[1] - 0x10;
+
+ this->windowContentVtx[vtxId + 1].v.tc[0] = this->windowContentVtx[vtxId + 3].v.tc[0] = 0x800;
+
+ vtxId += 4;
+
+ if (((this->menuMode == FS_MENU_MODE_CONFIG) && (this->configMode >= 2)) ||
+ ((this->menuMode == FS_MENU_MODE_SELECT) && (this->selectMode == 3))) {
+ if (this->menuMode == FS_MENU_MODE_CONFIG) {
+ if ((this->configMode == 4) || (this->configMode == 7) || (this->configMode == 0x16)) {
+ j = D_80814644[this->buttonIndex];
+ } else if ((this->configMode == 0x19) || (this->configMode == 0xC)) {
+ j = D_8081464C[this->buttonIndex];
+ } else {
+ j = D_80814638[this->buttonIndex];
+ }
+ } else {
+ j = D_80814650[this->confirmButtonIndex];
+ }
+
+ this->windowContentVtx[vtxId + 0].v.ob[0] = this->windowContentVtx[vtxId + 2].v.ob[0] = this->windowPosX - 0xA;
+
+ this->windowContentVtx[vtxId + 1].v.ob[0] = this->windowContentVtx[vtxId + 3].v.ob[0] =
+ this->windowContentVtx[vtxId + 0].v.ob[0] + 0x48;
+
+ this->windowContentVtx[vtxId + 0].v.ob[1] = this->windowContentVtx[vtxId + 1].v.ob[1] =
+ this->windowContentVtx[j].v.ob[1] + 4;
+
+ this->windowContentVtx[vtxId + 2].v.ob[1] = this->windowContentVtx[vtxId + 3].v.ob[1] =
+ this->windowContentVtx[vtxId + 0].v.ob[1] - 0x18;
+
+ this->windowContentVtx[vtxId + 1].v.tc[0] = this->windowContentVtx[vtxId + 3].v.tc[0] = 0x900;
+
+ this->windowContentVtx[vtxId + 2].v.tc[1] = this->windowContentVtx[vtxId + 3].v.tc[1] = 0x300;
+ }
+
+ this->windowContentVtx[vtxId + 4].v.ob[0] = this->windowContentVtx[vtxId + 6].v.ob[0] = this->windowPosX + 0x3A;
+
+ this->windowContentVtx[vtxId + 5].v.ob[0] = this->windowContentVtx[vtxId + 7].v.ob[0] =
+ this->windowContentVtx[vtxId + 4].v.ob[0] + 0x80;
+
+ this->windowContentVtx[vtxId + 4].v.ob[1] = this->windowContentVtx[vtxId + 5].v.ob[1] =
+ this->windowContentVtx[D_80814638[this->warningButtonIndex]].v.ob[1];
+
+ this->windowContentVtx[vtxId + 6].v.ob[1] = this->windowContentVtx[vtxId + 7].v.ob[1] =
+ this->windowContentVtx[vtxId + 4].v.ob[1] - 0x10;
+
+ this->windowContentVtx[vtxId + 5].v.tc[0] = this->windowContentVtx[vtxId + 7].v.tc[0] = 0x1000;
+}
+#else
+void FileSelect_SetWindowContentVtx(GameState* thisx);
+#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/FileSelect_SetWindowContentVtx.s")
+#endif
+
+u16 D_80814654[] = {
+ 0x88,
+ 0x194,
+ 0x2A0,
+};
+TexturePtr sFileSelRemainsTextures[] = {
+ gFileSelOdolwasRemainsTex,
+ gFileSelGohtsRemainsTex,
+ gFileSelGyorgsRemainsTex,
+ gFileSelTwinmoldsRemainsTex,
+};
+TexturePtr sFileSelDayENGTextures[] = {
+ gFileSelFirstDayENGTex,
+ gFileSelFirstDayENGTex,
+ gFileSelSecondDayENGTex,
+ gFileSelFinalDayENGTex,
+};
+TexturePtr sFileSelHeartPieceTextures[] = {
+ gFileSel0QuarterHeartENGTex,
+ gFileSel1QuarterHeartENGTex,
+ gFileSel2QuarterHeartENGTex,
+ gFileSel3QuarterHeartENGTex,
+};
+static TexturePtr sHeartTextures[2][5] = {
+ {
+ gHeartEmptyTex,
+ gHeartQuarterTex,
+ gHeartHalfTex,
+ gHeartThreeQuarterTex,
+ gHeartFullTex,
+ },
+ {
+ gDefenseHeartEmptyTex,
+ gDefenseHeartQuarterTex,
+ gDefenseHeartHalfTex,
+ gDefenseHeartThreeQuarterTex,
+ gDefenseHeartFullTex,
+ },
+};
+u8 sHealthToQuarterHeartCount[] = {
+ 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3,
+};
+s16 sFileSelRupeePrimColors[3][3] = {
+ { 200, 255, 100 }, // Default Wallet
+ { 170, 170, 255 }, // Adult Wallet
+ { 255, 105, 105 }, // Giant Wallet
+};
+s16 sFileSelRupeeEnvColors[3][3] = {
+ { 0, 80, 0 }, // Default Wallet
+ { 10, 10, 80 }, // Adult Wallet
+ { 40, 10, 0 }, // Giant Wallet
+};
+static s16 sHeartPrimColors[2][3] = {
+ { 255, 70, 50 },
+ { 200, 0, 0 },
+};
+static s16 sHeartEnvColors[2][3] = {
+ { 50, 40, 60 },
+ { 255, 255, 255 },
+};
+
+void FileSelect_DrawFileInfo(GameState* thisx, s16 fileIndex) {
+ FileSelectState* this = (FileSelectState*)thisx;
+ Font* font = &this->font;
+ s16 j;
+ s16 vtxOffset;
+ s32 heartType;
+ s16 i;
+ s16 sp20C;
+ s16 health;
+ s16 timeDigits[5];
+ u16 digits[3]; // rupees and mask count
+ u8 quarterHeartCount;
+
+ OPEN_DISPS(this->state.gfxCtx);
+
+ gDPPipeSync(POLY_OPA_DISP++);
+ gDPSetCombineLERP(POLY_OPA_DISP++, 0, 0, 0, PRIMITIVE, TEXEL0, 0, PRIMITIVE, 0, 0, 0, 0, PRIMITIVE, TEXEL0, 0,
+ PRIMITIVE, 0);
+
+ sp20C = fileIndex;
+
+ // draw file name
+ if (this->nameAlpha[fileIndex] != 0) {
+ gSPVertex(POLY_OPA_DISP++, &this->windowContentVtx[D_80814654[fileIndex] + (4 * 8)], 32, 0);
+ gDPSetPrimColor(POLY_OPA_DISP++, 0x00, 0x00, 0, 0, 0, this->nameAlpha[fileIndex]);
+
+ for (vtxOffset = 0, i = 0; vtxOffset < (4 * 8); i++, vtxOffset += 4) {
+ FileSelect_DrawTexQuadI4(this->state.gfxCtx,
+ font->fontBuf + this->fileNames[fileIndex][i] * FONT_CHAR_TEX_SIZE, vtxOffset);
+ }
+
+ gSPVertex(POLY_OPA_DISP++, &this->windowContentVtx[D_80814654[fileIndex]], 32, 0);
+ gDPSetPrimColor(POLY_OPA_DISP++, 0x00, 0x00, 255, 255, 255, this->nameAlpha[fileIndex]);
+
+ for (vtxOffset = 0, i = 0; vtxOffset < (4 * 8); i++, vtxOffset += 4) {
+ FileSelect_DrawTexQuadI4(this->state.gfxCtx,
+ font->fontBuf + this->fileNames[fileIndex][i] * FONT_CHAR_TEX_SIZE, vtxOffset);
+ }
+ }
+
+ if ((fileIndex == this->selectedFileIndex) || (fileIndex == this->copyDestFileIndex)) {
+ if (this->isOwlSave[fileIndex + 2]) {
+ sp20C = fileIndex + 2;
+ }
+
+ gDPPipeSync(POLY_OPA_DISP++);
+ gDPSetCombineMode(POLY_OPA_DISP++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM);
+ gDPSetPrimColor(POLY_OPA_DISP++, 0x00, 0x00, sFileSelRupeePrimColors[this->walletUpgrades[sp20C]][0],
+ sFileSelRupeePrimColors[this->walletUpgrades[sp20C]][1],
+ sFileSelRupeePrimColors[this->walletUpgrades[sp20C]][2], this->fileInfoAlpha[fileIndex]);
+ gDPSetEnvColor(POLY_OPA_DISP++, sFileSelRupeeEnvColors[this->walletUpgrades[sp20C]][0],
+ sFileSelRupeeEnvColors[this->walletUpgrades[sp20C]][1],
+ sFileSelRupeeEnvColors[this->walletUpgrades[sp20C]][2], 255);
+
+ gSPVertex(POLY_OPA_DISP++, &this->windowContentVtx[D_80814654[fileIndex] + 0xC8], 4, 0);
+
+ gDPLoadTextureBlock(POLY_OPA_DISP++, gFileSelRupeeTex, G_IM_FMT_IA, G_IM_SIZ_8b, 16, 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);
+ gSP1Quadrangle(POLY_OPA_DISP++, 0, 2, 3, 1, 0);
+
+ gDPPipeSync(POLY_OPA_DISP++);
+ gDPSetCombineLERP(POLY_OPA_DISP++, 1, 0, PRIMITIVE, 0, TEXEL0, 0, PRIMITIVE, 0, 1, 0, PRIMITIVE, 0, TEXEL0, 0,
+ PRIMITIVE, 0);
+
+ gDPSetPrimColor(POLY_OPA_DISP++, 0x00, 0x00, 0, 0, 0, this->fileInfoAlpha[fileIndex]);
+ gSPVertex(POLY_OPA_DISP++, &this->windowContentVtx[D_80814654[fileIndex] + 0x4C], 12, 0);
+
+ FileSelect_SplitNumber((u16)this->rupees[sp20C], &digits[0], &digits[1], &digits[2]);
+
+ for (vtxOffset = 0, i = sWalletFirstDigit[this->walletUpgrades[sp20C]]; i < 3; i++, vtxOffset += 4) {
+ FileSelect_DrawTexQuadI4(this->state.gfxCtx, font->fontBuf + digits[i] * FONT_CHAR_TEX_SIZE, vtxOffset);
+ }
+
+ if (this->rupees[sp20C] == gUpgradeCapacities[4][this->walletUpgrades[sp20C]]) {
+ gDPSetPrimColor(POLY_OPA_DISP++, 0x00, 0x00, 120, 255, 0, this->fileInfoAlpha[fileIndex]);
+ } else if (this->rupees[sp20C] != 0) {
+ gDPSetPrimColor(POLY_OPA_DISP++, 0x00, 0x00, 255, 255, 255, this->fileInfoAlpha[fileIndex]);
+ } else {
+ gDPSetPrimColor(POLY_OPA_DISP++, 0x00, 0x00, 100, 100, 100, this->fileInfoAlpha[fileIndex]);
+ }
+
+ gSPVertex(POLY_OPA_DISP++, &this->windowContentVtx[D_80814654[fileIndex] + 0x40], 12, 0);
+
+ for (vtxOffset = 0, i = sWalletFirstDigit[this->walletUpgrades[sp20C]]; i < 3; i++, vtxOffset += 4) {
+ FileSelect_DrawTexQuadI4(this->state.gfxCtx, font->fontBuf + digits[i] * FONT_CHAR_TEX_SIZE, vtxOffset);
+ }
+
+ gDPPipeSync(POLY_OPA_DISP++);
+ gDPSetCombineLERP(POLY_OPA_DISP++, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0,
+ PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0);
+
+ gDPSetPrimColor(POLY_OPA_DISP++, 0x00, 0x00, 255, 0, 0, this->fileInfoAlpha[fileIndex]);
+ gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, 255);
+
+ gSPVertex(POLY_OPA_DISP++, &this->windowContentVtx[D_80814654[fileIndex] + 0xCC], 4, 0);
+
+ POLY_OPA_DISP = FileSelect_DrawTexQuadIA8(
+ POLY_OPA_DISP, sFileSelHeartPieceTextures[this->heartPieceCount[sp20C]], 0x18, 0x10, (s16)0);
+
+ if (this->defenseHearts[sp20C] == 0) {
+ heartType = 0;
+ } else {
+ heartType = 1;
+ }
+
+ gDPSetPrimColor(POLY_OPA_DISP++, 0x00, 0x00, sHeartPrimColors[heartType][0], sHeartPrimColors[heartType][1],
+ sHeartPrimColors[heartType][2], this->fileInfoAlpha[fileIndex]);
+ gDPSetEnvColor(POLY_OPA_DISP++, sHeartEnvColors[heartType][0], sHeartEnvColors[heartType][1],
+ sHeartEnvColors[heartType][2], 255);
+
+ i = this->healthCapacity[sp20C] / 0x10;
+
+ health = this->health[sp20C];
+ if (health <= 0x30) {
+ health = 0x30;
+ }
+
+ quarterHeartCount = 4;
+ for (vtxOffset = 0, j = 0; j < i; j++, vtxOffset += 4) {
+ if (health < 0x10) {
+ if (health != 0) {
+ quarterHeartCount = sHealthToQuarterHeartCount[health];
+ health = 0;
+ } else {
+ quarterHeartCount = 0;
+ }
+ } else {
+ health -= 0x10;
+ }
+
+ gSPVertex(POLY_OPA_DISP++, &this->windowContentVtx[D_80814654[fileIndex] + 0x68 + vtxOffset], 4, 0);
+ POLY_OPA_DISP =
+ FileSelect_DrawTexQuadIA8(POLY_OPA_DISP, sHeartTextures[heartType][quarterHeartCount], 0x10, 0x10, 0);
+ }
+
+ gDPPipeSync(POLY_OPA_DISP++);
+ gDPSetCombineMode(POLY_OPA_DISP++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM);
+ gDPSetPrimColor(POLY_OPA_DISP++, 0x00, 0x00, 255, 255, 255, this->fileInfoAlpha[fileIndex]);
+ gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, 255);
+
+ for (vtxOffset = 0, j = 0; j < 4; j++, vtxOffset += 4) {
+ if (this->questItems[sp20C] & gBitFlags[j]) {
+ gSPVertex(POLY_OPA_DISP++, &this->windowContentVtx[D_80814654[fileIndex] + 0xB8 + vtxOffset], 4, 0);
+ gDPLoadTextureBlock(POLY_OPA_DISP++, sFileSelRemainsTextures[j], G_IM_FMT_RGBA, G_IM_SIZ_32b, 32, 32, 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);
+ gSP1Quadrangle(POLY_OPA_DISP++, 0, 2, 3, 1, 0);
+ }
+ }
+
+ gDPPipeSync(POLY_OPA_DISP++);
+ gDPSetCombineLERP(POLY_OPA_DISP++, 1, 0, PRIMITIVE, 0, TEXEL0, 0, PRIMITIVE, 0, 1, 0, PRIMITIVE, 0, TEXEL0, 0,
+ PRIMITIVE, 0);
+
+ gDPSetPrimColor(POLY_OPA_DISP++, 0x00, 0x00, 0, 0, 0, this->fileInfoAlpha[fileIndex]);
+ gSPVertex(POLY_OPA_DISP++, &this->windowContentVtx[D_80814654[fileIndex] + 0xD0], 8, 0);
+ gDPLoadTextureBlock_4b(POLY_OPA_DISP++, gFileSelMASKSENGTex, G_IM_FMT_I, 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);
+ gSP1Quadrangle(POLY_OPA_DISP++, 4, 6, 7, 5, 0);
+ gDPSetPrimColor(POLY_OPA_DISP++, 0x00, 0x00, 255, 255, 255, this->fileInfoAlpha[fileIndex]);
+ gSP1Quadrangle(POLY_OPA_DISP++, 0, 2, 3, 1, 0);
+
+ gDPPipeSync(POLY_OPA_DISP++);
+
+ gDPSetPrimColor(POLY_OPA_DISP++, 0x00, 0x00, 0, 0, 0, this->fileInfoAlpha[fileIndex]);
+ gSPVertex(POLY_OPA_DISP++, &this->windowContentVtx[D_80814654[fileIndex] + 0x60], 8, 0);
+
+ FileSelect_SplitNumber(this->maskCount[sp20C], &digits[0], &digits[1], &digits[2]);
+
+ for (vtxOffset = 0, i = 1; i < 3; i++, vtxOffset += 4) {
+ FileSelect_DrawTexQuadI4(this->state.gfxCtx, font->fontBuf + digits[i] * FONT_CHAR_TEX_SIZE, vtxOffset);
+ }
+
+ gDPSetPrimColor(POLY_OPA_DISP++, 0x00, 0x00, 255, 255, 255, this->fileInfoAlpha[fileIndex]);
+
+ gSPVertex(POLY_OPA_DISP++, &this->windowContentVtx[D_80814654[fileIndex] + 0x58], 8, 0);
+
+ for (vtxOffset = 0, i = 1; i < 3; i++, vtxOffset += 4) {
+
+ FileSelect_DrawTexQuadI4(this->state.gfxCtx, font->fontBuf + digits[i] * FONT_CHAR_TEX_SIZE, vtxOffset);
+ }
+ }
+
+ if (this->isOwlSave[fileIndex + 2]) {
+ gDPPipeSync(POLY_OPA_DISP++);
+ gDPSetCombineMode(POLY_OPA_DISP++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM);
+
+ gDPSetPrimColor(POLY_OPA_DISP++, 0x00, 0x00, 255, 255, 255, this->nameAlpha[fileIndex]);
+
+ gSPVertex(POLY_OPA_DISP++, &this->windowContentVtx[D_80814654[fileIndex] + 0xD8], 4, 0);
+
+ gDPLoadTextureBlock(POLY_OPA_DISP++, gFileSelOwlSaveIconTex, G_IM_FMT_RGBA, G_IM_SIZ_32b, 24, 12, 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);
+ gSP1Quadrangle(POLY_OPA_DISP++, 0, 2, 3, 1, 0);
+
+ gDPPipeSync(POLY_OPA_DISP++);
+ gDPSetCombineMode(POLY_OPA_DISP++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM);
+
+ gSPVertex(POLY_OPA_DISP++, &this->windowContentVtx[D_80814654[fileIndex] + 0xDC], 8, 0);
+
+ gDPSetPrimColor(POLY_OPA_DISP++, 0x00, 0x00, 0, 0, 0, this->fileInfoAlpha[fileIndex]);
+
+ gDPLoadTextureBlock_4b(POLY_OPA_DISP++, sFileSelDayENGTextures[this->day[sp20C]], G_IM_FMT_I, 48, 24, 0,
+ G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK,
+ G_TX_NOLOD, G_TX_NOLOD);
+ gSP1Quadrangle(POLY_OPA_DISP++, 4, 6, 7, 5, 0);
+
+ gDPSetPrimColor(POLY_OPA_DISP++, 0x00, 0x00, 255, 255, 255, this->fileInfoAlpha[fileIndex]);
+ gSP1Quadrangle(POLY_OPA_DISP++, 0, 2, 3, 1, 0);
+
+ timeDigits[0] = 0;
+ timeDigits[1] = TIME_TO_MINUTES_F(this->time[sp20C]) / 60.0f;
+
+ while (timeDigits[1] >= 10) {
+ timeDigits[0]++;
+ timeDigits[1] -= 10;
+ }
+
+ timeDigits[3] = 0;
+ timeDigits[4] = (s32)TIME_TO_MINUTES_F(this->time[sp20C]) % 60;
+
+ while (timeDigits[4] >= 10) {
+ timeDigits[3]++;
+ timeDigits[4] -= 10;
+ }
+ timeDigits[2] = 0x41;
+
+ gDPPipeSync(POLY_OPA_DISP++);
+ gDPSetCombineLERP(POLY_OPA_DISP++, 1, 0, PRIMITIVE, 0, TEXEL0, 0, PRIMITIVE, 0, 1, 0, PRIMITIVE, 0, TEXEL0, 0,
+ PRIMITIVE, 0);
+
+ gDPSetPrimColor(POLY_OPA_DISP++, 0x00, 0x00, 0, 0, 0, this->fileInfoAlpha[fileIndex]);
+ gSPVertex(POLY_OPA_DISP++, &this->windowContentVtx[D_80814654[fileIndex] + 0xF8], 20, 0);
+
+ for (i = 0, vtxOffset = 0; i < 5; i++, vtxOffset += 4) {
+ FileSelect_DrawTexQuadI4(this->state.gfxCtx, font->fontBuf + timeDigits[i] * FONT_CHAR_TEX_SIZE, vtxOffset);
+ }
+
+ gDPSetPrimColor(POLY_OPA_DISP++, 0x00, 0x00, 255, 255, 255, this->fileInfoAlpha[fileIndex]);
+ gSPVertex(POLY_OPA_DISP++, &this->windowContentVtx[D_80814654[fileIndex] + 0xE4], 20, 0);
+
+ for (i = 0, vtxOffset = 0; i < 5; i++, vtxOffset += 4) {
+ FileSelect_DrawTexQuadI4(this->state.gfxCtx, font->fontBuf + timeDigits[i] * FONT_CHAR_TEX_SIZE, vtxOffset);
+ }
+ }
+
+ gDPPipeSync(POLY_OPA_DISP++);
+
+ CLOSE_DISPS(this->state.gfxCtx);
+}
+
+TexturePtr sFileInfoBoxTextures[] = {
+ gFileSelFileInfoBox0Tex, gFileSelFileInfoBox1Tex, gFileSelFileInfoBox2Tex, gFileSelFileInfoBox3Tex,
+ gFileSelFileInfoBox4Tex, gFileSelFileExtraInfoBox0Tex, gFileSelFileExtraInfoBox1Tex,
+};
+
+TexturePtr sTitleLabels[] = {
+ gFileSelPleaseSelectAFileENGTex, gFileSelOpenThisFileENGTex, gFileSelCopyWhichFileENGTex,
+ gFileSelCopyToWhichFileENGTex, gFileSelAreYouSureCopyENGTex, gFileSelFileCopiedENGTex,
+ gFileSelEraseWhichFileENGTex, gFileSelAreYouSureEraseENGTex, gFileSelFileErasedENGTex,
+};
+
+TexturePtr sWarningLabels[] = {
+ gFileSelNoFileToCopyENGTex, gFileSelNoFileToEraseENGTex, gFileSelNoEmptyFileENGTex,
+ gFileSelFileEmptyENGTex, gFileSelFileInUseENGTex,
+};
+
+TexturePtr sFileButtonTextures[] = {
+ gFileSelFile1ButtonENGTex,
+ gFileSelFile2ButtonENGTex,
+ gFileSelFile3ButtonENGTex,
+};
+
+TexturePtr sActionButtonTextures[] = {
+ gFileSelCopyButtonENGTex,
+ gFileSelEraseButtonENGTex,
+ gFileSelYesButtonENGTex,
+ gFileSelQuitButtonENGTex,
+};
+
+/**
+ * Draw most window contents including buttons, labels, and icons.
+ * Does not include anything from the keyboard and settings windows.
+ */
+void FileSelect_DrawWindowContents(GameState* thisx) {
+ FileSelectState* this = (FileSelectState*)thisx;
+ s16 fileIndex;
+ s16 temp;
+ s16 i;
+ s16 quadVtxIndex;
+
+ if (1) {}
+
+ OPEN_DISPS(this->state.gfxCtx);
+
+ // draw title label
+ gDPPipeSync(POLY_OPA_DISP++);
+ gDPSetCombineLERP(POLY_OPA_DISP++, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0, PRIMITIVE,
+ ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0);
+ gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, this->titleAlpha[FS_TITLE_CUR]);
+ gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, 0);
+
+ gSPVertex(POLY_OPA_DISP++, &this->windowContentVtx[0], 4, 0);
+ gDPLoadTextureBlock(POLY_OPA_DISP++, sTitleLabels[this->titleLabel], G_IM_FMT_IA, G_IM_SIZ_8b, 128, 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);
+ gSP1Quadrangle(POLY_OPA_DISP++, 0, 2, 3, 1, 0);
+
+ // draw next title label
+ gDPPipeSync(POLY_OPA_DISP++);
+ gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, this->titleAlpha[FS_TITLE_NEXT]);
+ gDPLoadTextureBlock(POLY_OPA_DISP++, sTitleLabels[this->nextTitleLabel], G_IM_FMT_IA, G_IM_SIZ_8b, 128, 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);
+ gSP1Quadrangle(POLY_OPA_DISP++, 0, 2, 3, 1, 0);
+
+ temp = 4;
+
+ gDPPipeSync(POLY_OPA_DISP++);
+
+ // draw file info box (large box when a file is selected)
+ for (fileIndex = 0; fileIndex < 3; fileIndex++, temp += 28) {
+ if (fileIndex < 2) {
+ gDPPipeSync(POLY_OPA_DISP++);
+ gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, this->windowColor[0], this->windowColor[1], this->windowColor[2],
+ this->fileInfoAlpha[fileIndex]);
+ gSPVertex(POLY_OPA_DISP++, &this->windowContentVtx[temp], 28, 0);
+
+ for (quadVtxIndex = 0, i = 0; i < 7; i++, quadVtxIndex += 4) {
+ if ((i < 5) || (this->isOwlSave[fileIndex + 2] && (i >= 5))) {
+ gDPLoadTextureBlock(POLY_OPA_DISP++, sFileInfoBoxTextures[i], G_IM_FMT_IA, G_IM_SIZ_16b,
+ sFileInfoBoxPartWidths[i], 56, 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);
+ gSP1Quadrangle(POLY_OPA_DISP++, quadVtxIndex, quadVtxIndex + 2, quadVtxIndex + 3, quadVtxIndex + 1,
+ 0);
+ }
+ }
+ }
+ }
+
+ gDPPipeSync(POLY_OPA_DISP++);
+
+ for (i = 0; i < 3; i++, temp += 16) {
+ if (i < 2) {
+ // draw file button
+ gSPVertex(POLY_OPA_DISP++, &this->windowContentVtx[temp], 16, 0);
+
+ gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, sWindowContentColors[0], sWindowContentColors[1],
+ sWindowContentColors[2], this->fileButtonAlpha[i]);
+ gDPLoadTextureBlock(POLY_OPA_DISP++, sFileButtonTextures[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,
+ G_TX_NOLOD, G_TX_NOLOD);
+ gSP1Quadrangle(POLY_OPA_DISP++, 0, 2, 3, 1, 0);
+
+ // draw file name box
+ gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, sWindowContentColors[0], sWindowContentColors[1],
+ sWindowContentColors[2], this->nameBoxAlpha[i]);
+ gDPLoadTextureBlock(POLY_OPA_DISP++, gFileSelFileNameBoxTex, 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_NOLOD);
+ gSP1Quadrangle(POLY_OPA_DISP++, 4, 6, 7, 5, 0);
+
+ gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, sWindowContentColors[0], sWindowContentColors[1],
+ sWindowContentColors[2], this->connectorAlpha[i]);
+ gDPLoadTextureBlock(POLY_OPA_DISP++, gFileSelConnectorTex, G_IM_FMT_IA, G_IM_SIZ_8b, 24, 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);
+ gSP1Quadrangle(POLY_OPA_DISP++, 8, 10, 11, 9, 0);
+
+ if (this->isOwlSave[i + 2]) {
+ gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, sWindowContentColors[0], sWindowContentColors[1],
+ sWindowContentColors[2], this->nameBoxAlpha[i]);
+ gDPLoadTextureBlock(POLY_OPA_DISP++, gFileSelBlankButtonTex, G_IM_FMT_IA, G_IM_SIZ_16b, 52, 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);
+ gSP1Quadrangle(POLY_OPA_DISP++, 12, 14, 15, 13, 0);
+ }
+ }
+ }
+
+ // draw file info
+ for (fileIndex = 0; fileIndex < 2; fileIndex++) {
+ FileSelect_DrawFileInfo(&this->state, fileIndex);
+ }
+
+ gDPPipeSync(POLY_OPA_DISP++);
+ gDPSetCombineLERP(POLY_OPA_DISP++, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0, PRIMITIVE,
+ ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0);
+ gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, 0);
+ gSPVertex(POLY_OPA_DISP++, &this->windowContentVtx[0x3AC], 20, 0);
+
+ // draw primary action buttons (copy/erase)
+ for (quadVtxIndex = 0, i = 0; i < 2; i++, quadVtxIndex += 4) {
+ gDPPipeSync(POLY_OPA_DISP++);
+ gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, this->windowColor[0], this->windowColor[1], this->windowColor[2],
+ this->actionButtonAlpha[i]);
+ gDPLoadTextureBlock(POLY_OPA_DISP++, sActionButtonTextures[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, G_TX_NOLOD,
+ G_TX_NOLOD);
+ gSP1Quadrangle(POLY_OPA_DISP++, quadVtxIndex, quadVtxIndex + 2, quadVtxIndex + 3, quadVtxIndex + 1, 0);
+ }
+
+ gDPPipeSync(POLY_OPA_DISP++);
+
+ // draw confirm buttons (yes/quit)
+ for (quadVtxIndex = 0, i = FS_BTN_CONFIRM_YES; i <= FS_BTN_CONFIRM_QUIT; i++, quadVtxIndex += 4) {
+ temp = this->confirmButtonTexIndices[i];
+ gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, this->windowColor[0], this->windowColor[1], this->windowColor[2],
+ this->confirmButtonAlpha[i]);
+ gDPLoadTextureBlock(POLY_OPA_DISP++, sActionButtonTextures[temp], 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, G_TX_NOLOD,
+ G_TX_NOLOD);
+ gSP1Quadrangle(POLY_OPA_DISP++, quadVtxIndex, quadVtxIndex + 2, quadVtxIndex + 3, quadVtxIndex + 1, 0);
+ }
+
+ // draw options button
+ gDPPipeSync(POLY_OPA_DISP++);
+ gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, this->windowColor[0], this->windowColor[1], this->windowColor[2],
+ this->optionButtonAlpha);
+ gDPLoadTextureBlock(POLY_OPA_DISP++, gFileSelOptionsButtonENGTex, 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, G_TX_NOLOD,
+ G_TX_NOLOD);
+ gSP1Quadrangle(POLY_OPA_DISP++, 8, 10, 11, 9, 0);
+
+ // draw highlight over currently selected button
+ if (((this->menuMode == FS_MENU_MODE_CONFIG) &&
+ ((this->configMode == CM_MAIN_MENU) || (this->configMode == CM_SELECT_COPY_SOURCE) ||
+ (this->configMode == CM_SELECT_COPY_DEST) || (this->configMode == CM_COPY_CONFIRM) ||
+ (this->configMode == CM_ERASE_SELECT) || (this->configMode == CM_ERASE_CONFIRM))) ||
+ ((this->menuMode == FS_MENU_MODE_SELECT) && (this->selectMode == SM_CONFIRM_FILE))) {
+ gDPPipeSync(POLY_OPA_DISP++);
+
+ gDPSetCombineLERP(POLY_OPA_DISP++, 1, 0, PRIMITIVE, 0, TEXEL0, 0, PRIMITIVE, 0, 1, 0, PRIMITIVE, 0, TEXEL0, 0,
+ PRIMITIVE, 0);
+ gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, this->highlightColor[0], this->highlightColor[1],
+ this->highlightColor[2], this->highlightColor[3]);
+ gDPLoadTextureBlock(POLY_OPA_DISP++, gFileSelBigButtonHighlightTex, G_IM_FMT_I, G_IM_SIZ_8b, 72, 24, 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);
+ gSP1Quadrangle(POLY_OPA_DISP++, 12, 14, 15, 13, 0);
+ }
+
+ // draw warning labels
+ if (this->warningLabel > FS_WARNING_NONE) {
+ gDPPipeSync(POLY_OPA_DISP++);
+
+ gDPSetCombineLERP(POLY_OPA_DISP++, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0,
+ PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0);
+ gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, this->emptyFileTextAlpha);
+ gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, 0);
+ gDPLoadTextureBlock(POLY_OPA_DISP++, sWarningLabels[this->warningLabel], G_IM_FMT_IA, G_IM_SIZ_8b, 128, 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);
+ gSP1Quadrangle(POLY_OPA_DISP++, 16, 18, 19, 17, 0);
+ }
+
+ gDPPipeSync(POLY_OPA_DISP++);
+
+ gDPSetCombineMode(POLY_OPA_DISP++, G_CC_MODULATEIDECALA, G_CC_MODULATEIDECALA);
+
+ CLOSE_DISPS(this->state.gfxCtx);
+}
+
+void FileSelect_ConfigModeDraw(GameState* thisx) {
+ FileSelectState* this = (FileSelectState*)thisx;
+
+ OPEN_DISPS(this->state.gfxCtx);
+
+ gDPPipeSync(POLY_OPA_DISP++);
+
+ Gfx_SetupDL42_Opa(this->state.gfxCtx);
+ FileSelect_SetView(this, 0.0f, 0.0f, 64.0f);
+ FileSelect_SetWindowVtx(&this->state);
+ FileSelect_SetWindowContentVtx(&this->state);
+
+ if ((this->configMode != CM_NAME_ENTRY) && (this->configMode != CM_START_NAME_ENTRY)) {
+ gDPPipeSync(POLY_OPA_DISP++);
+ gDPSetCombineMode(POLY_OPA_DISP++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM);
+
+ gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, this->windowColor[0], this->windowColor[1], this->windowColor[2],
+ this->windowAlpha);
+ gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, 0);
+
+ Matrix_Translate(0.0f, 0.0f, -93.6f, MTXMODE_NEW);
+ Matrix_Scale(0.78f, 0.78f, 0.78f, MTXMODE_APPLY);
+
+ if (this->windowRot != 0) {
+ Matrix_RotateXFApply(this->windowRot / 100.0f);
+ }
+
+ gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(this->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+
+ gSPVertex(POLY_OPA_DISP++, &this->windowVtx[0], 32, 0);
+ gSPDisplayList(POLY_OPA_DISP++, gFileSelWindow1DL);
+
+ gSPVertex(POLY_OPA_DISP++, &this->windowVtx[32], 32, 0);
+ gSPDisplayList(POLY_OPA_DISP++, gFileSelWindow2DL);
+
+ gSPVertex(POLY_OPA_DISP++, &this->windowVtx[64], 16, 0);
+ gSPDisplayList(POLY_OPA_DISP++, gFileSelWindow3DL);
+
+ gDPPipeSync(POLY_OPA_DISP++);
+
+ FileSelect_DrawWindowContents(&this->state);
+ }
+
+ // draw name entry menu
+ if ((this->configMode >= CM_ROTATE_TO_NAME_ENTRY) && (this->configMode <= CM_NAME_ENTRY_TO_MAIN)) {
+ gDPPipeSync(POLY_OPA_DISP++);
+ gDPSetCombineMode(POLY_OPA_DISP++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM);
+ gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, this->windowColor[0], this->windowColor[1], this->windowColor[2],
+ this->windowAlpha);
+ gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, 0);
+
+ Matrix_Translate(0.0f, 0.0f, -93.6f, MTXMODE_NEW);
+ Matrix_Scale(0.78f, 0.78f, 0.78f, MTXMODE_APPLY);
+ Matrix_RotateXFApply((this->windowRot - 314.0f) / 100.0f);
+
+ gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(this->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+
+ gSPVertex(POLY_OPA_DISP++, &this->windowVtx[0], 32, 0);
+ gSPDisplayList(POLY_OPA_DISP++, gFileSelWindow1DL);
+
+ gSPVertex(POLY_OPA_DISP++, &this->windowVtx[32], 32, 0);
+ gSPDisplayList(POLY_OPA_DISP++, gFileSelWindow2DL);
+
+ gSPVertex(POLY_OPA_DISP++, &this->windowVtx[64], 16, 0);
+ gSPDisplayList(POLY_OPA_DISP++, gFileSelWindow3DL);
+
+ gDPPipeSync(POLY_OPA_DISP++);
+
+ FileSelect_DrawNameEntry(&this->state);
+ }
+
+ // draw options menu
+ if ((this->configMode >= CM_MAIN_TO_OPTIONS) && (this->configMode <= CM_OPTIONS_TO_MAIN)) {
+ gDPPipeSync(POLY_OPA_DISP++);
+ gDPSetCombineMode(POLY_OPA_DISP++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM);
+ gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, this->windowColor[0], this->windowColor[1], this->windowColor[2],
+ this->windowAlpha);
+ gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, 0);
+
+ Matrix_Translate(0.0f, 0.0f, -93.6f, MTXMODE_NEW);
+ Matrix_Scale(0.78f, 0.78f, 0.78f, MTXMODE_APPLY);
+ Matrix_RotateXFApply((this->windowRot - 314.0f) / 100.0f);
+
+ gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(this->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+
+ gSPVertex(POLY_OPA_DISP++, &this->windowVtx[0], 32, 0);
+ gSPDisplayList(POLY_OPA_DISP++, gFileSelWindow1DL);
+
+ gSPVertex(POLY_OPA_DISP++, &this->windowVtx[32], 32, 0);
+ gSPDisplayList(POLY_OPA_DISP++, gFileSelWindow2DL);
+
+ gSPVertex(POLY_OPA_DISP++, &this->windowVtx[64], 16, 0);
+ gSPDisplayList(POLY_OPA_DISP++, gFileSelWindow3DL);
+
+ gDPPipeSync(POLY_OPA_DISP++);
+
+ FileSelect_DrawOptions(&this->state);
+ }
+
+ gDPPipeSync(POLY_OPA_DISP++);
+
+ FileSelect_SetView(this, 0.0f, 0.0f, 64.0f);
+
+ CLOSE_DISPS(this->state.gfxCtx);
+}
+
+/**
+ * Fade out the main menu elements to transition to select mode.
+ * Update function for `SM_FADE_MAIN_TO_SELECT`
+ */
+void FileSelect_FadeMainToSelect(GameState* thisx) {
+ FileSelectState* this = (FileSelectState*)thisx;
+ SramContext* sramCtx = &this->sramCtx;
+ s16 i;
+
+ for (i = 0; i < 3; i++) {
+ if (i != this->buttonIndex) {
+ this->fileButtonAlpha[i] -= 50;
+ this->actionButtonAlpha[FS_BTN_ACTION_COPY] = this->actionButtonAlpha[FS_BTN_ACTION_ERASE] =
+ this->optionButtonAlpha = this->fileButtonAlpha[i];
+
+ if (!gSaveContext.flashSaveAvailable) {
+ if (NO_FLASH_SLOT_OCCUPIED(sramCtx, i)) {
+ this->nameAlpha[i] = this->nameBoxAlpha[i] = this->fileButtonAlpha[i];
+ this->connectorAlpha[i] -= 255 / 4;
+ }
+ } else {
+ if (SLOT_OCCUPIED(this, i)) {
+ this->nameAlpha[i] = this->nameBoxAlpha[i] = this->fileButtonAlpha[i];
+ this->connectorAlpha[i] -= 255 / 4;
+ }
+ }
+ }
+ }
+
+ this->titleAlpha[FS_TITLE_CUR] -= 255 / 4;
+ this->titleAlpha[FS_TITLE_NEXT] += 255 / 4;
+ this->actionTimer--;
+
+ if (this->actionTimer == 0) {
+ this->actionTimer = 4;
+ this->selectMode++; // SM_MOVE_FILE_TO_TOP
+ this->confirmButtonIndex = FS_BTN_CONFIRM_YES;
+ }
+}
+
+// Amount to move by to reach the top of the screen
+s16 sFileYOffsets[] = { 0, 16, 32 };
+
+/**
+ * Moves the selected file to the top of the window.
+ * Update function for `SM_MOVE_FILE_TO_TOP`
+ */
+void FileSelect_MoveSelectedFileToTop(GameState* thisx) {
+ FileSelectState* this = (FileSelectState*)thisx;
+ s32 yStep;
+
+ yStep = ABS_ALT(this->buttonYOffsets[this->buttonIndex] - sFileYOffsets[this->buttonIndex]) / this->actionTimer;
+ this->buttonYOffsets[this->buttonIndex] += yStep;
+ this->actionTimer--;
+
+ if ((this->actionTimer == 0) || (this->buttonYOffsets[this->buttonIndex] == sFileYOffsets[this->buttonIndex])) {
+ this->buttonYOffsets[FS_BTN_SELECT_YES] = this->buttonYOffsets[FS_BTN_SELECT_QUIT] = -24;
+ this->actionTimer = 4;
+ this->selectMode++; // SM_FADE_IN_FILE_INFO
+ }
+}
+
+/**
+ * Fade in the file info for the selected file.
+ * Update function for `SM_FADE_IN_FILE_INFO`
+ */
+void FileSelect_FadeInFileInfo(GameState* thisx) {
+ FileSelectState* this = (FileSelectState*)thisx;
+
+ this->fileInfoAlpha[this->buttonIndex] += 50;
+ this->nameBoxAlpha[this->buttonIndex] -= 100;
+
+ if (this->nameBoxAlpha[this->buttonIndex] <= 0) {
+ this->nameBoxAlpha[this->buttonIndex] = 0;
+ }
+
+ this->actionTimer--;
+
+ if (this->actionTimer == 0) {
+ this->fileInfoAlpha[this->buttonIndex] = 200;
+ this->actionTimer = 4;
+ this->selectMode++; // SM_CONFIRM_FILE
+ }
+
+ this->confirmButtonAlpha[FS_BTN_CONFIRM_YES] = this->confirmButtonAlpha[FS_BTN_CONFIRM_QUIT] =
+ this->fileInfoAlpha[this->buttonIndex];
+}
+
+/**
+ * Update the cursor and handle the option that the player picks for confirming the selected file.
+ * Update function for `SM_CONFIRM_FILE`
+ */
+void FileSelect_ConfirmFile(GameState* thisx) {
+ FileSelectState* this = (FileSelectState*)thisx;
+ Input* input = CONTROLLER1(&this->state);
+
+ if (CHECK_BTN_ALL(input->press.button, BTN_START) || (CHECK_BTN_ALL(input->press.button, BTN_A))) {
+ if (this->confirmButtonIndex == FS_BTN_CONFIRM_YES) {
+ Rumble_Request(300.0f, 180, 20, 100);
+ play_sound(NA_SE_SY_FSEL_DECIDE_L);
+ this->selectMode = SM_FADE_OUT;
+ func_801A4058(0xF);
+ } else { // FS_BTN_CONFIRM_QUIT
+ play_sound(NA_SE_SY_FSEL_CLOSE);
+ this->selectMode++; // SM_FADE_OUT_FILE_INFO
+ }
+ } else if (CHECK_BTN_ALL(input->press.button, BTN_B)) {
+ play_sound(NA_SE_SY_FSEL_CLOSE);
+ this->selectMode++; // SM_FADE_OUT_FILE_INFO
+ } else if (ABS_ALT(this->stickAdjY) >= 30) {
+ play_sound(NA_SE_SY_FSEL_CURSOR);
+ this->confirmButtonIndex ^= 1;
+ }
+}
+
+/**
+ * Fade out the file info for the selected file before returning to the main menu.
+ * Update function for `SM_FADE_OUT_FILE_INFO`
+ */
+void FileSelect_FadeOutFileInfo(GameState* thisx) {
+ FileSelectState* this = (FileSelectState*)thisx;
+
+ this->fileInfoAlpha[this->buttonIndex] -= 200 / 4;
+ this->nameBoxAlpha[this->buttonIndex] += 200 / 4;
+ this->actionTimer--;
+
+ if (this->actionTimer == 0) {
+ this->buttonYOffsets[FS_BTN_SELECT_YES] = this->buttonYOffsets[FS_BTN_SELECT_QUIT] = 0;
+ this->nameBoxAlpha[this->buttonIndex] = 200;
+ this->fileInfoAlpha[this->buttonIndex] = 0;
+ this->nextTitleLabel = FS_TITLE_SELECT_FILE;
+ this->actionTimer = 4;
+ this->selectMode++;
+ }
+
+ this->confirmButtonAlpha[FS_BTN_CONFIRM_YES] = this->confirmButtonAlpha[FS_BTN_CONFIRM_QUIT] =
+ this->fileInfoAlpha[this->buttonIndex];
+}
+
+/**
+ * Move the selected file back to the slot position then go to config mode for the main menu.
+ * Update function for `SM_MOVE_FILE_TO_SLOT`
+ */
+void FileSelect_MoveSelectedFileToSlot(GameState* thisx) {
+ FileSelectState* this = (FileSelectState*)thisx;
+ SramContext* sramCtx = &this->sramCtx;
+ s32 yStep;
+ s16 i;
+
+ yStep = ABS_ALT(this->buttonYOffsets[this->buttonIndex]) / this->actionTimer;
+ this->buttonYOffsets[this->buttonIndex] -= yStep;
+
+ if (this->buttonYOffsets[this->buttonIndex] <= 0) {
+ this->buttonYOffsets[this->buttonIndex] = 0;
+ }
+
+ for (i = 0; i < 3; i++) {
+ if (i != this->buttonIndex) {
+ this->fileButtonAlpha[i] += 200 / 4;
+
+ if (this->fileButtonAlpha[i] >= 200) {
+ this->fileButtonAlpha[i] = 200;
+ }
+
+ this->actionButtonAlpha[FS_BTN_ACTION_COPY] = this->actionButtonAlpha[FS_BTN_ACTION_ERASE] =
+ this->optionButtonAlpha = this->fileButtonAlpha[i];
+
+ if (!gSaveContext.flashSaveAvailable) {
+ if (NO_FLASH_SLOT_OCCUPIED(sramCtx, i)) {
+ this->nameBoxAlpha[i] = this->nameAlpha[i] = this->fileButtonAlpha[i];
+ this->connectorAlpha[i] += 255 / 4;
+ }
+ } else {
+ if (SLOT_OCCUPIED(this, i)) {
+ this->nameBoxAlpha[i] = this->nameAlpha[i] = this->fileButtonAlpha[i];
+ this->connectorAlpha[i] += 255 / 4;
+ }
+ }
+ }
+ }
+
+ this->titleAlpha[FS_TITLE_CUR] -= 255 / 4;
+ this->titleAlpha[FS_TITLE_NEXT] += 255 / 4;
+ this->actionTimer--;
+
+ if (this->actionTimer == 0) {
+ this->titleAlpha[FS_TITLE_CUR] = 255;
+ this->titleAlpha[FS_TITLE_NEXT] = 0;
+ this->titleLabel = this->nextTitleLabel;
+ this->actionTimer = 4;
+ this->menuMode = FS_MENU_MODE_CONFIG;
+ this->configMode = CM_MAIN_MENU;
+ this->nextConfigMode = CM_MAIN_MENU;
+ this->selectMode = SM_FADE_MAIN_TO_SELECT;
+ }
+}
+
+/**
+ * Fill the screen with black to fade out.
+ * Update function for `SM_FADE_OUT`
+ */
+void FileSelect_FadeOut(GameState* thisx) {
+ FileSelectState* this = (FileSelectState*)thisx;
+
+ this->screenFillAlpha += 40;
+
+ if (this->screenFillAlpha >= 255) {
+ this->screenFillAlpha = 255;
+ this->selectMode++; // SM_LOAD_GAME
+ }
+}
+
+/**
+ * Load the save for the appropriate file and start the game.
+ * Update function for `SM_LOAD_GAME`
+ */
+void FileSelect_LoadGame(GameState* thisx) {
+ FileSelectState* this = (FileSelectState*)thisx;
+ u16 i;
+
+ gSaveContext.fileNum = this->buttonIndex;
+ Sram_OpenSave(this, &this->sramCtx);
+
+ gSaveContext.gameMode = GAMEMODE_NORMAL;
+
+ STOP_GAMESTATE(&this->state);
+ SET_NEXT_GAMESTATE(&this->state, Play_Init, sizeof(PlayState));
+
+ gSaveContext.respawnFlag = 0;
+ gSaveContext.respawn[RESPAWN_MODE_DOWN].entrance = ENTR_LOAD_OPENING;
+ gSaveContext.seqId = (u8)NA_BGM_DISABLED;
+ gSaveContext.ambienceId = AMBIENCE_ID_DISABLED;
+ gSaveContext.showTitleCard = true;
+ gSaveContext.dogParams = 0;
+
+ for (i = 0; i < TIMER_ID_MAX; i++) {
+ gSaveContext.timerStates[i] = TIMER_STATE_OFF;
+ }
+
+ gSaveContext.prevHudVisibility = HUD_VISIBILITY_ALL;
+ gSaveContext.nayrusLoveTimer = 0;
+ gSaveContext.healthAccumulator = 0;
+ gSaveContext.magicFlag = 0;
+ gSaveContext.forcedSeqId = 0;
+ gSaveContext.skyboxTime = CLOCK_TIME(0, 0);
+ gSaveContext.nextTransitionType = TRANS_NEXT_TYPE_DEFAULT;
+ gSaveContext.cutsceneTrigger = 0;
+ gSaveContext.chamberCutsceneNum = 0;
+ gSaveContext.nextDayTime = 0xFFFF;
+ gSaveContext.retainWeatherMode = false;
+
+ gSaveContext.buttonStatus[EQUIP_SLOT_B] = BTN_ENABLED;
+ gSaveContext.buttonStatus[EQUIP_SLOT_C_LEFT] = BTN_ENABLED;
+ gSaveContext.buttonStatus[EQUIP_SLOT_C_DOWN] = BTN_ENABLED;
+ gSaveContext.buttonStatus[EQUIP_SLOT_C_RIGHT] = BTN_ENABLED;
+ gSaveContext.buttonStatus[EQUIP_SLOT_A] = BTN_ENABLED;
+
+ gSaveContext.hudVisibilityForceButtonAlphasByStatus = false;
+ gSaveContext.nextHudVisibility = HUD_VISIBILITY_IDLE;
+ gSaveContext.hudVisibility = HUD_VISIBILITY_IDLE;
+ gSaveContext.hudVisibilityTimer = 0;
+
+ gSaveContext.save.saveInfo.playerData.tatlTimer = 0;
+}
+
+void (*sSelectModeUpdateFuncs[])(GameState*) = {
+ FileSelect_FadeMainToSelect, // SM_FADE_MAIN_TO_SELECT
+ FileSelect_MoveSelectedFileToTop, // SM_MOVE_FILE_TO_TOP
+ FileSelect_FadeInFileInfo, // SM_FADE_IN_FILE_INFO
+ FileSelect_ConfirmFile, // SM_CONFIRM_FILE
+ FileSelect_FadeOutFileInfo, // SM_FADE_OUT_FILE_INFO
+ FileSelect_MoveSelectedFileToSlot, // SM_MOVE_FILE_TO_SLOT
+ FileSelect_FadeOut, // SM_FADE_OUT
+ FileSelect_LoadGame, // SM_LOAD_GAME
+};
+
+void FileSelect_SelectModeUpdate(GameState* thisx) {
+ FileSelectState* this = (FileSelectState*)thisx;
+
+ sSelectModeUpdateFuncs[this->selectMode](&this->state);
+}
+
+void FileSelect_SelectModeDraw(GameState* thisx) {
+ FileSelectState* this = (FileSelectState*)thisx;
+
+ OPEN_DISPS(this->state.gfxCtx);
+
+ gDPPipeSync(POLY_OPA_DISP++);
+
+ Gfx_SetupDL42_Opa(this->state.gfxCtx);
+ FileSelect_SetView(this, 0.0f, 0.0f, 64.0f);
+ FileSelect_SetWindowVtx(&this->state);
+ FileSelect_SetWindowContentVtx(&this->state);
+
+ gDPSetCombineMode(POLY_OPA_DISP++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM);
+ gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, this->windowColor[0], this->windowColor[1], this->windowColor[2],
+ this->windowAlpha);
+ gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, 0);
+
+ Matrix_Translate(0.0f, 0.0f, -93.6f, MTXMODE_NEW);
+ Matrix_Scale(0.78f, 0.78f, 0.78f, MTXMODE_APPLY);
+ Matrix_RotateXFApply(this->windowRot / 100.0f);
+ gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(this->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+
+ gSPVertex(POLY_OPA_DISP++, &this->windowVtx[0], 32, 0);
+ gSPDisplayList(POLY_OPA_DISP++, gFileSelWindow1DL);
+
+ gSPVertex(POLY_OPA_DISP++, &this->windowVtx[32], 32, 0);
+ gSPDisplayList(POLY_OPA_DISP++, gFileSelWindow2DL);
+
+ gSPVertex(POLY_OPA_DISP++, &this->windowVtx[64], 16, 0);
+ gSPDisplayList(POLY_OPA_DISP++, gFileSelWindow3DL);
+
+ FileSelect_DrawWindowContents(&this->state);
+ gDPPipeSync(POLY_OPA_DISP++);
+ FileSelect_SetView(this, 0.0f, 0.0f, 64.0f);
+
+ CLOSE_DISPS(this->state.gfxCtx);
+}
+
+void FileSelect_UpdateAndDrawSkybox(FileSelectState* this) {
+ s32 pad;
+ f32 eyeX;
+ f32 eyeY;
+ f32 eyeZ;
+
+ OPEN_DISPS(this->state.gfxCtx);
+
+ gDPPipeSync(POLY_OPA_DISP++);
+
+ eyeX = 1000.0f * Math_CosS(sFileSelectSkyboxRotation) - 1000.0f * Math_SinS(sFileSelectSkyboxRotation);
+ eyeY = -700.0f;
+ eyeZ = 1000.0f * Math_SinS(sFileSelectSkyboxRotation) + 1000.0f * Math_CosS(sFileSelectSkyboxRotation);
+
+ FileSelect_SetView(this, eyeX, eyeY, eyeZ);
+ Skybox_Draw(&this->skyboxCtx, this->state.gfxCtx, SKYBOX_NORMAL_SKY, this->envCtx.skyboxBlend, eyeX, eyeY, eyeZ);
+
+ gDPSetTextureLUT(POLY_OPA_DISP++, G_TT_NONE);
+
+ sFileSelectSkyboxRotation += -0xA;
+
+ CLOSE_DISPS(this->state.gfxCtx);
+}
+
+void (*gFileSelectDrawFuncs[])(GameState*) = {
+ FileSelect_InitModeDraw, // FS_MENU_MODE_INIT
+ FileSelect_ConfigModeDraw, // FS_MENU_MODE_CONFIG
+ FileSelect_SelectModeDraw, // FS_MENU_MODE_SELECT
+};
+void (*gFileSelectUpdateFuncs[])(GameState*) = {
+ FileSelect_InitModeUpdate, // FS_MENU_MODE_INIT
+ FileSelect_ConfigModeUpdate, // FS_MENU_MODE_CONFIG
+ FileSelect_SelectModeUpdate, // FS_MENU_MODE_SELECT
+};
+
+TexturePtr D_808147B4[] = { gFileSelPleaseWaitENGTex, gFileSelDecideCancelENGTex, gFileSelDecideSaveENGTex };
+s16 D_808147C0[] = { 144, 144, 152 };
+s16 D_808147C8[] = { 90, 90, 86 };
+
+void FileSelect_Main(GameState* thisx) {
+ FileSelectState* this = (FileSelectState*)thisx;
+ Input* input = CONTROLLER1(&this->state);
+ s32 texIndex;
+ s32 pad;
+
+ func_8012CF0C(this->state.gfxCtx, 0, 1, 0, 0, 0);
+
+ OPEN_DISPS(this->state.gfxCtx);
+
+ gSPSegment(POLY_OPA_DISP++, 0x01, this->staticSegment);
+ gSPSegment(POLY_OPA_DISP++, 0x02, this->parameterSegment);
+ gSPSegment(POLY_OPA_DISP++, 0x06, this->titleSegment);
+
+ this->stickAdjX = input->rel.stick_x;
+ this->stickAdjY = input->rel.stick_y;
+
+ if (this->stickAdjX < -30) {
+ if (this->stickXDir == -1) {
+ this->inputTimerX--;
+ if (this->inputTimerX < 0) {
+ this->inputTimerX = 2;
+ } else {
+ this->stickAdjX = 0;
+ }
+ } else {
+ this->inputTimerX = 10;
+ this->stickXDir = -1;
+ }
+ } else if (this->stickAdjX > 30) {
+ if (this->stickXDir == 1) {
+ this->inputTimerX--;
+ if (this->inputTimerX < 0) {
+ this->inputTimerX = 2;
+ } else {
+ this->stickAdjX = 0;
+ }
+ } else {
+ this->inputTimerX = 10;
+ this->stickXDir = 1;
+ }
+ } else {
+ this->stickXDir = 0;
+ }
+
+ if (this->stickAdjY < -30) {
+ if (this->stickYDir == -1) {
+ this->inputTimerY--;
+ if (this->inputTimerY < 0) {
+ this->inputTimerY = 2;
+ } else {
+ this->stickAdjY = 0;
+ }
+ } else {
+ this->inputTimerY = 10;
+ this->stickYDir = -1;
+ }
+ } else if (this->stickAdjY > 30) {
+ if (this->stickYDir == 1) {
+ this->inputTimerY--;
+ if (this->inputTimerY < 0) {
+ this->inputTimerY = 2;
+ } else {
+ this->stickAdjY = 0;
+ }
+ } else {
+ this->inputTimerY = 10;
+ this->stickYDir = 1;
+ }
+ } else {
+ this->stickYDir = 0;
+ }
+
+ this->emptyFileTextAlpha = 0;
+
+ FileSelect_PulsateCursor(&this->state);
+ gFileSelectUpdateFuncs[this->menuMode](&this->state);
+ FileSelect_UpdateAndDrawSkybox(this);
+ gFileSelectDrawFuncs[this->menuMode](&this->state);
+
+ Gfx_SetupDL39_Opa(this->state.gfxCtx);
+
+ gDPSetCombineLERP(POLY_OPA_DISP++, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0, PRIMITIVE,
+ ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0);
+ gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 100, 255, 255, this->controlsAlpha);
+ gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, 0);
+
+ if (this->sramCtx.status > 0) {
+ texIndex = 0;
+ } else if ((this->configMode >= CM_MAIN_TO_OPTIONS) && (this->configMode <= CM_OPTIONS_TO_MAIN)) {
+ texIndex = 2;
+ } else {
+ texIndex = 1;
+ }
+
+ gDPLoadTextureBlock(POLY_OPA_DISP++, D_808147B4[texIndex], G_IM_FMT_IA, G_IM_SIZ_8b, D_808147C0[texIndex], 16, 0,
+ G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK,
+ G_TX_NOLOD);
+
+ gSPTextureRectangle(POLY_OPA_DISP++, D_808147C8[texIndex] << 2, 204 << 2,
+ (D_808147C8[texIndex] + D_808147C0[texIndex]) << 2, (204 + 16) << 2, G_TX_RENDERTILE, 0, 0,
+ 1 << 10, 1 << 10);
+
+ gDPPipeSync(POLY_OPA_DISP++);
+ gSPDisplayList(POLY_OPA_DISP++, sScreenFillSetupDL);
+ gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 0, 0, 0, this->screenFillAlpha);
+ gSPDisplayList(POLY_OPA_DISP++, D_0E000000.fillRect);
+
+ CLOSE_DISPS(this->state.gfxCtx);
+}
+
+void FileSelect_InitContext(GameState* thisx) {
+ FileSelectState* this = (FileSelectState*)thisx;
+ EnvironmentContext* envCtx = &this->envCtx;
+
+ Sram_Alloc(&this->state, &this->sramCtx);
+ func_801457CC(&this->state, &this->sramCtx);
+
+ this->menuMode = FS_MENU_MODE_INIT;
+
+ this->buttonIndex = this->selectMode = this->selectedFileIndex = this->copyDestFileIndex =
+ this->confirmButtonIndex = 0;
+
+ this->confirmButtonTexIndices[0] = 2;
+ this->confirmButtonTexIndices[1] = 3;
+ this->titleLabel = FS_TITLE_SELECT_FILE;
+ this->nextTitleLabel = FS_TITLE_OPEN_FILE;
+
+ this->screenFillAlpha = 255;
+ this->highlightPulseDir = 1;
+ this->unk_244F4 = 0xC;
+ this->highlightColor[0] = 155;
+ this->highlightColor[1] = 255;
+ this->highlightColor[2] = 255;
+ this->highlightColor[3] = 70;
+ this->configMode = CM_FADE_IN_START;
+ this->windowRot = 0.0f;
+
+ this->stickXDir = this->inputTimerX = 0;
+ this->stickYDir = this->inputTimerY = 0;
+
+ this->kbdX = this->kbdY = this->charIndex = 0;
+
+ this->kbdButton = FS_KBD_BTN_NONE;
+
+ this->windowColor[0] = 100;
+ this->windowColor[1] = 150;
+ this->windowColor[2] = 255;
+
+ this->windowAlpha = this->titleAlpha[FS_TITLE_CUR] = this->titleAlpha[FS_TITLE_NEXT] = this->fileButtonAlpha[0] =
+ this->fileButtonAlpha[1] = this->fileButtonAlpha[2] = this->nameBoxAlpha[0] = this->nameBoxAlpha[1] =
+ this->nameBoxAlpha[2] = this->nameAlpha[0] = this->nameAlpha[1] = this->nameAlpha[2] =
+ this->connectorAlpha[0] = this->connectorAlpha[1] = this->connectorAlpha[2] = this->fileInfoAlpha[0] =
+ this->fileInfoAlpha[1] = this->fileInfoAlpha[2] = this->actionButtonAlpha[FS_BTN_ACTION_COPY] =
+ this->actionButtonAlpha[FS_BTN_ACTION_ERASE] = this->actionButtonAlpha[2] =
+ this->actionButtonAlpha[3] = this->optionButtonAlpha = this->nameEntryBoxAlpha =
+ this->controlsAlpha = this->emptyFileTextAlpha = 0;
+
+ this->windowPosX = 6;
+ this->actionTimer = 4;
+ this->warningLabel = FS_WARNING_NONE;
+
+ this->warningButtonIndex = this->buttonYOffsets[0] = this->buttonYOffsets[1] = this->buttonYOffsets[2] =
+ this->buttonYOffsets[3] = this->buttonYOffsets[4] = this->buttonYOffsets[5] = this->fileNamesY[0] =
+ this->fileNamesY[1] = this->fileNamesY[2] = 0;
+
+ this->unk_2451E[0] = 0;
+ this->unk_2451E[1] = 3;
+ this->unk_2451E[2] = 6;
+ this->unk_2451E[3] = 8;
+ this->unk_2451E[4] = 10;
+ this->highlightTimer = 20;
+
+ ShrinkWindow_Letterbox_SetSizeTarget(0);
+
+ gSaveContext.skyboxTime = 0;
+ gSaveContext.save.time = 0;
+
+ Skybox_Init(&this->state, &this->skyboxCtx, 1);
+ R_TIME_SPEED = 10;
+
+ envCtx->changeSkyboxState = 0;
+ envCtx->changeSkyboxTimer = 0;
+ envCtx->changeLightEnabled = false;
+ envCtx->changeLightTimer = 0;
+ envCtx->skyboxDmaState = 0;
+ envCtx->skybox1Index = 99;
+ envCtx->skybox2Index = 99;
+ envCtx->lightConfig = 0;
+ envCtx->changeLightNextConfig = 0;
+ envCtx->lightSetting = 0;
+ envCtx->skyboxConfig = 2;
+ envCtx->skyboxDisabled = 0;
+ envCtx->skyboxBlend = 0;
+ envCtx->glareAlpha = 0.0f;
+ envCtx->lensFlareAlphaScale = 0.0f;
+
+ gSaveContext.buttonStatus[EQUIP_SLOT_B] = BTN_ENABLED;
+ gSaveContext.buttonStatus[EQUIP_SLOT_C_LEFT] = BTN_ENABLED;
+ gSaveContext.buttonStatus[EQUIP_SLOT_C_DOWN] = BTN_ENABLED;
+ gSaveContext.buttonStatus[EQUIP_SLOT_C_RIGHT] = BTN_ENABLED;
+ gSaveContext.buttonStatus[EQUIP_SLOT_A] = BTN_ENABLED;
+}
+
+void FileSelect_Destroy(GameState* this) {
+ ShrinkWindow_Destroy();
+}
+
+void FileSelect_Init(GameState* thisx) {
+ s32 pad;
+ FileSelectState* this = (FileSelectState*)thisx;
+ size_t size;
+
+ Game_SetFramerateDivisor(&this->state, 1);
+ Matrix_Init(&this->state);
+ ShrinkWindow_Init();
+ View_Init(&this->view, this->state.gfxCtx);
+ this->state.main = FileSelect_Main;
+ this->state.destroy = FileSelect_Destroy;
+ FileSelect_InitContext(&this->state);
+ Font_LoadOrderedFont(&this->font);
+
+ size = SEGMENT_ROM_SIZE(title_static);
+ this->staticSegment = THA_AllocTailAlign16(&this->state.heap, size);
+ DmaMgr_SendRequest0(this->staticSegment, SEGMENT_ROM_START(title_static), size);
+
+ size = SEGMENT_ROM_SIZE(parameter_static);
+ this->parameterSegment = THA_AllocTailAlign16(&this->state.heap, size);
+ DmaMgr_SendRequest0(this->parameterSegment, SEGMENT_ROM_START(parameter_static), size);
+
+ size = gObjectTable[OBJECT_MAG].vromEnd - gObjectTable[OBJECT_MAG].vromStart;
+ this->titleSegment = THA_AllocTailAlign16(&this->state.heap, size);
+ DmaMgr_SendRequest0(this->titleSegment, gObjectTable[OBJECT_MAG].vromStart, size);
+
+ Audio_SetSpec(0xA);
+ // Setting ioData to 1 and writing it to ioPort 7 will skip the harp intro
+ Audio_PlaySequenceWithSeqPlayerIO(SEQ_PLAYER_BGM_MAIN, NA_BGM_FILE_SELECT, 0, 7, 1);
+}
diff --git a/src/overlays/gamestates/ovl_file_choose/z_file_copy_erase.c b/src/overlays/gamestates/ovl_file_choose/z_file_copy_erase.c
new file mode 100644
index 0000000000..7f8e5789c1
--- /dev/null
+++ b/src/overlays/gamestates/ovl_file_choose/z_file_copy_erase.c
@@ -0,0 +1,1253 @@
+/*
+ * File: z_file_copy_erase.c
+ * Overlay: ovl_file_choose
+ * Description: Copying and Erasing Files
+ */
+
+#include "z_file_select.h"
+#include "z64rumble.h"
+
+// When choosing a file to copy or erase, the 6 main menu buttons are placed at these offsets
+s16 sChooseFileYOffsets[] = { -48, -48, -48, -24, -24, 0 };
+
+s16 D_8081424C[3][3] = {
+ { 0, -48, -48 },
+ { -64, 16, -48 },
+ { -64, -64, 32 },
+};
+
+s16 sEraseDelayTimer = 15;
+
+/**
+ * Move buttons into place for the select source screen and fade in the proper labels.
+ * Update function for `CM_SETUP_COPY_SOURCE`
+ */
+void FileSelect_SetupCopySource(GameState* thisx) {
+ FileSelectState* this = (FileSelectState*)thisx;
+ s32 yStep;
+ s16 i;
+
+ for (i = 0; i < 5; i++) {
+ yStep = ABS_ALT(this->buttonYOffsets[i] - sChooseFileYOffsets[i]) / this->actionTimer;
+
+ if (this->buttonYOffsets[i] >= sChooseFileYOffsets[i]) {
+ this->buttonYOffsets[i] -= yStep;
+ } else {
+ this->buttonYOffsets[i] += yStep;
+ }
+ }
+
+ this->actionButtonAlpha[FS_BTN_ACTION_COPY] -= 200 / 4;
+ this->actionButtonAlpha[FS_BTN_ACTION_ERASE] -= 200 / 4;
+ this->optionButtonAlpha -= 200 / 4;
+ this->confirmButtonAlpha[FS_BTN_CONFIRM_QUIT] += 200 / 4;
+ this->titleAlpha[FS_TITLE_CUR] -= 255 / 4;
+ this->titleAlpha[FS_TITLE_NEXT] += 255 / 4;
+ this->actionTimer--;
+
+ if (this->actionTimer == 0) {
+ this->actionTimer = 4;
+
+ this->actionButtonAlpha[FS_BTN_ACTION_COPY] = this->actionButtonAlpha[FS_BTN_ACTION_ERASE] =
+ this->optionButtonAlpha = 0;
+
+ this->confirmButtonAlpha[FS_BTN_CONFIRM_QUIT] = 200;
+ this->titleLabel = this->nextTitleLabel;
+
+ this->titleAlpha[FS_TITLE_CUR] = 255;
+ this->titleAlpha[FS_TITLE_NEXT] = 0;
+ this->buttonIndex = FS_BTN_COPY_QUIT;
+ this->configMode++; // CM_SELECT_COPY_SOURCE
+ }
+}
+
+/**
+ * Allow the player to select a file to copy or exit back to the main menu.
+ * Update function for `CM_SELECT_COPY_SOURCE`
+ */
+void FileSelect_SelectCopySource(GameState* thisx) {
+ FileSelectState* this = (FileSelectState*)thisx;
+ SramContext* sramCtx = &this->sramCtx;
+ Input* input = CONTROLLER1(&this->state);
+
+ if (((this->buttonIndex == FS_BTN_COPY_QUIT) && CHECK_BTN_ANY(input->press.button, BTN_A | BTN_START)) ||
+ CHECK_BTN_ALL(input->press.button, BTN_B)) {
+ this->actionTimer = 4;
+ this->buttonIndex = FS_BTN_MAIN_COPY;
+ this->nextTitleLabel = FS_TITLE_SELECT_FILE;
+ this->configMode = CM_COPY_RETURN_MAIN;
+ this->warningLabel = FS_WARNING_NONE;
+ play_sound(NA_SE_SY_FSEL_CLOSE);
+ } else if (CHECK_BTN_ANY(input->press.button, BTN_A | BTN_START)) {
+ if (!gSaveContext.flashSaveAvailable) {
+ if (NO_FLASH_SLOT_OCCUPIED(sramCtx, this->buttonIndex)) {
+ this->actionTimer = 4;
+ this->selectedFileIndex = this->buttonIndex;
+ this->configMode = CM_SETUP_COPY_DEST_1;
+ this->nextTitleLabel = FS_TITLE_COPY_TO;
+ play_sound(NA_SE_SY_FSEL_DECIDE_L);
+ } else {
+ play_sound(NA_SE_SY_FSEL_ERROR);
+ }
+ } else if (SLOT_OCCUPIED(this, this->buttonIndex)) {
+ this->actionTimer = 4;
+ this->selectedFileIndex = this->buttonIndex;
+ this->configMode = CM_SETUP_COPY_DEST_1;
+ this->nextTitleLabel = FS_TITLE_COPY_TO;
+ play_sound(NA_SE_SY_FSEL_DECIDE_L);
+ } else {
+ play_sound(NA_SE_SY_FSEL_ERROR);
+ }
+ } else {
+ if (ABS_ALT(this->stickAdjY) >= 30) {
+ play_sound(NA_SE_SY_FSEL_CURSOR);
+ if (this->stickAdjY >= 30) {
+ this->buttonIndex--;
+ // Instead of removing File 3 entirely, the index is manually adjusted to skip it
+ if (this->buttonIndex == FS_BTN_COPY_FILE_3) {
+ this->buttonIndex = FS_BTN_COPY_FILE_2;
+ }
+ if (this->buttonIndex < FS_BTN_COPY_FILE_1) {
+ this->buttonIndex = FS_BTN_COPY_QUIT;
+ }
+ } else {
+ this->buttonIndex++;
+ // Instead of removing File 3 entirely, the index is manually adjusted to skip it
+ if (this->buttonIndex == FS_BTN_COPY_FILE_3) {
+ this->buttonIndex = FS_BTN_COPY_QUIT;
+ }
+ if (this->buttonIndex > FS_BTN_COPY_QUIT) {
+ this->buttonIndex = FS_BTN_COPY_FILE_1;
+ }
+ }
+ }
+
+ if (this->buttonIndex != FS_BTN_COPY_QUIT) {
+ if (!gSaveContext.flashSaveAvailable) {
+ if (!NO_FLASH_SLOT_OCCUPIED(sramCtx, this->buttonIndex)) {
+ this->warningLabel = FS_WARNING_FILE_EMPTY;
+ this->warningButtonIndex = this->buttonIndex;
+ this->emptyFileTextAlpha = 255;
+ } else {
+ this->warningLabel = FS_WARNING_NONE;
+ }
+ } else if (!SLOT_OCCUPIED(this, this->buttonIndex)) {
+ this->warningLabel = FS_WARNING_FILE_EMPTY;
+ this->warningButtonIndex = this->buttonIndex;
+ this->emptyFileTextAlpha = 255;
+ } else {
+ this->warningLabel = FS_WARNING_NONE;
+ }
+ }
+ }
+}
+
+/**
+ * Move the menu buttons into place for the copy destination selection and switch titles.
+ * Update function for `CM_SETUP_COPY_DEST_1`
+ */
+void FileSelect_SetupCopyDest1(GameState* thisx) {
+ FileSelectState* this = (FileSelectState*)thisx;
+ s32 yStep;
+ s16 i;
+
+ for (i = 0; i < 3; i++) {
+ yStep = ABS_ALT(this->buttonYOffsets[i] - D_8081424C[this->buttonIndex][i]) / this->actionTimer;
+
+ if (D_8081424C[this->buttonIndex][i] >= this->buttonYOffsets[i]) {
+ this->buttonYOffsets[i] += yStep;
+ } else {
+ this->buttonYOffsets[i] -= yStep;
+ }
+ }
+
+ this->titleAlpha[FS_TITLE_CUR] -= 255 / 4;
+ this->titleAlpha[FS_TITLE_NEXT] += 255 / 4;
+ this->nameBoxAlpha[this->buttonIndex] -= 200 / 4;
+
+ this->actionTimer--;
+ if (this->actionTimer == 0) {
+ this->buttonYOffsets[this->buttonIndex] = D_8081424C[this->buttonIndex][this->buttonIndex];
+ this->titleLabel = this->nextTitleLabel;
+ this->titleAlpha[FS_TITLE_CUR] = 255;
+ this->titleAlpha[FS_TITLE_NEXT] = 0;
+ this->actionTimer = 4;
+ this->configMode++; // CM_SETUP_COPY_DEST_2
+ }
+}
+
+/**
+ * Show the file info of the file selected to copy from.
+ * Update function for `CM_SETUP_COPY_DEST_2`
+ */
+void FileSelect_SetupCopyDest2(GameState* thisx) {
+ FileSelectState* this = (FileSelectState*)thisx;
+
+ this->nameBoxAlpha[this->buttonIndex] -= 200 / 4;
+ this->fileInfoAlpha[this->buttonIndex] += 200 / 4;
+ this->actionTimer--;
+
+ if (this->actionTimer == 0) {
+ this->nameBoxAlpha[this->buttonIndex] = 0;
+ this->fileInfoAlpha[this->buttonIndex] = 200;
+ this->buttonIndex = FS_BTN_COPY_QUIT;
+ this->actionTimer = 4;
+ this->configMode = CM_SELECT_COPY_DEST;
+ }
+}
+
+/**
+ * Allow the player to select a slot to copy to or exit to the copy select screen.
+ * Update function for `CM_SELECT_COPY_DEST`
+ */
+void FileSelect_SelectCopyDest(GameState* thisx) {
+ FileSelectState* this = (FileSelectState*)thisx;
+ SramContext* sramCtx = &this->sramCtx;
+ Input* input = CONTROLLER1(&this->state);
+
+ if (((this->buttonIndex == FS_BTN_COPY_QUIT) && CHECK_BTN_ANY(input->press.button, BTN_A | BTN_START)) ||
+ CHECK_BTN_ALL(input->press.button, BTN_B)) {
+ this->buttonIndex = this->selectedFileIndex;
+ this->nextTitleLabel = FS_TITLE_COPY_FROM;
+ this->actionTimer = 4;
+ this->configMode = CM_EXIT_TO_COPY_SOURCE_1;
+ play_sound(NA_SE_SY_FSEL_CLOSE);
+ } else if (CHECK_BTN_ANY(input->press.button, BTN_A | BTN_START)) {
+ if (!gSaveContext.flashSaveAvailable) {
+ if (!NO_FLASH_SLOT_OCCUPIED(sramCtx, this->buttonIndex)) {
+ this->copyDestFileIndex = this->buttonIndex;
+ this->nextTitleLabel = FS_TITLE_COPY_CONFIRM;
+ this->actionTimer = 4;
+ this->configMode = CM_SETUP_COPY_CONFIRM_1;
+ play_sound(NA_SE_SY_FSEL_DECIDE_L);
+ } else {
+ play_sound(NA_SE_SY_FSEL_ERROR);
+ }
+ } else if (!SLOT_OCCUPIED(this, this->buttonIndex)) {
+ this->copyDestFileIndex = this->buttonIndex;
+ this->nextTitleLabel = FS_TITLE_COPY_CONFIRM;
+ this->actionTimer = 4;
+ this->configMode = CM_SETUP_COPY_CONFIRM_1;
+ play_sound(NA_SE_SY_FSEL_DECIDE_L);
+ } else {
+ play_sound(NA_SE_SY_FSEL_ERROR);
+ }
+ } else {
+ if (ABS_ALT(this->stickAdjY) >= 30) {
+ play_sound(NA_SE_SY_FSEL_CURSOR);
+ if (this->stickAdjY >= 30) {
+ this->buttonIndex--;
+ // Instead of removing File 3 entirely, the index is manually adjusted to skip it
+ if (this->buttonIndex == FS_BTN_COPY_FILE_3) {
+ this->buttonIndex = FS_BTN_COPY_FILE_2;
+ }
+ if (this->buttonIndex == this->selectedFileIndex) {
+ this->buttonIndex--;
+ if (this->buttonIndex < FS_BTN_COPY_FILE_1) {
+ this->buttonIndex = FS_BTN_COPY_QUIT;
+ }
+ // Instead of removing File 3 entirely, the index is manually adjusted to skip it
+ if (this->buttonIndex == FS_BTN_COPY_FILE_3) {
+ this->buttonIndex = FS_BTN_COPY_FILE_2;
+ }
+ } else if (this->buttonIndex < FS_BTN_COPY_FILE_1) {
+ this->buttonIndex = FS_BTN_COPY_QUIT;
+ }
+ } else {
+ this->buttonIndex++;
+ if (this->buttonIndex > FS_BTN_COPY_QUIT) {
+ this->buttonIndex = FS_BTN_COPY_FILE_1;
+ }
+ if (this->buttonIndex == this->selectedFileIndex) {
+ this->buttonIndex++;
+ }
+ // Instead of removing File 3 entirely, the index is manually adjusted to skip it
+ if (this->buttonIndex == FS_BTN_COPY_FILE_3) {
+ this->buttonIndex = FS_BTN_COPY_QUIT;
+ }
+ }
+ }
+ if (this->buttonIndex != FS_BTN_COPY_QUIT) {
+ if (!gSaveContext.flashSaveAvailable) {
+ if (NO_FLASH_SLOT_OCCUPIED(sramCtx, this->buttonIndex)) {
+ this->warningLabel = FS_WARNING_FILE_IN_USE;
+ this->warningButtonIndex = this->buttonIndex;
+ this->emptyFileTextAlpha = 255;
+ } else {
+ this->warningLabel = FS_WARNING_NONE;
+ }
+ } else if (SLOT_OCCUPIED(this, this->buttonIndex)) {
+ this->warningLabel = FS_WARNING_FILE_IN_USE;
+ this->warningButtonIndex = this->buttonIndex;
+ this->emptyFileTextAlpha = 255;
+ } else {
+ this->warningLabel = FS_WARNING_NONE;
+ }
+ }
+ }
+}
+
+/**
+ * Fade out file info, bring back the name box, and get ready to return to copy source screen.
+ * Update function for `CM_EXIT_TO_COPY_SOURCE_1`
+ */
+void FileSelect_ExitToCopySource1(GameState* thisx) {
+ FileSelectState* this = (FileSelectState*)thisx;
+
+ this->fileInfoAlpha[this->buttonIndex] -= 200 / 4;
+ this->nameBoxAlpha[this->buttonIndex] += 200 / 4;
+ this->actionTimer--;
+
+ if (this->actionTimer == 0) {
+ this->nextTitleLabel = FS_TITLE_COPY_FROM;
+ this->nameBoxAlpha[this->buttonIndex] = 200;
+ this->fileInfoAlpha[this->buttonIndex] = 0;
+ this->actionTimer = 4;
+ this->configMode++; // CM_EXIT_TO_COPY_SOURCE_2
+ }
+}
+
+/**
+ * Move the buttons back into place and return to copy source select.
+ * Update function for `CM_EXIT_TO_COPY_SOURCE_2`
+ */
+void FileSelect_ExitToCopySource2(GameState* thisx) {
+ FileSelectState* this = (FileSelectState*)thisx;
+ SramContext* sramCtx = &this->sramCtx;
+ s16 i;
+ s32 yStep;
+
+ for (i = 0; i < 3; i++) {
+ yStep = ABS_ALT(this->buttonYOffsets[i] - sChooseFileYOffsets[i]) / this->actionTimer;
+
+ if (this->buttonYOffsets[i] >= sChooseFileYOffsets[i]) {
+ this->buttonYOffsets[i] -= yStep;
+ } else {
+ this->buttonYOffsets[i] += yStep;
+ }
+ }
+
+ this->titleAlpha[FS_TITLE_CUR] -= 255 / 4;
+ this->titleAlpha[FS_TITLE_NEXT] += 255 / 4;
+ this->actionTimer--;
+
+ if (this->actionTimer == 0) {
+ this->titleLabel = this->nextTitleLabel;
+ this->titleAlpha[FS_TITLE_CUR] = 255;
+ this->titleAlpha[FS_TITLE_NEXT] = 0;
+ this->buttonIndex = FS_BTN_COPY_QUIT;
+ this->configMode = CM_SELECT_COPY_SOURCE;
+ }
+}
+
+s16 D_80814264[] = { -56, -40, -24, 0 };
+
+/**
+ * Rearrange buttons on the screen to prepare for copy confirmation.
+ * Update function for `CM_SETUP_COPY_CONFIRM_1`
+ */
+void FileSelect_SetupCopyConfirm1(GameState* thisx) {
+ FileSelectState* this = (FileSelectState*)thisx;
+ SramContext* sramCtx = &this->sramCtx;
+ s16 i;
+ s32 yStep;
+
+ this->titleAlpha[FS_TITLE_CUR] -= 255 / 4;
+ this->titleAlpha[FS_TITLE_NEXT] += 255 / 4;
+
+ for (i = 0; i < 3; i++) {
+ if ((i != this->copyDestFileIndex) && (i != this->selectedFileIndex)) {
+ this->fileButtonAlpha[i] -= 200 / 4;
+
+ if (!gSaveContext.flashSaveAvailable) {
+ if (NO_FLASH_SLOT_OCCUPIED(sramCtx, i)) {
+ this->connectorAlpha[i] -= 255 / 4;
+ this->nameBoxAlpha[i] = this->nameAlpha[i] = this->fileButtonAlpha[i];
+ }
+ } else if (SLOT_OCCUPIED(this, i)) {
+ this->connectorAlpha[i] -= 255 / 4;
+ this->nameBoxAlpha[i] = this->nameAlpha[i] = this->fileButtonAlpha[i];
+ }
+ } else if (i == this->copyDestFileIndex) {
+ yStep = ABS_ALT(this->buttonYOffsets[i] - D_80814264[i]) / this->actionTimer;
+ this->buttonYOffsets[i] += yStep;
+
+ if (this->buttonYOffsets[i] >= D_80814264[i]) {
+ this->buttonYOffsets[i] = D_80814264[i];
+ }
+ }
+ }
+
+ this->actionTimer--;
+
+ if (this->actionTimer == 0) {
+ this->titleLabel = this->nextTitleLabel;
+ this->titleAlpha[FS_TITLE_CUR] = 255;
+ this->titleAlpha[FS_TITLE_NEXT] = 0;
+ this->actionTimer = 4;
+ this->configMode++;
+ }
+}
+
+/**
+ * Fade in the 'Yes' button before allowing the player to decide.
+ * Update function for `CM_SETUP_COPY_CONFIRM_2`
+ */
+void FileSelect_SetupCopyConfirm2(GameState* thisx) {
+ FileSelectState* this = (FileSelectState*)thisx;
+
+ this->confirmButtonAlpha[FS_BTN_CONFIRM_YES] += 200 / 4;
+ this->actionTimer--;
+
+ if (this->actionTimer == 0) {
+ this->configMode = CM_COPY_CONFIRM;
+ this->buttonIndex = FS_BTN_CONFIRM_QUIT;
+ }
+}
+
+/**
+ * Allow the player to confirm the copy, or quit back to the destination select.
+ * If yes is selected, the actual copy occurs in this function before moving on to the animation.
+ * Update function for `CM_COPY_CONFIRM`
+ */
+void FileSelect_CopyConfirm(GameState* thisx) {
+ FileSelectState* this = (FileSelectState*)thisx;
+ SramContext* sramCtx = &this->sramCtx;
+ Input* input = CONTROLLER1(&this->state);
+ u16 dayTime;
+
+ if (((this->buttonIndex != FS_BTN_CONFIRM_YES) && CHECK_BTN_ANY(input->press.button, BTN_A | BTN_START)) ||
+ CHECK_BTN_ALL(input->press.button, BTN_B)) {
+ this->actionTimer = 4;
+ this->nextTitleLabel = FS_TITLE_COPY_TO;
+ this->configMode = CM_RETURN_TO_COPY_DEST;
+ play_sound(NA_SE_SY_FSEL_CLOSE);
+ } else if (CHECK_BTN_ANY(input->press.button, BTN_A | BTN_START)) {
+ dayTime = gSaveContext.save.time;
+ gSaveContext.save.time = dayTime;
+ this->nameAlpha[this->copyDestFileIndex] = 0;
+ this->fileInfoAlpha[this->copyDestFileIndex] = this->nameAlpha[this->copyDestFileIndex];
+ this->nextTitleLabel = FS_TITLE_COPY_COMPLETE;
+ this->actionTimer = 4;
+ Sram_CopySave(this, sramCtx);
+ if (!gSaveContext.flashSaveAvailable) {
+ this->configMode = CM_COPY_ANIM_1;
+ } else {
+ Sram_SetFlashPagesDefault(sramCtx, gFlashSaveStartPages[this->copyDestFileIndex * 2],
+ gFlashSpecialSaveNumPages[this->copyDestFileIndex * 2]);
+ Sram_StartWriteToFlashDefault(sramCtx);
+ this->configMode = CM_COPY_WAIT_FOR_FLASH_SAVE;
+ }
+ Rumble_Request(300.0f, 180, 20, 100);
+ play_sound(NA_SE_SY_FSEL_DECIDE_L);
+ } else if (ABS_ALT(this->stickAdjY) >= 30) {
+ play_sound(NA_SE_SY_FSEL_CURSOR);
+ this->buttonIndex ^= 1;
+ }
+}
+
+/**
+ * Update and wait for the save to flash to complete.
+ * Update function for `CM_COPY_WAIT_FOR_FLASH_SAVE`
+ */
+void FileSelect_CopyWaitForFlashSave(GameState* thisx) {
+ FileSelectState* this = (FileSelectState*)thisx;
+ SramContext* sramCtx = &this->sramCtx;
+ u16 i;
+
+ Sram_UpdateWriteToFlashDefault(sramCtx);
+
+ if (sramCtx->status == 0) {
+ this->configMode = CM_COPY_ANIM_1;
+
+ for (i = 0; i < 6; i++) {
+ this->newf[this->copyDestFileIndex][i] = gSaveContext.save.saveInfo.playerData.newf[i];
+ }
+
+ this->threeDayResetCount[this->copyDestFileIndex] = gSaveContext.save.saveInfo.playerData.threeDayResetCount;
+
+ for (i = 0; i < 8; i++) {
+ this->fileNames[this->copyDestFileIndex][i] = gSaveContext.save.saveInfo.playerData.playerName[i];
+ }
+
+ this->healthCapacity[this->copyDestFileIndex] = gSaveContext.save.saveInfo.playerData.healthCapacity;
+ this->health[this->copyDestFileIndex] = gSaveContext.save.saveInfo.playerData.health;
+ this->defenseHearts[this->copyDestFileIndex] = gSaveContext.save.saveInfo.inventory.defenseHearts;
+ }
+}
+
+/**
+ * Move buttons back in place and return to copy destination select.
+ * Update function for `CM_RETURN_TO_COPY_DEST`
+ */
+void FileSelect_ReturnToCopyDest(GameState* thisx) {
+ FileSelectState* this = (FileSelectState*)thisx;
+ SramContext* sramCtx = &this->sramCtx;
+ s16 i;
+ s32 yStep;
+
+ this->titleAlpha[FS_TITLE_CUR] -= 255 / 4;
+ this->titleAlpha[FS_TITLE_NEXT] += 255 / 4;
+ this->confirmButtonAlpha[FS_BTN_CONFIRM_YES] -= 200 / 4;
+
+ for (i = 0; i < 3; i++) {
+ if ((i != this->copyDestFileIndex) && (i != this->selectedFileIndex)) {
+ this->fileButtonAlpha[i] += 200 / 4;
+
+ if (!gSaveContext.flashSaveAvailable) {
+ if (NO_FLASH_SLOT_OCCUPIED(sramCtx, i)) {
+ this->nameBoxAlpha[i] = this->nameAlpha[i] = this->fileButtonAlpha[i];
+ this->connectorAlpha[i] += 255 / 4;
+ }
+ } else if (SLOT_OCCUPIED(this, i)) {
+ this->nameBoxAlpha[i] = this->nameAlpha[i] = this->fileButtonAlpha[i];
+ this->connectorAlpha[i] += 255 / 4;
+ }
+ }
+
+ yStep = ABS_ALT(this->buttonYOffsets[i] - D_8081424C[this->selectedFileIndex][i]) / this->actionTimer;
+
+ if (D_8081424C[this->selectedFileIndex][i] >= this->buttonYOffsets[i]) {
+ this->buttonYOffsets[i] += yStep;
+ } else {
+ this->buttonYOffsets[i] -= yStep;
+ }
+ }
+
+ this->actionTimer--;
+
+ if (this->actionTimer == 0) {
+ this->titleLabel = this->nextTitleLabel;
+ this->titleAlpha[FS_TITLE_CUR] = 255;
+ this->titleAlpha[FS_TITLE_NEXT] = 0;
+ this->actionTimer = 4;
+ this->buttonIndex = FS_BTN_COPY_QUIT;
+ this->configMode = CM_SELECT_COPY_DEST;
+ }
+}
+
+/**
+ * Hide title
+ * Update function for `CM_COPY_ANIM_1`
+ */
+void FileSelect_CopyAnim1(GameState* thisx) {
+ FileSelectState* this = (FileSelectState*)thisx;
+
+ this->titleAlpha[FS_TITLE_CUR] -= 255 / 4;
+ this->confirmButtonAlpha[FS_BTN_CONFIRM_YES] -= 200 / 4;
+ this->confirmButtonAlpha[FS_BTN_CONFIRM_QUIT] -= 200 / 4;
+ this->actionTimer--;
+
+ if (this->actionTimer == 0) {
+ this->titleAlpha[FS_TITLE_CUR] = 0;
+ this->actionTimer = 4;
+ this->configMode++; // CM_COPY_ANIM_2
+ }
+}
+
+/**
+ * Move a copy of the file window down and fade in the file info.
+ * Update function for `CM_COPY_ANIM_2`
+ */
+void FileSelect_CopyAnim2(GameState* thisx) {
+ FileSelectState* this = (FileSelectState*)thisx;
+ s32 yStep;
+
+ this->fileInfoAlpha[this->copyDestFileIndex] += 200 / 4;
+ this->nameAlpha[this->copyDestFileIndex] += 200 / 4;
+ this->titleAlpha[FS_TITLE_NEXT] += 255 / 4;
+ yStep = ABS_ALT(this->fileNamesY[this->copyDestFileIndex] + 56) / this->actionTimer;
+ this->fileNamesY[this->copyDestFileIndex] -= yStep;
+
+ if (this->fileNamesY[this->copyDestFileIndex] <= -56) {
+ this->fileNamesY[this->copyDestFileIndex] = -56;
+ }
+
+ this->actionTimer--;
+
+ if (this->actionTimer == 0) {
+ this->actionTimer = 45;
+ this->titleLabel = this->nextTitleLabel;
+ this->titleAlpha[FS_TITLE_CUR] = 255;
+ this->titleAlpha[FS_TITLE_NEXT] = 0;
+ this->configMode++; // CM_COPY_ANIM_3
+ }
+}
+
+/**
+ * Play a sound effect to indicate that the copy has completed. Wait for a timer or for
+ * the player to press a button before moving on.
+ * Update function for `CM_COPY_ANIM_3`
+ */
+void FileSelect_CopyAnim3(GameState* thisx) {
+ FileSelectState* this = (FileSelectState*)thisx;
+ Input* input = CONTROLLER1(&this->state);
+
+ if (this->actionTimer == 38) {
+ this->connectorAlpha[this->copyDestFileIndex] = 255;
+ play_sound(NA_SE_EV_DIAMOND_SWITCH);
+ }
+
+ this->actionTimer--;
+
+ if (this->actionTimer < 37) {
+ if (CHECK_BTN_ANY(input->press.button, BTN_A | BTN_B | BTN_START) || (this->actionTimer == 0)) {
+ this->actionTimer = 4;
+ this->nextTitleLabel = FS_TITLE_SELECT_FILE;
+ play_sound(NA_SE_SY_FSEL_DECIDE_L);
+ this->configMode = CM_COPY_ANIM_4;
+ }
+ }
+}
+
+/**
+ * Fade out the info boxes for both files and bring in their name boxes. Fade out title.
+ * Update function for `CM_COPY_ANIM_4`
+ */
+void FileSelect_CopyAnim4(GameState* thisx) {
+ FileSelectState* this = (FileSelectState*)thisx;
+
+ this->fileInfoAlpha[this->selectedFileIndex] -= 200 / 4;
+ this->fileInfoAlpha[this->copyDestFileIndex] -= 200 / 4;
+ this->nameBoxAlpha[this->selectedFileIndex] += 200 / 4;
+ this->nameBoxAlpha[this->copyDestFileIndex] += 200 / 4;
+ this->titleAlpha[FS_TITLE_CUR] -= 255 / 4;
+ this->actionTimer--;
+
+ if (this->actionTimer == 0) {
+ this->fileNamesY[this->copyDestFileIndex] = this->buttonYOffsets[3] = 0;
+ this->actionTimer = 4;
+ this->titleAlpha[FS_TITLE_CUR] = 0;
+ this->configMode++;
+ }
+}
+
+/**
+ * Restore all buttons and labels back to their original place and go back to the main menu.
+ * Update function for `CM_COPY_ANIM_5`
+ */
+void FileSelect_CopyAnim5(GameState* thisx) {
+ FileSelectState* this = (FileSelectState*)thisx;
+ SramContext* sramCtx = &this->sramCtx;
+ s16 i;
+ s32 yStep;
+
+ for (i = 0; i < 5; i++) {
+ yStep = ABS_ALT(this->buttonYOffsets[i]) / this->actionTimer;
+
+ if (this->buttonYOffsets[i] >= 0) {
+ this->buttonYOffsets[i] -= yStep;
+ } else {
+ this->buttonYOffsets[i] += yStep;
+ }
+ }
+
+ for (i = 0; i < 3; i++) {
+ if (i != this->buttonIndex) {
+ this->fileButtonAlpha[i] += 200 / 4;
+
+ if (!gSaveContext.flashSaveAvailable) {
+ if (NO_FLASH_SLOT_OCCUPIED(sramCtx, i)) {
+ this->nameBoxAlpha[i] = this->nameAlpha[i] = this->fileButtonAlpha[i];
+ this->connectorAlpha[i] += 255 / 4;
+ }
+ } else if (SLOT_OCCUPIED(this, i)) {
+ this->nameBoxAlpha[i] = this->nameAlpha[i] = this->fileButtonAlpha[i];
+ this->connectorAlpha[i] += 255 / 4;
+ }
+ }
+ }
+
+ this->actionButtonAlpha[FS_BTN_ACTION_COPY] += 200 / 4;
+ this->actionButtonAlpha[FS_BTN_ACTION_ERASE] += 200 / 4;
+ this->optionButtonAlpha += 200 / 4;
+ this->titleAlpha[FS_TITLE_NEXT] += 255 / 4;
+ this->actionTimer--;
+
+ if (this->actionTimer == 0) {
+ for (i = 0; i < 3; i++) {
+ this->connectorAlpha[i] = 0;
+ this->fileButtonAlpha[i] = 200;
+ this->nameBoxAlpha[i] = this->nameAlpha[i] = this->connectorAlpha[i];
+
+ if (!gSaveContext.flashSaveAvailable) {
+ if (NO_FLASH_SLOT_OCCUPIED(sramCtx, i)) {
+ this->nameBoxAlpha[i] = this->nameAlpha[i] = this->fileButtonAlpha[i];
+ this->connectorAlpha[i] = 255;
+ }
+ } else if (SLOT_OCCUPIED(this, i)) {
+ this->nameBoxAlpha[i] = this->nameAlpha[i] = this->fileButtonAlpha[i];
+ this->connectorAlpha[i] = 255;
+ }
+ }
+
+ this->fileNamesY[this->selectedFileIndex] = 0;
+ this->highlightColor[3] = 70;
+ this->highlightPulseDir = 1;
+ this->highlightTimer = 20;
+ this->titleLabel = this->nextTitleLabel;
+ this->titleAlpha[FS_TITLE_CUR] = 255;
+ this->titleAlpha[FS_TITLE_NEXT] = 0;
+ this->configMode = CM_MAIN_MENU;
+ }
+}
+
+/**
+ * Exit from the copy source screen to the main menu. Return all buttons and labels to their original place.
+ * Update function for `CM_COPY_RETURN_MAIN`
+ */
+void FileSelect_ExitCopyToMain(GameState* thisx) {
+ FileSelectState* this = (FileSelectState*)thisx;
+ s16 i;
+ s32 yStep;
+
+ for (i = 0; i < 5; i++) {
+ yStep = ABS_ALT(this->buttonYOffsets[i]) / this->actionTimer;
+
+ if (this->buttonYOffsets[i] >= 0) {
+ this->buttonYOffsets[i] -= yStep;
+ } else {
+ this->buttonYOffsets[i] += yStep;
+ }
+ }
+
+ this->actionButtonAlpha[FS_BTN_ACTION_COPY] += 200 / 4;
+ this->confirmButtonAlpha[FS_BTN_CONFIRM_QUIT] -= 200 / 4;
+ this->titleAlpha[FS_TITLE_CUR] -= 255 / 4;
+ this->titleAlpha[FS_TITLE_NEXT] += 255 / 4;
+ this->actionTimer--;
+
+ if (this->actionTimer == 0) {
+ this->actionButtonAlpha[FS_BTN_ACTION_COPY] = 200;
+ this->confirmButtonAlpha[FS_BTN_CONFIRM_QUIT] = 0;
+ this->titleLabel = this->nextTitleLabel;
+ this->titleAlpha[FS_TITLE_CUR] = 255;
+ this->titleAlpha[FS_TITLE_NEXT] = 0;
+ this->configMode = CM_MAIN_MENU;
+ }
+
+ this->optionButtonAlpha = this->actionButtonAlpha[FS_BTN_ACTION_ERASE] =
+ this->actionButtonAlpha[FS_BTN_ACTION_COPY];
+}
+
+/**
+ * Move buttons into place for the erase select screen and fade in the proper labels.
+ * Update function for `CM_SETUP_ERASE_SELECT`
+ */
+void FileSelect_SetupEraseSelect(GameState* thisx) {
+ FileSelectState* this = (FileSelectState*)thisx;
+ s16 i;
+ s32 yStep;
+
+ for (i = 0; i < 5; i++) {
+ yStep = ABS_ALT(this->buttonYOffsets[i] - sChooseFileYOffsets[i]) / this->actionTimer;
+
+ if (this->buttonYOffsets[i] >= sChooseFileYOffsets[i]) {
+ this->buttonYOffsets[i] -= yStep;
+ } else {
+ this->buttonYOffsets[i] += yStep;
+ }
+ }
+
+ this->actionButtonAlpha[FS_BTN_ACTION_COPY] -= 100;
+ this->actionButtonAlpha[FS_BTN_ACTION_ERASE] -= 100;
+ this->optionButtonAlpha -= 100;
+ this->confirmButtonAlpha[FS_BTN_CONFIRM_QUIT] += 200 / 4;
+
+ if (this->actionButtonAlpha[FS_BTN_ACTION_COPY] <= 0) {
+ this->actionButtonAlpha[FS_BTN_ACTION_COPY] = this->actionButtonAlpha[FS_BTN_ACTION_ERASE] =
+ this->optionButtonAlpha = 0;
+ }
+
+ this->titleAlpha[FS_TITLE_CUR] -= 255 / 4;
+ this->titleAlpha[FS_TITLE_NEXT] += 255 / 4;
+ this->actionTimer--;
+
+ if (this->actionTimer == 0) {
+ this->highlightColor[3] = 70;
+ this->highlightPulseDir = 1;
+ this->highlightTimer = 20;
+ this->actionButtonAlpha[FS_BTN_ACTION_COPY] = this->actionButtonAlpha[FS_BTN_ACTION_ERASE] =
+ this->optionButtonAlpha = 0;
+ this->confirmButtonAlpha[FS_BTN_CONFIRM_QUIT] = 200;
+ this->titleLabel = this->nextTitleLabel;
+ this->titleAlpha[FS_TITLE_CUR] = 255;
+ this->titleAlpha[FS_TITLE_NEXT] = 0;
+ this->buttonIndex = FS_BTN_ERASE_QUIT;
+ this->configMode++; // CM_ERASE_SELECT
+ }
+}
+
+/**
+ * Allow the player to select a file to erase or exit back to the main menu.
+ * Update function for `CM_ERASE_SELECT`
+ */
+void FileSelect_EraseSelect(GameState* thisx) {
+ FileSelectState* this = (FileSelectState*)thisx;
+ SramContext* sramCtx = &this->sramCtx;
+ Input* input = CONTROLLER1(&this->state);
+
+ if (((this->buttonIndex == FS_BTN_COPY_QUIT) && CHECK_BTN_ANY(input->press.button, BTN_A | BTN_START)) ||
+ CHECK_BTN_ALL(input->press.button, BTN_B)) {
+ this->buttonIndex = FS_BTN_MAIN_ERASE;
+ this->actionTimer = 4;
+ this->nextTitleLabel = FS_TITLE_SELECT_FILE;
+ this->configMode = CM_EXIT_ERASE_TO_MAIN;
+ this->warningLabel = FS_WARNING_NONE;
+ play_sound(NA_SE_SY_FSEL_CLOSE);
+ } else if (CHECK_BTN_ANY(input->press.button, BTN_A | BTN_START)) {
+
+ if (!gSaveContext.flashSaveAvailable) {
+ if (NO_FLASH_SLOT_OCCUPIED(sramCtx, this->buttonIndex)) {
+ this->actionTimer = 4;
+ this->selectedFileIndex = this->buttonIndex;
+ this->configMode = CM_SETUP_ERASE_CONFIRM_1;
+ this->nextTitleLabel = FS_TITLE_ERASE_CONFIRM;
+ play_sound(NA_SE_SY_FSEL_DECIDE_L);
+ } else {
+ play_sound(NA_SE_SY_FSEL_ERROR);
+ }
+ } else if (SLOT_OCCUPIED(this, this->buttonIndex)) {
+ this->actionTimer = 4;
+ this->selectedFileIndex = this->buttonIndex;
+ this->configMode = CM_SETUP_ERASE_CONFIRM_1;
+ this->nextTitleLabel = FS_TITLE_ERASE_CONFIRM;
+ play_sound(NA_SE_SY_FSEL_DECIDE_L);
+ } else {
+ play_sound(NA_SE_SY_FSEL_ERROR);
+ }
+ } else {
+ if (ABS_ALT(this->stickAdjY) >= 30) {
+ play_sound(NA_SE_SY_FSEL_CURSOR);
+
+ if (this->stickAdjY >= 30) {
+ this->buttonIndex--;
+ if (this->buttonIndex == FS_BTN_ERASE_FILE_3) {
+ this->buttonIndex = FS_BTN_ERASE_FILE_2;
+ }
+ if (this->buttonIndex < FS_BTN_ERASE_FILE_1) {
+ this->buttonIndex = FS_BTN_ERASE_QUIT;
+ }
+ } else {
+ this->buttonIndex++;
+ if (this->buttonIndex == FS_BTN_ERASE_FILE_3) {
+ this->buttonIndex = FS_BTN_ERASE_QUIT;
+ }
+ if (this->buttonIndex > FS_BTN_ERASE_QUIT) {
+ this->buttonIndex = FS_BTN_ERASE_FILE_1;
+ }
+ }
+ }
+
+ if (this->buttonIndex != FS_BTN_ERASE_QUIT) {
+ if (!gSaveContext.flashSaveAvailable) {
+ if (!NO_FLASH_SLOT_OCCUPIED(sramCtx, this->buttonIndex)) {
+ this->warningLabel = FS_WARNING_FILE_EMPTY;
+ this->warningButtonIndex = this->buttonIndex;
+ this->emptyFileTextAlpha = 255;
+ } else {
+ this->warningLabel = FS_WARNING_NONE;
+ }
+ } else if (!SLOT_OCCUPIED(this, this->buttonIndex)) {
+ this->warningLabel = FS_WARNING_FILE_EMPTY;
+ this->warningButtonIndex = this->buttonIndex;
+ this->emptyFileTextAlpha = 255;
+ } else {
+ this->warningLabel = FS_WARNING_NONE;
+ }
+ } else {
+ this->warningLabel = FS_WARNING_NONE;
+ }
+ }
+}
+
+s16 D_8081426C[] = { 0, 16, 32 };
+
+/**
+ * Update function for `CM_SETUP_ERASE_CONFIRM_1`
+ */
+void FileSelect_SetupEraseConfirm1(GameState* thisx) {
+ FileSelectState* this = (FileSelectState*)thisx;
+ SramContext* sramCtx = &this->sramCtx;
+ s16 i;
+ s32 yStep;
+
+ for (i = 0; i < 3; i++) {
+ if (i != this->buttonIndex) {
+ this->fileButtonAlpha[i] -= 200 / 4;
+
+ if (!gSaveContext.flashSaveAvailable) {
+ if (NO_FLASH_SLOT_OCCUPIED(sramCtx, i)) {
+ this->connectorAlpha[i] -= 255 / 4;
+ this->nameBoxAlpha[i] = this->nameAlpha[i] = this->fileButtonAlpha[i];
+ }
+ } else if (SLOT_OCCUPIED(this, i)) {
+ this->connectorAlpha[i] -= 255 / 4;
+ this->nameBoxAlpha[i] = this->nameAlpha[i] = this->fileButtonAlpha[i];
+ }
+ } else {
+ this->nameBoxAlpha[i] -= 200 / 4;
+ }
+ }
+ this->titleAlpha[FS_TITLE_CUR] -= 255 / 8;
+ this->titleAlpha[FS_TITLE_NEXT] += 255 / 8;
+
+ yStep = ABS_ALT(this->buttonYOffsets[this->buttonIndex] - D_8081426C[this->buttonIndex]) / this->actionTimer;
+
+ if (this->buttonYOffsets[this->buttonIndex] >= D_8081426C[this->buttonIndex]) {
+ this->buttonYOffsets[this->buttonIndex] -= yStep;
+ } else {
+ this->buttonYOffsets[this->buttonIndex] += yStep;
+ }
+
+ this->actionTimer--;
+
+ if (this->actionTimer == 0) {
+ for (i = 0; i < 3; i++) {
+ if (i != this->buttonIndex) {
+ this->fileButtonAlpha[i] = 0;
+
+ if (!gSaveContext.flashSaveAvailable) {
+ if (NO_FLASH_SLOT_OCCUPIED(sramCtx, i)) {
+ this->connectorAlpha[i] = 0;
+ this->nameBoxAlpha[i] = this->nameAlpha[i] = this->fileButtonAlpha[i] = 0;
+ }
+ } else if (SLOT_OCCUPIED(this, i)) {
+ this->connectorAlpha[i] = 0;
+ this->nameBoxAlpha[i] = this->nameAlpha[i] = this->fileButtonAlpha[i] = 0;
+ }
+ } else {
+ this->nameBoxAlpha[i] = 0;
+ }
+ }
+
+ this->buttonYOffsets[this->buttonIndex] = D_8081426C[this->buttonIndex];
+ this->actionTimer = 4;
+ this->configMode++;
+ }
+}
+
+/**
+ * Show the file info of the file selected to erase.
+ * Update function for `CM_SETUP_ERASE_CONFIRM_2`
+ */
+void FileSelect_SetupEraseConfirm2(GameState* thisx) {
+ FileSelectState* this = (FileSelectState*)thisx;
+
+ this->confirmButtonAlpha[FS_BTN_CONFIRM_YES] += 200 / 4;
+ this->titleAlpha[FS_TITLE_CUR] -= 255 / 8;
+ this->titleAlpha[FS_TITLE_NEXT] += 255 / 8;
+ this->fileInfoAlpha[this->buttonIndex] += 200 / 4;
+ this->actionTimer--;
+
+ if (this->actionTimer == 0) {
+ this->actionTimer = 4;
+ this->titleLabel = this->nextTitleLabel;
+ this->fileInfoAlpha[this->buttonIndex] = this->titleAlpha[FS_TITLE_CUR] = 255;
+ this->titleAlpha[FS_TITLE_NEXT] = 0;
+ this->confirmButtonAlpha[FS_BTN_CONFIRM_YES] = 200;
+ this->buttonIndex = FS_BTN_CONFIRM_QUIT;
+ this->configMode = CM_ERASE_CONFIRM;
+ }
+}
+
+/**
+ * Allow the player to confirm their choice to erase or return back to erase select.
+ * Update function for `CM_ERASE_CONFIRM`
+ */
+void FileSelect_EraseConfirm(GameState* thisx) {
+ FileSelectState* this = (FileSelectState*)thisx;
+ SramContext* sramCtx = &this->sramCtx;
+ Input* input = CONTROLLER1(&this->state);
+
+ if (((this->buttonIndex != FS_BTN_CONFIRM_YES) && CHECK_BTN_ANY(input->press.button, BTN_A | BTN_START)) ||
+ CHECK_BTN_ALL(input->press.button, BTN_B)) {
+ this->buttonIndex = this->selectedFileIndex;
+ this->nextTitleLabel = FS_TITLE_ERASE_FILE;
+ this->configMode = CM_EXIT_TO_ERASE_SELECT_1;
+ this->actionTimer = 4;
+ play_sound(NA_SE_SY_FSEL_CLOSE);
+ } else if (CHECK_BTN_ANY(input->press.button, BTN_A | BTN_START)) {
+ Sram_EraseSave(this, sramCtx, this->selectedFileIndex);
+ if (!gSaveContext.flashSaveAvailable) {
+ this->configMode = CM_ERASE_ANIM_1;
+ } else {
+ Sram_SetFlashPagesDefault(sramCtx, gFlashSaveStartPages[this->selectedFileIndex * 2],
+ gFlashSpecialSaveNumPages[this->selectedFileIndex * 2]);
+ Sram_StartWriteToFlashDefault(sramCtx);
+ this->configMode = CM_ERASE_WAIT_FOR_FLASH_SAVE;
+ }
+ this->connectorAlpha[this->selectedFileIndex] = 0;
+ play_sound(NA_SE_EV_DIAMOND_SWITCH);
+ this->actionTimer = 4;
+ this->nextTitleLabel = FS_TITLE_ERASE_COMPLETE;
+ Rumble_Request(200.0f, 255, 20, 150);
+ sEraseDelayTimer = 15;
+ } else if (ABS_ALT(this->stickAdjY) >= 30) {
+ play_sound(NA_SE_SY_FSEL_CURSOR);
+ this->buttonIndex ^= 1;
+ }
+}
+
+/**
+ * Fade out file info, bring back the name box, and get ready to return to erase select screen.
+ * Update function for `CM_EXIT_TO_ERASE_SELECT_1`
+ */
+void FileSelect_ExitToEraseSelect1(GameState* thisx) {
+ FileSelectState* this = (FileSelectState*)thisx;
+
+ this->fileInfoAlpha[this->buttonIndex] -= 200 / 4;
+ this->nameBoxAlpha[this->buttonIndex] += 200 / 4;
+ this->confirmButtonAlpha[FS_BTN_CONFIRM_YES] -= 200 / 4;
+ this->actionTimer--;
+
+ if (this->actionTimer == 0) {
+ this->actionTimer = 4;
+ this->fileInfoAlpha[this->buttonIndex] = 0;
+ this->configMode++; // CM_EXIT_TO_ERASE_SELECT_2
+ }
+}
+
+/**
+ * Move the buttons back into place and return to erase select.
+ * Update function for `CM_EXIT_TO_ERASE_SELECT_2`
+ */
+void FileSelect_ExitToEraseSelect2(GameState* thisx) {
+ FileSelectState* this = (FileSelectState*)thisx;
+ SramContext* sramCtx = &this->sramCtx;
+ s16 i;
+ s32 yStep;
+
+ yStep =
+ ABS_ALT(this->buttonYOffsets[this->buttonIndex] - sChooseFileYOffsets[this->buttonIndex]) / this->actionTimer;
+
+ if (this->buttonYOffsets[this->buttonIndex] >= sChooseFileYOffsets[this->buttonIndex]) {
+ this->buttonYOffsets[this->buttonIndex] -= yStep;
+ } else {
+ this->buttonYOffsets[this->buttonIndex] += yStep;
+ }
+
+ for (i = 0; i < 3; i++) {
+ if (i != this->buttonIndex) {
+ this->fileButtonAlpha[i] += 200 / 4;
+
+ if (!gSaveContext.flashSaveAvailable) {
+ if (NO_FLASH_SLOT_OCCUPIED(sramCtx, i)) {
+ this->nameBoxAlpha[i] = this->nameAlpha[i] = this->fileButtonAlpha[i];
+ this->connectorAlpha[i] += 255 / 4;
+ }
+ } else if (SLOT_OCCUPIED(this, i)) {
+ this->nameBoxAlpha[i] = this->nameAlpha[i] = this->fileButtonAlpha[i];
+ this->connectorAlpha[i] += 255 / 4;
+ }
+ }
+ }
+
+ this->titleAlpha[FS_TITLE_CUR] -= 255 / 4;
+ this->titleAlpha[FS_TITLE_NEXT] += 255 / 4;
+ this->actionTimer--;
+
+ if (this->actionTimer == 0) {
+ this->buttonYOffsets[this->buttonIndex] = sChooseFileYOffsets[this->buttonIndex];
+ this->actionTimer = 4;
+ this->buttonIndex = FS_BTN_ERASE_QUIT;
+ this->titleLabel = this->nextTitleLabel;
+ this->titleAlpha[FS_TITLE_CUR] = 255;
+ this->titleAlpha[FS_TITLE_NEXT] = 0;
+ this->configMode = CM_ERASE_SELECT;
+ }
+}
+
+/**
+ * Wait for an initial delay, then start fading out the selected file.
+ * The actual file deletion occurs in this function.
+ * Update function for `CM_ERASE_ANIM_1`
+ */
+void FileSelect_EraseAnim1(GameState* thisx) {
+ static s16 D_80814E80;
+ FileSelectState* this = (FileSelectState*)thisx;
+ SramContext* sramCtx = &this->sramCtx;
+
+ if (sEraseDelayTimer == 0) {
+ if (this->actionTimer == 4) {
+ D_80814E80 = 1;
+ }
+
+ if (this->actionTimer != 0) {
+ this->titleAlpha[FS_TITLE_CUR] -= 255 / 4;
+ this->titleAlpha[FS_TITLE_NEXT] += 255 / 4;
+ this->fileInfoAlpha[this->selectedFileIndex] -= 200 / 4;
+ this->confirmButtonAlpha[FS_BTN_CONFIRM_YES] -= 200 / 4;
+ this->confirmButtonAlpha[FS_BTN_CONFIRM_QUIT] -= 200 / 4;
+ }
+
+ this->fileNamesY[this->selectedFileIndex] -= D_80814E80;
+ D_80814E80 += 2;
+
+ this->actionTimer--;
+ if (this->actionTimer == 0) {
+ this->configMode = CM_ERASE_ANIM_2;
+ this->titleLabel = this->nextTitleLabel;
+ this->titleAlpha[FS_TITLE_CUR] = 255;
+ this->titleAlpha[FS_TITLE_NEXT] = this->connectorAlpha[this->selectedFileIndex] = 0;
+
+ //! FAKE: there should be a better chained assignment
+ this->confirmButtonAlpha[FS_BTN_CONFIRM_YES] = this->confirmButtonAlpha[FS_BTN_CONFIRM_QUIT] = 0;
+ if (1) {}
+ if (0) {}
+ this->fileInfoAlpha[this->selectedFileIndex] = this->nameAlpha[this->selectedFileIndex] =
+ this->nameBoxAlpha[this->selectedFileIndex] = this->confirmButtonAlpha[FS_BTN_CONFIRM_QUIT];
+
+ this->actionTimer = 45;
+ }
+ } else {
+ sEraseDelayTimer--;
+
+ if (sEraseDelayTimer == 0) {
+ play_sound(NA_SE_OC_ABYSS);
+ }
+ }
+}
+
+/**
+ * Update and wait for the save to flash to complete.
+ * Update function for `CM_ERASE_WAIT_FOR_FLASH_SAVE`
+ */
+void FileSelect_EraseWaitForFlashSave(GameState* thisx) {
+ FileSelectState* this = (FileSelectState*)thisx;
+ SramContext* sramCtx = &this->sramCtx;
+ u16 i;
+
+ Sram_UpdateWriteToFlashDefault(sramCtx);
+
+ if (sramCtx->status == 0) {
+ this->configMode = CM_ERASE_ANIM_1;
+ for (i = 0; i < 6; i++) {
+ this->newf[this->selectedFileIndex][i] = gSaveContext.save.saveInfo.playerData.newf[i];
+ }
+ }
+}
+
+/**
+ * Wait for a delay timer or for the palyer to press a button before returning to the main menu.
+ * Update function for `CM_ERASE_ANIM_2`
+ */
+void FileSelect_EraseAnim2(GameState* thisx) {
+ FileSelectState* this = (FileSelectState*)thisx;
+ Input* input = CONTROLLER1(&this->state);
+
+ if (CHECK_BTN_ANY(input->press.button, BTN_A | BTN_B | BTN_START) || (--this->actionTimer == 0)) {
+ this->buttonYOffsets[3] = 0;
+ this->actionTimer = 4;
+ this->nextTitleLabel = FS_TITLE_SELECT_FILE;
+ this->configMode++; // CM_ERASE_ANIM_3
+ play_sound(NA_SE_SY_FSEL_CLOSE);
+ }
+}
+
+/**
+ * Exit from the erase animation to the main menu. Return all buttons and labels to their original place.
+ * Update function for `CM_ERASE_ANIM_3`
+ */
+void FileSelect_EraseAnim3(GameState* thisx) {
+ FileSelectState* this = (FileSelectState*)thisx;
+ SramContext* sramCtx = &this->sramCtx;
+ s16 i;
+ s32 yStep;
+
+ for (i = 0; i < 5; i++) {
+ yStep = ABS_ALT(this->buttonYOffsets[i]) / this->actionTimer;
+
+ if (this->buttonYOffsets[i] >= 0) {
+ this->buttonYOffsets[i] -= yStep;
+ } else {
+ this->buttonYOffsets[i] += yStep;
+ }
+ }
+
+ for (i = 0; i < 3; i++) {
+ this->fileButtonAlpha[i] += 200 / 4;
+
+ if (!gSaveContext.flashSaveAvailable) {
+ if (NO_FLASH_SLOT_OCCUPIED(sramCtx, i)) {
+ this->nameBoxAlpha[i] = this->nameAlpha[i] = this->fileButtonAlpha[i];
+ this->connectorAlpha[i] += 255 / 4;
+ }
+ } else if (SLOT_OCCUPIED(this, i)) {
+ this->nameBoxAlpha[i] = this->nameAlpha[i] = this->fileButtonAlpha[i];
+ this->connectorAlpha[i] += 255 / 4;
+ }
+ }
+
+ if (this->fileButtonAlpha[this->selectedFileIndex] >= 200) {
+ this->fileButtonAlpha[this->selectedFileIndex] = 200;
+ }
+
+ this->titleAlpha[FS_TITLE_CUR] -= 255 / 4;
+ this->titleAlpha[FS_TITLE_NEXT] += 255 / 4;
+ this->actionTimer--;
+
+ if (this->actionTimer == 0) {
+ this->fileNamesY[this->selectedFileIndex] = 0;
+ this->highlightColor[3] = 70;
+ this->highlightPulseDir = 1;
+ this->highlightTimer = 20;
+ this->actionButtonAlpha[FS_BTN_ACTION_COPY] = 200;
+ this->confirmButtonAlpha[FS_BTN_CONFIRM_YES] = this->confirmButtonAlpha[FS_BTN_CONFIRM_QUIT] = 0;
+ this->titleLabel = this->nextTitleLabel;
+ this->titleAlpha[FS_TITLE_CUR] = 255;
+ this->titleAlpha[FS_TITLE_NEXT] = 0;
+ this->configMode = CM_MAIN_MENU;
+ }
+
+ this->optionButtonAlpha = this->actionButtonAlpha[FS_BTN_ACTION_ERASE] =
+ this->actionButtonAlpha[FS_BTN_ACTION_COPY];
+}
+
+/**
+ * Exit from the erase select screen to the main menu. Return all buttons and labels to their original place.
+ * Update function for `CM_EXIT_ERASE_TO_MAIN`
+ */
+void FileSelect_ExitEraseToMain(GameState* thisx) {
+ FileSelectState* this = (FileSelectState*)thisx;
+ s16 i;
+ s32 yStep;
+
+ for (i = 0; i < 5; i++) {
+ yStep = ABS_ALT(this->buttonYOffsets[i]) / this->actionTimer;
+
+ if (this->buttonYOffsets[i] >= 0) {
+ this->buttonYOffsets[i] -= yStep;
+ } else {
+ this->buttonYOffsets[i] += yStep;
+ }
+ }
+
+ this->actionButtonAlpha[FS_BTN_ACTION_COPY] += 200 / 4;
+ this->actionButtonAlpha[FS_BTN_ACTION_ERASE] += 200 / 4;
+ this->optionButtonAlpha += 200 / 4;
+ this->confirmButtonAlpha[FS_BTN_CONFIRM_QUIT] -= 200 / 2;
+
+ if (this->confirmButtonAlpha[FS_BTN_CONFIRM_QUIT] <= 0) {
+ this->confirmButtonAlpha[FS_BTN_CONFIRM_QUIT] = 0;
+ }
+
+ this->titleAlpha[FS_TITLE_CUR] -= 255 / 4;
+ this->titleAlpha[FS_TITLE_NEXT] += 255 / 4;
+ this->actionTimer--;
+
+ if (this->actionTimer == 0) {
+ this->highlightColor[3] = 70;
+ this->highlightPulseDir = 1;
+ this->highlightTimer = 20;
+ this->actionButtonAlpha[FS_BTN_ACTION_COPY] = 200;
+ this->confirmButtonAlpha[FS_BTN_CONFIRM_QUIT] = 0;
+ this->titleLabel = this->nextTitleLabel;
+ this->titleAlpha[FS_TITLE_CUR] = 255;
+ this->titleAlpha[FS_TITLE_NEXT] = 0;
+ this->configMode = CM_MAIN_MENU;
+ }
+
+ this->optionButtonAlpha = this->actionButtonAlpha[FS_BTN_ACTION_ERASE] =
+ this->actionButtonAlpha[FS_BTN_ACTION_COPY];
+}
diff --git a/src/overlays/gamestates/ovl_file_choose/z_file_nameset_NES.c b/src/overlays/gamestates/ovl_file_choose/z_file_nameset_NES.c
index c6e3983d8e..02236002a8 100644
--- a/src/overlays/gamestates/ovl_file_choose/z_file_nameset_NES.c
+++ b/src/overlays/gamestates/ovl_file_choose/z_file_nameset_NES.c
@@ -1,78 +1,1059 @@
/*
* File: z_file_nameset_NES.c
* Overlay: ovl_file_choose
- * Description:
+ * Description: Entering name on a new file, selecting options from the options menu
*/
-#include "z_file_choose.h"
+#include "prevent_bss_reordering.h"
+#include "z_file_select.h"
#include "z64rumble.h"
+#include "misc/title_static/title_static.h"
+#include "overlays/ovl_file_choose/ovl_file_choose.h"
-extern UNK_TYPE D_01002800;
-extern UNK_TYPE D_01007980;
-extern UNK_TYPE D_0102A6B0;
-extern UNK_TYPE D_0102B170;
-extern UNK_TYPE D_010310F0;
-extern UNK_TYPE D_010311F0;
+void FileSelect_DrawTexQuadI4(GraphicsContext* gfxCtx, TexturePtr texture, s16 point) {
+ OPEN_DISPS(gfxCtx);
-// there are uses of D_0E000000.fillRect (appearing as D_0E0002E0) in this file
-extern GfxMasterList D_0E000000;
+ gDPLoadTextureBlock_4b(POLY_OPA_DISP++, texture, G_IM_FMT_I, 16, 16, 0, G_TX_NOMIRROR | G_TX_CLAMP,
+ G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
+ gSP1Quadrangle(POLY_OPA_DISP++, point, point + 2, point + 3, point + 1, 0);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_80804010.s")
+ CLOSE_DISPS(gfxCtx);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_808041A0.s")
+void FileSelect_DrawMultiTexQuadI4(GraphicsContext* gfxCtx, TexturePtr texture1, TexturePtr texture2, s16 point) {
+ OPEN_DISPS(gfxCtx);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_80804654.s")
+ gDPLoadTextureBlock_4b(POLY_OPA_DISP++, texture1, G_IM_FMT_I, 16, 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);
+ gDPLoadMultiBlock_4b(POLY_OPA_DISP++, texture2, 0x0080, 1, G_IM_FMT_I, 16, 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);
+ gSP1Quadrangle(POLY_OPA_DISP++, point, point + 2, point + 3, point + 1, 0);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_808047D8.s")
+ CLOSE_DISPS(gfxCtx);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_8080489C.s")
+s16 D_80814280[] = {
+ 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 0, 1, 1, 2, 1, 1, 4, 2, 2, 2, 1, 1, 0, 2, 0, 1, 1, 1, 1, 1, 0,
+ 1, 1, 1, 2, 2, 2, 2, 2, 3, 2, 2, 4, 3, 2, 4, 1, 2, 2, 1, 1, 2, 2, 3, 2, 2, 0, 2, 2, 2, 0, 3, 1, 0,
+};
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_80804DAC.s")
+s16 D_80814304[] = {
+ 1, 2, 0, 1, 1, 2, 1, 1, 4, 2, 2, 2, 1, 1, 0, 2, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 2, 2, 2, 2, 2, 3,
+ 2, 2, 4, 3, 2, 4, 1, 2, 2, 1, 1, 2, 2, 3, 2, 2, 0, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 3,
+};
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_80804E74.s")
+s16 D_80814384[] = {
+ 0, 1, 0, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 2, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+};
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_80804F98.s")
+s16 D_80814404[] = {
+ -94, -96, -48, 0, 32, 64,
+};
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_8080525C.s")
+s16 D_80814410[] = {
+ 56, 44, 44, 28, 28, 44,
+};
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_808052B0.s")
+s16 D_8081441C[] = {
+ 72, -48, -48, -48, -48, -48,
+};
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_808054A4.s")
+void FileSelect_SetKeyboardVtx(GameState* thisx) {
+ FileSelectState* this = (FileSelectState*)thisx;
+ s16 phi_t2;
+ s16 phi_t0;
+ s16 phi_t3;
+ s16 phi_s1;
+ s16 phi_t1;
+ s16 phi_s2;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_808055D0.s")
+ this->keyboardVtx = GRAPH_ALLOC(this->state.gfxCtx, sizeof(Vtx) * 4 * 5 * 13);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_808058A4.s")
+ phi_s1 = 0x26;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_80805918.s")
+ for (phi_t2 = 0, phi_s2 = 0, phi_t3 = 0; phi_s2 < 5; phi_s2++) {
+ phi_t0 = -0x60;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_80805A58.s")
+ for (phi_t1 = 0; phi_t1 < 13; phi_t1++, phi_t3 += 4, phi_t2++) {
+ //! @bug D_80814304 is accessed out of bounds when drawing the empty space character (value of 64). Under
+ //! normal circumstances it reads a halfword from D_80814384.
+ this->keyboardVtx[phi_t3].v.ob[0] = this->keyboardVtx[phi_t3 + 2].v.ob[0] = D_80814304[phi_t2] + phi_t0;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_80805B30.s")
+ this->keyboardVtx[phi_t3 + 1].v.ob[0] = this->keyboardVtx[phi_t3 + 3].v.ob[0] =
+ D_80814304[phi_t2] + phi_t0 + 12;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_80805C1C.s")
+ this->keyboardVtx[phi_t3].v.ob[1] = this->keyboardVtx[phi_t3 + 1].v.ob[1] = phi_s1;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_80806014.s")
+ this->keyboardVtx[phi_t3 + 2].v.ob[1] = this->keyboardVtx[phi_t3 + 3].v.ob[1] = phi_s1 - 12;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_80806148.s")
+ this->keyboardVtx[phi_t3].v.ob[2] = this->keyboardVtx[phi_t3 + 1].v.ob[2] =
+ this->keyboardVtx[phi_t3 + 2].v.ob[2] = this->keyboardVtx[phi_t3 + 3].v.ob[2] = 0;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_80806310.s")
+ this->keyboardVtx[phi_t3].v.flag = this->keyboardVtx[phi_t3 + 1].v.flag =
+ this->keyboardVtx[phi_t3 + 2].v.flag = this->keyboardVtx[phi_t3 + 3].v.flag = 0;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_808067E0.s")
+ this->keyboardVtx[phi_t3].v.tc[0] = this->keyboardVtx[phi_t3].v.tc[1] =
+ this->keyboardVtx[phi_t3 + 1].v.tc[1] = this->keyboardVtx[phi_t3 + 2].v.tc[0] = 0;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_80806BC8.s")
+ this->keyboardVtx[phi_t3 + 1].v.tc[0] = this->keyboardVtx[phi_t3 + 2].v.tc[1] =
+ this->keyboardVtx[phi_t3 + 3].v.tc[0] = this->keyboardVtx[phi_t3 + 3].v.tc[1] = 16 << 5;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_80806CA0.s")
+ this->keyboardVtx[phi_t3].v.cn[0] = this->keyboardVtx[phi_t3 + 1].v.cn[0] =
+ this->keyboardVtx[phi_t3 + 2].v.cn[0] = this->keyboardVtx[phi_t3 + 3].v.cn[0] =
+ this->keyboardVtx[phi_t3].v.cn[1] = this->keyboardVtx[phi_t3 + 1].v.cn[1] =
+ this->keyboardVtx[phi_t3 + 2].v.cn[1] = this->keyboardVtx[phi_t3 + 3].v.cn[1] =
+ this->keyboardVtx[phi_t3].v.cn[2] = this->keyboardVtx[phi_t3 + 1].v.cn[2] =
+ this->keyboardVtx[phi_t3 + 2].v.cn[2] = this->keyboardVtx[phi_t3 + 3].v.cn[2] =
+ this->keyboardVtx[phi_t3].v.cn[3] = this->keyboardVtx[phi_t3 + 1].v.cn[3] =
+ this->keyboardVtx[phi_t3 + 2].v.cn[3] = this->keyboardVtx[phi_t3 + 3].v.cn[3] =
+ 255;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_80806E84.s")
+ phi_t0 += 0x10;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_80806F30.s")
+ phi_s1 -= 0x10;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_808071E4.s")
+ this->keyboard2Vtx = GRAPH_ALLOC(this->state.gfxCtx, sizeof(Vtx) * 24);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_80807390.s")
+ for (phi_t1 = 0, phi_t3 = 0; phi_t3 < 6; phi_t3++, phi_t1 += 4) {
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_8080742C.s")
+ this->keyboard2Vtx[phi_t1 + 0].v.ob[0] = this->keyboard2Vtx[phi_t1 + 2].v.ob[0] = D_80814404[phi_t3] + 1;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_808074B4.s")
+ this->keyboard2Vtx[phi_t1 + 1].v.ob[0] = this->keyboard2Vtx[phi_t1 + 3].v.ob[0] =
+ this->keyboard2Vtx[phi_t1 + 0].v.ob[0] + D_80814410[phi_t3] - 2;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_808077AC.s")
+ this->keyboard2Vtx[phi_t1 + 0].v.ob[1] = this->keyboard2Vtx[phi_t1 + 1].v.ob[1] = D_8081441C[phi_t3] - 1;
+
+ this->keyboard2Vtx[phi_t1 + 2].v.ob[1] = this->keyboard2Vtx[phi_t1 + 3].v.ob[1] =
+ this->keyboard2Vtx[phi_t1 + 0].v.ob[1] - 0xE;
+
+ this->keyboard2Vtx[phi_t1 + 0].v.ob[2] = this->keyboard2Vtx[phi_t1 + 1].v.ob[2] =
+ this->keyboard2Vtx[phi_t1 + 2].v.ob[2] = this->keyboard2Vtx[phi_t1 + 3].v.ob[2] = 0;
+
+ this->keyboard2Vtx[phi_t1 + 0].v.flag = this->keyboard2Vtx[phi_t1 + 1].v.flag =
+ this->keyboard2Vtx[phi_t1 + 2].v.flag = this->keyboard2Vtx[phi_t1 + 3].v.flag = 0;
+
+ this->keyboard2Vtx[phi_t1 + 0].v.tc[0] = this->keyboard2Vtx[phi_t1 + 0].v.tc[1] =
+ this->keyboard2Vtx[phi_t1 + 1].v.tc[1] = this->keyboard2Vtx[phi_t1 + 2].v.tc[0] = 0;
+
+ this->keyboard2Vtx[phi_t1 + 1].v.tc[0] = this->keyboard2Vtx[phi_t1 + 3].v.tc[0] = D_80814410[phi_t3] << 5;
+
+ this->keyboard2Vtx[phi_t1 + 2].v.tc[1] = this->keyboard2Vtx[phi_t1 + 3].v.tc[1] = 16 << 5;
+
+ this->keyboard2Vtx[phi_t1 + 0].v.cn[0] = this->keyboard2Vtx[phi_t1 + 1].v.cn[0] =
+ this->keyboard2Vtx[phi_t1 + 2].v.cn[0] = this->keyboard2Vtx[phi_t1 + 3].v.cn[0] =
+ this->keyboard2Vtx[phi_t1 + 0].v.cn[1] = this->keyboard2Vtx[phi_t1 + 1].v.cn[1] =
+ this->keyboard2Vtx[phi_t1 + 2].v.cn[1] = this->keyboard2Vtx[phi_t1 + 3].v.cn[1] =
+ this->keyboard2Vtx[phi_t1 + 0].v.cn[2] = this->keyboard2Vtx[phi_t1 + 1].v.cn[2] =
+ this->keyboard2Vtx[phi_t1 + 2].v.cn[2] = this->keyboard2Vtx[phi_t1 + 3].v.cn[2] =
+ this->keyboard2Vtx[phi_t1 + 0].v.cn[3] = this->keyboard2Vtx[phi_t1 + 1].v.cn[3] =
+ this->keyboard2Vtx[phi_t1 + 2].v.cn[3] = this->keyboard2Vtx[phi_t1 + 3].v.cn[3] =
+ 255;
+ }
+}
+
+TexturePtr sBackspaceEndTextures[] = {
+ gFileSelBackspaceButtonTex,
+ gFileSelENDButtonENGTex,
+};
+
+u16 sBackspaceEndWidths[] = { 28, 44 };
+
+s16 D_80814434[] = {
+ -30, -16, -6, 4, 14, 24, 34, 44, 54, -16, -16, 0,
+};
+
+s16 D_8081444C[] = {
+ 72, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 0,
+};
+
+/**
+ * Set vertices used by all elements of the name entry screen that are NOT the keyboard.
+ * This includes the cursor highlight, the name entry plate and characters, and the buttons.
+ */
+void FileSelect_SetNameEntryVtx(GameState* thisx) {
+ FileSelectState* this = (FileSelectState*)thisx;
+ Font* font = &this->font;
+ u8 temp;
+ s16 var_s0;
+ s16 var_t1;
+ s16 sp108;
+
+ OPEN_DISPS(this->state.gfxCtx);
+
+ gDPPipeSync(POLY_OPA_DISP++);
+ gDPSetCombineLERP(POLY_OPA_DISP++, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0, PRIMITIVE,
+ ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0);
+ gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, this->titleAlpha[FS_TITLE_CUR]);
+
+ gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, 0);
+ gSPVertex(POLY_OPA_DISP++, this->keyboard2Vtx, 24, 0);
+ gDPLoadTextureBlock(POLY_OPA_DISP++, gFileSelNameENGTex, G_IM_FMT_IA, G_IM_SIZ_8b, 56, 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);
+ gSP1Quadrangle(POLY_OPA_DISP++, 0, 2, 3, 1, 0);
+ gDPPipeSync(POLY_OPA_DISP++);
+
+ for (var_t1 = 0, var_s0 = 0x10; var_t1 < 2; var_t1++, var_s0 += 4) {
+ gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, this->windowColor[0], this->windowColor[1], this->windowColor[2], 255);
+ gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, 0);
+ gDPLoadTextureBlock(POLY_OPA_DISP++, sBackspaceEndTextures[var_t1], G_IM_FMT_IA, G_IM_SIZ_16b,
+ sBackspaceEndWidths[var_t1], 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);
+ gSP1Quadrangle(POLY_OPA_DISP++, var_s0, var_s0 + 2, var_s0 + 3, var_s0 + 1, 0);
+ }
+
+ this->nameEntryVtx = GRAPH_ALLOC(this->state.gfxCtx, 44 * sizeof(Vtx));
+
+ for (var_s0 = 0, var_t1 = 0; var_t1 < 44; var_t1 += 4, var_s0++) {
+ if ((var_s0 > 0) && (var_s0 < 9)) {
+ temp = this->fileNames[this->buttonIndex][var_s0 - 1];
+
+ this->nameEntryVtx[var_t1 + 0].v.ob[0] = this->nameEntryVtx[var_t1 + 2].v.ob[0] =
+ D_80814434[var_s0] + this->nameEntryBoxPosX + D_80814280[temp];
+
+ this->nameEntryVtx[var_t1 + 1].v.ob[0] = this->nameEntryVtx[var_t1 + 3].v.ob[0] =
+ this->nameEntryVtx[var_t1 + 0].v.ob[0] + 10;
+ } else {
+ this->nameEntryVtx[var_t1 + 0].v.ob[0] = this->nameEntryVtx[var_t1 + 2].v.ob[0] =
+ D_80814434[var_s0] + this->nameEntryBoxPosX;
+
+ this->nameEntryVtx[var_t1 + 1].v.ob[0] = this->nameEntryVtx[var_t1 + 3].v.ob[0] =
+ this->nameEntryVtx[var_t1 + 0].v.ob[0] + 10;
+ }
+
+ this->nameEntryVtx[var_t1 + 0].v.ob[1] = this->nameEntryVtx[var_t1 + 1].v.ob[1] = D_8081444C[var_s0];
+
+ this->nameEntryVtx[var_t1 + 2].v.ob[1] = this->nameEntryVtx[var_t1 + 3].v.ob[1] =
+ this->nameEntryVtx[var_t1 + 0].v.ob[1] - 10;
+
+ this->nameEntryVtx[var_t1 + 0].v.ob[2] = this->nameEntryVtx[var_t1 + 1].v.ob[2] =
+ this->nameEntryVtx[var_t1 + 2].v.ob[2] = this->nameEntryVtx[var_t1 + 3].v.ob[2] = 0;
+
+ this->nameEntryVtx[var_t1 + 0].v.flag = this->nameEntryVtx[var_t1 + 1].v.flag =
+ this->nameEntryVtx[var_t1 + 2].v.flag = this->nameEntryVtx[var_t1 + 3].v.flag = 0;
+
+ this->nameEntryVtx[var_t1 + 0].v.tc[0] = this->nameEntryVtx[var_t1 + 0].v.tc[1] =
+ this->nameEntryVtx[var_t1 + 1].v.tc[1] = this->nameEntryVtx[var_t1 + 2].v.tc[0] = 0;
+
+ this->nameEntryVtx[var_t1 + 1].v.tc[0] = this->nameEntryVtx[var_t1 + 2].v.tc[1] =
+ this->nameEntryVtx[var_t1 + 3].v.tc[0] = this->nameEntryVtx[var_t1 + 3].v.tc[1] = 16 << 5;
+
+ this->nameEntryVtx[var_t1 + 0].v.cn[0] = this->nameEntryVtx[var_t1 + 1].v.cn[0] =
+ this->nameEntryVtx[var_t1 + 2].v.cn[0] = this->nameEntryVtx[var_t1 + 3].v.cn[0] =
+ this->nameEntryVtx[var_t1 + 0].v.cn[1] = this->nameEntryVtx[var_t1 + 1].v.cn[1] =
+ this->nameEntryVtx[var_t1 + 2].v.cn[1] = this->nameEntryVtx[var_t1 + 3].v.cn[1] =
+ this->nameEntryVtx[var_t1 + 0].v.cn[2] = this->nameEntryVtx[var_t1 + 1].v.cn[2] =
+ this->nameEntryVtx[var_t1 + 2].v.cn[2] = this->nameEntryVtx[var_t1 + 3].v.cn[2] =
+ this->nameEntryVtx[var_t1 + 0].v.cn[3] = this->nameEntryVtx[var_t1 + 1].v.cn[3] =
+ this->nameEntryVtx[var_t1 + 2].v.cn[3] = this->nameEntryVtx[var_t1 + 3].v.cn[3] =
+ 255;
+ }
+
+ this->nameEntryVtx[1].v.ob[0] = this->nameEntryVtx[3].v.ob[0] = this->nameEntryVtx[0].v.ob[0] + 0x6C;
+ this->nameEntryVtx[2].v.ob[1] = this->nameEntryVtx[3].v.ob[1] = this->nameEntryVtx[0].v.ob[1] - 0x10;
+ this->nameEntryVtx[1].v.tc[0] = this->nameEntryVtx[3].v.tc[0] = 108 << 5;
+
+ gDPPipeSync(POLY_OPA_DISP++);
+ gDPSetCombineLERP(POLY_OPA_DISP++, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0, PRIMITIVE,
+ ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0);
+ gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, this->windowColor[0], this->windowColor[1], this->windowColor[2],
+ this->nameEntryBoxAlpha);
+ gSPVertex(POLY_OPA_DISP++, this->nameEntryVtx, 4, 0);
+
+ gDPLoadTextureBlock(POLY_OPA_DISP++, gFileSelFileNameBoxTex, 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_NOLOD);
+ gSP1Quadrangle(POLY_OPA_DISP++, 0, 2, 3, 1, 0);
+ gDPPipeSync(POLY_OPA_DISP++);
+ gDPSetCombineLERP(POLY_OPA_DISP++, 0, 0, 0, PRIMITIVE, TEXEL0, 0, PRIMITIVE, 0, 0, 0, 0, PRIMITIVE, TEXEL0, 0,
+ PRIMITIVE, 0);
+ gSPVertex(POLY_OPA_DISP++, this->nameEntryVtx + 4, 32, 0);
+ gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, this->nameEntryBoxAlpha);
+
+ for (sp108 = 0, var_s0 = 0; var_s0 < 0x20; var_s0 += 4, sp108++) {
+ FileSelect_DrawTexQuadI4(
+ this->state.gfxCtx, font->fontBuf + this->fileNames[this->buttonIndex][sp108] * FONT_CHAR_TEX_SIZE, var_s0);
+ }
+
+ this->nameEntryVtx[37].v.tc[0] = this->nameEntryVtx[38].v.tc[1] = this->nameEntryVtx[39].v.tc[0] =
+ this->nameEntryVtx[39].v.tc[1] = this->nameEntryVtx[41].v.tc[0] = this->nameEntryVtx[42].v.tc[1] =
+ this->nameEntryVtx[43].v.tc[0] = this->nameEntryVtx[43].v.tc[1] = 24 << 5;
+
+ if ((this->kbdButton == FS_KBD_BTN_HIRA) || (this->kbdButton == FS_KBD_BTN_KATA) ||
+ (this->kbdButton == FS_KBD_BTN_END)) {
+ this->nameEntryVtx[41].v.tc[0] = this->nameEntryVtx[43].v.tc[0] = 56 << 5;
+ } else if ((this->kbdButton == FS_KBD_BTN_ENG) || (this->kbdButton == FS_KBD_BTN_BACKSPACE)) {
+ this->nameEntryVtx[41].v.tc[0] = this->nameEntryVtx[43].v.tc[0] = 40 << 5;
+ }
+
+ CLOSE_DISPS(this->state.gfxCtx);
+}
+
+void FileSelect_DrawKeyboard(GameState* thisx) {
+ FileSelectState* this = (FileSelectState*)thisx;
+ Font* font = &this->font;
+ s16 i;
+ s16 tmp;
+ s16 vtx;
+
+ OPEN_DISPS(this->state.gfxCtx);
+
+ Gfx_SetupDL42_Opa(this->state.gfxCtx);
+ gDPSetCycleType(POLY_OPA_DISP++, G_CYC_2CYCLE);
+ gDPSetRenderMode(POLY_OPA_DISP++, G_RM_PASS, G_RM_XLU_SURF2);
+ gDPSetCombineLERP(POLY_OPA_DISP++, 0, 0, 0, PRIMITIVE, TEXEL1, TEXEL0, PRIM_LOD_FRAC, TEXEL0, 0, 0, 0, COMBINED, 0,
+ 0, 0, COMBINED);
+ gDPSetPrimColor(POLY_OPA_DISP++, 0, this->charBgAlpha, 255, 255, 255, 255);
+
+ for (i = 0, vtx = 0; vtx < 0x100; vtx += 32) {
+ gSPVertex(POLY_OPA_DISP++, &this->keyboardVtx[vtx], 32, 0);
+
+ for (tmp = 0; tmp < 32; i++, tmp += 4) {
+ FileSelect_DrawTexQuadI4(this->state.gfxCtx, font->fontBuf + D_808141F0[i] * FONT_CHAR_TEX_SIZE, tmp);
+ }
+ }
+
+ gSPVertex(POLY_OPA_DISP++, &this->keyboardVtx[0x100], 4, 0);
+ FileSelect_DrawTexQuadI4(this->state.gfxCtx, font->fontBuf + D_808141F0[i] * FONT_CHAR_TEX_SIZE, 0);
+
+ CLOSE_DISPS(this->state.gfxCtx);
+}
+
+void FileSelect_DrawNameEntry(GameState* thisx) {
+ FileSelectState* this = (FileSelectState*)thisx;
+ SramContext* sramCtx = &this->sramCtx;
+ Font* font = &this->font;
+ Input* input = CONTROLLER1(&this->state);
+ s16 i;
+ s16 tmp;
+ u16 time;
+ s16 validName;
+
+ OPEN_DISPS(this->state.gfxCtx);
+
+ FileSelect_SetKeyboardVtx(&this->state);
+ FileSelect_SetNameEntryVtx(&this->state);
+ FileSelect_PulsateCursor(&this->state);
+
+ tmp = (this->newFileNameCharCount * 4) + 4;
+ this->nameEntryVtx[36].v.ob[0] = this->nameEntryVtx[38].v.ob[0] = this->nameEntryVtx[tmp].v.ob[0] - 6;
+ this->nameEntryVtx[37].v.ob[0] = this->nameEntryVtx[39].v.ob[0] = this->nameEntryVtx[36].v.ob[0] + 24;
+ this->nameEntryVtx[36].v.ob[1] = this->nameEntryVtx[37].v.ob[1] = this->nameEntryVtx[tmp].v.ob[1] + 7;
+ this->nameEntryVtx[38].v.ob[1] = this->nameEntryVtx[39].v.ob[1] = this->nameEntryVtx[36].v.ob[1] - 24;
+
+ if ((this->kbdButton == FS_KBD_BTN_HIRA) || (this->kbdButton == FS_KBD_BTN_KATA) ||
+ (this->kbdButton == FS_KBD_BTN_END)) {
+ this->nameEntryVtx[40].v.ob[0] = this->nameEntryVtx[42].v.ob[0] =
+ this->keyboard2Vtx[(this->kbdX + 1) * 4].v.ob[0] - 4;
+ this->nameEntryVtx[41].v.ob[0] = this->nameEntryVtx[43].v.ob[0] = this->nameEntryVtx[40].v.ob[0] + 52;
+ this->nameEntryVtx[40].v.ob[1] = this->nameEntryVtx[41].v.ob[1] =
+ this->keyboard2Vtx[(this->kbdX + 1) * 4].v.ob[1] + 4;
+ } else if ((this->kbdButton == FS_KBD_BTN_ENG) || (this->kbdButton == FS_KBD_BTN_BACKSPACE)) {
+ this->nameEntryVtx[40].v.ob[0] = this->nameEntryVtx[42].v.ob[0] =
+ this->keyboard2Vtx[(this->kbdX + 1) * 4].v.ob[0] - 4;
+ this->nameEntryVtx[41].v.ob[0] = this->nameEntryVtx[43].v.ob[0] = this->nameEntryVtx[40].v.ob[0] + 40;
+ this->nameEntryVtx[40].v.ob[1] = this->nameEntryVtx[41].v.ob[1] =
+ this->keyboard2Vtx[(this->kbdX + 1) * 4].v.ob[1] + 4;
+ } else {
+ this->nameEntryVtx[40].v.ob[0] = this->nameEntryVtx[42].v.ob[0] =
+ this->keyboardVtx[this->charIndex * 4].v.ob[0] - D_80814304[this->charIndex] - 6;
+ this->nameEntryVtx[41].v.ob[0] = this->nameEntryVtx[43].v.ob[0] = this->nameEntryVtx[40].v.ob[0] + 24;
+ this->nameEntryVtx[40].v.ob[1] = this->nameEntryVtx[41].v.ob[1] =
+ this->keyboardVtx[this->charIndex * 4].v.ob[1] + 6;
+ }
+
+ this->nameEntryVtx[42].v.ob[1] = this->nameEntryVtx[43].v.ob[1] = this->nameEntryVtx[40].v.ob[1] - 24;
+
+ gSPVertex(POLY_OPA_DISP++, &this->nameEntryVtx[36], 8, 0);
+ gDPPipeSync(POLY_OPA_DISP++);
+ gDPSetCombineLERP(POLY_OPA_DISP++, 1, 0, PRIMITIVE, 0, TEXEL0, 0, PRIMITIVE, 0, 1, 0, PRIMITIVE, 0, TEXEL0, 0,
+ PRIMITIVE, 0);
+ gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, this->highlightColor[0], this->highlightColor[1], this->highlightColor[2],
+ this->highlightColor[3]);
+
+ gDPLoadTextureBlock(POLY_OPA_DISP++, gFileSelCharHighlightTex, G_IM_FMT_I, G_IM_SIZ_8b, 24, 24, 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);
+
+ gSP1Quadrangle(POLY_OPA_DISP++, 0, 2, 3, 1, 0);
+
+ if ((this->kbdButton == FS_KBD_BTN_HIRA) || (this->kbdButton == FS_KBD_BTN_KATA) ||
+ (this->kbdButton == FS_KBD_BTN_END)) {
+ gDPLoadTextureBlock(POLY_OPA_DISP++, gFileSelMediumButtonHighlightTex, G_IM_FMT_I, G_IM_SIZ_8b, 56, 24, 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);
+ } else if ((this->kbdButton == FS_KBD_BTN_ENG) || (this->kbdButton == FS_KBD_BTN_BACKSPACE)) {
+ gDPLoadTextureBlock(POLY_OPA_DISP++, gFileSelSmallButtonHighlightTex, G_IM_FMT_I, G_IM_SIZ_8b, 40, 24, 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);
+ }
+
+ gSP1Quadrangle(POLY_OPA_DISP++, 4, 6, 7, 5, 0);
+
+ FileSelect_DrawKeyboard(&this->state);
+ gDPPipeSync(POLY_OPA_DISP++);
+ Gfx_SetupDL42_Opa(this->state.gfxCtx);
+
+ gDPSetCombineLERP(POLY_OPA_DISP++, 0, 0, 0, PRIMITIVE, TEXEL0, 0, PRIMITIVE, 0, 0, 0, 0, PRIMITIVE, TEXEL0, 0,
+ PRIMITIVE, 0);
+ gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, 255);
+
+ if (this->configMode == CM_NAME_ENTRY) {
+ if (CHECK_BTN_ALL(input->press.button, BTN_START)) {
+ play_sound(NA_SE_SY_FSEL_DECIDE_L);
+ // place cursor on END button
+ this->kbdY = 5;
+ this->kbdX = 4;
+ } else if (CHECK_BTN_ALL(input->press.button, BTN_B)) {
+ if ((this->newFileNameCharCount == 7) && (this->fileNames[this->buttonIndex][7] != 0x3E)) {
+
+ for (i = this->newFileNameCharCount; i < 7; i++) {
+ this->fileNames[this->buttonIndex][i] = this->fileNames[this->buttonIndex][i + 1];
+ }
+
+ this->fileNames[this->buttonIndex][i] = 0x3E;
+ play_sound(NA_SE_SY_FSEL_CLOSE);
+ } else {
+ this->newFileNameCharCount--;
+
+ if (this->newFileNameCharCount < 0) {
+ this->newFileNameCharCount = 0;
+ this->configMode = CM_NAME_ENTRY_TO_MAIN;
+ play_sound(NA_SE_SY_FSEL_CLOSE);
+ } else {
+ for (i = this->newFileNameCharCount; i < 7; i++) {
+ this->fileNames[this->buttonIndex][i] = this->fileNames[this->buttonIndex][i + 1];
+ }
+
+ this->fileNames[this->buttonIndex][i] = 0x3E;
+ play_sound(NA_SE_SY_FSEL_CLOSE);
+ }
+ }
+ } else {
+ if (this->charPage <= FS_CHAR_PAGE_ENG) {
+ if (this->kbdY != 5) {
+ // draw the character the cursor is hovering over in yellow
+ gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 0, 255);
+
+ //! @bug D_80814384 is accessed out of bounds when drawing the empty space character (value of 64).
+ //! Under normal circumstances it reads a halfword from D_80814404.
+ this->keyboardVtx[(this->charIndex * 4) + 0].v.ob[0] =
+ this->keyboardVtx[(this->charIndex * 4) + 2].v.ob[0] =
+ this->keyboardVtx[(this->charIndex * 4) + 0].v.ob[0] + D_80814384[this->charIndex] - 2;
+
+ this->keyboardVtx[(this->charIndex * 4) + 1].v.ob[0] =
+ this->keyboardVtx[(this->charIndex * 4) + 3].v.ob[0] =
+ this->keyboardVtx[(this->charIndex * 4) + 0].v.ob[0] + 0x10;
+
+ this->keyboardVtx[(this->charIndex * 4) + 0].v.ob[1] =
+ this->keyboardVtx[(this->charIndex * 4) + 1].v.ob[1] =
+ this->keyboardVtx[(this->charIndex * 4) + 0].v.ob[1] + 2;
+
+ this->keyboardVtx[(this->charIndex * 4) + 2].v.ob[1] =
+ this->keyboardVtx[(this->charIndex * 4) + 3].v.ob[1] =
+ this->keyboardVtx[(this->charIndex * 4) + 0].v.ob[1] - 0x10;
+
+ gSPVertex(POLY_OPA_DISP++, &this->keyboardVtx[this->charIndex * 4], 4, 0);
+
+ FileSelect_DrawTexQuadI4(this->state.gfxCtx,
+ font->fontBuf + D_808141F0[this->charIndex] * FONT_CHAR_TEX_SIZE, 0);
+
+ if (CHECK_BTN_ALL(input->press.button, BTN_A)) {
+ play_sound(NA_SE_SY_FSEL_DECIDE_S);
+ this->fileNames[this->buttonIndex][this->newFileNameCharCount] = D_808141F0[this->charIndex];
+
+ this->newFileNameCharCount++;
+
+ if (this->newFileNameCharCount > 7) {
+ this->newFileNameCharCount = 7;
+ }
+ }
+ } else if (CHECK_BTN_ALL(input->press.button, BTN_A)) {
+ if (this->charPage != this->kbdButton) {
+ if (this->kbdButton == FS_KBD_BTN_BACKSPACE) {
+ if ((this->newFileNameCharCount == 7) && (this->fileNames[this->buttonIndex][7] != 0x3E)) {
+
+ for (i = this->newFileNameCharCount; i < 7; i++) {
+ this->fileNames[this->buttonIndex][i] = this->fileNames[this->buttonIndex][i + 1];
+ }
+
+ this->fileNames[this->buttonIndex][i] = 0x3E;
+ play_sound(NA_SE_SY_FSEL_CLOSE);
+ } else {
+ this->newFileNameCharCount--;
+
+ if (this->newFileNameCharCount < 0) {
+ this->newFileNameCharCount = 0;
+ }
+
+ for (i = this->newFileNameCharCount; i < 7; i++) {
+ this->fileNames[this->buttonIndex][i] = this->fileNames[this->buttonIndex][i + 1];
+ }
+
+ this->fileNames[this->buttonIndex][i] = 0x3E;
+ play_sound(NA_SE_SY_FSEL_CLOSE);
+ }
+ } else if (this->kbdButton == FS_KBD_BTN_END) {
+ validName = false;
+
+ for (i = 0; i < 8; i++) {
+ if (this->fileNames[this->buttonIndex][i] != 0x3E) {
+ validName = true;
+ break;
+ }
+ }
+
+ if (validName) {
+ play_sound(NA_SE_SY_FSEL_DECIDE_L);
+ gSaveContext.fileNum = this->buttonIndex;
+ time = ((void)0, gSaveContext.save.time);
+ Sram_InitSave(this, sramCtx);
+ gSaveContext.save.time = time;
+
+ if (!gSaveContext.flashSaveAvailable) {
+ this->configMode = CM_NAME_ENTRY_TO_MAIN;
+ } else {
+ Sram_SetFlashPagesDefault(sramCtx, gFlashSaveStartPages[this->buttonIndex * 2],
+ gFlashSpecialSaveNumPages[this->buttonIndex * 2]);
+ Sram_StartWriteToFlashDefault(sramCtx);
+ this->configMode = CM_NAME_ENTRY_WAIT_FOR_FLASH_SAVE;
+ }
+
+ this->nameBoxAlpha[this->buttonIndex] = this->nameAlpha[this->buttonIndex] = 200;
+ this->connectorAlpha[this->buttonIndex] = 255;
+ Rumble_Request(300.0f, 180, 20, 100);
+ } else {
+ play_sound(NA_SE_SY_FSEL_ERROR);
+ }
+ }
+ }
+ }
+
+ if (CHECK_BTN_ALL(input->press.button, BTN_CRIGHT)) {
+ play_sound(NA_SE_SY_FSEL_CURSOR);
+ this->newFileNameCharCount++;
+
+ if (this->newFileNameCharCount > 7) {
+ this->newFileNameCharCount = 7;
+ }
+ } else if (CHECK_BTN_ALL(input->press.button, BTN_CLEFT)) {
+ play_sound(NA_SE_SY_FSEL_CURSOR);
+ this->newFileNameCharCount--;
+
+ if (this->newFileNameCharCount < 0) {
+ this->newFileNameCharCount = 0;
+ }
+ }
+ }
+ }
+ }
+
+ gDPPipeSync(POLY_OPA_DISP++);
+ gDPSetCombineMode(POLY_OPA_DISP++, G_CC_MODULATEIDECALA, G_CC_MODULATEIDECALA);
+
+ CLOSE_DISPS(this->state.gfxCtx);
+}
+
+/**
+ * Fade in the name entry box and slide it to the center of the screen from the right side.
+ * After the name entry box is in place, init the keyboard/cursor and change modes.
+ * Update function for `CM_START_NAME_ENTRY`
+ */
+void FileSelect_StartNameEntry(GameState* thisx) {
+ FileSelectState* this = (FileSelectState*)thisx;
+
+ this->nameEntryBoxAlpha += 25;
+
+ if (this->nameEntryBoxAlpha >= 255) {
+ this->nameEntryBoxAlpha = 255;
+ }
+
+ this->nameEntryBoxPosX -= 30;
+
+ if (this->nameEntryBoxPosX <= 0) {
+ this->nameEntryBoxPosX = 0;
+ this->nameEntryBoxAlpha = 255;
+ this->kbdX = 0;
+ this->kbdY = 0;
+ this->kbdButton = FS_KBD_BTN_NONE;
+ this->configMode = CM_NAME_ENTRY;
+ }
+}
+
+/**
+ * Update the keyboard cursor and play sound effects at the appropriate times.
+ * There are many special cases for warping the cursor depending on where
+ * the cursor currently is.
+ * Update function for `CM_NAME_ENTRY`
+ */
+void FileSelect_UpdateKeyboardCursor(GameState* thisx) {
+ FileSelectState* this = (FileSelectState*)thisx;
+ s16 prevKbdX;
+
+ this->kbdButton = FS_KBD_BTN_NONE;
+
+ if (this->kbdY != 5) {
+ if (this->stickAdjX < -30) {
+ play_sound(NA_SE_SY_FSEL_CURSOR);
+ this->charIndex--;
+ this->kbdX--;
+ if (this->kbdX < 0) {
+ this->kbdX = 12;
+ this->charIndex = (this->kbdY * 13) + this->kbdX;
+ }
+ } else if (this->stickAdjX > 30) {
+ play_sound(NA_SE_SY_FSEL_CURSOR);
+ this->charIndex++;
+ this->kbdX++;
+ if (this->kbdX > 12) {
+ this->kbdX = 0;
+ this->charIndex = (this->kbdY * 13) + this->kbdX;
+ }
+ }
+ } else {
+ if (this->stickAdjX < -30) {
+ play_sound(NA_SE_SY_FSEL_CURSOR);
+ this->kbdX--;
+ if (this->kbdX < 3) {
+ this->kbdX = 4;
+ }
+ } else if (this->stickAdjX > 30) {
+ play_sound(NA_SE_SY_FSEL_CURSOR);
+ this->kbdX++;
+ if (this->kbdX > 4) {
+ this->kbdX = 3;
+ }
+ }
+ }
+
+ if (this->stickAdjY > 30) {
+ play_sound(NA_SE_SY_FSEL_CURSOR);
+
+ this->kbdY--;
+
+ if (this->kbdY < 0) {
+ // Don't go to bottom row
+ if (this->kbdX < 8) {
+ this->kbdY = 4;
+ this->charIndex = (s32)(this->kbdX + 52);
+ } else {
+ this->kbdY = 5;
+ this->charIndex += 52;
+ prevKbdX = this->kbdX;
+
+ if (this->kbdX < 10) {
+ this->kbdX = 3;
+ } else if (this->kbdX < 13) {
+ this->kbdX = 4;
+ }
+ this->unk_2451E[this->kbdX] = prevKbdX;
+ }
+ } else {
+ this->charIndex -= 13;
+
+ if (this->kbdY == 4) {
+ this->charIndex = 52;
+ this->kbdX = this->unk_2451E[this->kbdX];
+ this->charIndex += this->kbdX;
+ }
+ }
+ } else if (this->stickAdjY < -30) {
+ play_sound(NA_SE_SY_FSEL_CURSOR);
+ this->kbdY++;
+
+ if (this->kbdY > 5) {
+ this->kbdY = 0;
+ this->kbdX = this->unk_2451E[this->kbdX];
+ this->charIndex = this->kbdX;
+ } else {
+ this->charIndex += 13;
+
+ if (this->kbdY == 5) {
+ if (this->kbdX < 8) {
+ this->kbdY = 0;
+ this->charIndex = this->kbdX;
+ } else {
+ prevKbdX = this->kbdX;
+
+ if (this->kbdX < 3) {
+ this->kbdX = 0;
+ } else if (this->kbdX < 6) {
+ this->kbdX = 1;
+ } else if (this->kbdX < 8) {
+ this->kbdX = 2;
+ } else if (this->kbdX < 10) {
+ this->kbdX = 3;
+ } else if (this->kbdX < 13) {
+ this->kbdX = 4;
+ }
+ this->unk_2451E[this->kbdX] = prevKbdX;
+ }
+ }
+ }
+ }
+ if (this->kbdY == 5) {
+ this->kbdButton = this->kbdX;
+ }
+}
+
+/**
+ * Update and wait for the save to flash to complete.
+ * Update function for `CM_NAME_ENTRY_WAIT_FOR_FLASH_SAVE`
+ */
+void FileSelect_NameEntryWaitForFlashSave(GameState* thisx) {
+ FileSelectState* this = (FileSelectState*)thisx;
+ SramContext* sramCtx = &this->sramCtx;
+
+ Sram_UpdateWriteToFlashDefault(sramCtx);
+
+ if (sramCtx->status == 0) {
+ this->configMode = CM_NAME_ENTRY_TO_MAIN;
+ }
+}
+
+/**
+ * This function is mostly a copy paste of `FileSelect_StartNameEntry`.
+ * The name entry box fades and slides in even though it is not visible.
+ * After this is complete, change to the options config mode.
+ * Update function for `CM_START_OPTIONS`
+ */
+void FileSelect_StartOptions(GameState* thisx) {
+ FileSelectState* this = (FileSelectState*)thisx;
+
+ this->nameEntryBoxAlpha += 25;
+
+ if (this->nameEntryBoxAlpha >= 255) {
+ this->nameEntryBoxAlpha = 255;
+ }
+
+ this->nameEntryBoxPosX -= 30;
+
+ if (this->nameEntryBoxPosX <= 0) {
+ this->nameEntryBoxPosX = 0;
+ this->nameEntryBoxAlpha = 255;
+ this->configMode = CM_OPTIONS_MENU;
+ }
+}
+
+u8 sSelectedSetting;
+// bss padding
+s32 D_80814E94;
+s32 D_80814E98;
+s32 D_80814E9C;
+s32 D_80814EA0;
+
+/**
+ * Update the cursor and appropriate settings for the options menu.
+ * If the player presses B, write the selected options to the SRAM header
+ * and set config mode to rotate back to the main menu.
+ * Update function for `CM_OPTIONS_MENU`
+ */
+void FileSelect_UpdateOptionsMenu(GameState* thisx) {
+ FileSelectState* this = (FileSelectState*)thisx;
+ SramContext* sramCtx = &this->sramCtx;
+ Input* input = CONTROLLER1(&this->state);
+
+ if (CHECK_BTN_ALL(input->press.button, BTN_B)) {
+ play_sound(NA_SE_SY_FSEL_DECIDE_L);
+ Sram_WriteSaveOptionsToBuffer(sramCtx);
+
+ if (!gSaveContext.flashSaveAvailable) {
+ this->configMode = CM_OPTIONS_TO_MAIN;
+ } else {
+ Sram_SetFlashPagesDefault(sramCtx, gFlashSaveStartPages[8], gFlashSpecialSaveNumPages[8]);
+ Sram_StartWriteToFlashDefault(sramCtx);
+ this->configMode = CM_OPTIONS_WAIT_FOR_FLASH_SAVE;
+ }
+ func_801A3D98(gSaveContext.options.audioSetting);
+ return;
+ }
+
+ if (this->stickAdjX < -30) {
+ play_sound(NA_SE_SY_FSEL_CURSOR);
+
+ if (sSelectedSetting == FS_SETTING_AUDIO) {
+ gSaveContext.options.audioSetting--;
+
+ // because audio setting is unsigned, can't check for < 0
+ if (gSaveContext.options.audioSetting > 0xF0) {
+ gSaveContext.options.audioSetting = SAVE_AUDIO_SURROUND;
+ }
+ } else {
+ gSaveContext.options.zTargetSetting ^= 1;
+ }
+ } else if (this->stickAdjX > 30) {
+ play_sound(NA_SE_SY_FSEL_CURSOR);
+
+ if (sSelectedSetting == FS_SETTING_AUDIO) {
+ gSaveContext.options.audioSetting++;
+ if (gSaveContext.options.audioSetting > SAVE_AUDIO_SURROUND) {
+ gSaveContext.options.audioSetting = SAVE_AUDIO_STEREO;
+ }
+ } else {
+ gSaveContext.options.zTargetSetting ^= 1;
+ }
+ }
+
+ if ((this->stickAdjY < -30) || (this->stickAdjY > 30)) {
+ play_sound(NA_SE_SY_FSEL_CURSOR);
+ sSelectedSetting ^= 1;
+ return;
+ }
+ if (CHECK_BTN_ALL(input->press.button, BTN_A)) {
+ play_sound(NA_SE_SY_FSEL_DECIDE_L);
+ sSelectedSetting ^= 1;
+ }
+}
+
+/**
+ * Update and wait for the save to flash to complete.
+ * Update function for `CM_OPTIONS_WAIT_FOR_FLASH_SAVE`
+ */
+void FileSelect_OptionsWaitForFlashSave(GameState* thisx) {
+ FileSelectState* this = (FileSelectState*)thisx;
+ SramContext* sramCtx = &this->sramCtx;
+
+ Sram_UpdateWriteToFlashDefault(sramCtx);
+
+ if (sramCtx->status == 0) {
+ this->configMode = CM_OPTIONS_TO_MAIN;
+ }
+}
+
+typedef struct {
+ /* 0x0 */ TexturePtr texture;
+ /* 0x4 */ u16 width;
+ /* 0x6 */ u16 height;
+} OptionsMenuTextureInfo; // size = 0x8
+
+OptionsMenuTextureInfo gOptionsMenuHeaders[] = {
+ { gFileSelOptionsENGTex, 128, 16 }, { gFileSelSoundENGTex, 64, 16 },
+ { gFileSelTargetingENGTex, 64, 16 }, { gFileSelCheckBrightnessENGTex, 96, 16 },
+ { gFileSelDolbySurroundLogoENGTex, 48, 17 },
+};
+
+OptionsMenuTextureInfo gOptionsMenuSettings[] = {
+ { gFileSelStereoENGTex, 48, 16 }, { gFileSelMonoENGTex, 48, 16 }, { gFileSelHeadsetENGTex, 48, 16 },
+ { gFileSelSurroundENGTex, 48, 16 }, { gFileSelSwitchENGTex, 48, 16 }, { gFileSelHoldENGTex, 48, 16 },
+};
+
+void FileSelect_DrawOptionsImpl(GameState* thisx) {
+ static s16 sCursorPrimRed = 255;
+ static s16 sCursorPrimGreen = 255;
+ static s16 sCursorPrimBlue = 255;
+ static s16 sCursorEnvRed = 0;
+ static s16 sCursorEnvGreen = 0;
+ static s16 sCursorEnvBlue = 0;
+ static s16 sCursorPulseDir = 1;
+ static s16 sCursorFlashTimer = 20;
+ static s16 sCursorPrimColors[][3] = {
+ { 255, 255, 255 },
+ { 0, 255, 255 },
+ };
+ static s16 sCursorEnvColors[][3] = {
+ { 0, 0, 0 },
+ { 0, 150, 150 },
+ };
+ FileSelectState* this = (FileSelectState*)thisx;
+ s16 cursorRedStep;
+ s16 cursorGreenStep;
+ s16 cursorBlueStep;
+ s16 i;
+ s16 j;
+ s16 vtx;
+
+ OPEN_DISPS(this->state.gfxCtx);
+
+ cursorRedStep = ABS_ALT(sCursorPrimRed - sCursorPrimColors[sCursorPulseDir][0]) / sCursorFlashTimer;
+ cursorGreenStep = ABS_ALT(sCursorPrimGreen - sCursorPrimColors[sCursorPulseDir][1]) / sCursorFlashTimer;
+ cursorBlueStep = ABS_ALT(sCursorPrimBlue - sCursorPrimColors[sCursorPulseDir][2]) / sCursorFlashTimer;
+
+ if (sCursorPrimRed >= sCursorPrimColors[sCursorPulseDir][0]) {
+ sCursorPrimRed -= cursorRedStep;
+ } else {
+ sCursorPrimRed += cursorRedStep;
+ }
+
+ if (sCursorPrimGreen >= sCursorPrimColors[sCursorPulseDir][1]) {
+ sCursorPrimGreen -= cursorGreenStep;
+ } else {
+ sCursorPrimGreen += cursorGreenStep;
+ }
+
+ if (sCursorPrimBlue >= sCursorPrimColors[sCursorPulseDir][2]) {
+ sCursorPrimBlue -= cursorBlueStep;
+ } else {
+ sCursorPrimBlue += cursorBlueStep;
+ }
+
+ cursorRedStep = ABS_ALT(sCursorEnvRed - sCursorEnvColors[sCursorPulseDir][0]) / sCursorFlashTimer;
+ cursorGreenStep = ABS_ALT(sCursorEnvGreen - sCursorEnvColors[sCursorPulseDir][1]) / sCursorFlashTimer;
+ cursorBlueStep = ABS_ALT(sCursorEnvBlue - sCursorEnvColors[sCursorPulseDir][2]) / sCursorFlashTimer;
+
+ if (sCursorEnvRed >= sCursorEnvColors[sCursorPulseDir][0]) {
+ sCursorEnvRed -= cursorRedStep;
+ } else {
+ sCursorEnvRed += cursorRedStep;
+ }
+
+ if (sCursorEnvGreen >= sCursorEnvColors[sCursorPulseDir][1]) {
+ sCursorEnvGreen -= cursorGreenStep;
+ } else {
+ sCursorEnvGreen += cursorGreenStep;
+ }
+
+ if (sCursorEnvBlue >= sCursorEnvColors[sCursorPulseDir][2]) {
+ sCursorEnvBlue -= cursorBlueStep;
+ } else {
+ sCursorEnvBlue += cursorBlueStep;
+ }
+
+ if (--sCursorFlashTimer == 0) {
+ sCursorPrimRed = sCursorPrimColors[sCursorPulseDir][0];
+ sCursorPrimGreen = sCursorPrimColors[sCursorPulseDir][1];
+ sCursorPrimBlue = sCursorPrimColors[sCursorPulseDir][2];
+
+ sCursorEnvRed = sCursorEnvColors[sCursorPulseDir][0];
+ sCursorEnvGreen = sCursorEnvColors[sCursorPulseDir][1];
+ sCursorEnvBlue = sCursorEnvColors[sCursorPulseDir][2];
+
+ sCursorFlashTimer = 20;
+
+ if (++sCursorPulseDir > 1) {
+ sCursorPulseDir = 0;
+ }
+ }
+
+ // blue divider lines
+ gDPPipeSync(POLY_OPA_DISP++);
+ gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 0, 255, 255, this->titleAlpha[FS_TITLE_CUR]);
+ gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, 0);
+
+ gDPLoadTextureBlock_4b(POLY_OPA_DISP++, gFileSelOptionsDividerTex, G_IM_FMT_IA, 256, 2, 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);
+
+ Matrix_Push();
+ Matrix_Translate(0.0f, 0.1f, 0.0f, MTXMODE_APPLY);
+ gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(this->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPVertex(POLY_OPA_DISP++, gOptionsDividerTopVtx, 4, 0);
+ gSP1Quadrangle(POLY_OPA_DISP++, 0, 2, 3, 1, 0);
+ Matrix_Pop();
+
+ Matrix_Push();
+ Matrix_Translate(0.0f, 0.2f, 0.0f, MTXMODE_APPLY);
+ gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(this->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPVertex(POLY_OPA_DISP++, gOptionsDividerMiddleVtx, 4, 0);
+ gSP1Quadrangle(POLY_OPA_DISP++, 0, 2, 3, 1, 0);
+ Matrix_Pop();
+
+ Matrix_Push();
+ Matrix_Translate(0.0f, 0.4f, 0.0f, MTXMODE_APPLY);
+ gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(this->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPVertex(POLY_OPA_DISP++, gOptionsDividerBottomVtx, 4, 0);
+ gSP1Quadrangle(POLY_OPA_DISP++, 0, 2, 3, 1, 0);
+ Matrix_Pop();
+
+ gSPVertex(POLY_OPA_DISP++, D_80813DF0, 32, 0);
+ gDPPipeSync(POLY_OPA_DISP++);
+ gDPSetCombineLERP(POLY_OPA_DISP++, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0, PRIMITIVE,
+ ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0);
+ gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, this->titleAlpha[FS_TITLE_CUR]);
+ gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, 255);
+
+ for (i = 0, vtx = 0; i < 5; i++, vtx += 4) {
+ if (i == 4) {
+ gDPPipeSync(POLY_OPA_DISP++);
+ if (gSaveContext.options.audioSetting == SAVE_AUDIO_SURROUND) {
+ gDPSetEnvColor(POLY_OPA_DISP++, 255, 255, 255, 255);
+ } else {
+ gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 0, 0, 0, this->titleAlpha[FS_TITLE_CUR]);
+ gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, 255);
+ }
+ }
+
+ gDPLoadTextureBlock(POLY_OPA_DISP++, gOptionsMenuHeaders[i].texture, G_IM_FMT_IA, G_IM_SIZ_8b,
+ gOptionsMenuHeaders[i].width, gOptionsMenuHeaders[i].height, 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);
+ gSP1Quadrangle(POLY_OPA_DISP++, vtx, vtx + 2, vtx + 3, vtx + 1, 0);
+ }
+
+ gDPPipeSync(POLY_OPA_DISP++);
+ gDPSetCombineLERP(POLY_OPA_DISP++, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0, PRIMITIVE,
+ ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0);
+
+ gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, this->titleAlpha[FS_TITLE_CUR]);
+ gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, 255);
+ gSPVertex(POLY_OPA_DISP++, D_80813F30, 32, 0);
+
+ for (i = 0, vtx = 0; i < 4; i++, vtx += 4) {
+ gDPPipeSync(POLY_OPA_DISP++);
+ if (i == gSaveContext.options.audioSetting) {
+ if (sSelectedSetting == FS_SETTING_AUDIO) {
+ gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, sCursorPrimRed, sCursorPrimGreen, sCursorPrimBlue,
+ this->titleAlpha[FS_TITLE_CUR]);
+ gDPSetEnvColor(POLY_OPA_DISP++, sCursorEnvRed, sCursorEnvGreen, sCursorEnvBlue, 255);
+ } else {
+ gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, this->titleAlpha[FS_TITLE_CUR]);
+ gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, 255);
+ }
+ } else {
+ gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 120, 120, 120, this->titleAlpha[FS_TITLE_CUR]);
+ gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, 255);
+ }
+
+ gDPLoadTextureBlock(POLY_OPA_DISP++, gOptionsMenuSettings[i].texture, G_IM_FMT_IA, G_IM_SIZ_8b,
+ gOptionsMenuSettings[i].width, gOptionsMenuHeaders[i].height, 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);
+ gSP1Quadrangle(POLY_OPA_DISP++, vtx, vtx + 2, vtx + 3, vtx + 1, 0);
+ }
+
+ for (; i < 6; i++, vtx += 4) {
+ gDPPipeSync(POLY_OPA_DISP++);
+
+ if (i == (gSaveContext.options.zTargetSetting + 4)) {
+ if (sSelectedSetting == FS_SETTING_ZTARGET) {
+ gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, sCursorPrimRed, sCursorPrimGreen, sCursorPrimBlue,
+ this->titleAlpha[FS_TITLE_CUR]);
+ gDPSetEnvColor(POLY_OPA_DISP++, sCursorEnvRed, sCursorEnvGreen, sCursorEnvBlue, 255);
+ } else {
+ gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, this->titleAlpha[FS_TITLE_CUR]);
+ gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, 255);
+ }
+ } else {
+ gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 120, 120, 120, this->titleAlpha[FS_TITLE_CUR]);
+ gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, 255);
+ }
+
+ gDPLoadTextureBlock(POLY_OPA_DISP++, gOptionsMenuSettings[i].texture, G_IM_FMT_IA, G_IM_SIZ_8b,
+ gOptionsMenuSettings[i].width, gOptionsMenuHeaders[i].height, 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);
+ gSP1Quadrangle(POLY_OPA_DISP++, vtx, vtx + 2, vtx + 3, vtx + 1, 0);
+ }
+
+ gDPPipeSync(POLY_OPA_DISP++);
+
+ // check brightness bars
+ gDPLoadTextureBlock_4b(POLY_OPA_DISP++, gFileSelBrightnessCheckTex, G_IM_FMT_IA, 96, 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);
+ gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 55, 55, 55, this->titleAlpha[FS_TITLE_CUR]);
+ gDPSetEnvColor(POLY_OPA_DISP++, 40, 40, 40, 255);
+ gSP1Quadrangle(POLY_OPA_DISP++, vtx, vtx + 2, vtx + 3, vtx + 1, 0);
+
+ vtx += 4;
+
+ gDPPipeSync(POLY_OPA_DISP++);
+ gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 30, 30, 30, this->titleAlpha[FS_TITLE_CUR]);
+ gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, 255);
+ gSP1Quadrangle(POLY_OPA_DISP++, vtx, vtx + 2, vtx + 3, vtx + 1, 0);
+
+ CLOSE_DISPS(this->state.gfxCtx);
+}
+
+void FileSelect_DrawOptions(GameState* thisx) {
+ FileSelect_DrawOptionsImpl(thisx);
+}
diff --git a/src/overlays/gamestates/ovl_file_choose/z_file_nameset_data.c b/src/overlays/gamestates/ovl_file_choose/z_file_nameset_data.c
new file mode 100644
index 0000000000..47619b66d6
--- /dev/null
+++ b/src/overlays/gamestates/ovl_file_choose/z_file_nameset_data.c
@@ -0,0 +1,17 @@
+#include "z_file_select.h"
+
+// Vtx Data
+#include "overlays/ovl_file_choose/ovl_file_choose.c"
+
+u8 D_808141F0[] = {
+ // 'A' 'B' 'C' 'D' 'E' 'F' 'G' 'H' 'I' 'J' 'K' 'L' 'M'
+ /* Row 0 */ 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
+ // 'N' 'O' 'P' 'Q' 'R' 'S' 'T' 'U' 'V' 'W' 'X' 'Y' 'Z'
+ /* Row 1 */ 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23,
+ // 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm'
+ /* Row 2 */ 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,
+ // 'n' 'o' 'p' 'q' 'r' 's' 't' 'u' 'v' 'w' 'x' 'y' 'z'
+ /* Row 3 */ 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D,
+ // '1' '2' '3' '4' '5' '6' '7' '8' '9' '0' '.' '-' ' '
+ /* Row 4 */ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x00, 0x40, 0x3F, 0x3E
+};
diff --git a/src/overlays/gamestates/ovl_file_choose/z_file_select.h b/src/overlays/gamestates/ovl_file_choose/z_file_select.h
new file mode 100644
index 0000000000..7dcc72a9da
--- /dev/null
+++ b/src/overlays/gamestates/ovl_file_choose/z_file_select.h
@@ -0,0 +1,327 @@
+#ifndef FILE_SELECT_H
+#define FILE_SELECT_H
+
+#include "global.h"
+
+// `sramCtx->noFlashSaveBuf` is never allocated space, so should never be used
+// Slot offsets are also based on OoT SaveContext sizes, and contains incorrect sizes from MM
+// Macros appear to be remnant from OoT
+#define NO_FLASH_GET_NEWF(sramCtx, slotNum, index) \
+ (sramCtx->noFlashSaveBuf[gSramSlotOffsets[slotNum] + offsetof(SaveContext, save.saveInfo.playerData.newf[index])])
+#define NO_FLASH_SLOT_OCCUPIED(sramCtx, slotNum) \
+ ((NO_FLASH_GET_NEWF(sramCtx, slotNum, 0) == 'Z') || (NO_FLASH_GET_NEWF(sramCtx, slotNum, 1) == 'E') || \
+ (NO_FLASH_GET_NEWF(sramCtx, slotNum, 2) == 'L') || (NO_FLASH_GET_NEWF(sramCtx, slotNum, 3) == 'D') || \
+ (NO_FLASH_GET_NEWF(sramCtx, slotNum, 4) == 'A') || (NO_FLASH_GET_NEWF(sramCtx, slotNum, 5) == '3'))
+
+#define GET_NEWF(fileSelect, slotNum, index) (fileSelect->newf[slotNum][index])
+#define SLOT_OCCUPIED(fileSelect, slotNum) \
+ ((GET_NEWF(fileSelect, slotNum, 0) == 'Z') && (GET_NEWF(fileSelect, slotNum, 1) == 'E') && \
+ (GET_NEWF(fileSelect, slotNum, 2) == 'L') && (GET_NEWF(fileSelect, slotNum, 3) == 'D') && \
+ (GET_NEWF(fileSelect, slotNum, 4) == 'A') && (GET_NEWF(fileSelect, slotNum, 5) == '3'))
+
+// 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
+// Select mode: Displays the selected file with various details about it, and allows the player to confirm and open it
+typedef enum {
+ /* 0 */ FS_MENU_MODE_INIT,
+ /* 1 */ FS_MENU_MODE_CONFIG,
+ /* 2 */ FS_MENU_MODE_SELECT
+} MenuMode;
+
+typedef enum {
+ /* 0x00 */ CM_FADE_IN_START,
+ /* 0x01 */ CM_FADE_IN_END,
+ /* 0x02 */ CM_MAIN_MENU,
+ /* 0x03 */ CM_SETUP_COPY_SOURCE,
+ /* 0x04 */ CM_SELECT_COPY_SOURCE,
+ /* 0x05 */ CM_SETUP_COPY_DEST_1,
+ /* 0x06 */ CM_SETUP_COPY_DEST_2,
+ /* 0x07 */ CM_SELECT_COPY_DEST,
+ /* 0x08 */ CM_EXIT_TO_COPY_SOURCE_1,
+ /* 0x09 */ CM_EXIT_TO_COPY_SOURCE_2,
+ /* 0x0A */ CM_SETUP_COPY_CONFIRM_1,
+ /* 0x0B */ CM_SETUP_COPY_CONFIRM_2,
+ /* 0x0C */ CM_COPY_CONFIRM,
+ /* 0x0D */ CM_COPY_WAIT_FOR_FLASH_SAVE,
+ /* 0x0E */ CM_RETURN_TO_COPY_DEST,
+ /* 0x0F */ CM_COPY_ANIM_1,
+ /* 0x10 */ CM_COPY_ANIM_2,
+ /* 0x11 */ CM_COPY_ANIM_3,
+ /* 0x12 */ CM_COPY_ANIM_4,
+ /* 0x13 */ CM_COPY_ANIM_5,
+ /* 0x14 */ CM_COPY_RETURN_MAIN,
+ /* 0x15 */ CM_SETUP_ERASE_SELECT,
+ /* 0x16 */ CM_ERASE_SELECT,
+ /* 0x17 */ CM_SETUP_ERASE_CONFIRM_1,
+ /* 0x18 */ CM_SETUP_ERASE_CONFIRM_2,
+ /* 0x19 */ CM_ERASE_CONFIRM,
+ /* 0x1A */ CM_EXIT_TO_ERASE_SELECT_1,
+ /* 0x1B */ CM_EXIT_TO_ERASE_SELECT_2,
+ /* 0x1C */ CM_ERASE_ANIM_1,
+ /* 0x1D */ CM_ERASE_WAIT_FOR_FLASH_SAVE,
+ /* 0x1E */ CM_ERASE_ANIM_2,
+ /* 0x1F */ CM_ERASE_ANIM_3,
+ /* 0x20 */ CM_EXIT_ERASE_TO_MAIN,
+ /* 0x21 */ CM_UNUSED_31,
+ /* 0x22 */ CM_ROTATE_TO_NAME_ENTRY,
+ /* 0x23 */ CM_START_NAME_ENTRY,
+ /* 0x24 */ CM_NAME_ENTRY,
+ /* 0x25 */ CM_NAME_ENTRY_WAIT_FOR_FLASH_SAVE,
+ /* 0x26 */ CM_NAME_ENTRY_TO_MAIN,
+ /* 0x27 */ CM_MAIN_TO_OPTIONS,
+ /* 0x28 */ CM_START_OPTIONS,
+ /* 0x29 */ CM_OPTIONS_MENU,
+ /* 0x2A */ CM_OPTIONS_WAIT_FOR_FLASH_SAVE,
+ /* 0x2B */ CM_OPTIONS_TO_MAIN,
+ /* 0x2C */ CM_UNUSED_DELAY
+} ConfigMode;
+
+typedef enum {
+ /* 0 */ SM_FADE_MAIN_TO_SELECT,
+ /* 1 */ SM_MOVE_FILE_TO_TOP,
+ /* 2 */ SM_FADE_IN_FILE_INFO,
+ /* 3 */ SM_CONFIRM_FILE,
+ /* 4 */ SM_FADE_OUT_FILE_INFO,
+ /* 5 */ SM_MOVE_FILE_TO_SLOT,
+ /* 6 */ SM_FADE_OUT,
+ /* 7 */ SM_LOAD_GAME
+} SelectMode;
+
+typedef enum {
+ /* 0 */ FS_TITLE_SELECT_FILE, // "Please select a file."
+ /* 1 */ FS_TITLE_OPEN_FILE, // "Open this file?"
+ /* 2 */ FS_TITLE_COPY_FROM, // "Copy which file?"
+ /* 3 */ FS_TITLE_COPY_TO, // "Copy to which file?"
+ /* 4 */ FS_TITLE_COPY_CONFIRM, // "Are you sure?"
+ /* 5 */ FS_TITLE_COPY_COMPLETE, // "File copied."
+ /* 6 */ FS_TITLE_ERASE_FILE, // "Erase which file?"
+ /* 7 */ FS_TITLE_ERASE_CONFIRM, // "Are you sure?"
+ /* 8 */ FS_TITLE_ERASE_COMPLETE // "File erased."
+} TitleLabel;
+
+typedef enum {
+ /* 0 */ FS_TITLE_CUR,
+ /* 1 */ FS_TITLE_NEXT
+} TitleIndex;
+
+typedef enum {
+ /* -1 */ FS_WARNING_NONE = -1,
+ /* 0 */ FS_WARNING_NO_FILE_COPY, // "No file to copy."
+ /* 1 */ FS_WARNING_NO_FILE_ERASE, // "No file to erase."
+ /* 2 */ FS_WARNING_NO_EMPTY_FILES, // "There is no empty file."
+ /* 3 */ FS_WARNING_FILE_EMPTY, // "This is an empty file."
+ /* 4 */ FS_WARNING_FILE_IN_USE // "This file is in use."
+} WarningLabel;
+
+typedef enum {
+ /* 0 */ FS_BTN_MAIN_FILE_1,
+ /* 1 */ FS_BTN_MAIN_FILE_2,
+ /* 2 */ FS_BTN_MAIN_FILE_3,
+ /* 3 */ FS_BTN_MAIN_COPY,
+ /* 4 */ FS_BTN_MAIN_ERASE,
+ /* 5 */ FS_BTN_MAIN_OPTIONS
+} MainMenuButtonIndex;
+
+typedef enum {
+ /* 0 */ FS_BTN_COPY_FILE_1,
+ /* 1 */ FS_BTN_COPY_FILE_2,
+ /* 2 */ FS_BTN_COPY_FILE_3,
+ /* 3 */ FS_BTN_COPY_QUIT
+} CopyMenuButtonIndex;
+
+typedef enum {
+ /* 0 */ FS_BTN_ERASE_FILE_1,
+ /* 1 */ FS_BTN_ERASE_FILE_2,
+ /* 2 */ FS_BTN_ERASE_FILE_3,
+ /* 3 */ FS_BTN_ERASE_QUIT
+} EraseMenuButtonIndex;
+
+typedef enum {
+ /* 0 */ FS_BTN_SELECT_FILE_1,
+ /* 1 */ FS_BTN_SELECT_FILE_2,
+ /* 2 */ FS_BTN_SELECT_FILE_3,
+ /* 3 */ FS_BTN_SELECT_YES,
+ /* 4 */ FS_BTN_SELECT_QUIT
+} SelectMenuButtonIndex;
+
+typedef enum {
+ /* 0 */ FS_BTN_CONFIRM_YES,
+ /* 1 */ FS_BTN_CONFIRM_QUIT
+} ConfirmButtonIndex;
+
+typedef enum {
+ /* 0 */ FS_BTN_ACTION_COPY,
+ /* 1 */ FS_BTN_ACTION_ERASE
+} ActionButtonIndex;
+
+typedef enum {
+ /* 0 */ FS_SETTING_AUDIO,
+ /* 1 */ FS_SETTING_ZTARGET
+} SettingIndex;
+
+typedef enum {
+ /* 0 */ FS_CHAR_PAGE_HIRA,
+ /* 1 */ FS_CHAR_PAGE_KATA,
+ /* 2 */ FS_CHAR_PAGE_ENG
+} CharPage;
+
+typedef enum {
+ /* 0 */ FS_KBD_BTN_HIRA,
+ /* 1 */ FS_KBD_BTN_KATA,
+ /* 2 */ FS_KBD_BTN_ENG,
+ /* 3 */ FS_KBD_BTN_BACKSPACE,
+ /* 4 */ FS_KBD_BTN_END,
+ /* 99 */ FS_KBD_BTN_NONE = 99
+} KeyboardButton;
+
+typedef struct FileSelectState {
+ /* 0x00000 */ GameState state;
+ /* 0x000A4 */ Vtx* windowVtx;
+ /* 0x000A8 */ u8* staticSegment;
+ /* 0x000AC */ u8* parameterSegment;
+ /* 0x000B0 */ u8* titleSegment;
+ /* 0x000B8 */ View view;
+ /* 0x00220 */ SramContext sramCtx;
+ /* 0x00248 */ SkyboxContext skyboxCtx;
+ /* 0x00470 */ MessageContext msgCtx;
+ /* 0x12550 */ Font font;
+ /* 0x242E0 */ EnvironmentContext envCtx;
+ /* 0x243E0 */ UNK_TYPE1 pad243E0[0x4];
+ /* 0x243E4 */ Vtx* windowContentVtx;
+ /* 0x243E8 */ Vtx* keyboardVtx;
+ /* 0x243EC */ Vtx* nameEntryVtx;
+ /* 0x243F0 */ Vtx* keyboard2Vtx;
+ /* 0x243F4 */ u8 newf[4][6];
+ /* 0x2440C */ u16 threeDayResetCount[4];
+ /* 0x24414 */ char fileNames[4][8];
+ /* 0x24434 */ s16 healthCapacity[4];
+ /* 0x2443C */ s16 health[4];
+ /* 0x24444 */ u32 questItems[4];
+ /* 0x24454 */ s8 defenseHearts[4];
+ /* 0x24458 */ u16 time[4];
+ /* 0x24460 */ s16 day[4];
+ /* 0x24468 */ u8 isOwlSave[4];
+ /* 0x2446C */ s16 rupees[4];
+ /* 0x24474 */ u8 walletUpgrades[4];
+ /* 0x24478 */ u8 maskCount[4];
+ /* 0x2447C */ u8 heartPieceCount[4];
+ /* 0x24480 */ s16 buttonIndex; // enum will depend on `ConfigMode`
+ /* 0x24482 */ s16 confirmButtonIndex; // see `ConfirmButtonIndex` enum
+ /* 0x24484 */ s16 menuMode; // see `MenuMode` enum
+ /* 0x24486 */ s16 configMode; // see `ConfigMode` enum
+ /* 0x24488 */ s16 prevConfigMode; // see `ConfigMode` enum
+ /* 0x2448A */ s16 nextConfigMode; // see `ConfigMode` enum
+ /* 0x2448C */ s16 selectMode; // see `SelectMode` enum
+ /* 0x2448E */ s16 selectedFileIndex;
+ /* 0x24490 */ UNK_TYPE1 pad24490[0x2];
+ /* 0x24492 */ s16 fileNamesY[3];
+ /* 0x24498 */ s16 actionTimer;
+ /* 0x2449A */ s16 buttonYOffsets[6];
+ /* 0x244A6 */ s16 copyDestFileIndex;
+ /* 0x244A8 */ s16 warningLabel;
+ /* 0x244AA */ s16 warningButtonIndex;
+ /* 0x244AC */ s16 titleLabel; // see `TitleLabel` enum
+ /* 0x244AE */ s16 nextTitleLabel; // see `TitleLabel` enum
+ /* 0x244B0 */ s16 windowColor[3];
+ /* 0x244B6 */ s16 titleAlpha[2]; // see `TitleIndex` enum
+ /* 0x244BA */ s16 windowAlpha;
+ /* 0x244BC */ s16 fileButtonAlpha[3];
+ /* 0x244C2 */ s16 nameBoxAlpha[3];
+ /* 0x244C8 */ s16 nameAlpha[3];
+ /* 0x244CE */ s16 connectorAlpha[3];
+ /* 0x244D4 */ s16 fileInfoAlpha[3];
+ /* 0x244DA */ s16 actionButtonAlpha[2];
+ /* 0x244DA */ s16 confirmButtonAlpha[2];
+ /* 0x244E2 */ s16 optionButtonAlpha;
+ /* 0x244E4 */ s16 nameEntryBoxAlpha;
+ /* 0x244E6 */ s16 controlsAlpha;
+ /* 0x244E8 */ s16 emptyFileTextAlpha;
+ /* 0x244EA */ s16 highlightColor[4];
+ /* 0x244F2 */ s16 highlightPulseDir;
+ /* 0x244F4 */ s16 unk_244F4;
+ /* 0x244F6 */ s16 confirmButtonTexIndices[2];
+ /* 0x244FA */ s16 inputTimerX;
+ /* 0x244FC */ s16 inputTimerY;
+ /* 0x244FE */ s16 stickXDir;
+ /* 0x24500 */ s16 stickYDir;
+ /* 0x24502 */ s16 stickAdjX;
+ /* 0x24504 */ s16 stickAdjY;
+ /* 0x24506 */ s16 nameEntryBoxPosX;
+ /* 0x24508 */ s16 windowPosX;
+ /* 0x2450A */ s16 screenFillAlpha;
+ /* 0x2450C */ f32 windowRot;
+ /* 0x24510 */ s16 kbdButton;
+ /* 0x24512 */ s16 charPage;
+ /* 0x24514 */ s16 charBgAlpha;
+ /* 0x24516 */ s16 charIndex;
+ /* 0x24518 */ s16 kbdX;
+ /* 0x2451A */ s16 kbdY;
+ /* 0x2451C */ s16 newFileNameCharCount;
+ /* 0x2451E */ s16 unk_2451E[5];
+ /* 0x24528 */ s16 highlightTimer;
+ /* 0x2452A */ s16 unk_2452A;
+ /* 0x2452C */ s16 unk_2452C[4];
+ /* 0x24534 */ s16 unk_24534[4];
+ /* 0x2453C */ s16 unk_2453C[4];
+ /* 0x24544 */ s16 unk_24544[4];
+ /* 0x2454C */ s16 unk_2454C;
+ /* 0x2454E */ s16 unk_2454E;
+ /* 0x24550 */ s16 unk_24550;
+} FileSelectState; // size = 0x24558
+
+void FileSelect_Init(GameState* thisx);
+void FileSelect_Destroy(GameState* thisx);
+
+void FileSelect_PulsateCursor(GameState* thisx);
+void FileSelect_DrawNameEntry(GameState* thisx);
+void FileSelect_DrawOptions(GameState* thisx);
+void FileSelect_DrawTexQuadI4(GraphicsContext* gfxCtx, TexturePtr texture, s16 point);
+
+// Copying Files
+void FileSelect_SetupCopySource(GameState* thisx);
+void FileSelect_SelectCopySource(GameState* thisx);
+void FileSelect_SetupCopyDest1(GameState* thisx);
+void FileSelect_SetupCopyDest2(GameState* thisx);
+void FileSelect_SelectCopyDest(GameState* thisx);
+void FileSelect_ExitToCopySource1(GameState* thisx);
+void FileSelect_ExitToCopySource2(GameState* thisx);
+void FileSelect_SetupCopyConfirm1(GameState* thisx);
+void FileSelect_SetupCopyConfirm2(GameState* thisx);
+void FileSelect_CopyConfirm(GameState* thisx);
+void FileSelect_CopyWaitForFlashSave(GameState* thisx);
+void FileSelect_ReturnToCopyDest(GameState* thisx);
+void FileSelect_CopyAnim1(GameState* thisx);
+void FileSelect_CopyAnim2(GameState* thisx);
+void FileSelect_CopyAnim3(GameState* thisx);
+void FileSelect_CopyAnim4(GameState* thisx);
+void FileSelect_CopyAnim5(GameState* thisx);
+void FileSelect_ExitCopyToMain(GameState* thisx);
+
+// Erasing Files
+void FileSelect_SetupEraseSelect(GameState* thisx);
+void FileSelect_EraseSelect(GameState* thisx);
+void FileSelect_SetupEraseConfirm1(GameState* thisx);
+void FileSelect_SetupEraseConfirm2(GameState* thisx);
+void FileSelect_EraseConfirm(GameState* thisx);
+void FileSelect_ExitToEraseSelect1(GameState* thisx);
+void FileSelect_ExitToEraseSelect2(GameState* thisx);
+void FileSelect_EraseAnim1(GameState* thisx);
+void FileSelect_EraseWaitForFlashSave(GameState* thisx);
+void FileSelect_EraseAnim2(GameState* thisx);
+void FileSelect_EraseAnim3(GameState* thisx);
+void FileSelect_ExitEraseToMain(GameState* thisx);
+
+// Entering Name
+void FileSelect_StartNameEntry(GameState* thisx);
+void FileSelect_UpdateKeyboardCursor(GameState* thisx);
+void FileSelect_NameEntryWaitForFlashSave(GameState* thisx);
+
+// Selecting Options
+void FileSelect_StartOptions(GameState* thisx);
+void FileSelect_UpdateOptionsMenu(GameState* thisx);
+void FileSelect_OptionsWaitForFlashSave(GameState* thisx);
+
+extern u8 D_808141F0[];
+extern s16 D_80814280[];
+
+#endif
diff --git a/src/overlays/gamestates/ovl_title/z_title.c b/src/overlays/gamestates/ovl_title/z_title.c
index 8e270b8367..abde294e5c 100644
--- a/src/overlays/gamestates/ovl_title/z_title.c
+++ b/src/overlays/gamestates/ovl_title/z_title.c
@@ -171,7 +171,7 @@ void ConsoleLogo_Init(GameState* thisx) {
gSaveContext.fileNum = 0xFF;
}
- gSaveContext.unk_3F3F = true;
+ gSaveContext.flashSaveAvailable = true;
Sram_Alloc(thisx, &this->sramCtx);
this->ult = 0;
this->timer = 20;
diff --git a/src/overlays/kaleido_scope/ovl_kaleido_scope/z_kaleido_debug.c b/src/overlays/kaleido_scope/ovl_kaleido_scope/z_kaleido_debug.c
index 1eb46728fd..8517fdf209 100644
--- a/src/overlays/kaleido_scope/ovl_kaleido_scope/z_kaleido_debug.c
+++ b/src/overlays/kaleido_scope/ovl_kaleido_scope/z_kaleido_debug.c
@@ -285,7 +285,7 @@ void KaleidoScope_DrawInventoryEditorText(Gfx** gfxp) {
GfxPrint_SetPos(&printer, 23, 22);
GfxPrint_Printf(&printer, "%s", "セイ");
- // Life (double defence)
+ // Life (double defense)
GfxPrint_SetPos(&printer, 4, 25);
GfxPrint_Printf(&printer, "%s", "イ");
GfxPrint_SetPos(&printer, 4, 26);
@@ -601,7 +601,7 @@ void KaleidoScope_DrawInventoryEditor(PlayState* play) {
counterDigits[1] += 21;
}
- // Double Defence
+ // Double Defense
KaleidoScope_DrawDigit(play, gSaveContext.save.saveInfo.playerData.doubleDefense, 44, 202);
// Magic
@@ -1048,16 +1048,13 @@ void KaleidoScope_UpdateInventoryEditor(PlayState* play) {
// Dungeon Items
slot = sCurSection - INV_EDITOR_SECTION_DUNGEON_ITEMS;
if (CHECK_BTN_ALL(input->press.button, BTN_CLEFT)) {
- // Map
- gSaveContext.save.saveInfo.inventory.dungeonItems[slot] ^= 4;
+ gSaveContext.save.saveInfo.inventory.dungeonItems[slot] ^= (1 << DUNGEON_MAP);
}
if (CHECK_BTN_ALL(input->press.button, BTN_CDOWN)) {
- // Compass
- gSaveContext.save.saveInfo.inventory.dungeonItems[slot] ^= 2;
+ gSaveContext.save.saveInfo.inventory.dungeonItems[slot] ^= (1 << DUNGEON_COMPASS);
}
if (CHECK_BTN_ALL(input->press.button, BTN_CRIGHT)) {
- // Boss Key
- gSaveContext.save.saveInfo.inventory.dungeonItems[slot] ^= 1;
+ gSaveContext.save.saveInfo.inventory.dungeonItems[slot] ^= (1 << DUNGEON_BOSS_KEY);
}
} else if (sCurSection < INV_EDITOR_SECTION_DOUBLE_DEFENSE) {
@@ -1077,7 +1074,7 @@ void KaleidoScope_UpdateInventoryEditor(PlayState* play) {
}
} else {
- // Double Defence
+ // Double Defense
if (CHECK_BTN_ALL(input->press.button, BTN_CUP) || CHECK_BTN_ALL(input->press.button, BTN_CLEFT) ||
CHECK_BTN_ALL(input->press.button, BTN_CDOWN) || CHECK_BTN_ALL(input->press.button, BTN_CRIGHT)) {
gSaveContext.save.saveInfo.playerData.doubleDefense ^= 1;
diff --git a/src/overlays/kaleido_scope/ovl_kaleido_scope/z_kaleido_scope_NES.c b/src/overlays/kaleido_scope/ovl_kaleido_scope/z_kaleido_scope_NES.c
index 9d210a728c..64da25451f 100644
--- a/src/overlays/kaleido_scope/ovl_kaleido_scope/z_kaleido_scope_NES.c
+++ b/src/overlays/kaleido_scope/ovl_kaleido_scope/z_kaleido_scope_NES.c
@@ -3060,12 +3060,12 @@ void KaleidoScope_Update(PlayState* play) {
Play_SaveCycleSceneFlags(&play->state);
gSaveContext.save.saveInfo.playerData.savedSceneId = play->sceneId;
func_8014546C(sramCtx);
- if (gSaveContext.unk_3F3F == 0) {
+ if (!gSaveContext.flashSaveAvailable) {
pauseCtx->savePromptState = PAUSE_SAVEPROMPT_STATE_5;
} else {
- func_80147008(sramCtx, D_801C67C8[gSaveContext.fileNum],
- D_801C67F0[gSaveContext.fileNum]);
- func_80147020(sramCtx);
+ Sram_SetFlashPagesDefault(sramCtx, gFlashSaveStartPages[gSaveContext.fileNum],
+ gFlashSaveNumPages[gSaveContext.fileNum]);
+ Sram_StartWriteToFlashDefault(sramCtx);
pauseCtx->savePromptState = PAUSE_SAVEPROMPT_STATE_4;
}
sDelayTimer = 90;
@@ -3327,11 +3327,12 @@ void KaleidoScope_Update(PlayState* play) {
gSaveContext.save.saveInfo.playerData.savedSceneId = play->sceneId;
gSaveContext.save.saveInfo.playerData.health = 0x30;
func_8014546C(sramCtx);
- if (gSaveContext.unk_3F3F == 0) {
+ if (!gSaveContext.flashSaveAvailable) {
pauseCtx->state = PAUSE_STATE_GAMEOVER_8;
} else {
- func_80147008(sramCtx, D_801C67C8[gSaveContext.fileNum], D_801C67F0[gSaveContext.fileNum]);
- func_80147020(sramCtx);
+ Sram_SetFlashPagesDefault(sramCtx, gFlashSaveStartPages[gSaveContext.fileNum],
+ gFlashSaveNumPages[gSaveContext.fileNum]);
+ Sram_StartWriteToFlashDefault(sramCtx);
pauseCtx->state = PAUSE_STATE_GAMEOVER_7;
}
sDelayTimer = 90;
diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt
index 4c65de06c4..e4f96e594b 100644
--- a/tools/disasm/functions.txt
+++ b/tools/disasm/functions.txt
@@ -2802,21 +2802,21 @@
0x8014546C:("func_8014546C",),
0x80145698:("func_80145698",),
0x801457CC:("func_801457CC",),
- 0x80146580:("func_80146580",),
- 0x80146628:("func_80146628",),
+ 0x80146580:("Sram_EraseSave",),
+ 0x80146628:("Sram_CopySave",),
0x80146AA0:("Sram_InitSave",),
- 0x80146DF8:("func_80146DF8",),
+ 0x80146DF8:("Sram_WriteSaveOptionsToBuffer",),
0x80146E40:("Sram_InitSram",),
0x80146E70:("Sram_Alloc",),
- 0x80146EBC:("func_80146EBC",),
+ 0x80146EBC:("Sram_SyncWriteToFlash",),
0x80146EE8:("Sram_SaveSpecialEnterClockTown",),
0x80146F5C:("Sram_SaveSpecialNewDay",),
- 0x80147008:("func_80147008",),
- 0x80147020:("func_80147020",),
- 0x80147068:("func_80147068",),
- 0x80147138:("func_80147138",),
- 0x80147150:("func_80147150",),
- 0x80147198:("func_80147198",),
+ 0x80147008:("Sram_SetFlashPagesDefault",),
+ 0x80147020:("Sram_StartWriteToFlashDefault",),
+ 0x80147068:("Sram_UpdateWriteToFlashDefault",),
+ 0x80147138:("Sram_SetFlashPagesOwlSave",),
+ 0x80147150:("Sram_StartWriteToFlashOwlSave",),
+ 0x80147198:("Sram_UpdateWriteToFlashOwlSave",),
0x80147314:("func_80147314",),
0x80147414:("func_80147414",),
0x8014750C:("Sram_nop8014750C",),
@@ -4107,87 +4107,87 @@
0x80803EC0:("TitleSetup_Main",),
0x80803F0C:("TitleSetup_Destroy",),
0x80803F30:("TitleSetup_Init",),
- 0x80804010:("func_80804010",),
- 0x808041A0:("func_808041A0",),
- 0x80804654:("func_80804654",),
- 0x808047D8:("func_808047D8",),
- 0x8080489C:("func_8080489C",),
- 0x80804DAC:("func_80804DAC",),
- 0x80804E74:("func_80804E74",),
- 0x80804F98:("func_80804F98",),
- 0x8080525C:("func_8080525C",),
- 0x808052B0:("func_808052B0",),
- 0x808054A4:("func_808054A4",),
- 0x808055D0:("func_808055D0",),
- 0x808058A4:("func_808058A4",),
- 0x80805918:("func_80805918",),
- 0x80805A58:("func_80805A58",),
- 0x80805B30:("func_80805B30",),
- 0x80805C1C:("func_80805C1C",),
- 0x80806014:("func_80806014",),
- 0x80806148:("func_80806148",),
- 0x80806310:("func_80806310",),
- 0x808067E0:("func_808067E0",),
- 0x80806BC8:("func_80806BC8",),
- 0x80806CA0:("func_80806CA0",),
- 0x80806E84:("func_80806E84",),
- 0x80806F30:("func_80806F30",),
- 0x808071E4:("func_808071E4",),
- 0x80807390:("func_80807390",),
- 0x8080742C:("func_8080742C",),
- 0x808074B4:("func_808074B4",),
- 0x808077AC:("func_808077AC",),
- 0x80807940:("func_80807940",),
- 0x80807A78:("func_80807A78",),
- 0x80807C58:("func_80807C58",),
- 0x80808214:("func_80808214",),
- 0x80808D30:("func_80808D30",),
- 0x80808F1C:("func_80808F1C",),
- 0x80809DF0:("func_80809DF0",),
- 0x80809EA0:("func_80809EA0",),
- 0x8080A3CC:("func_8080A3CC",),
- 0x8080A418:("func_8080A418",),
- 0x8080A4A0:("func_8080A4A0",),
- 0x8080A6BC:("func_8080A6BC",),
- 0x8080A708:("func_8080A708",),
- 0x8080BBFC:("func_8080BBFC",),
- 0x8080BC20:("func_8080BC20",),
- 0x8080BC44:("FileSelect_nop8080bc44",),
- 0x8080BC4C:("FileSelect_nop8080BC4C",),
- 0x8080BC58:("func_8080BC58",),
- 0x8080BDAC:("func_8080BDAC",),
- 0x8080BDDC:("FileSelect_RenderView",),
- 0x8080BE60:("func_8080BE60",),
- 0x8080C040:("func_8080C040",),
- 0x8080C228:("func_8080C228",),
- 0x8080C29C:("func_8080C29C",),
- 0x8080C324:("func_8080C324",),
- 0x8080C3A8:("func_8080C3A8",),
- 0x8080D164:("func_8080D164",),
- 0x8080D170:("func_8080D170",),
- 0x8080D1BC:("func_8080D1BC",),
- 0x8080D220:("func_8080D220",),
- 0x8080D284:("func_8080D284",),
- 0x8080D2EC:("func_8080D2EC",),
- 0x8080D3D0:("func_8080D3D0",),
- 0x8080D40C:("func_8080D40C",),
- 0x8080D6D4:("func_8080D6D4",),
- 0x8080F25C:("func_8080F25C",),
- 0x808108DC:("func_808108DC",),
- 0x80811CB8:("func_80811CB8",),
- 0x80812460:("func_80812460",),
- 0x80812668:("func_80812668",),
- 0x80812760:("func_80812760",),
- 0x80812840:("func_80812840",),
- 0x80812980:("func_80812980",),
- 0x80812A6C:("func_80812A6C",),
- 0x80812D44:("func_80812D44",),
- 0x80812D94:("func_80812D94",),
- 0x80812E94:("func_80812E94",),
- 0x80812ED0:("func_80812ED0",),
+ 0x80804010:("FileSelect_SetupCopySource",),
+ 0x808041A0:("FileSelect_SelectCopySource",),
+ 0x80804654:("FileSelect_SetupCopyDest1",),
+ 0x808047D8:("FileSelect_SetupCopyDest2",),
+ 0x8080489C:("FileSelect_SelectCopyDest",),
+ 0x80804DAC:("FileSelect_ExitToCopySource1",),
+ 0x80804E74:("FileSelect_ExitToCopySource2",),
+ 0x80804F98:("FileSelect_SetupCopyConfirm1",),
+ 0x8080525C:("FileSelect_SetupCopyConfirm2",),
+ 0x808052B0:("FileSelect_CopyConfirm",),
+ 0x808054A4:("FileSelect_CopyWaitForFlashSave",),
+ 0x808055D0:("FileSelect_ReturnToCopyDest",),
+ 0x808058A4:("FileSelect_CopyAnim1",),
+ 0x80805918:("FileSelect_CopyAnim2",),
+ 0x80805A58:("FileSelect_CopyAnim3",),
+ 0x80805B30:("FileSelect_CopyAnim4",),
+ 0x80805C1C:("FileSelect_CopyAnim5",),
+ 0x80806014:("FileSelect_ExitCopyToMain",),
+ 0x80806148:("FileSelect_SetupEraseSelect",),
+ 0x80806310:("FileSelect_EraseSelect",),
+ 0x808067E0:("FileSelect_SetupEraseConfirm1",),
+ 0x80806BC8:("FileSelect_SetupEraseConfirm2",),
+ 0x80806CA0:("FileSelect_EraseConfirm",),
+ 0x80806E84:("FileSelect_ExitToEraseSelect1",),
+ 0x80806F30:("FileSelect_ExitToEraseSelect2",),
+ 0x808071E4:("FileSelect_EraseAnim1",),
+ 0x80807390:("FileSelect_EraseWaitForFlashSave",),
+ 0x8080742C:("FileSelect_EraseAnim2",),
+ 0x808074B4:("FileSelect_EraseAnim3",),
+ 0x808077AC:("FileSelect_ExitEraseToMain",),
+ 0x80807940:("FileSelect_DrawTexQuadI4",),
+ 0x80807A78:("FileSelect_DrawMultiTexQuadI4",),
+ 0x80807C58:("FileSelect_SetKeyboardVtx",),
+ 0x80808214:("FileSelect_SetNameEntryVtx",),
+ 0x80808D30:("FileSelect_DrawKeyboard",),
+ 0x80808F1C:("FileSelect_DrawNameEntry",),
+ 0x80809DF0:("FileSelect_StartNameEntry",),
+ 0x80809EA0:("FileSelect_UpdateKeyboardCursor",),
+ 0x8080A3CC:("FileSelect_NameEntryWaitForFlashSave",),
+ 0x8080A418:("FileSelect_StartOptions",),
+ 0x8080A4A0:("FileSelect_UpdateOptionsMenu",),
+ 0x8080A6BC:("FileSelect_OptionsWaitForFlashSave",),
+ 0x8080A708:("FileSelect_DrawOptionsImpl",),
+ 0x8080BBFC:("FileSelect_DrawOptions",),
+ 0x8080BC20:("FileSelect_IncrementConfigMode",),
+ 0x8080BC44:("FileSelect_Noop1",),
+ 0x8080BC4C:("FileSelect_Noop2",),
+ 0x8080BC58:("FileSelect_InitModeUpdate",),
+ 0x8080BDAC:("FileSelect_InitModeDraw",),
+ 0x8080BDDC:("FileSelect_SetView",),
+ 0x8080BE60:("FileSelect_DrawTexQuadIA8",),
+ 0x8080C040:("FileSelect_FadeInMenuElements",),
+ 0x8080C228:("FileSelect_SplitNumber",),
+ 0x8080C29C:("FileSelect_StartFadeIn",),
+ 0x8080C324:("FileSelect_FinishFadeIn",),
+ 0x8080C3A8:("FileSelect_UpdateMainMenu",),
+ 0x8080D164:("FileSelect_UnusedCM31",),
+ 0x8080D170:("FileSelect_UnusedCMDelay",),
+ 0x8080D1BC:("FileSelect_RotateToNameEntry",),
+ 0x8080D220:("FileSelect_RotateToOptions",),
+ 0x8080D284:("FileSelect_RotateToMain",),
+ 0x8080D2EC:("FileSelect_PulsateCursor",),
+ 0x8080D3D0:("FileSelect_ConfigModeUpdate",),
+ 0x8080D40C:("FileSelect_SetWindowVtx",),
+ 0x8080D6D4:("FileSelect_SetWindowContentVtx",),
+ 0x8080F25C:("FileSelect_DrawFileInfo",),
+ 0x808108DC:("FileSelect_DrawWindowContents",),
+ 0x80811CB8:("FileSelect_ConfigModeDraw",),
+ 0x80812460:("FileSelect_FadeMainToSelect",),
+ 0x80812668:("FileSelect_MoveSelectedFileToTop",),
+ 0x80812760:("FileSelect_FadeInFileInfo",),
+ 0x80812840:("FileSelect_ConfirmFile",),
+ 0x80812980:("FileSelect_FadeOutFileInfo",),
+ 0x80812A6C:("FileSelect_MoveSelectedFileToSlot",),
+ 0x80812D44:("FileSelect_FadeOut",),
+ 0x80812D94:("FileSelect_LoadGame",),
+ 0x80812E94:("FileSelect_SelectModeUpdate",),
+ 0x80812ED0:("FileSelect_SelectModeDraw",),
0x8081313C:("FileSelect_UpdateAndDrawSkybox",),
0x80813268:("FileSelect_Main",),
- 0x80813908:("func_80813908",),
+ 0x80813908:("FileSelect_InitContext",),
0x80813C74:("FileSelect_Destroy",),
0x80813C98:("FileSelect_Init",),
0x80814EB0:("DayTelop_Update",),
diff --git a/tools/disasm/variables.txt b/tools/disasm/variables.txt
index daa6aff8f0..3a14118c56 100644
--- a/tools/disasm/variables.txt
+++ b/tools/disasm/variables.txt
@@ -1927,14 +1927,14 @@
0x801C5F44:("D_801C5F44","UNK_TYPE4","",0x4),
0x801C5FC0:("sPersistentCycleFlags","u32","[452]",0x710),
0x801C66D0:("D_801C66D0","UNK_TYPE2","",0x2),
- 0x801C6798:("D_801C6798","UNK_TYPE4","",0x4),
+ 0x801C6798:("gSramSlotOffsets","UNK_TYPE4","",0x4),
0x801C67B0:("gAmmoItems","UNK_TYPE1","",0x1),
- 0x801C67C8:("D_801C67C8","s32","[10]",0x28),
- 0x801C67F0:("D_801C67F0","s32","[10]",0x28),
- 0x801C6818:("D_801C6818","s32","[10]",0x28),
- 0x801C6840:("D_801C6840","UNK_TYPE1","",0x1),
- 0x801C6850:("D_801C6850","UNK_TYPE1","",0x1),
- 0x801C6870:("D_801C6870","UNK_TYPE1","",0x1),
+ 0x801C67C8:("gFlashSaveStartPages","s32","[10]",0x28),
+ 0x801C67F0:("gFlashSaveNumPages","s32","[10]",0x28),
+ 0x801C6818:("gFlashSpecialSaveNumPages","s32","[10]",0x28),
+ 0x801C6840:("gFlashOwlSaveStartPages","UNK_TYPE1","",0x1),
+ 0x801C6850:("gFlashOwlSaveNumPages","UNK_TYPE1","",0x1),
+ 0x801C6870:("gFlashSaveSizes","UNK_TYPE1","",0x1),
0x801C6890:("D_801C6890","UNK_TYPE1","",0x1),
0x801C6898:("sSaveDefaultPlayerData","SavePlayerData","",0x28),
0x801C68C0:("sSaveDefaultItemEquips","ItemEquips","",0x22),
@@ -4544,13 +4544,13 @@
0x80803FC8:("openingCutscenes","u32","[2]",0x8),
0x80813DF0:("D_80813DF0","UNK_TYPE1","",0x1),
0x80813F30:("D_80813F30","UNK_TYPE1","",0x1),
- 0x80814130:("D_80814130","UNK_TYPE1","",0x1),
- 0x80814170:("D_80814170","UNK_TYPE1","",0x1),
- 0x808141B0:("D_808141B0","UNK_TYPE1","",0x1),
+ 0x80814130:("gOptionsDividerTopVtx","UNK_TYPE1","",0x1),
+ 0x80814170:("gOptionsDividerMiddleVtx","UNK_TYPE1","",0x1),
+ 0x808141B0:("gOptionsDividerBottomVtx","UNK_TYPE1","",0x1),
0x808141F0:("D_808141F0","UNK_TYPE1","",0x1),
- 0x80814240:("D_80814240","UNK_TYPE2","",0x2),
+ 0x80814240:("sChooseFileYOffsets","UNK_TYPE2","",0x2),
0x8081424C:("D_8081424C","UNK_TYPE2","",0x2),
- 0x80814260:("D_80814260","UNK_TYPE2","",0x2),
+ 0x80814260:("sEraseDelayTimer","UNK_TYPE2","",0x2),
0x80814264:("D_80814264","UNK_TYPE2","",0x2),
0x8081426C:("D_8081426C","UNK_TYPE1","",0x1),
0x80814280:("D_80814280","UNK_TYPE1","",0x1),
@@ -4559,31 +4559,31 @@
0x80814404:("D_80814404","UNK_TYPE2","",0x2),
0x80814410:("D_80814410","UNK_TYPE2","",0x2),
0x8081441C:("D_8081441C","UNK_TYPE2","",0x2),
- 0x80814428:("D_80814428","UNK_TYPE4","",0x4),
- 0x80814430:("D_80814430","UNK_TYPE2","",0x2),
+ 0x80814428:("sBackspaceEndTextures","UNK_TYPE4","",0x4),
+ 0x80814430:("sBackspaceEndWidths","UNK_TYPE2","",0x2),
0x80814434:("D_80814434","UNK_TYPE2","",0x2),
0x8081444C:("D_8081444C","UNK_TYPE1","",0x1),
- 0x80814464:("D_80814464","UNK_TYPE4","",0x4),
- 0x8081448C:("D_8081448C","UNK_TYPE4","",0x4),
- 0x808144BC:("D_808144BC","UNK_TYPE2","",0x2),
- 0x808144C0:("D_808144C0","UNK_TYPE2","",0x2),
- 0x808144C4:("D_808144C4","UNK_TYPE2","",0x2),
- 0x808144C8:("D_808144C8","UNK_TYPE2","",0x2),
- 0x808144CC:("D_808144CC","UNK_TYPE2","",0x2),
- 0x808144D0:("D_808144D0","UNK_TYPE2","",0x2),
- 0x808144D4:("D_808144D4","UNK_TYPE2","",0x2),
- 0x808144D8:("D_808144D8","UNK_TYPE2","",0x2),
- 0x808144DC:("D_808144DC","UNK_TYPE1","",0x1),
- 0x808144E8:("D_808144E8","UNK_TYPE1","",0x1),
- 0x80814510:("D_80814510","Gfx","[5]",0x28),
- 0x80814538:("D_80814538","UNK_TYPE2","",0x2),
- 0x80814548:("D_80814548","UNK_TYPE2","",0x2),
- 0x80814550:("fileChooseSkyboxRotation","s16","",0x2),
- 0x80814554:("D_80814554","UNK_TYPE1","",0x1),
- 0x8081455C:("D_8081455C","UNK_TYPE1","",0x1),
+ 0x80814464:("gOptionsMenuHeaders","UNK_TYPE4","",0x4),
+ 0x8081448C:("gOptionsMenuSettings","UNK_TYPE4","",0x4),
+ 0x808144BC:("sCursorPrimRed","UNK_TYPE2","",0x2),
+ 0x808144C0:("sCursorPrimGreen","UNK_TYPE2","",0x2),
+ 0x808144C4:("sCursorPrimBlue","UNK_TYPE2","",0x2),
+ 0x808144C8:("sCursorEnvRed","UNK_TYPE2","",0x2),
+ 0x808144CC:("sCursorEnvGreen","UNK_TYPE2","",0x2),
+ 0x808144D0:("sCursorEnvBlue","UNK_TYPE2","",0x2),
+ 0x808144D4:("sCursorPulseDir","UNK_TYPE2","",0x2),
+ 0x808144D8:("sCursorFlashTimer","UNK_TYPE2","",0x2),
+ 0x808144DC:("sCursorPrimColors","UNK_TYPE1","",0x1),
+ 0x808144E8:("sCursorEnvColors","UNK_TYPE1","",0x1),
+ 0x80814510:("sScreenFillSetupDL","Gfx","[5]",0x28),
+ 0x80814538:("sFileInfoBoxPartWidths","UNK_TYPE2","",0x2),
+ 0x80814548:("sWindowContentColors","UNK_TYPE2","",0x2),
+ 0x80814550:("sFileSelectSkyboxRotation","s16","",0x2),
+ 0x80814554:("sWalletFirstDigit","UNK_TYPE1","",0x1),
+ 0x8081455C:("sEmptyName","UNK_TYPE1","",0x1),
0x80814564:("D_80814564","UNK_TYPE2","",0x2),
- 0x80814568:("D_80814568","UNK_TYPE","[45]",0xb4),
- 0x8081461C:("D_8081461C","s16","[2]",0x4),
+ 0x80814568:("sConfigModeUpdateFuncs","UNK_TYPE","[45]",0xb4),
+ 0x8081461C:("sCursorAlphaTargets","s16","[2]",0x4),
0x80814620:("D_80814620","UNK_TYPE2","",0x2),
0x80814628:("D_80814628","UNK_TYPE2","",0x2),
0x80814630:("D_80814630","UNK_TYPE2","",0x2),
@@ -4592,24 +4592,24 @@
0x8081464C:("D_8081464C","UNK_TYPE1","",0x1),
0x80814650:("D_80814650","UNK_TYPE1","",0x1),
0x80814654:("D_80814654","UNK_TYPE1","",0x1),
- 0x8081465C:("D_8081465C","UNK_TYPE4","",0x4),
- 0x8081466C:("D_8081466C","UNK_TYPE1","",0x1),
- 0x8081467C:("D_8081467C","UNK_TYPE1","",0x1),
- 0x8081468C:("D_8081468C","UNK_TYPE4","",0x4),
- 0x808146B4:("D_808146B4","UNK_TYPE1","",0x1),
- 0x808146C4:("D_808146C4","UNK_TYPE1","",0x1),
- 0x808146D8:("D_808146D8","UNK_TYPE1","",0x1),
- 0x808146EC:("D_808146EC","UNK_TYPE2","",0x2),
- 0x808146F8:("D_808146F8","UNK_TYPE2","",0x2),
- 0x80814704:("D_80814704","UNK_TYPE4","",0x4),
- 0x80814720:("D_80814720","UNK_TYPE1","",0x1),
- 0x80814744:("D_80814744","UNK_TYPE1","",0x1),
- 0x80814758:("D_80814758","UNK_TYPE4","",0x4),
- 0x80814764:("D_80814764","UNK_TYPE4","",0x4),
- 0x80814774:("D_80814774","UNK_TYPE1","",0x1),
- 0x8081477C:("D_8081477C","UNK_TYPE","[8]",0x20),
- 0x8081479C:("D_8081479C","UNK_TYPE","[3]",0xc),
- 0x808147A8:("D_808147A8","UNK_TYPE","[3]",0xc),
+ 0x8081465C:("sFileSelRemainsTextures","UNK_TYPE4","",0x4),
+ 0x8081466C:("sFileSelDayENGTextures","UNK_TYPE1","",0x1),
+ 0x8081467C:("sFileSelHeartPieceTextures","UNK_TYPE1","",0x1),
+ 0x8081468C:("sHeartTextures","UNK_TYPE4","",0x4),
+ 0x808146B4:("sHealthToQuarterHeartCount","UNK_TYPE1","",0x1),
+ 0x808146C4:("sFileSelRupeePrimColors","UNK_TYPE1","",0x1),
+ 0x808146D8:("sFileSelRupeeEnvColors","UNK_TYPE1","",0x1),
+ 0x808146EC:("sHeartPrimColors","UNK_TYPE2","",0x2),
+ 0x808146F8:("sHeartEnvColors","UNK_TYPE2","",0x2),
+ 0x80814704:("sFileInfoBoxTextures","UNK_TYPE4","",0x4),
+ 0x80814720:("sTitleLabels","UNK_TYPE1","",0x1),
+ 0x80814744:("sWarningLabels","UNK_TYPE1","",0x1),
+ 0x80814758:("sFileButtonTextures","UNK_TYPE4","",0x4),
+ 0x80814764:("sActionButtonTextures","UNK_TYPE4","",0x4),
+ 0x80814774:("sFileYOffsets","UNK_TYPE1","",0x1),
+ 0x8081477C:("sSelectModeUpdateFuncs","UNK_TYPE","[8]",0x20),
+ 0x8081479C:("gFileSelectDrawFuncs","UNK_TYPE","[3]",0xc),
+ 0x808147A8:("gFileSelectUpdateFuncs","UNK_TYPE","[3]",0xc),
0x808147B4:("D_808147B4","UNK_TYPE4","",0x4),
0x808147C0:("D_808147C0","UNK_TYPE2","",0x2),
0x808147C8:("D_808147C8","UNK_TYPE2","",0x2),
@@ -4622,7 +4622,7 @@
0x808147EC:("D_808147EC","f32","",0x4),
0x808147F0:("D_808147F0","f32","",0x4),
0x80814E80:("D_80814E80","UNK_TYPE1","",0x1),
- 0x80814E90:("D_80814E90","UNK_TYPE1","",0x1),
+ 0x80814E90:("sSelectedSetting","UNK_TYPE1","",0x1),
0x80815FF0:("D_80815FF0","u8","",0x1),
0x80815FF4:("sDayLeftTextures","TexturePtr","[4]",0x10),
0x80816004:("sDayRightTextures","TexturePtr","[4]",0x10),
diff --git a/tools/sizes/code_functions.csv b/tools/sizes/code_functions.csv
index 6713041f7f..3d5839a69f 100644
--- a/tools/sizes/code_functions.csv
+++ b/tools/sizes/code_functions.csv
@@ -2316,21 +2316,21 @@ asm/non_matchings/code/z_sram_NES/Sram_OpenSave.s,Sram_OpenSave,0x80144E78,0x17D
asm/non_matchings/code/z_sram_NES/func_8014546C.s,func_8014546C,0x8014546C,0x8B
asm/non_matchings/code/z_sram_NES/func_80145698.s,func_80145698,0x80145698,0x4D
asm/non_matchings/code/z_sram_NES/func_801457CC.s,func_801457CC,0x801457CC,0x36D
-asm/non_matchings/code/z_sram_NES/func_80146580.s,func_80146580,0x80146580,0x2A
-asm/non_matchings/code/z_sram_NES/func_80146628.s,func_80146628,0x80146628,0x11E
+asm/non_matchings/code/z_sram_NES/Sram_EraseSave.s,Sram_EraseSave,0x80146580,0x2A
+asm/non_matchings/code/z_sram_NES/Sram_CopySave.s,Sram_CopySave,0x80146628,0x11E
asm/non_matchings/code/z_sram_NES/Sram_InitSave.s,Sram_InitSave,0x80146AA0,0xD6
-asm/non_matchings/code/z_sram_NES/func_80146DF8.s,func_80146DF8,0x80146DF8,0x12
+asm/non_matchings/code/z_sram_NES/Sram_WriteSaveOptionsToBuffer.s,Sram_WriteSaveOptionsToBuffer,0x80146DF8,0x12
asm/non_matchings/code/z_sram_NES/Sram_InitSram.s,Sram_InitSram,0x80146E40,0xC
asm/non_matchings/code/z_sram_NES/Sram_Alloc.s,Sram_Alloc,0x80146E70,0x13
-asm/non_matchings/code/z_sram_NES/func_80146EBC.s,func_80146EBC,0x80146EBC,0xB
+asm/non_matchings/code/z_sram_NES/Sram_SyncWriteToFlash.s,Sram_SyncWriteToFlash,0x80146EBC,0xB
asm/non_matchings/code/z_sram_NES/Sram_SaveSpecialEnterClockTown.s,Sram_SaveSpecialEnterClockTown,0x80146EE8,0x1D
asm/non_matchings/code/z_sram_NES/Sram_SaveSpecialNewDay.s,Sram_SaveSpecialNewDay,0x80146F5C,0x2B
-asm/non_matchings/code/z_sram_NES/func_80147008.s,func_80147008,0x80147008,0x6
-asm/non_matchings/code/z_sram_NES/func_80147020.s,func_80147020,0x80147020,0x12
-asm/non_matchings/code/z_sram_NES/func_80147068.s,func_80147068,0x80147068,0x34
-asm/non_matchings/code/z_sram_NES/func_80147138.s,func_80147138,0x80147138,0x6
-asm/non_matchings/code/z_sram_NES/func_80147150.s,func_80147150,0x80147150,0x12
-asm/non_matchings/code/z_sram_NES/func_80147198.s,func_80147198,0x80147198,0x5F
+asm/non_matchings/code/z_sram_NES/Sram_SetFlashPagesDefault.s,Sram_SetFlashPagesDefault,0x80147008,0x6
+asm/non_matchings/code/z_sram_NES/Sram_StartWriteToFlashDefault.s,Sram_StartWriteToFlashDefault,0x80147020,0x12
+asm/non_matchings/code/z_sram_NES/Sram_UpdateWriteToFlashDefault.s,Sram_UpdateWriteToFlashDefault,0x80147068,0x34
+asm/non_matchings/code/z_sram_NES/Sram_SetFlashPagesOwlSave.s,Sram_SetFlashPagesOwlSave,0x80147138,0x6
+asm/non_matchings/code/z_sram_NES/Sram_StartWriteToFlashOwlSave.s,Sram_StartWriteToFlashOwlSave,0x80147150,0x12
+asm/non_matchings/code/z_sram_NES/Sram_UpdateWriteToFlashOwlSave.s,Sram_UpdateWriteToFlashOwlSave,0x80147198,0x5F
asm/non_matchings/code/z_sram_NES/func_80147314.s,func_80147314,0x80147314,0x40
asm/non_matchings/code/z_sram_NES/func_80147414.s,func_80147414,0x80147414,0x3E
asm/non_matchings/code/z_sram_NES/Sram_nop8014750C.s,Sram_nop8014750C,0x8014750C,0x5