diff --git a/assets/xml/overlays/ovl_file_choose.xml b/assets/xml/overlays/ovl_file_choose.xml
index aa9dcbb84b..a97188b446 100644
--- a/assets/xml/overlays/ovl_file_choose.xml
+++ b/assets/xml/overlays/ovl_file_choose.xml
@@ -3,25 +3,31 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
+
-
+
-
-
-
-
-
-
-
+
diff --git a/assets/xml/overlays/ovl_file_choose_pal.xml b/assets/xml/overlays/ovl_file_choose_pal.xml
new file mode 100644
index 0000000000..9721f7e0de
--- /dev/null
+++ b/assets/xml/overlays/ovl_file_choose_pal.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/baseroms/gc-eu-mq-dbg/config.yml b/baseroms/gc-eu-mq-dbg/config.yml
index 115ee5c051..9d6db2827f 100644
--- a/baseroms/gc-eu-mq-dbg/config.yml
+++ b/baseroms/gc-eu-mq-dbg/config.yml
@@ -956,9 +956,9 @@ assets:
start_offset: 0x780
end_offset: 0x4128
- name: overlays/ovl_file_choose
- xml_path: assets/xml/overlays/ovl_file_choose.xml
+ xml_path: assets/xml/overlays/ovl_file_choose_pal.xml
start_offset: 0xDE70
- end_offset: 0xE6B0
+ end_offset: 0xE740
- name: overlays/ovl_Magic_Dark
xml_path: assets/xml/overlays/ovl_Magic_Dark.xml
start_offset: 0xD10
diff --git a/baseroms/gc-eu-mq/config.yml b/baseroms/gc-eu-mq/config.yml
index 59b1802e49..e803b25ea7 100644
--- a/baseroms/gc-eu-mq/config.yml
+++ b/baseroms/gc-eu-mq/config.yml
@@ -940,9 +940,9 @@ assets:
start_offset: 0x6E0
end_offset: 0x4088
- name: overlays/ovl_file_choose
- xml_path: assets/xml/overlays/ovl_file_choose.xml
+ xml_path: assets/xml/overlays/ovl_file_choose_pal.xml
start_offset: 0xD740
- end_offset: 0xDF80
+ end_offset: 0xE010
- name: overlays/ovl_Magic_Dark
xml_path: assets/xml/overlays/ovl_Magic_Dark.xml
start_offset: 0xC90
diff --git a/baseroms/gc-eu/config.yml b/baseroms/gc-eu/config.yml
index 7d54a02590..690c8b8ce6 100644
--- a/baseroms/gc-eu/config.yml
+++ b/baseroms/gc-eu/config.yml
@@ -940,9 +940,9 @@ assets:
start_offset: 0x6E0
end_offset: 0x4088
- name: overlays/ovl_file_choose
- xml_path: assets/xml/overlays/ovl_file_choose.xml
+ xml_path: assets/xml/overlays/ovl_file_choose_pal.xml
start_offset: 0xD740
- end_offset: 0xDF80
+ end_offset: 0xE010
- name: overlays/ovl_Magic_Dark
xml_path: assets/xml/overlays/ovl_Magic_Dark.xml
start_offset: 0xC90
diff --git a/baseroms/gc-us/config.yml b/baseroms/gc-us/config.yml
index c66c4322ea..eb3aca9bf6 100644
--- a/baseroms/gc-us/config.yml
+++ b/baseroms/gc-us/config.yml
@@ -940,8 +940,8 @@ assets:
end_offset: 0x4088
- name: overlays/ovl_file_choose
xml_path: assets/xml/overlays/ovl_file_choose.xml
- start_offset: 0xD740
- end_offset: 0xDF80
+ start_offset: 0xEC40
+ end_offset: 0xF320
- name: overlays/ovl_Magic_Dark
xml_path: assets/xml/overlays/ovl_Magic_Dark.xml
start_offset: 0xC90
diff --git a/extract_assets.py b/extract_assets.py
index 815b1af498..a3f915c241 100755
--- a/extract_assets.py
+++ b/extract_assets.py
@@ -17,6 +17,7 @@ def SignalHandler(sig, frame):
# Don't exit immediately to update the extracted assets file.
def ExtractFile(assetConfig: version_config.AssetConfig, outputPath: Path, outputSourcePath: Path):
+ name = assetConfig.name
xmlPath = assetConfig.xml_path
version = globalVersionConfig.version
if globalAbort.is_set():
@@ -31,15 +32,15 @@ def ExtractFile(assetConfig: version_config.AssetConfig, outputPath: Path, outpu
execStr = f"{zapdPath} e -eh -i {xmlPath} -b extracted/{version}/baserom -o {outputPath} -osf {outputSourcePath} -gsf 1 -rconf {configPath} --cs-float both {ZAPDArgs}"
- if "code" in xmlPath.parts or "overlays" in xmlPath.parts:
+ if name.startswith("code/") or name.startswith("overlays/"):
assert assetConfig.start_offset is not None
assert assetConfig.end_offset is not None
execStr += f" --start-offset 0x{assetConfig.start_offset:X}"
execStr += f" --end-offset 0x{assetConfig.end_offset:X}"
- if "overlays" in xmlPath.parts:
- overlayName = xmlPath.stem
+ if name.startswith("overlays/"):
+ overlayName = name.split("/")[1]
baseAddress = globalVersionConfig.dmadata_segments[overlayName].vram + assetConfig.start_offset
execStr += f" --base-address 0x{baseAddress:X}"
diff --git a/include/macros.h b/include/macros.h
index ed67abc4ac..37eb4fc9eb 100644
--- a/include/macros.h
+++ b/include/macros.h
@@ -249,9 +249,9 @@ extern struct GraphicsContext* __gfxCtx;
#endif /* OOT_DEBUG */
#if OOT_NTSC
-#define LANGUAGE_ARRAY(jpn, nes, ger, fra) { jpn, nes }
+#define LANGUAGE_ARRAY(jpn, eng, ger, fra) { jpn, eng }
#else
-#define LANGUAGE_ARRAY(jpn, nes, ger, fra) { nes, ger, fra }
+#define LANGUAGE_ARRAY(jpn, eng, ger, fra) { eng, ger, fra }
#endif
/**
diff --git a/include/z64.h b/include/z64.h
index 7e0b60ee5e..1c24f026c7 100644
--- a/include/z64.h
+++ b/include/z64.h
@@ -207,7 +207,9 @@ typedef struct {
/* 0x000A4 */ Vtx* windowVtx;
/* 0x000A8 */ u8* staticSegment;
/* 0x000AC */ u8* parameterSegment;
+#if OOT_PAL
/* 0x000B0 */ char unk_B0[0x8];
+#endif
/* 0x000B8 */ View view;
/* 0x001E0 */ SramContext sramCtx;
/* 0x001E4 */ char unk_1E4[0x4];
@@ -226,7 +228,9 @@ typedef struct {
/* 0x1CA1C */ u32 questItems[3];
/* 0x1CA28 */ s16 n64ddFlags[3];
/* 0x1CA2E */ s8 defense[3];
+#if OOT_PAL
/* 0x1CA32 */ u16 health[3];
+#endif
/* 0x1CA38 */ s16 buttonIndex;
/* 0x1CA3A */ s16 confirmButtonIndex; // 0: yes, 1: quit
/* 0x1CA3C */ s16 menuMode;
diff --git a/src/code/z_sram.c b/src/code/z_sram.c
index fb2a4d1195..af77828f56 100644
--- a/src/code/z_sram.c
+++ b/src/code/z_sram.c
@@ -10,7 +10,9 @@
#define HEALTH_CAP offsetof(SaveContext, save.info.playerData.healthCapacity)
#define QUEST offsetof(SaveContext, save.info.inventory.questItems)
#define DEFENSE offsetof(SaveContext, save.info.inventory.defenseHearts)
+#if OOT_PAL
#define HEALTH offsetof(SaveContext, save.info.playerData.health)
+#endif
#define SLOT_OFFSET(index) (SRAM_HEADER_SIZE + 0x10 + (index * SLOT_SIZE))
@@ -726,13 +728,17 @@ void Sram_VerifyAndLoadAllSaves(FileSelectState* fileSelect, SramContext* sramCt
MemCpy(&fileSelect->defense[1], sramCtx->readBuff + SLOT_OFFSET(1) + DEFENSE, sizeof(fileSelect->defense[0]));
MemCpy(&fileSelect->defense[2], sramCtx->readBuff + SLOT_OFFSET(2) + DEFENSE, sizeof(fileSelect->defense[0]));
+#if OOT_PAL
MemCpy(&fileSelect->health[0], sramCtx->readBuff + SLOT_OFFSET(0) + HEALTH, sizeof(fileSelect->health[0]));
MemCpy(&fileSelect->health[1], sramCtx->readBuff + SLOT_OFFSET(1) + HEALTH, sizeof(fileSelect->health[0]));
MemCpy(&fileSelect->health[2], sramCtx->readBuff + SLOT_OFFSET(2) + HEALTH, sizeof(fileSelect->health[0]));
+#endif
PRINTF("f_64dd=%d, %d, %d\n", fileSelect->n64ddFlags[0], fileSelect->n64ddFlags[1], fileSelect->n64ddFlags[2]);
PRINTF("heart_status=%d, %d, %d\n", fileSelect->defense[0], fileSelect->defense[1], fileSelect->defense[2]);
+#if OOT_PAL
PRINTF("now_life=%d, %d, %d\n", fileSelect->health[0], fileSelect->health[1], fileSelect->health[2]);
+#endif
}
void Sram_InitSave(FileSelectState* fileSelect, SramContext* sramCtx) {
@@ -821,11 +827,15 @@ void Sram_InitSave(FileSelectState* fileSelect, SramContext* sramCtx) {
MemCpy(&fileSelect->n64ddFlags[gSaveContext.fileNum], sramCtx->readBuff + j + N64DD,
sizeof(fileSelect->n64ddFlags[0]));
MemCpy(&fileSelect->defense[gSaveContext.fileNum], sramCtx->readBuff + j + DEFENSE, sizeof(fileSelect->defense[0]));
+#if OOT_PAL
MemCpy(&fileSelect->health[gSaveContext.fileNum], sramCtx->readBuff + j + HEALTH, sizeof(fileSelect->health[0]));
+#endif
PRINTF("f_64dd[%d]=%d\n", gSaveContext.fileNum, fileSelect->n64ddFlags[gSaveContext.fileNum]);
PRINTF("heart_status[%d]=%d\n", gSaveContext.fileNum, fileSelect->defense[gSaveContext.fileNum]);
+#if OOT_PAL
PRINTF("now_life[%d]=%d\n", gSaveContext.fileNum, fileSelect->health[gSaveContext.fileNum]);
+#endif
}
void Sram_EraseSave(FileSelectState* fileSelect, SramContext* sramCtx) {
@@ -879,8 +889,10 @@ void Sram_CopySave(FileSelectState* fileSelect, SramContext* sramCtx) {
sizeof(fileSelect->n64ddFlags[0]));
MemCpy(&fileSelect->defense[fileSelect->copyDestFileIndex], sramCtx->readBuff + offset + DEFENSE,
sizeof(fileSelect->defense[0]));
+#if OOT_PAL
MemCpy(&fileSelect->health[fileSelect->copyDestFileIndex], (sramCtx->readBuff + offset) + HEALTH,
sizeof(fileSelect->health[0]));
+#endif
PRINTF("f_64dd[%d]=%d\n", gSaveContext.fileNum, fileSelect->n64ddFlags[gSaveContext.fileNum]);
PRINTF("heart_status[%d]=%d\n", gSaveContext.fileNum, fileSelect->defense[gSaveContext.fileNum]);
@@ -903,22 +915,30 @@ void Sram_InitSram(GameState* gameState, SramContext* sramCtx) {
for (i = 0; i < ARRAY_COUNTU(sZeldaMagic) - 3; i++) {
if (sZeldaMagic[i + SRAM_HEADER_MAGIC] != sramCtx->readBuff[i + SRAM_HEADER_MAGIC]) {
PRINTF("SRAM破壊!!!!!!\n"); // "SRAM destruction! ! ! ! ! !"
+#if OOT_PAL
gSaveContext.language = sramCtx->readBuff[SRAM_HEADER_LANGUAGE];
+#endif
+
MemCpy(sramCtx->readBuff, sZeldaMagic, sizeof(sZeldaMagic));
+
+#if OOT_PAL
sramCtx->readBuff[SRAM_HEADER_LANGUAGE] = gSaveContext.language;
+#endif
Sram_WriteSramHeader(sramCtx);
}
}
gSaveContext.audioSetting = sramCtx->readBuff[SRAM_HEADER_SOUND] & 3;
gSaveContext.zTargetSetting = sramCtx->readBuff[SRAM_HEADER_ZTARGET] & 1;
- gSaveContext.language = sramCtx->readBuff[SRAM_HEADER_LANGUAGE];
+#if OOT_PAL
+ gSaveContext.language = sramCtx->readBuff[SRAM_HEADER_LANGUAGE];
if (gSaveContext.language >= LANGUAGE_MAX) {
gSaveContext.language = LANGUAGE_ENG;
sramCtx->readBuff[SRAM_HEADER_LANGUAGE] = gSaveContext.language;
Sram_WriteSramHeader(sramCtx);
}
+#endif
#if OOT_DEBUG
if (CHECK_BTN_ANY(gameState->input[2].cur.button, BTN_DRIGHT)) {
diff --git a/src/overlays/gamestates/ovl_file_choose/file_select.h b/src/overlays/gamestates/ovl_file_choose/file_select.h
index b4d0db5b24..15f78f1437 100644
--- a/src/overlays/gamestates/ovl_file_choose/file_select.h
+++ b/src/overlays/gamestates/ovl_file_choose/file_select.h
@@ -157,7 +157,13 @@ typedef enum {
typedef enum {
/* 0 */ FS_CHAR_PAGE_HIRA,
/* 1 */ FS_CHAR_PAGE_KATA,
- /* 2 */ FS_CHAR_PAGE_ENG
+ /* 2 */ FS_CHAR_PAGE_ENG,
+ /* 3 */ FS_CHAR_PAGE_HIRA_TO_KATA,
+ /* 4 */ FS_CHAR_PAGE_KATA_TO_HIRA,
+ /* 5 */ FS_CHAR_PAGE_HIRA_TO_ENG,
+ /* 6 */ FS_CHAR_PAGE_ENG_TO_HIRA,
+ /* 7 */ FS_CHAR_PAGE_KATA_TO_ENG,
+ /* 8 */ FS_CHAR_PAGE_ENG_TO_KATA
} CharPage;
typedef enum {
@@ -214,6 +220,4 @@ void FileSelect_DrawOptions(GameState* thisx);
void FileSelect_DrawNameEntry(GameState* thisx);
void FileSelect_DrawCharacter(GraphicsContext* gfxCtx, void* texture, s16 vtx);
-extern s16 D_808123F0[];
-
#endif
diff --git a/src/overlays/gamestates/ovl_file_choose/z_file_choose.c b/src/overlays/gamestates/ovl_file_choose/z_file_choose.c
index df6118dce8..3876619b1c 100644
--- a/src/overlays/gamestates/ovl_file_choose/z_file_choose.c
+++ b/src/overlays/gamestates/ovl_file_choose/z_file_choose.c
@@ -189,7 +189,16 @@ void FileSelect_UpdateMainMenu(GameState* thisx) {
&gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
this->configMode = CM_ROTATE_TO_NAME_ENTRY;
this->kbdButton = FS_KBD_BTN_NONE;
+
+#if OOT_NTSC
+ this->charPage = FS_CHAR_PAGE_HIRA;
+ if (gSaveContext.language != LANGUAGE_JPN) {
+ this->charPage = FS_CHAR_PAGE_ENG;
+ }
+#else
this->charPage = FS_CHAR_PAGE_ENG;
+#endif
+
this->kbdX = 0;
this->kbdY = 0;
this->charIndex = 0;
@@ -224,7 +233,7 @@ void FileSelect_UpdateMainMenu(GameState* thisx) {
this->nextTitleLabel = FS_TITLE_ERASE_FILE;
} else {
this->configMode = CM_MAIN_TO_OPTIONS;
- this->kbdButton = 0;
+ this->kbdButton = FS_KBD_BTN_HIRA;
this->kbdX = 0;
this->kbdY = 0;
this->charBgAlpha = 0;
@@ -798,6 +807,11 @@ static s16 sQuestItemRed[] = { 255, 255, 255, 0, 255, 0, 255, 200, 200 };
static s16 sQuestItemGreen[] = { 255, 255, 255, 255, 60, 100, 130, 50, 200 };
static s16 sQuestItemBlue[] = { 255, 255, 255, 0, 0, 255, 0, 255, 0 };
static s16 sQuestItemFlags[] = { 0x0012, 0x0013, 0x0014, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005 };
+
+#if OOT_NTSC
+static void* sSaveXTextures[] = { gFileSelSaveXJPNTex, gFileSelSaveXENGTex };
+#endif
+
static s16 sNamePrimColors[2][3] = { { 255, 255, 255 }, { 100, 100, 100 } };
static void* sHeartTextures[] = { gHeartFullTex, gDefenseHeartFullTex };
static s16 sHeartPrimColors[2][3] = { { 255, 70, 50 }, { 200, 0, 0 } };
@@ -1729,9 +1743,11 @@ void FileSelect_Main(GameState* thisx) {
void FileSelect_InitContext(GameState* thisx) {
FileSelectState* this = (FileSelectState*)thisx;
EnvironmentContext* envCtx = &this->envCtx;
+#if OOT_PAL
SramContext* sramCtx = &this->sramCtx;
+#endif
- Sram_Alloc(&this->state, sramCtx);
+ Sram_Alloc(&this->state, &this->sramCtx);
ZREG(7) = 32;
ZREG(8) = 22;
@@ -1888,6 +1904,7 @@ void FileSelect_InitContext(GameState* thisx) {
this->n64ddFlags[0] = this->n64ddFlags[1] = this->n64ddFlags[2] = this->defense[0] = this->defense[1] =
this->defense[2] = 0;
+#if OOT_PAL
SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000), sramCtx->readBuff, SRAM_SIZE, OS_READ);
gSaveContext.language = sramCtx->readBuff[SRAM_HEADER_LANGUAGE];
@@ -1895,6 +1912,7 @@ void FileSelect_InitContext(GameState* thisx) {
if (gSaveContext.language >= LANGUAGE_MAX) {
sramCtx->readBuff[SRAM_HEADER_LANGUAGE] = gSaveContext.language = LANGUAGE_ENG;
}
+#endif
}
void FileSelect_Destroy(GameState* thisx) {
diff --git a/src/overlays/gamestates/ovl_file_choose/z_file_nameset.c b/src/overlays/gamestates/ovl_file_choose/z_file_nameset.c
index b6f452546b..f369ce7f32 100644
--- a/src/overlays/gamestates/ovl_file_choose/z_file_nameset.c
+++ b/src/overlays/gamestates/ovl_file_choose/z_file_nameset.c
@@ -3,6 +3,31 @@
#include "assets/textures/title_static/title_static.h"
#include "assets/overlays/ovl_file_choose/ovl_file_choose.h"
+void FileSelect_DrawCharacter(GraphicsContext* gfxCtx, void* texture, s16 vtx) {
+ OPEN_DISPS(gfxCtx, "../z_file_nameset_PAL.c", 110);
+
+ 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++, vtx, vtx + 2, vtx + 3, vtx + 1, 0);
+
+ CLOSE_DISPS(gfxCtx, "../z_file_nameset_PAL.c", 119);
+}
+
+#if OOT_NTSC
+void FileSelect_DrawCharacterTransition(GraphicsContext* gfxCtx, void* texture1, void* texture2, s16 vtx) {
+ OPEN_DISPS(gfxCtx, "", 0);
+
+ 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++, vtx, vtx + 2, vtx + 3, vtx + 1, 0);
+
+ CLOSE_DISPS(gfxCtx, "", 0);
+}
+#endif
+
+#if OOT_PAL
static s16 D_808124C0[] = {
0x0002, 0x0003, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0001, 0x0002, 0x0000, 0x0001,
0x0001, 0x0002, 0x0001, 0x0001, 0x0004, 0x0002, 0x0002, 0x0002, 0x0001, 0x0001, 0x0000, 0x0002, 0x0000, 0x0001,
@@ -18,20 +43,10 @@ static s16 D_80812544[] = {
0x0002, 0x0002, 0x0001, 0x0001, 0x0002, 0x0002, 0x0003, 0x0002, 0x0002, 0x0000, 0x0002, 0x0002, 0x0002,
0x0003, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0001, 0x0003,
};
-
-void FileSelect_DrawCharacter(GraphicsContext* gfxCtx, void* texture, s16 vtx) {
- OPEN_DISPS(gfxCtx, "../z_file_nameset_PAL.c", 110);
-
- 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++, vtx, vtx + 2, vtx + 3, vtx + 1, 0);
-
- CLOSE_DISPS(gfxCtx, "../z_file_nameset_PAL.c", 119);
-}
+#endif
void FileSelect_SetKeyboardVtx(GameState* thisx) {
FileSelectState* this = (FileSelectState*)thisx;
- s16 val;
s16 phi_t2;
s16 phi_t0;
s16 phi_t3;
@@ -43,14 +58,49 @@ void FileSelect_SetKeyboardVtx(GameState* thisx) {
phi_s1 = 0x26;
+#if OOT_NTSC
for (phi_t2 = 0, phi_s2 = 0, phi_t3 = 0; phi_s2 < 5; phi_s2++) {
- phi_t0 = -0x60;
+ for (phi_t0 = -0x60, phi_t1 = 0; phi_t1 < 13; phi_t1++, phi_t3 += 4) {
+ this->keyboardVtx[phi_t3].v.ob[0] = this->keyboardVtx[phi_t3 + 2].v.ob[0] = phi_t0;
+ this->keyboardVtx[phi_t3 + 1].v.ob[0] = this->keyboardVtx[phi_t3 + 3].v.ob[0] = phi_t0 + 12;
- for (phi_t1 = 0; phi_t1 < 13; phi_t1++, phi_t3 += 4, phi_t2++) {
- //! @bug D_80812544 is accessed out of bounds when drawing the empty space character (value of 64). Under
- //! normal circumstances it reads a halfword from sNameLabelTextures.
+ this->keyboardVtx[phi_t3].v.ob[1] = this->keyboardVtx[phi_t3 + 1].v.ob[1] = phi_s1;
+
+ this->keyboardVtx[phi_t3 + 2].v.ob[1] = this->keyboardVtx[phi_t3 + 3].v.ob[1] = phi_s1 - 12;
+
+ 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;
+
+ 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;
+
+ 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;
+
+ 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] = 0x200;
+
+ 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;
+
+ phi_t0 += 0x10;
+ }
+
+ phi_s1 -= 0x10;
+ }
+#else
+ for (phi_t2 = 0, phi_s2 = 0, phi_t3 = 0; phi_s2 < 5; phi_s2++) {
+ for (phi_t0 = -0x60, phi_t1 = 0; phi_t1 < 13; phi_t1++, phi_t3 += 4, phi_t2++) {
+ //! @bug D_80812544 is accessed out of bounds when drawing the empty space character (value
+ //! of 64). Under normal circumstances it reads a halfword from sNameLabelTextures.
this->keyboardVtx[phi_t3].v.ob[0] = this->keyboardVtx[phi_t3 + 2].v.ob[0] = D_80812544[phi_t2] + phi_t0;
-
this->keyboardVtx[phi_t3 + 1].v.ob[0] = this->keyboardVtx[phi_t3 + 3].v.ob[0] =
D_80812544[phi_t2] + phi_t0 + 12;
@@ -85,6 +135,7 @@ void FileSelect_SetKeyboardVtx(GameState* thisx) {
phi_s1 -= 0x10;
}
+#endif
}
static void* sNameLabelTextures[] =
@@ -124,7 +175,9 @@ void FileSelect_SetNameEntryVtx(GameState* thisx) {
Font* font = &this->font;
s16 phi_s0;
s16 phi_t1;
+#if OOT_PAL
u8 temp;
+#endif
s16 phi_v0;
if (1) {}
@@ -143,26 +196,55 @@ void FileSelect_SetNameEntryVtx(GameState* thisx) {
gSP1Quadrangle(POLY_OPA_DISP++, 0, 2, 3, 1, 0);
gDPPipeSync(POLY_OPA_DISP++);
+#if OOT_NTSC
+ for (phi_t1 = 0, phi_s0 = 4; phi_t1 < 5; phi_t1++, phi_s0 += 4) {
+ if (gSaveContext.language == LANGUAGE_JPN) {
+ gDPPipeSync(POLY_OPA_DISP++);
+ 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++, sButtonTextures[phi_t1], G_IM_FMT_IA, G_IM_SIZ_16b,
+ sButtonWidths[phi_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++, phi_s0, phi_s0 + 2, phi_s0 + 3, phi_s0 + 1, 0);
+ } else if (phi_t1 >= 3) {
+ 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++, sButtonTextures[phi_t1], G_IM_FMT_IA, G_IM_SIZ_16b,
+ sButtonWidths[phi_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++, phi_s0, phi_s0 + 2, phi_s0 + 3, phi_s0 + 1, 0);
+ }
+ }
+#else
phi_s0 = 0x10;
for (phi_t1 = 0; phi_t1 < 2; phi_t1++, phi_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);
-#if OOT_NTSC
- // TODO: implement NTSC version
- gDPLoadTextureBlock(POLY_OPA_DISP++, sButtonTextures[phi_t1], G_IM_FMT_IA, G_IM_SIZ_16b, sButtonWidths[phi_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);
-#else
+
gDPLoadTextureBlock(POLY_OPA_DISP++, sButtonTextures[gSaveContext.language][phi_t1], G_IM_FMT_IA, G_IM_SIZ_16b,
sButtonWidths[phi_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);
-#endif
+
gSP1Quadrangle(POLY_OPA_DISP++, phi_s0, phi_s0 + 2, phi_s0 + 3, phi_s0 + 1, 0);
}
+#endif
this->nameEntryVtx = GRAPH_ALLOC(this->state.gfxCtx, 44 * sizeof(Vtx));
for (phi_s0 = 0, phi_t1 = 0; phi_t1 < 44; phi_t1 += 4, phi_s0++) {
+#if OOT_NTSC
+ this->nameEntryVtx[phi_t1].v.ob[0] = this->nameEntryVtx[phi_t1 + 2].v.ob[0] =
+ D_808125EC[phi_s0] + this->nameEntryBoxPosX;
+
+ this->nameEntryVtx[phi_t1 + 1].v.ob[0] = this->nameEntryVtx[phi_t1 + 3].v.ob[0] =
+ this->nameEntryVtx[phi_t1].v.ob[0] + 0xA;
+#else
if ((phi_s0 > 0) && (phi_s0 < 9)) {
temp = this->fileNames[this->buttonIndex][phi_s0 - 1];
@@ -178,6 +260,7 @@ void FileSelect_SetNameEntryVtx(GameState* thisx) {
this->nameEntryVtx[phi_t1 + 1].v.ob[0] = this->nameEntryVtx[phi_t1 + 3].v.ob[0] =
this->nameEntryVtx[phi_t1].v.ob[0] + 0xA;
}
+#endif
this->nameEntryVtx[phi_t1].v.ob[1] = this->nameEntryVtx[phi_t1 + 1].v.ob[1] = D_80812604[phi_s0];
@@ -237,9 +320,9 @@ void FileSelect_SetNameEntryVtx(GameState* thisx) {
this->nameEntryVtx[0x27].v.tc[1] = this->nameEntryVtx[0x29].v.tc[0] = this->nameEntryVtx[0x2A].v.tc[1] =
this->nameEntryVtx[0x2B].v.tc[0] = this->nameEntryVtx[0x2B].v.tc[1] = 0x300;
- if ((this->kbdButton == 0) || (this->kbdButton == 1) || (this->kbdButton == 4)) {
+ if (this->kbdButton == FS_KBD_BTN_HIRA || this->kbdButton == FS_KBD_BTN_KATA || this->kbdButton == FS_KBD_BTN_END) {
this->nameEntryVtx[0x29].v.tc[0] = this->nameEntryVtx[0x2B].v.tc[0] = 0x700;
- } else if ((this->kbdButton == 2) || (this->kbdButton == 3)) {
+ } else if (this->kbdButton == FS_KBD_BTN_ENG || this->kbdButton == FS_KBD_BTN_BACKSPACE) {
this->nameEntryVtx[0x29].v.tc[0] = this->nameEntryVtx[0x2B].v.tc[0] = 0x500;
}
@@ -264,22 +347,189 @@ void FileSelect_DrawKeyboard(GameState* thisx) {
0, 0, COMBINED);
gDPSetPrimColor(POLY_OPA_DISP++, 0, this->charBgAlpha, 255, 255, 255, 255);
- while (vtx < 0x100) {
+#if OOT_NTSC
+ if (this->charPage == FS_CHAR_PAGE_HIRA || this->charPage == FS_CHAR_PAGE_HIRA_TO_KATA ||
+ this->charPage == FS_CHAR_PAGE_HIRA_TO_ENG) {
+ if (this->charPage != FS_CHAR_PAGE_HIRA_TO_ENG) {
+ for (; vtx < 0x100; vtx += 32) {
+ gSPVertex(POLY_OPA_DISP++, &this->keyboardVtx[vtx], 32, 0);
+
+ for (tmp = 0; tmp < 32; i++, tmp += 4) {
+ FileSelect_DrawCharacterTransition(this->state.gfxCtx,
+ font->fontBuf + gCharPageHira[i] * FONT_CHAR_TEX_SIZE,
+ font->fontBuf + gCharPageKata[i] * FONT_CHAR_TEX_SIZE, tmp);
+ }
+ }
+ gSPVertex(POLY_OPA_DISP++, &this->keyboardVtx[0x100], 4, 0);
+ FileSelect_DrawCharacterTransition(this->state.gfxCtx,
+ font->fontBuf + gCharPageHira[i] * FONT_CHAR_TEX_SIZE,
+ font->fontBuf + gCharPageKata[i] * FONT_CHAR_TEX_SIZE, 0);
+ } else {
+ for (; vtx < 0x100; vtx += 32) {
+ gSPVertex(POLY_OPA_DISP++, &this->keyboardVtx[vtx], 32, 0);
+
+ for (tmp = 0; tmp < 32; i++, tmp += 4) {
+ FileSelect_DrawCharacterTransition(this->state.gfxCtx,
+ font->fontBuf + gCharPageHira[i] * FONT_CHAR_TEX_SIZE,
+ font->fontBuf + gCharPageEng[i] * FONT_CHAR_TEX_SIZE, tmp);
+ }
+ }
+ gSPVertex(POLY_OPA_DISP++, &this->keyboardVtx[0x100], 4, 0);
+ FileSelect_DrawCharacterTransition(this->state.gfxCtx,
+ font->fontBuf + gCharPageHira[i] * FONT_CHAR_TEX_SIZE,
+ font->fontBuf + gCharPageEng[i] * FONT_CHAR_TEX_SIZE, 0);
+ }
+ } else if (this->charPage == FS_CHAR_PAGE_KATA || this->charPage == FS_CHAR_PAGE_KATA_TO_HIRA ||
+ this->charPage == FS_CHAR_PAGE_KATA_TO_ENG) {
+ if (this->charPage != FS_CHAR_PAGE_KATA_TO_ENG) {
+ for (; vtx < 0x100; vtx += 32) {
+ gSPVertex(POLY_OPA_DISP++, &this->keyboardVtx[vtx], 32, 0);
+
+ for (tmp = 0; tmp < 32; i++, tmp += 4) {
+ FileSelect_DrawCharacterTransition(this->state.gfxCtx,
+ font->fontBuf + gCharPageKata[i] * FONT_CHAR_TEX_SIZE,
+ font->fontBuf + gCharPageHira[i] * FONT_CHAR_TEX_SIZE, tmp);
+ }
+ }
+ gSPVertex(POLY_OPA_DISP++, &this->keyboardVtx[0x100], 4, 0);
+ FileSelect_DrawCharacterTransition(this->state.gfxCtx,
+ font->fontBuf + gCharPageKata[i] * FONT_CHAR_TEX_SIZE,
+ font->fontBuf + gCharPageHira[i] * FONT_CHAR_TEX_SIZE, 0);
+ } else {
+ for (; vtx < 0x100; vtx += 32) {
+ gSPVertex(POLY_OPA_DISP++, &this->keyboardVtx[vtx], 32, 0);
+
+ for (tmp = 0; tmp < 32; i++, tmp += 4) {
+ FileSelect_DrawCharacterTransition(this->state.gfxCtx,
+ font->fontBuf + gCharPageKata[i] * FONT_CHAR_TEX_SIZE,
+ font->fontBuf + gCharPageEng[i] * FONT_CHAR_TEX_SIZE, tmp);
+ }
+ }
+ gSPVertex(POLY_OPA_DISP++, &this->keyboardVtx[0x100], 4, 0);
+ FileSelect_DrawCharacterTransition(this->state.gfxCtx,
+ font->fontBuf + gCharPageKata[i] * FONT_CHAR_TEX_SIZE,
+ font->fontBuf + gCharPageEng[i] * FONT_CHAR_TEX_SIZE, 0);
+ }
+ } else {
+ if (this->charPage != FS_CHAR_PAGE_ENG_TO_KATA) {
+ for (; vtx < 0x100; vtx += 32) {
+ gSPVertex(POLY_OPA_DISP++, &this->keyboardVtx[vtx], 32, 0);
+
+ for (tmp = 0; tmp < 32; i++, tmp += 4) {
+ FileSelect_DrawCharacterTransition(this->state.gfxCtx,
+ font->fontBuf + gCharPageEng[i] * FONT_CHAR_TEX_SIZE,
+ font->fontBuf + gCharPageHira[i] * FONT_CHAR_TEX_SIZE, tmp);
+ }
+ }
+ gSPVertex(POLY_OPA_DISP++, &this->keyboardVtx[0x100], 4, 0);
+ FileSelect_DrawCharacterTransition(this->state.gfxCtx, font->fontBuf + gCharPageEng[i] * FONT_CHAR_TEX_SIZE,
+ font->fontBuf + gCharPageHira[i] * FONT_CHAR_TEX_SIZE, 0);
+ } else {
+ for (; vtx < 0x100; vtx += 32) {
+ gSPVertex(POLY_OPA_DISP++, &this->keyboardVtx[vtx], 32, 0);
+
+ for (tmp = 0; tmp < 32; i++, tmp += 4) {
+ FileSelect_DrawCharacterTransition(this->state.gfxCtx,
+ font->fontBuf + gCharPageEng[i] * FONT_CHAR_TEX_SIZE,
+ font->fontBuf + gCharPageKata[i] * FONT_CHAR_TEX_SIZE, tmp);
+ }
+ }
+ gSPVertex(POLY_OPA_DISP++, &this->keyboardVtx[0x100], 4, 0);
+ FileSelect_DrawCharacterTransition(this->state.gfxCtx, font->fontBuf + gCharPageEng[i] * FONT_CHAR_TEX_SIZE,
+ font->fontBuf + gCharPageKata[i] * FONT_CHAR_TEX_SIZE, 0);
+ }
+ }
+#else
+ for (; vtx < 0x100; vtx += 32) {
gSPVertex(POLY_OPA_DISP++, &this->keyboardVtx[vtx], 32, 0);
for (tmp = 0; tmp < 32; i++, tmp += 4) {
- FileSelect_DrawCharacter(this->state.gfxCtx, font->fontBuf + D_808123F0[i] * FONT_CHAR_TEX_SIZE, tmp);
+ FileSelect_DrawCharacter(this->state.gfxCtx, font->fontBuf + gCharPageEng[i] * FONT_CHAR_TEX_SIZE, tmp);
}
-
- vtx += 32;
}
gSPVertex(POLY_OPA_DISP++, &this->keyboardVtx[0x100], 4, 0);
- FileSelect_DrawCharacter(this->state.gfxCtx, font->fontBuf + D_808123F0[i] * FONT_CHAR_TEX_SIZE, 0);
+ FileSelect_DrawCharacter(this->state.gfxCtx, font->fontBuf + gCharPageEng[i] * FONT_CHAR_TEX_SIZE, 0);
+#endif
CLOSE_DISPS(this->state.gfxCtx, "../z_file_nameset_PAL.c", 347);
}
+#if OOT_NTSC
+// Tables for applying or removing Japanese diacritics (dakuten and handakuten) to filename characters.
+// For the range of characters between RangeMin[i] and RangeMax[i], the modified character can be found
+// by adding RangeOffset[i].
+static s16 sRemoveDiacriticRangeMin[12] = { 0x0F, 0x23, 0x41, 0x50, 0x55, 0x5F, 0x73, 0x91, 0xA0, 0xA5, 0x5C, 0xAA };
+static s16 sRemoveDiacriticRangeMax[12] = { 0x1D, 0x27, 0x4F, 0x54, 0x59, 0x6D, 0x77, 0x9F, 0xA4, 0xA9, 0x5C, 0xAA };
+static s16 sRemoveDiacriticRangeOffset[12] = { 0x32, 0x2D, -0x32, 0x05, -0x32, 0x32,
+ 0x2D, -0x32, 0x05, -0x32, 0x4E, -0x4E };
+static s16 sDakutenDiacriticRangeMin[8] = { 0x0F, 0x23, 0x55, 0x5F, 0x73, 0xA5, 0x5C, 0xAA };
+static s16 sDakutenDiacriticRangeMax[8] = { 0x1D, 0x27, 0x59, 0x6D, 0x77, 0xA9, 0x5C, 0xAA };
+static s16 sDakutenDiacriticRangeOffset[8] = { 0x32, 0x2D, -0x05, 0x32, 0x2D, -0x05, 0x4E, -0x4E };
+static s16 sHandakutenDiacriticRangeMin[4] = { 0x23, 0x50, 0x73, 0xA0 };
+static s16 sHandakutenDiacriticRangeMax[4] = { 0x27, 0x54, 0x77, 0xA4 };
+static s16 sHandakutenDiacriticRangeOffset[4] = { 0x32, 0x05, 0x32, 0x05 };
+
+/**
+ * Apply a Japanese diacritic to a character in the filename. The diacritic can be
+ * FILENAME_DAKUTEN, FILENAME_HANDAKUTEN, or FILENAME_SPACE (which removes any
+ * diacritic). Returns true if the diacritic was successfully applied (or removed).
+ */
+s32 FileSelect_ApplyDiacriticToCharacter(GameState* thisx, s16 diacritic, s16 charIndex) {
+ FileSelectState* this = (FileSelectState*)thisx;
+ s16 i;
+
+ if (diacritic == FILENAME_SPACE) {
+ for (i = 0; i < ARRAY_COUNTU(sRemoveDiacriticRangeOffset); i++) {
+ if (sRemoveDiacriticRangeMin[i] <= this->fileNames[this->buttonIndex][charIndex] &&
+ this->fileNames[this->buttonIndex][charIndex] <= sRemoveDiacriticRangeMax[i]) {
+ this->fileNames[this->buttonIndex][charIndex] += sRemoveDiacriticRangeOffset[i];
+ return true;
+ }
+ }
+ } else if (diacritic == FILENAME_DAKUTEN) {
+ for (i = 0; i < ARRAY_COUNTU(sDakutenDiacriticRangeOffset); i++) {
+ if (sDakutenDiacriticRangeMin[i] <= this->fileNames[this->buttonIndex][charIndex] &&
+ this->fileNames[this->buttonIndex][charIndex] <= sDakutenDiacriticRangeMax[i]) {
+ this->fileNames[this->buttonIndex][charIndex] += sDakutenDiacriticRangeOffset[i];
+ return true;
+ }
+ }
+ } else if (diacritic == FILENAME_HANDAKUTEN) {
+ for (i = 0; i < ARRAY_COUNTU(sHandakutenDiacriticRangeOffset); i++) {
+ if (sHandakutenDiacriticRangeMin[i] <= this->fileNames[this->buttonIndex][charIndex] &&
+ this->fileNames[this->buttonIndex][charIndex] <= sHandakutenDiacriticRangeMax[i]) {
+ this->fileNames[this->buttonIndex][charIndex] += sHandakutenDiacriticRangeOffset[i];
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+/**
+ * Apply a Japanese diacritic to the filename, either replacing the current
+ * character or the previous character in the filename. The diacritic can be
+ * FILENAME_DAKUTEN, FILENAME_HANDAKUTEN, or FILENAME_SPACE (which removes any
+ * diacritic). Returns true if the diacritic was successfully applied (or removed).
+ */
+s32 FileSelect_ApplyDiacriticToFilename(GameState* thisx, s16 diacritic) {
+ FileSelectState* this = (FileSelectState*)thisx;
+ s32 pad;
+
+ if (!FileSelect_ApplyDiacriticToCharacter(&this->state, diacritic, this->newFileNameCharCount)) {
+ if (this->newFileNameCharCount != 0) {
+ if (!FileSelect_ApplyDiacriticToCharacter(&this->state, diacritic, this->newFileNameCharCount - 1)) {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ }
+ return true;
+}
+#endif
+
void FileSelect_DrawNameEntry(GameState* thisx) {
FileSelectState* this = (FileSelectState*)thisx;
Font* font = &this->font;
@@ -323,8 +573,13 @@ void FileSelect_DrawNameEntry(GameState* thisx) {
this->kbdButton);
}
+#if OOT_NTSC
+ this->nameEntryVtx[40].v.ob[0] = this->nameEntryVtx[42].v.ob[0] =
+ this->keyboardVtx[this->charIndex * 4].v.ob[0] - 6;
+#else
this->nameEntryVtx[40].v.ob[0] = this->nameEntryVtx[42].v.ob[0] =
this->keyboardVtx[this->charIndex * 4].v.ob[0] - D_80812544[this->charIndex] - 6;
+#endif
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;
@@ -399,18 +654,208 @@ void FileSelect_DrawNameEntry(GameState* thisx) {
}
} else {
if (this->charPage <= FS_CHAR_PAGE_ENG) {
+#if OOT_NTSC
if (this->kbdY != 5) {
// draw the character the cursor is hovering over in yellow
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 0, 255);
+
+ if (this->charPage == FS_CHAR_PAGE_HIRA) {
+ gSPVertex(POLY_OPA_DISP++, &this->keyboardVtx[(this->charIndex * 4)], 4, 0);
+ FileSelect_DrawCharacter(
+ this->state.gfxCtx, font->fontBuf + gCharPageHira[this->charIndex] * FONT_CHAR_TEX_SIZE, 0);
+ if (CHECK_BTN_ALL(input->press.button, BTN_A)) {
+ if ((gCharPageHira[this->charIndex] == FILENAME_DAKUTEN) ||
+ (gCharPageHira[this->charIndex] == FILENAME_HANDAKUTEN)) {
+ if (!FileSelect_ApplyDiacriticToFilename(&this->state,
+ gCharPageHira[this->charIndex])) {
+ Audio_PlaySfxGeneral(NA_SE_SY_FSEL_ERROR, &gSfxDefaultPos, 4,
+ &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
+ &gSfxDefaultReverb);
+ } else {
+ Audio_PlaySfxGeneral(NA_SE_SY_FSEL_DECIDE_S, &gSfxDefaultPos, 4,
+ &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
+ &gSfxDefaultReverb);
+ }
+ } else {
+ Audio_PlaySfxGeneral(NA_SE_SY_FSEL_DECIDE_S, &gSfxDefaultPos, 4,
+ &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
+ &gSfxDefaultReverb);
+ this->fileNames[this->buttonIndex][this->newFileNameCharCount] =
+ gCharPageHira[this->charIndex];
+ this->newFileNameCharCount++;
+ if (this->newFileNameCharCount >= 8) {
+ this->newFileNameCharCount = 7;
+ }
+ }
+ }
+ } else if (this->charPage == FS_CHAR_PAGE_KATA) {
+ gSPVertex(POLY_OPA_DISP++, &this->keyboardVtx[(this->charIndex * 4)], 4, 0);
+ FileSelect_DrawCharacter(
+ this->state.gfxCtx, font->fontBuf + gCharPageKata[this->charIndex] * FONT_CHAR_TEX_SIZE, 0);
+ if (CHECK_BTN_ALL(input->press.button, BTN_A)) {
+ if ((gCharPageHira[this->charIndex] == FILENAME_DAKUTEN) ||
+ (gCharPageHira[this->charIndex] == FILENAME_HANDAKUTEN)) {
+ if (!FileSelect_ApplyDiacriticToFilename(&this->state,
+ gCharPageHira[this->charIndex])) {
+ Audio_PlaySfxGeneral(NA_SE_SY_FSEL_ERROR, &gSfxDefaultPos, 4,
+ &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
+ &gSfxDefaultReverb);
+ } else {
+ Audio_PlaySfxGeneral(NA_SE_SY_FSEL_DECIDE_S, &gSfxDefaultPos, 4,
+ &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
+ &gSfxDefaultReverb);
+ }
+ } else {
+ Audio_PlaySfxGeneral(NA_SE_SY_FSEL_DECIDE_S, &gSfxDefaultPos, 4,
+ &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
+ &gSfxDefaultReverb);
+ this->fileNames[this->buttonIndex][this->newFileNameCharCount] =
+ gCharPageKata[this->charIndex];
+ this->newFileNameCharCount++;
+ if (this->newFileNameCharCount >= 8) {
+ this->newFileNameCharCount = 7;
+ }
+ }
+ }
+ } else {
+ gSPVertex(POLY_OPA_DISP++, &this->keyboardVtx[this->charIndex * 4], 4, 0);
+
+ FileSelect_DrawCharacter(this->state.gfxCtx,
+ font->fontBuf + gCharPageEng[this->charIndex] * FONT_CHAR_TEX_SIZE, 0);
+
+ if (CHECK_BTN_ALL(input->press.button, BTN_A)) {
+ Audio_PlaySfxGeneral(NA_SE_SY_FSEL_DECIDE_S, &gSfxDefaultPos, 4,
+ &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
+ &gSfxDefaultReverb);
+ this->fileNames[this->buttonIndex][this->newFileNameCharCount] =
+ gCharPageEng[this->charIndex];
+ this->newFileNameCharCount++;
+
+ if (this->newFileNameCharCount > 7) {
+ this->newFileNameCharCount = 7;
+ }
+ }
+ }
+ } else if (CHECK_BTN_ALL(input->press.button, BTN_A) && (this->charPage != this->kbdButton)) {
+ if (this->kbdButton == FS_KBD_BTN_HIRA) {
+ if (this->charPage == FS_CHAR_PAGE_KATA) {
+ this->charPage = FS_CHAR_PAGE_KATA_TO_HIRA;
+ } else {
+ this->charPage = FS_CHAR_PAGE_ENG_TO_HIRA;
+ }
+ Audio_PlaySfxGeneral(NA_SE_SY_WIN_OPEN, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale,
+ &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
+ } else if (this->kbdButton == FS_KBD_BTN_KATA) {
+ if (this->charPage == FS_CHAR_PAGE_HIRA) {
+ this->charPage = FS_CHAR_PAGE_HIRA_TO_KATA;
+ } else {
+ this->charPage = FS_CHAR_PAGE_ENG_TO_KATA;
+ }
+ Audio_PlaySfxGeneral(NA_SE_SY_WIN_OPEN, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale,
+ &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
+ } else if (this->kbdButton == FS_KBD_BTN_ENG) {
+ if (this->charPage == FS_CHAR_PAGE_HIRA) {
+ this->charPage = FS_CHAR_PAGE_HIRA_TO_ENG;
+ } else {
+ this->charPage = FS_CHAR_PAGE_KATA_TO_ENG;
+ }
+ Audio_PlaySfxGeneral(NA_SE_SY_WIN_OPEN, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale,
+ &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
+ } else {
+ if (this->kbdButton == FS_KBD_BTN_BACKSPACE) {
+ if ((this->newFileNameCharCount == 7) &&
+ (this->fileNames[this->buttonIndex][7] != FILENAME_SPACE)) {
+ for (i = this->newFileNameCharCount; i < 7; i++) {
+ this->fileNames[this->buttonIndex][i] = this->fileNames[this->buttonIndex][i + 1];
+ }
+
+ this->fileNames[this->buttonIndex][i] = FILENAME_SPACE;
+ Audio_PlaySfxGeneral(NA_SE_SY_FSEL_DECIDE_S, &gSfxDefaultPos, 4,
+ &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
+ &gSfxDefaultReverb);
+ } 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] = FILENAME_SPACE;
+ Audio_PlaySfxGeneral(NA_SE_SY_FSEL_DECIDE_S, &gSfxDefaultPos, 4,
+ &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
+ &gSfxDefaultReverb);
+ }
+ } else if (this->kbdButton == FS_KBD_BTN_END) {
+ validName = false;
+
+ for (i = 0; i < 8; i++) {
+ if (this->fileNames[this->buttonIndex][i] != FILENAME_SPACE) {
+ validName = true;
+ break;
+ }
+ }
+
+ if (validName) {
+ Audio_PlaySfxGeneral(NA_SE_SY_FSEL_DECIDE_L, &gSfxDefaultPos, 4,
+ &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
+ &gSfxDefaultReverb);
+ gSaveContext.fileNum = this->buttonIndex;
+ dayTime = ((void)0, gSaveContext.save.dayTime);
+ Sram_InitSave(this, &this->sramCtx);
+ gSaveContext.save.dayTime = dayTime;
+ this->configMode = CM_NAME_ENTRY_TO_MAIN;
+ this->nameBoxAlpha[this->buttonIndex] = this->nameAlpha[this->buttonIndex] = 200;
+ this->connectorAlpha[this->buttonIndex] = 255;
+ Rumble_Request(300.0f, 180, 20, 100);
+ } else {
+ Audio_PlaySfxGeneral(NA_SE_SY_FSEL_ERROR, &gSfxDefaultPos, 4,
+ &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
+ &gSfxDefaultReverb);
+ }
+ }
+ }
+ }
+
+ if (CHECK_BTN_ALL(input->press.button, BTN_CRIGHT)) {
+ Audio_PlaySfxGeneral(NA_SE_SY_FSEL_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale,
+ &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
+ this->newFileNameCharCount++;
+
+ if (this->newFileNameCharCount > 7) {
+ this->newFileNameCharCount = 7;
+ }
+ } else if (CHECK_BTN_ALL(input->press.button, BTN_CLEFT)) {
+ Audio_PlaySfxGeneral(NA_SE_SY_FSEL_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale,
+ &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
+ this->newFileNameCharCount--;
+
+ if (this->newFileNameCharCount < 0) {
+ this->newFileNameCharCount = 0;
+ }
+ } else if (CHECK_BTN_ALL(input->press.button, BTN_Z)) {
+ if (FileSelect_ApplyDiacriticToFilename(&this->state, FILENAME_SPACE)) {
+ Audio_PlaySfxGeneral(NA_SE_SY_FSEL_DECIDE_S, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale,
+ &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
+ }
+ }
+#else
+ if (this->kbdY != 5) {
+ // draw the character the cursor is hovering over in yellow
+ gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 0, 255);
+
gSPVertex(POLY_OPA_DISP++, &this->keyboardVtx[this->charIndex * 4], 4, 0);
FileSelect_DrawCharacter(this->state.gfxCtx,
- font->fontBuf + D_808123F0[this->charIndex] * FONT_CHAR_TEX_SIZE, 0);
+ font->fontBuf + gCharPageEng[this->charIndex] * FONT_CHAR_TEX_SIZE, 0);
if (CHECK_BTN_ALL(input->press.button, BTN_A)) {
Audio_PlaySfxGeneral(NA_SE_SY_FSEL_DECIDE_S, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale,
&gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
- this->fileNames[this->buttonIndex][this->newFileNameCharCount] = D_808123F0[this->charIndex];
+ this->fileNames[this->buttonIndex][this->newFileNameCharCount] = gCharPageEng[this->charIndex];
this->newFileNameCharCount++;
if (this->newFileNameCharCount > 7) {
@@ -491,6 +936,7 @@ void FileSelect_DrawNameEntry(GameState* thisx) {
this->newFileNameCharCount = 0;
}
}
+#endif
}
}
}
@@ -522,7 +968,7 @@ void FileSelect_StartNameEntry(GameState* thisx) {
this->nameEntryBoxAlpha = 255;
this->kbdX = 0;
this->kbdY = 0;
- this->kbdButton = 99;
+ this->kbdButton = FS_KBD_BTN_NONE;
this->configMode = CM_NAME_ENTRY;
}
}
@@ -537,7 +983,199 @@ void FileSelect_UpdateKeyboardCursor(GameState* thisx) {
FileSelectState* this = (FileSelectState*)thisx;
s16 prevKbdX;
- this->kbdButton = 99;
+#if OOT_NTSC
+ Input* input = &this->state.input[0];
+ s32 pad;
+
+ if (this->charPage <= FS_CHAR_PAGE_ENG) {
+ if (CHECK_BTN_ALL(input->press.button, BTN_R)) {
+ if (gSaveContext.language == LANGUAGE_JPN) {
+ if (this->charPage == FS_CHAR_PAGE_HIRA) {
+ this->charPage = FS_CHAR_PAGE_HIRA_TO_KATA;
+ Audio_PlaySfxGeneral(NA_SE_SY_WIN_OPEN, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale,
+ &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
+ } else if (this->charPage == FS_CHAR_PAGE_KATA) {
+ this->charPage = FS_CHAR_PAGE_KATA_TO_ENG;
+ Audio_PlaySfxGeneral(NA_SE_SY_WIN_OPEN, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale,
+ &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
+ } else if (this->charPage == FS_CHAR_PAGE_ENG) {
+ this->charPage = FS_CHAR_PAGE_ENG_TO_HIRA;
+ Audio_PlaySfxGeneral(NA_SE_SY_WIN_OPEN, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale,
+ &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
+ }
+ }
+ } else {
+ this->kbdButton = FS_KBD_BTN_NONE;
+
+ if (this->kbdY != 5) {
+ if (this->stickAdjX < -30) {
+ Audio_PlaySfxGeneral(NA_SE_SY_FSEL_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale,
+ &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
+ this->charIndex--;
+ this->kbdX--;
+ if (this->kbdX < 0) {
+ this->kbdX = 12;
+ this->charIndex = this->kbdY * 13 + this->kbdX;
+ }
+ } else if (this->stickAdjX > 30) {
+ Audio_PlaySfxGeneral(NA_SE_SY_FSEL_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale,
+ &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
+ this->charIndex++;
+ this->kbdX++;
+ if (this->kbdX >= 13) {
+ this->kbdX = 0;
+ this->charIndex = this->kbdY * 13 + this->kbdX;
+ }
+ }
+ } else if (gSaveContext.language == LANGUAGE_JPN) {
+ if (this->stickAdjX < -30) {
+ Audio_PlaySfxGeneral(NA_SE_SY_FSEL_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale,
+ &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
+ this->kbdX--;
+ if (this->kbdX < 0) {
+ this->kbdX = 4;
+ }
+ } else if (this->stickAdjX > 30) {
+ Audio_PlaySfxGeneral(NA_SE_SY_FSEL_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale,
+ &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
+ this->kbdX++;
+ if (this->kbdX >= 5) {
+ this->kbdX = 0;
+ }
+ }
+ } else {
+ if (this->stickAdjX < -30) {
+ Audio_PlaySfxGeneral(NA_SE_SY_FSEL_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale,
+ &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
+ this->kbdX--;
+ if (this->kbdX < 3) {
+ this->kbdX = 4;
+ }
+ } else if (this->stickAdjX > 30) {
+ Audio_PlaySfxGeneral(NA_SE_SY_FSEL_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale,
+ &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
+ this->kbdX++;
+ if (this->kbdX >= 5) {
+ this->kbdX = 3;
+ }
+ }
+ }
+
+ if (this->stickAdjY > 30) {
+ Audio_PlaySfxGeneral(NA_SE_SY_FSEL_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale,
+ &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
+ this->kbdY--;
+ if (this->kbdY < 0) {
+ if (gSaveContext.language == LANGUAGE_JPN) {
+ this->kbdY = 5;
+ this->charIndex += 52;
+ 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_1CAD6[this->kbdX] = prevKbdX;
+ } else {
+ // don't go to bottom row
+ if (this->kbdX < 8) {
+ this->kbdY = 4;
+ this->charIndex = 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_1CAD6[this->kbdX] = prevKbdX;
+ }
+ }
+ } else {
+ this->charIndex -= 13;
+ if (this->kbdY == 4) {
+ this->charIndex = 52;
+ this->kbdX = this->unk_1CAD6[this->kbdX];
+ this->charIndex += this->kbdX;
+ }
+ }
+ } else if (this->stickAdjY < -30) {
+ Audio_PlaySfxGeneral(NA_SE_SY_FSEL_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale,
+ &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
+ this->kbdY++;
+
+ if (this->kbdY >= 6) {
+ this->kbdY = 0;
+ this->kbdX = this->unk_1CAD6[this->kbdX];
+ this->charIndex = this->kbdX;
+ } else {
+ this->charIndex += 13;
+
+ if (this->kbdY == 5) {
+ if (gSaveContext.language != LANGUAGE_JPN) {
+ 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_1CAD6[this->kbdX] = prevKbdX;
+ }
+ } 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_1CAD6[this->kbdX] = prevKbdX;
+ }
+ }
+ }
+ }
+ if (this->kbdY == 5) {
+ this->kbdButton = this->kbdX;
+ }
+ }
+ } else {
+ this->charBgAlpha += ZREG(9);
+ if (this->charBgAlpha >= 255) {
+ this->charBgAlpha = 0;
+ this->charPage = gNextCharPage[this->charPage];
+ }
+ }
+#else
+ this->kbdButton = FS_KBD_BTN_NONE;
if (this->kbdY != 5) {
if (this->stickAdjX < -30) {
@@ -547,16 +1185,16 @@ void FileSelect_UpdateKeyboardCursor(GameState* thisx) {
this->kbdX--;
if (this->kbdX < 0) {
this->kbdX = 12;
- this->charIndex = (this->kbdY * 13) + this->kbdX;
+ this->charIndex = this->kbdY * 13 + this->kbdX;
}
} else if (this->stickAdjX > 30) {
Audio_PlaySfxGeneral(NA_SE_SY_FSEL_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale,
&gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
this->charIndex++;
this->kbdX++;
- if (this->kbdX > 12) {
+ if (this->kbdX >= 13) {
this->kbdX = 0;
- this->charIndex = (this->kbdY * 13) + this->kbdX;
+ this->charIndex = this->kbdY * 13 + this->kbdX;
}
}
} else {
@@ -571,7 +1209,7 @@ void FileSelect_UpdateKeyboardCursor(GameState* thisx) {
Audio_PlaySfxGeneral(NA_SE_SY_FSEL_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale,
&gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
this->kbdX++;
- if (this->kbdX > 4) {
+ if (this->kbdX >= 5) {
this->kbdX = 3;
}
}
@@ -581,17 +1219,15 @@ void FileSelect_UpdateKeyboardCursor(GameState* thisx) {
Audio_PlaySfxGeneral(NA_SE_SY_FSEL_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale,
&gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
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);
+ this->charIndex = 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) {
@@ -602,7 +1238,6 @@ void FileSelect_UpdateKeyboardCursor(GameState* thisx) {
}
} else {
this->charIndex -= 13;
-
if (this->kbdY == 4) {
this->charIndex = 52;
this->kbdX = this->unk_1CAD6[this->kbdX];
@@ -614,7 +1249,7 @@ void FileSelect_UpdateKeyboardCursor(GameState* thisx) {
&gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
this->kbdY++;
- if (this->kbdY > 5) {
+ if (this->kbdY >= 6) {
this->kbdY = 0;
this->kbdX = this->unk_1CAD6[this->kbdX];
this->charIndex = this->kbdX;
@@ -645,10 +1280,10 @@ void FileSelect_UpdateKeyboardCursor(GameState* thisx) {
}
}
}
-
if (this->kbdY == 5) {
this->kbdButton = this->kbdX;
}
+#endif
}
/**
@@ -748,33 +1383,50 @@ void FileSelect_UpdateOptionsMenu(GameState* thisx) {
}
}
+#if OOT_NTSC
+typedef struct {
+ /* 0x00 */ void* texture[2];
+ /* 0x08 */ u16 width;
+ /* 0x0A */ u16 height;
+} OptionsMenuTextureInfo; // size = 0x0C
+
+#define OPTIONS_MENU_TEXTURE_WIDTHS(jpn, eng, ger, fra) jpn
+#define OPTIONS_MENU_TEXTURE_WIDTH(info) info.width
+#define OPTIONS_MENU_TEXTURE_HEIGHT(info) info.height
+#else
typedef struct {
/* 0x00 */ void* texture[3];
/* 0x0C */ u16 width[3];
/* 0x12 */ u16 height;
} OptionsMenuTextureInfo; // size = 0x14
+#define OPTIONS_MENU_TEXTURE_WIDTHS(jpn, eng, ger, fra) \
+ { eng, ger, fra }
+#define OPTIONS_MENU_TEXTURE_WIDTH(info) info.width[gSaveContext.language]
+#define OPTIONS_MENU_TEXTURE_HEIGHT(info) info.height
+#endif
+
static OptionsMenuTextureInfo sOptionsMenuHeaders[] = {
{
LANGUAGE_ARRAY(gFileSelOptionsJPNTex, gFileSelOptionsENGTex, gFileSelOptionsGERTex, gFileSelOptionsENGTex),
- { 128, 128, 128 },
+ OPTIONS_MENU_TEXTURE_WIDTHS(128, 128, 128, 128),
16,
},
{
LANGUAGE_ARRAY(gFileSelSOUNDENGTex, gFileSelSOUNDENGTex, gFileSelSOUNDENGTex, gFileSelSOUNDFRATex),
- { 64, 64, 64 },
+ OPTIONS_MENU_TEXTURE_WIDTHS(64, 64, 64, 64),
16,
},
{
LANGUAGE_ARRAY(gFileSelLTargetingJPNTex, gFileSelLTargetingENGTex, gFileSelLTargetingGERTex,
gFileSelLTargetingFRATex),
- { 64, 144, 64 },
+ OPTIONS_MENU_TEXTURE_WIDTHS(64, 64, 144, 64),
16,
},
{
LANGUAGE_ARRAY(gFileSelCheckBrightnessJPNTex, gFileSelCheckBrightnessENGTex, gFileSelCheckBrightnessGERTex,
gFileSelCheckBrightnessFRATex),
- { 128, 128, 128 },
+ OPTIONS_MENU_TEXTURE_WIDTHS(96, 128, 128, 128),
16,
},
};
@@ -782,32 +1434,32 @@ static OptionsMenuTextureInfo sOptionsMenuHeaders[] = {
static OptionsMenuTextureInfo sOptionsMenuSettings[] = {
{
LANGUAGE_ARRAY(gFileSelStereoJPNTex, gFileSelStereoENGTex, gFileSelStereoENGTex, gFileSelStereoFRATex),
- { 48, 48, 48 },
+ OPTIONS_MENU_TEXTURE_WIDTHS(48, 48, 48, 48),
16,
},
{
LANGUAGE_ARRAY(gFileSelMonoJPNTex, gFileSelMonoENGTex, gFileSelMonoENGTex, gFileSelMonoENGTex),
- { 48, 48, 48 },
+ OPTIONS_MENU_TEXTURE_WIDTHS(48, 48, 48, 48),
16,
},
{
LANGUAGE_ARRAY(gFileSelHeadsetJPNTex, gFileSelHeadsetENGTex, gFileSelHeadsetGERTex, gFileSelHeadsetFRATex),
- { 48, 48, 48 },
+ OPTIONS_MENU_TEXTURE_WIDTHS(48, 48, 48, 48),
16,
},
{
LANGUAGE_ARRAY(gFileSelSurroundJPNTex, gFileSelSurroundENGTex, gFileSelSurroundENGTex, gFileSelSurroundENGTex),
- { 48, 48, 48 },
+ OPTIONS_MENU_TEXTURE_WIDTHS(48, 48, 48, 48),
16,
},
{
LANGUAGE_ARRAY(gFileSelSwitchJPNTex, gFileSelSwitchENGTex, gFileSelSwitchGERTex, gFileSelSwitchFRATex),
- { 48, 80, 48 },
+ OPTIONS_MENU_TEXTURE_WIDTHS(48, 48, 80, 48),
16,
},
{
LANGUAGE_ARRAY(gFileSelHoldJPNTex, gFileSelHoldENGTex, gFileSelHoldGERTex, gFileSelHoldFRATex),
- { 48, 80, 48 },
+ OPTIONS_MENU_TEXTURE_WIDTHS(48, 48, 80, 48),
16,
},
};
@@ -917,9 +1569,9 @@ void FileSelect_DrawOptionsImpl(GameState* thisx) {
for (i = 0, vtx = 0; i < 4; i++, vtx += 4) {
gDPLoadTextureBlock(POLY_OPA_DISP++, sOptionsMenuHeaders[i].texture[gSaveContext.language], G_IM_FMT_IA,
- G_IM_SIZ_8b, sOptionsMenuHeaders[i].width[gSaveContext.language],
- sOptionsMenuHeaders[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);
+ G_IM_SIZ_8b, OPTIONS_MENU_TEXTURE_WIDTH(sOptionsMenuHeaders[i]),
+ OPTIONS_MENU_TEXTURE_HEIGHT(sOptionsMenuHeaders[i]), 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);
}
@@ -952,9 +1604,9 @@ void FileSelect_DrawOptionsImpl(GameState* thisx) {
//! @bug Mistakenly using sOptionsMenuHeaders instead of sOptionsMenuSettings for the height.
//! This works out anyway because all heights are 16.
gDPLoadTextureBlock(POLY_OPA_DISP++, sOptionsMenuSettings[i].texture[gSaveContext.language], G_IM_FMT_IA,
- G_IM_SIZ_8b, sOptionsMenuSettings[i].width[gSaveContext.language],
- sOptionsMenuHeaders[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);
+ G_IM_SIZ_8b, OPTIONS_MENU_TEXTURE_WIDTH(sOptionsMenuSettings[i]),
+ OPTIONS_MENU_TEXTURE_HEIGHT(sOptionsMenuHeaders[i]), 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);
}
@@ -979,9 +1631,9 @@ void FileSelect_DrawOptionsImpl(GameState* thisx) {
//! This is also an OOB read that happens to access the height of the first two elements in
//! sOptionsMenuSettings, and since all heights are 16, it works out anyway.
gDPLoadTextureBlock(POLY_OPA_DISP++, sOptionsMenuSettings[i].texture[gSaveContext.language], G_IM_FMT_IA,
- G_IM_SIZ_8b, sOptionsMenuSettings[i].width[gSaveContext.language],
- sOptionsMenuHeaders[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);
+ G_IM_SIZ_8b, OPTIONS_MENU_TEXTURE_WIDTH(sOptionsMenuSettings[i]),
+ OPTIONS_MENU_TEXTURE_HEIGHT(sOptionsMenuHeaders[i]), 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);
}
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
index d6bc09c282..2fc9670b89 100644
--- a/src/overlays/gamestates/ovl_file_choose/z_file_nameset_data.c
+++ b/src/overlays/gamestates/ovl_file_choose/z_file_nameset_data.c
@@ -1,11 +1 @@
-#include "file_select.h"
-
#include "assets/overlays/ovl_file_choose/ovl_file_choose.c"
-
-s16 D_808123F0[] = {
- 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016,
- 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, 0x0020, 0x0021, 0x0022, 0x0023,
- 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, 0x0030,
- 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D,
- 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0040, 0x003F, 0x003E,
-};
diff --git a/tools/disasm/gc-us/functions.txt b/tools/disasm/gc-us/functions.txt
index 5300b4ed5e..03b61b40f5 100644
--- a/tools/disasm/gc-us/functions.txt
+++ b/tools/disasm/gc-us/functions.txt
@@ -3150,9 +3150,12 @@ FileSelect_EraseAnim2 = 0x808061A4; // type:func
FileSelect_EraseAnim3 = 0x80806268; // type:func
FileSelect_ExitEraseToMain = 0x808064D4; // type:func
FileSelect_DrawCharacter = 0x80806670; // type:func
+FileSelect_DrawCharacterTransition = 0x808067A8; // type:func
FileSelect_SetKeyboardVtx = 0x80806988; // type:func
FileSelect_SetNameEntryVtx = 0x80806C4C; // type:func
FileSelect_DrawKeyboard = 0x80807930; // type:func
+FileSelect_ApplyDiacriticToCharacter = 0x808081F4; // type:func
+FileSelect_ApplyDiacriticToFilename = 0x808083FC; // type:func
FileSelect_DrawNameEntry = 0x8080847C; // type:func
FileSelect_StartNameEntry = 0x808098E0; // type:func
FileSelect_UpdateKeyboardCursor = 0x80809994; // type:func