From 42741242d1ce423ed7c7025d5de54f120bbe9da6 Mon Sep 17 00:00:00 2001 From: Dargor Date: Wed, 2 Sep 2026 22:08:58 -0300 Subject: [PATCH 1/4] menushop: decompiled five menushop functions - decompiled five menushop functions: func_801E5D28 func_801E5DBC func_801E6ACC func_801E6EB0 func_801E791C - refactored three functions in order to use MenuDisplayConfig struct func_801E6F60 func_801E8B60 func_801E9554 - created menushop header file for struct, variable and function declaration --- include/menushop.h | 31 +++++ src/menu/menushop/menushop.c | 219 +++++++++++++++++++++++++++-------- 2 files changed, 203 insertions(+), 47 deletions(-) create mode 100644 include/menushop.h diff --git a/include/menushop.h b/include/menushop.h new file mode 100644 index 00000000..7a320244 --- /dev/null +++ b/include/menushop.h @@ -0,0 +1,31 @@ +#ifndef MENUSHOP_H +#define MENUSHOP_H + +typedef struct { + u8 unk0; + u8 unk1; +} Struct_801E5DBC; + +typedef struct { + u16 unk0; + u8 unk2; +} Struct_801E6ACC; + +extern u8 D_80077EBC[]; +extern u8 D_801EA3F0[]; +extern u8 D_801EA70C[]; +extern u8 D_801F7F98[]; +extern u8 D_801E9B64[]; +extern u8 D_801E9B6C[]; +extern u8 D_801EA170[]; +extern u8 D_801EAA28[]; +extern s32 D_801EAA48[]; +extern s32 D_801EAD68[]; +extern u8 D_801EB088[]; +extern s32 g_menuColor; +extern s32 D_80077E70; +extern s32 func_801E8AB0; +extern s32 func_801E5E90(s32); +extern s32 func_801E79D4; + +#endif /* MENUSHOP_H */ diff --git a/src/menu/menushop/menushop.c b/src/menu/menushop/menushop.c index c497e4c3..ce04af71 100644 --- a/src/menu/menushop/menushop.c +++ b/src/menu/menushop/menushop.c @@ -1,14 +1,7 @@ #include "common.h" - -extern u8 D_801EA70C[]; -extern u8 D_801F7F98[]; -extern u8 D_801E9B64[]; -extern u8 D_801E9B6C[]; -extern u8 g_menuDisplayCfg[]; -extern s32 g_menuColor; -extern s32 D_80077E70; -extern s32 func_801E6EB0; -extern s32 func_801E8AB0; +#include "gamestate.h" +#include "menu.h" +#include "menushop.h" /** * @brief Look up a shop item byte from a table or item data. @@ -97,9 +90,75 @@ void func_801E5BA4(s32 a0, s32 a1) { INCLUDE_ASM("asm/ovl/menushop/nonmatchings/menushop", func_801E5C08); -INCLUDE_ASM("asm/ovl/menushop/nonmatchings/menushop", func_801E5D28); +s32 func_801E5D28(void) { + s32 result; + u8* ptr1; + u8* ptr2; + s32 i; + s32 val1; + s32 val2; + + if (g_gameState.mainData.partyLockFlag & 1) { + result = g_gameState.mainData.party.dreamGil; + } else { + result = g_gameState.mainData.party.gil; + } + + ptr1 = D_80077EBC; + i = 0xC7; + ptr2 = D_801EB088; + ptr2 += 0xC7; + + for (; i >= 0; i--, ptr2--) { + *ptr2 = 0; + } + + for (i = 0; i < 0xC6; i++) { + val1 = *ptr1; + ptr1++; + + val2 = *ptr1; + ptr1++; + + if (val1 != 0) { + D_801EB088[val1] = val2; + } + } + + return result; +} + +void func_801E5DBC(void) { + u8 sp[16]; + s32 counter; + s32 i; + Struct_801E5DBC *ptr; + + ptr = (Struct_801E5DBC *)D_801EAA28; + counter = 0; + + for (i = 0 ; i < 16; i++, ptr++) { + if (ptr->unk0 != 0) { + if (ptr->unk1 != 0) { + sp[counter] = i; + counter++; + } + } + } + + ptr = (Struct_801E5DBC *)D_801EAA28; + + for (i = 0; i < counter; i++) { + if (i != sp[i]) { + ptr[i] = ptr[sp[i]]; + } + } -INCLUDE_ASM("asm/ovl/menushop/nonmatchings/menushop", func_801E5DBC); + for (; i < 16; i++) { + ptr[i].unk0 = 0; + ptr[i].unk1 = 0; + } +} void func_801E5E88(void) { } @@ -108,7 +167,42 @@ INCLUDE_ASM("asm/ovl/menushop/nonmatchings/menushop", func_801E5E90); INCLUDE_ASM("asm/ovl/menushop/nonmatchings/menushop", func_801E6A68); -INCLUDE_ASM("asm/ovl/menushop/nonmatchings/menushop", func_801E6ACC); +void func_801E6ACC(void) { + Struct_801E6ACC *ptr; + s32 result; + s32 i; + s32 x; + s32 y; + + result = func_801F72B4(); + ptr = (Struct_801E6ACC *)D_801EA3F0; + + for (i = 0; i < 200; i++) { + if (result & 1) { + D_801EAD68[i] = (ptr[i].unk0 * 15) / 2; + } else { + D_801EAD68[i] = ptr[i].unk0 * 10; + } + + if (result & 2) { + x = ptr[i].unk2 * 10; + y = ptr[i].unk0 * x; + D_801EAA48[i] = y * 3 / 40; + } else { + x = ptr[i].unk2 * 10; + y = ptr[i].unk0 * x; + D_801EAA48[i] = y / 20; + } + + if (D_801EAA48[i] == 0) { + D_801EAA48[i] = 1; + } + if (D_801EAD68[i] == 0) { + D_801EAD68[i] = 1; + } + } +} + INCLUDE_ASM("asm/ovl/menushop/nonmatchings/menushop", func_801E6C3C); @@ -116,7 +210,25 @@ INCLUDE_ASM("asm/ovl/menushop/nonmatchings/menushop", func_801E6D54); INCLUDE_ASM("asm/ovl/menushop/nonmatchings/menushop", func_801E6E0C); -INCLUDE_ASM("asm/ovl/menushop/nonmatchings/menushop", func_801E6EB0); +s32 func_801E6EB0(s32 arg0, s32 arg1, s32 arg2, s32 arg3, s32 arg4) { + u8 buffer[0x80]; + s32 msg; + s32 temp_s0; + s32 temp_s1; + s32 temp_v0; + s32 result; + + msg = ((s32 *)(g_menuDisplayCfg.dataPtr))[arg2]; + result = arg1; + if (msg != 0) { + temp_v0 = (arg4 + 0xA); + temp_s0 = g_menuDisplayCfg.x + temp_v0; + temp_s1 = g_menuDisplayCfg.y + 5; + decodeMessage(msg, buffer, -1); + result = func_801F0FEC(arg0, arg1, temp_s0, temp_s1, buffer, 7); + } + return result; +} /** * @brief Configure display parameters and invoke callback for shop list rendering. @@ -133,18 +245,17 @@ INCLUDE_ASM("asm/ovl/menushop/nonmatchings/menushop", func_801E6EB0); * @param arg5 X position for the display configuration. */ void func_801E6F60(u8 *a0, s32 a1, s32 a2, s32 a3, s32 arg5) { - s32 cfg = (s32)g_menuDisplayCfg; - *(u8 *)(cfg + 0x10) = 0; - *(u8 *)(cfg + 0x11) = 0; - *(s16 *)&g_menuDisplayCfg[0] = a3; - *(s16 *)(cfg + 0x04) = 0x144; - *(s16 *)(cfg + 0x06) = 0x14; - *(u8 *)(cfg + 0x13) = 1; - *(u8 *)(cfg + 0x16) = 0; - *(u8 *)(cfg + 0x17) = 1; - *(s16 *)(cfg + 0x02) = arg5; - *(s16 *)(cfg + 0x14) = *(u16 *)(a0 + 0x3A); - *(s32 *)(cfg + 0x20) = (s32)(a0 + 0x20); + g_menuDisplayCfg.iconType = 0; + g_menuDisplayCfg.iconSubType = 0; + g_menuDisplayCfg.x = a3; + g_menuDisplayCfg.w = 0x144; + g_menuDisplayCfg.h = 0x14; + g_menuDisplayCfg.columnCount = 1; + g_menuDisplayCfg.pageStart = 0; + g_menuDisplayCfg.pageEnd = 1; + g_menuDisplayCfg.y = arg5; + g_menuDisplayCfg.scrollOffset = *(u16 *)(a0 + 0x3A); + g_menuDisplayCfg.dataPtr = (s32)(a0 + 0x20); { func_801EFBB4(a1, a2, (s32)&func_801E6EB0); } @@ -162,7 +273,24 @@ INCLUDE_ASM("asm/ovl/menushop/nonmatchings/menushop", func_801E7628); INCLUDE_ASM("asm/ovl/menushop/nonmatchings/menushop", func_801E77EC); -INCLUDE_ASM("asm/ovl/menushop/nonmatchings/menushop", func_801E791C); +void func_801E791C(s32 arg0, s32 arg1, s32 arg2, s32 arg3, s32 arg4) { + s32 var_v0; + MenuDisplayConfig *cfg; + + cfg = &g_menuDisplayCfg; + + var_v0 = arg2; + if (arg0 != 0) { + var_v0 = func_801F0FEC(arg1, var_v0, arg3 + 0xC, arg4 + 5, arg0, 7); + } + cfg->iconType = 0; + cfg->iconSubType = 0; + cfg->x = arg3; + cfg->w = 0xDA; + cfg->y = (s16) arg4; + cfg->h = 0x15; + func_801EF9AC(arg1, var_v0, 0x1000, g_menuColor); +} INCLUDE_ASM("asm/ovl/menushop/nonmatchings/menushop", func_801E79D4); @@ -266,18 +394,17 @@ INCLUDE_ASM("asm/ovl/menushop/nonmatchings/menushop", func_801E8AB0); * @param arg5 X position for the display configuration. */ void func_801E8B60(u8 *a0, s32 a1, s32 a2, s32 a3, s32 arg5) { - s32 cfg = (s32)g_menuDisplayCfg; - *(u8 *)(cfg + 0x10) = 0; - *(u8 *)(cfg + 0x11) = 0; - *(s16 *)&g_menuDisplayCfg[0] = a3; - *(s16 *)(cfg + 0x04) = 0x144; - *(s16 *)(cfg + 0x06) = 0x14; - *(u8 *)(cfg + 0x13) = 1; - *(u8 *)(cfg + 0x16) = 0; - *(u8 *)(cfg + 0x17) = 1; - *(s16 *)(cfg + 0x02) = arg5; - *(s16 *)(cfg + 0x14) = *(u16 *)(a0 + 0x36); - *(s32 *)(cfg + 0x20) = (s32)(a0 + 0x20); + g_menuDisplayCfg.iconType = 0; + g_menuDisplayCfg.iconSubType = 0; + g_menuDisplayCfg.x = a3; + g_menuDisplayCfg.w = 0x144; + g_menuDisplayCfg.h = 0x14; + g_menuDisplayCfg.columnCount = 1; + g_menuDisplayCfg.pageStart = 0; + g_menuDisplayCfg.pageEnd = 1; + g_menuDisplayCfg.y = arg5; + g_menuDisplayCfg.scrollOffset = *(u16 *)(a0 + 0x36); + g_menuDisplayCfg.dataPtr = (s32)(a0 + 0x20); { func_801EFBB4(a1, a2, (s32)&func_801E8AB0); } @@ -326,16 +453,14 @@ INCLUDE_ASM("asm/ovl/menushop/nonmatchings/menushop", func_801E90F8); */ void func_801E9554(s32 a0, s32 a1, s32 a2, s32 a3, s32 arg4) { s32 result; - u8 *cfg; result = func_801E90F8(a0, a1, a2, a3, arg4); - cfg = g_menuDisplayCfg; - *(u8 *)(cfg + 0x10) = 0x57; - *(u8 *)(cfg + 0x11) = 0; - *(s16 *)&g_menuDisplayCfg[0] = a3; - *(s16 *)(cfg + 0x04) = 0x150; - *(s16 *)(cfg + 0x02) = arg4; - *(s16 *)(cfg + 0x06) = 0x26; + g_menuDisplayCfg.iconType = 0x57; + g_menuDisplayCfg.iconSubType = 0; + g_menuDisplayCfg.x = a3; + g_menuDisplayCfg.w = 0x150; + g_menuDisplayCfg.y = arg4; + g_menuDisplayCfg.h = 0x26; func_801EF9AC(a1, result, 0x1000, g_menuColor); } From 69869be0344fab35bdda0de156a69e9c0079face Mon Sep 17 00:00:00 2001 From: Dargor Date: Thu, 3 Sep 2026 13:45:05 -0300 Subject: [PATCH 2/4] menushop: refactor two functions - func_801E5D28: change D_801EB088 from a u8 array to a struct - func_801E8B60: change the first argument from a u8 array to a struct --- include/menushop.h | 13 ++++++++++++- src/menu/menushop/menushop.c | 15 ++++++--------- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/include/menushop.h b/include/menushop.h index 7a320244..baac0759 100644 --- a/include/menushop.h +++ b/include/menushop.h @@ -11,6 +11,17 @@ typedef struct { u8 unk2; } Struct_801E6ACC; +typedef struct { + u8 unk0[0xC7]; +} Struct_D_801EB088; + +typedef struct { + u8 pad000[0x20]; + s32 *unk20; + u8 pad024[0x12]; + u16 unk36; +} Struct_801E8B60; + extern u8 D_80077EBC[]; extern u8 D_801EA3F0[]; extern u8 D_801EA70C[]; @@ -21,7 +32,7 @@ extern u8 D_801EA170[]; extern u8 D_801EAA28[]; extern s32 D_801EAA48[]; extern s32 D_801EAD68[]; -extern u8 D_801EB088[]; +extern Struct_D_801EB088 D_801EB088; extern s32 g_menuColor; extern s32 D_80077E70; extern s32 func_801E8AB0; diff --git a/src/menu/menushop/menushop.c b/src/menu/menushop/menushop.c index ce04af71..f7c30e47 100644 --- a/src/menu/menushop/menushop.c +++ b/src/menu/menushop/menushop.c @@ -105,12 +105,9 @@ s32 func_801E5D28(void) { } ptr1 = D_80077EBC; - i = 0xC7; - ptr2 = D_801EB088; - ptr2 += 0xC7; - for (; i >= 0; i--, ptr2--) { - *ptr2 = 0; + for (i = 0; i < 0xC8; i++) { + D_801EB088.unk0[i] = 0; } for (i = 0; i < 0xC6; i++) { @@ -121,7 +118,7 @@ s32 func_801E5D28(void) { ptr1++; if (val1 != 0) { - D_801EB088[val1] = val2; + D_801EB088.unk0[val1] = val2; } } @@ -393,7 +390,7 @@ INCLUDE_ASM("asm/ovl/menushop/nonmatchings/menushop", func_801E8AB0); * @param a3 Y position for the display configuration. * @param arg5 X position for the display configuration. */ -void func_801E8B60(u8 *a0, s32 a1, s32 a2, s32 a3, s32 arg5) { +void func_801E8B60(Struct_801E8B60 *a0, s32 a1, s32 a2, s32 a3, s32 arg5) { g_menuDisplayCfg.iconType = 0; g_menuDisplayCfg.iconSubType = 0; g_menuDisplayCfg.x = a3; @@ -403,8 +400,8 @@ void func_801E8B60(u8 *a0, s32 a1, s32 a2, s32 a3, s32 arg5) { g_menuDisplayCfg.pageStart = 0; g_menuDisplayCfg.pageEnd = 1; g_menuDisplayCfg.y = arg5; - g_menuDisplayCfg.scrollOffset = *(u16 *)(a0 + 0x36); - g_menuDisplayCfg.dataPtr = (s32)(a0 + 0x20); + g_menuDisplayCfg.scrollOffset = a0->unk36; + g_menuDisplayCfg.dataPtr = &a0->unk20; { func_801EFBB4(a1, a2, (s32)&func_801E8AB0); } From 4648b8dbd67d7607a32ea0ef6ff1bb84328b8dd3 Mon Sep 17 00:00:00 2001 From: Dargor Date: Thu, 3 Sep 2026 22:25:45 -0300 Subject: [PATCH 3/4] menushop: decomp func_801E7B9C --- include/menumain.h | 11 ++++++++++- include/menushop.h | 4 ++-- src/menu/menushop/menushop.c | 22 +++++++++++++++++++++- 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/include/menumain.h b/include/menumain.h index b98d3151..147ac00c 100644 --- a/include/menumain.h +++ b/include/menumain.h @@ -56,7 +56,16 @@ typedef struct MenuTask { s32 (*drawCb)(struct MenuTask *, s32, s32); /* 0x0C: (task, ctx, dl) -> dl (func_801F16AC). */ u16 state; /* 0x10: per-task state word, zeroed on alloc. */ s8 inUse; /* 0x12: pool slot occupied. */ - u8 pad13[0x65]; + u8 pad13[0x15]; + u32 unk28; + u8 *unk2C; + u32 unk30; + u16 pad34; + u16 unk36; + u16 unk38; + u8 pad3A[0xB]; + u8 unk45; + u8 pad46[0x32]; } MenuTask; /* 0x78 bytes */ /** diff --git a/include/menushop.h b/include/menushop.h index baac0759..1cfc120a 100644 --- a/include/menushop.h +++ b/include/menushop.h @@ -36,7 +36,7 @@ extern Struct_D_801EB088 D_801EB088; extern s32 g_menuColor; extern s32 D_80077E70; extern s32 func_801E8AB0; -extern s32 func_801E5E90(s32); -extern s32 func_801E79D4; +extern void func_801E5E90(void*); +extern s32 func_801E79D4(void*, s32, s32); #endif /* MENUSHOP_H */ diff --git a/src/menu/menushop/menushop.c b/src/menu/menushop/menushop.c index f7c30e47..233366b8 100644 --- a/src/menu/menushop/menushop.c +++ b/src/menu/menushop/menushop.c @@ -2,6 +2,7 @@ #include "gamestate.h" #include "menu.h" #include "menushop.h" +#include "menumain.h" /** * @brief Look up a shop item byte from a table or item data. @@ -291,7 +292,26 @@ void func_801E791C(s32 arg0, s32 arg1, s32 arg2, s32 arg3, s32 arg4) { INCLUDE_ASM("asm/ovl/menushop/nonmatchings/menushop", func_801E79D4); -INCLUDE_ASM("asm/ovl/menushop/nonmatchings/menushop", func_801E7B9C); +void func_801E7B9C(s32 a0) { + MenuTask *temp_s0; + + temp_s0 = (MenuTask *)func_801F179C((s32)func_801E5E90, (s32)func_801E79D4); + func_801F1D2C(0, (s32)"shop.bin", (s32)D_801EA170); + func_801F1D2C(0, (s32)"price.bin", (s32)D_801EA3F0); + func_801F1D2C(0, (s32)"mitem.bin", (s32)D_801EA70C); + if (temp_s0 != NULL) { + temp_s0->unk2C = D_80077EBC; + temp_s0->unk36 = 0x1000; + temp_s0->unk30 = 0; + temp_s0->unk28 = func_801E5D28(); + temp_s0->unk45 = D_801E9B6C[func_801EFFF0()]; + func_801E6D54(temp_s0->unk45); + func_801E5E90(temp_s0); + if (func_801EFFB8() == 0x17) { + func_801F1D84(); + } + } +} /** * @brief Process shop state and dispatch to appropriate handler. From d13fd0a07869e3413086d089fc782d01086294b8 Mon Sep 17 00:00:00 2001 From: Dargor Date: Fri, 4 Sep 2026 22:08:18 -0300 Subject: [PATCH 4/4] menushop: decomp and refactors - Decompiled func_801E6A68 - Renamed some structs and their attributes to be more descriptive - Added constants for the number of items in the shop, item prices, and item slots --- include/menushop.h | 35 +++++++++----- src/menu/menushop/menushop.c | 90 ++++++++++++++++++++++++++---------- 2 files changed, 88 insertions(+), 37 deletions(-) diff --git a/include/menushop.h b/include/menushop.h index 1cfc120a..fc668e34 100644 --- a/include/menushop.h +++ b/include/menushop.h @@ -1,15 +1,25 @@ #ifndef MENUSHOP_H #define MENUSHOP_H +#define SHOP_COUNT 20 +#define SHOP_ITEM_COUNT 16 +#define ITEM_PRICE_COUNT 200 +#define ITEM_SLOT_COUNT 198 + +typedef struct { + u8 itemId; /**< 0x0: item ID. */ + u8 rarity; /**< 0x1: item rarity (0x00 = Rare, 0xFF = Common). */ +} ShopItemRarity; /* 0x2 = 2 bytes */ + typedef struct { - u8 unk0; - u8 unk1; -} Struct_801E5DBC; + u8 itemId; /**< 0x0: item ID. */ + u8 visible; /**< 0x1: item visibility flag. */ +} ShopItemVisibility; /* 0x2 = 2 bytes */ typedef struct { - u16 unk0; - u8 unk2; -} Struct_801E6ACC; + u16 basePrice; /**< 0x0: base price. */ + u8 sellRate; /**< 0x2: sell rate. */ +} ShopItemPrice; /* 0x3 = 3 bytes */ typedef struct { u8 unk0[0xC7]; @@ -22,16 +32,17 @@ typedef struct { u16 unk36; } Struct_801E8B60; -extern u8 D_80077EBC[]; -extern u8 D_801EA3F0[]; +extern ShopData D_80077CC8[SHOP_COUNT]; /**< Shop data table. */ +extern u8 D_80077EBC[ITEM_SLOT_COUNT]; /**< Item slot inventory. */ +extern ShopItemPrice D_801EA3F0[ITEM_PRICE_COUNT]; /**< Item price table. */ extern u8 D_801EA70C[]; extern u8 D_801F7F98[]; extern u8 D_801E9B64[]; extern u8 D_801E9B6C[]; -extern u8 D_801EA170[]; -extern u8 D_801EAA28[]; -extern s32 D_801EAA48[]; -extern s32 D_801EAD68[]; +extern ShopItemRarity D_801EA170[SHOP_COUNT][SHOP_ITEM_COUNT]; /**< Shop item rarity tables. */ +extern ShopItemVisibility D_801EAA28[SHOP_ITEM_COUNT]; /**< Shop item visibility table. */ +extern s32 D_801EAA48[ITEM_PRICE_COUNT]; /**< Item sell prices. */ +extern s32 D_801EAD68[ITEM_PRICE_COUNT]; /**< Item buy prices. */ extern Struct_D_801EB088 D_801EB088; extern s32 g_menuColor; extern s32 D_80077E70; diff --git a/src/menu/menushop/menushop.c b/src/menu/menushop/menushop.c index 233366b8..6723752c 100644 --- a/src/menu/menushop/menushop.c +++ b/src/menu/menushop/menushop.c @@ -107,11 +107,11 @@ s32 func_801E5D28(void) { ptr1 = D_80077EBC; - for (i = 0; i < 0xC8; i++) { + for (i = 0; i < ITEM_PRICE_COUNT; i++) { D_801EB088.unk0[i] = 0; } - for (i = 0; i < 0xC6; i++) { + for (i = 0; i < ITEM_SLOT_COUNT; i++) { val1 = *ptr1; ptr1++; @@ -126,25 +126,31 @@ s32 func_801E5D28(void) { return result; } +/** + * @brief Compacts the shop item list in place. + * + * Scans the 16 entries in D_801EAA28 and keeps only entries whose + * itemId and visible fields are both non-zero. Valid entries are moved to + * the beginning of the table in their original order, while all + * remaining entries are cleared. + */ void func_801E5DBC(void) { - u8 sp[16]; + u8 sp[SHOP_ITEM_COUNT]; s32 counter; s32 i; - Struct_801E5DBC *ptr; + ShopItemVisibility *ptr; - ptr = (Struct_801E5DBC *)D_801EAA28; + ptr = D_801EAA28; counter = 0; - for (i = 0 ; i < 16; i++, ptr++) { - if (ptr->unk0 != 0) { - if (ptr->unk1 != 0) { - sp[counter] = i; - counter++; - } + for (i = 0 ; i < SHOP_ITEM_COUNT; i++, ptr++) { + if (ptr->itemId != 0 && ptr->visible != 0) { + sp[counter] = i; + counter++; } } - ptr = (Struct_801E5DBC *)D_801EAA28; + ptr = D_801EAA28; for (i = 0; i < counter; i++) { if (i != sp[i]) { @@ -152,9 +158,9 @@ void func_801E5DBC(void) { } } - for (; i < 16; i++) { - ptr[i].unk0 = 0; - ptr[i].unk1 = 0; + for (; i < SHOP_ITEM_COUNT; i++) { + ptr[i].itemId = 0; + ptr[i].visible = 0; } } @@ -163,32 +169,66 @@ void func_801E5E88(void) { INCLUDE_ASM("asm/ovl/menushop/nonmatchings/menushop", func_801E5E90); -INCLUDE_ASM("asm/ovl/menushop/nonmatchings/menushop", func_801E6A68); +/** + * @brief Populate shop item visibility data for a shop. + * + * Copies item IDs from the shop's rarity table and visibility flags from + * the shop inventory into the shared visibility table. + */ +void func_801E6A68(s32 shopId) { + ShopItemVisibility *visibility; + ShopItemRarity *rarity; + ShopData *shop; + s32 i; + + visibility = D_801EAA28; + rarity = D_801EA170[0]; + rarity += shopId * 16; + + shop = &D_80077CC8[shopId]; + + for (i = 0; i < SHOP_ITEM_COUNT; i++) { + visibility->itemId = rarity[i].itemId; + visibility->visible = shop->items[i]; + visibility++; + } +} + +/** + * @brief Calculates and stores shop buy and sell prices. + * + * The flags returned by func_801F72B4 determine the price modifiers: + * - bit 0 reduces the buy price by 25%. + * - bit 1 increases the sell price by 50%. + * Buy prices are stored in D_801EAD68, and sell prices in D_801EAA48. + * Prices are calculated using integer arithmetic and are clamped to a + * minimum value of 1. + */ void func_801E6ACC(void) { - Struct_801E6ACC *ptr; + ShopItemPrice *itemPrice; s32 result; s32 i; s32 x; s32 y; result = func_801F72B4(); - ptr = (Struct_801E6ACC *)D_801EA3F0; + itemPrice = D_801EA3F0; - for (i = 0; i < 200; i++) { + for (i = 0; i < ITEM_PRICE_COUNT; i++) { if (result & 1) { - D_801EAD68[i] = (ptr[i].unk0 * 15) / 2; + D_801EAD68[i] = (itemPrice[i].basePrice * 15) / 2; } else { - D_801EAD68[i] = ptr[i].unk0 * 10; + D_801EAD68[i] = itemPrice[i].basePrice * 10; } if (result & 2) { - x = ptr[i].unk2 * 10; - y = ptr[i].unk0 * x; + x = itemPrice[i].sellRate * 10; + y = itemPrice[i].basePrice * x; D_801EAA48[i] = y * 3 / 40; } else { - x = ptr[i].unk2 * 10; - y = ptr[i].unk0 * x; + x = itemPrice[i].sellRate * 10; + y = itemPrice[i].basePrice * x; D_801EAA48[i] = y / 20; }