diff --git a/config/us/pilotwings64.us.yaml b/config/us/pilotwings64.us.yaml index 996d4c4..e71d255 100644 --- a/config/us/pilotwings64.us.yaml +++ b/config/us/pilotwings64.us.yaml @@ -395,7 +395,7 @@ segments: - [0x905C0, c, app/code_905C0] - [0x915B0, c, app/code_915B0] - [0x91670, c, app/hsound] - - [0x92810, c, app/code_92810] + - [0x92810, c, app/menu] - [0x92BF0, c, app/level] - [0x936F0, c, app/credits] - [0x94E60, c, app/code_94E60] @@ -562,7 +562,7 @@ segments: - [0xDAC60, .rodata, app/code_905C0] - [0xDADB0, .rodata, app/code_915B0] - [0xDAE00, .rodata, app/hsound] - - [0xDAF00, .rodata, app/code_92810] + - [0xDAF00, .rodata, app/menu] - [0xDAF30, .rodata, app/level] - [0xDB1D0, .rodata, app/credits] - [0xDB750, .rodata, app/code_94E60] @@ -615,6 +615,8 @@ segments: - [0xDE6B0, .rodata, app/wind_objects] - { type: bss, vram: 0x803571F0, name: app_bss_803571F0 } + - { type: .bss, vram: 0x80369F10, name: app/menu } + - { type: bss, vram: 0x80369F30, name: app_bss_80369F10 } - { type: .bss, vram: 0x8037AB50, name: app/thermals } - { type: bss, vram: 0x8037ACE0, name: app_bss_8037ACD8 } diff --git a/config/us/sym/symbol_addrs_app.txt b/config/us/sym/symbol_addrs_app.txt index 1215069..49cf47d 100644 --- a/config/us/sym/symbol_addrs_app.txt +++ b/config/us/sym/symbol_addrs_app.txt @@ -178,7 +178,16 @@ levelLoadMapObjects = 0x8030BDC8; // type:func credits_8030CDA0 = 0x8030CDA0; // type:func creditsScene = 0x8030D2F0; // type:func -popupDialogBoxInit = 0x8030B52C; // type:func + +menuInit = 0x8030B52C; // type:func +menuCreate = 0x8030B2E0; // type:func +menuCreateVarHeight = 0x8030B38C; // type:func +menuCreateItems = 0x8030B48C; // type:func +menu_8030B50C = 0x8030B50C; // type:func +menuSetProps = 0x8030B54C; // type:func +menu_8030B668 = 0x8030B668; // type:func +menuSetItem = 0x8030B688; // type:func +menu_8030B69C = 0x8030B69C; // type:func introSceneRunner = 0x803439B4; // type:func diff --git a/config/us/sym/symbol_addrs_kernel.txt b/config/us/sym/symbol_addrs_kernel.txt index f928383..bd92c4f 100644 --- a/config/us/sym/symbol_addrs_kernel.txt +++ b/config/us/sym/symbol_addrs_kernel.txt @@ -506,6 +506,13 @@ gLandingStrips = 0x8036C438; // size:0x78 gRadarThermCirc = 0x8036C520; // size:0x88 gHudState = 0x8036C5A8; // size:0xC7C +gMenuItems = 0x80369F10; // size:0x14 +gMenuSpriteIdBase = 0x80369F24; +gMenuSpriteHeight = 0x80369F26; +gMenuCountVarHeight = 0x80369F28; + +gFcnDrawMenuItem = 0x8036BE08; + gLevelCommObjs = 0x8037A600; // size:0x478 gLevelClass = 0x8037AA78; gLevelTest = 0x8037AA7C; diff --git a/src/app/code_92810.c b/src/app/code_92810.c deleted file mode 100644 index 7e025e2..0000000 --- a/src/app/code_92810.c +++ /dev/null @@ -1,21 +0,0 @@ -#include "common.h" - -#pragma GLOBAL_ASM("asm/nonmatchings/app/code_92810/func_8030B2E0.s") - -#pragma GLOBAL_ASM("asm/nonmatchings/app/code_92810/func_8030B38C.s") - -#pragma GLOBAL_ASM("asm/nonmatchings/app/code_92810/func_8030B48C.s") - -#pragma GLOBAL_ASM("asm/nonmatchings/app/code_92810/func_8030B50C.s") - -#pragma GLOBAL_ASM("asm/nonmatchings/app/code_92810/popupDialogBoxInit.s") - -#pragma GLOBAL_ASM("asm/nonmatchings/app/code_92810/func_8030B54C.s") - -#pragma GLOBAL_ASM("asm/nonmatchings/app/code_92810/func_8030B5C4.s") - -#pragma GLOBAL_ASM("asm/nonmatchings/app/code_92810/func_8030B668.s") - -#pragma GLOBAL_ASM("asm/nonmatchings/app/code_92810/func_8030B688.s") - -#pragma GLOBAL_ASM("asm/nonmatchings/app/code_92810/func_8030B69C.s") diff --git a/src/app/code_99D40.c b/src/app/code_99D40.c index e97386d..46eeb07 100644 --- a/src/app/code_99D40.c +++ b/src/app/code_99D40.c @@ -1,4 +1,5 @@ #include "common.h" +#include "code_99D40.h" #pragma GLOBAL_ASM("asm/nonmatchings/app/code_99D40/func_80312810.s") diff --git a/src/app/code_99D40.h b/src/app/code_99D40.h new file mode 100644 index 0000000..7b69276 --- /dev/null +++ b/src/app/code_99D40.h @@ -0,0 +1,16 @@ +#ifndef APP_CODE_99D40_H +#define APP_CODE_99D40_H + +#include + +// function pointer to draw menu item +extern void (*gFcnDrawMenuItem)(s16, s16, s16); + +void func_80312810(s32, s32, s32, f32, f32, s32, s32 itemCount); +void func_80312908(void); +void func_80312B50(void); +void func_80312B5C(void); +void func_80312F38(void); +void func_80312F44(s32); + +#endif // APP_CODE_99D40_H diff --git a/src/app/code_C9440.h b/src/app/code_C9440.h index 1af2f39..1805e14 100644 --- a/src/app/code_C9440.h +++ b/src/app/code_C9440.h @@ -4,7 +4,7 @@ #include void func_80341F10(s32); -s16* func_80342198(s16); +s16* func_80342198(s32); void func_80342404(s16*, s32, s32, s32); #endif // APP_CODE_C9440_H diff --git a/src/app/menu.c b/src/app/menu.c new file mode 100644 index 0000000..4c3569f --- /dev/null +++ b/src/app/menu.c @@ -0,0 +1,97 @@ +#include "common.h" +#include +#include +#include "code_99D40.h" +#include "code_C9440.h" +#include "menu.h" + +// forward declarations +static void menuCreate(s32 x, s32 y, s32 arg2, f32 xscale, f32 yscale, s32 itemCount); +static void menuDrawItem(s16 arg0, s16 arg1, s16 idx); + +// arrays of pointers to 16-bit strings +// e.g. "Option" from main menu is 0x0078 0x0093 0x0097 0x008c 0x0092 0091 0x0ffe 0xffff +static s16* gMenuItems[5]; +static s16 gMenuSpriteIdBase; +static s16 gMenuSpriteHeight; +static s16 gMenuCountVarHeight; + +static void menuCreate(s32 x, s32 y, s32 arg2, f32 xscale, f32 yscale, s32 itemCount) { + s32 i; + + gMenuSpriteHeight = 0; + if (itemCount > ARRAY_COUNT(gMenuItems)) { + _uvDebugPrintf("kmenu_init : too may elements in the menu [%d]\n", itemCount); + } + func_80312810(x, y, arg2, xscale, yscale, 0, itemCount); + + // clang-format off: needs to be on same line to match + for (i = 0; i < ARRAY_COUNT(gMenuItems); i++) { gMenuItems[i] = NULL; } + // clang-format on + + gFcnDrawMenuItem = &menuDrawItem; +} + +// menuCreateVarHeight is unused, but serves as a wrapper for menuCreate +// it computes non-zero gMenuSpriteHeight, triggering different code paths below +void menuCreateVarHeight(s32 x, s32 y, s32 arg2, f32 xscale, f32 yscale, s32* items, s32 count) { + s32 i; + + menuCreate(x, y, arg2, xscale, yscale, count); + gMenuCountVarHeight = (s16)count; + gMenuSpriteIdBase = 0xF; + + for (i = 0; i < count; i++) { + uvSprtProps(gMenuSpriteIdBase + i, 3, 1, 2, x, ((gMenuSpriteHeight + 6) * i) + y, 9, items[i], 0); + gMenuSpriteHeight = uvSprtGetHeight(gMenuSpriteIdBase + i); + } +} + +void menuCreateItems(s32 x, s32 y, s32 arg2, f32 xscale, f32 yscale, s32* items, s32 itemCount) { + s32 temp_v0; + s32 i; + + menuCreate(x, y, arg2, xscale, yscale, itemCount); + + for (i = 0; i < itemCount; i++) { + gMenuItems[i] = func_80342198(items[i]); + } +} + +void menu_8030B50C(void) { + func_80312908(); +} + +void menuInit(void) { + func_80312B5C(); +} + +void menuSetProps(void) { + s32 i; + + func_80312B50(); + for (i = 0; i < gMenuCountVarHeight; i++) { + uvSprtProps(gMenuSpriteIdBase + i, 3, 0, 0); + } +} + +static void menuDrawItem(s16 arg0, s16 arg1, s16 idx) { + if (gMenuSpriteHeight != 0) { + uvSprtProps(gMenuSpriteIdBase + idx, 2, arg0, arg1 + gMenuSpriteHeight + 2, 0); + uvSprtDraw(gMenuSpriteIdBase + idx); + } else { + func_80219874(arg0, arg1, gMenuItems[idx], 100, 0xFFE); + } +} + +void menu_8030B668(void) { + func_80312F38(); +} + +void menuSetItem(s32 idx, s16* str) { + gMenuItems[idx] = str; +} + +void menu_8030B69C(s32 arg0) { + func_80312F44(arg0); +} diff --git a/src/app/menu.h b/src/app/menu.h new file mode 100644 index 0000000..358c4b6 --- /dev/null +++ b/src/app/menu.h @@ -0,0 +1,15 @@ +#ifndef APP_MENU_H +#define APP_MENU_H + +#include + +void menuCreateVarHeight(s32 x, s32 y, s32 arg2, f32 xscale, f32 yscale, s32* items, s32 count); +void menuCreateItems(s32 x, s32 y, s32 arg2, f32 xscale, f32 yscale, s32* items, s32 itemCount); +void menu_8030B50C(void); +void menuInit(void); +void menuSetProps(void); +void menu_8030B668(void); +void menuSetItem(s32 idx, s16* str); +void menu_8030B69C(s32); + +#endif // APP_MENU_H