diff --git a/include/gamestate.h b/include/gamestate.h index fc2e9793..c8321dca 100644 --- a/include/gamestate.h +++ b/include/gamestate.h @@ -107,7 +107,7 @@ enum GfId { * 20 entries at g_gameState + 0x950 (0x80077CC8). */ typedef struct { - /* 0x00 */ u8 items[16]; /**< Item IDs available for sale. */ + /* 0x00 */ u8 items[16]; /**< Flags indicating whether each item is visible in the shop. */ /* 0x10 */ u8 visited; /**< Shop has been visited flag. */ /* 0x11 */ u8 pad[3]; /**< Padding. */ } ShopData; /* 0x14 = 20 bytes */ diff --git a/include/menumain.h b/include/menumain.h index b98d3151..79f2e4cd 100644 --- a/include/menumain.h +++ b/include/menumain.h @@ -30,7 +30,7 @@ DR_AREA *func_801EF800(P_TAG *, DR_AREA *, u8 *); /**< Link a custom-rect DR_AREA prim. */ DR_AREA *func_801EF8D8(P_TAG *, DR_AREA *); /**< Link a clip-restore DR_AREA prim. */ s32 func_801EF9AC(s32, s32, s32, s32); /**< Panel/window render helper. */ -void func_801EFBB4(s32, s32, s32); /**< Panel/window render helper. */ +s32 func_801EFBB4(s32, s32, s32); /**< Panel/window render helper. */ s32 func_801F179C(s32, s32); /**< Allocate a menu state task (tickCb, drawCb). */ s32 func_801F6AD0(s32); /**< Party/character query helper. */ void func_801F7B60(void); /**< Menu teardown/exit helper. */ @@ -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 new file mode 100644 index 00000000..e322166e --- /dev/null +++ b/include/menushop.h @@ -0,0 +1,67 @@ +#ifndef MENUSHOP_H +#define MENUSHOP_H + +#include "gamestate.h" + +#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 itemId; /**< 0x0: item ID. */ + u8 visible; /**< 0x1: item visibility flag. */ +} ShopItemVisibility; /* 0x2 = 2 bytes */ + +typedef struct { + u16 basePrice; /**< 0x0: base price. */ + u8 sellRate; /**< 0x2: sell rate. */ +} ShopItemPrice; /* 0x3 = 3 bytes */ + +typedef struct { + u8 pad000[0x20]; + s32 *unk20; /**< 0x20: pointer to data. */ + u8 pad024[0x12]; + u16 unk36; /**< 0x36: scroll offset. */ +} Struct_801E8B60; + +typedef struct { + u8 pad000[0x3A]; + s16 unk3A; /**< 0x3A: scroll offset. */ + u8 pad03D[0x4]; + u8 unk40; /**< 0x40: page start. */ + u8 unk41; /**< 0x41: page end. */ + u8 pad041[0x4]; + u8 unk46; /**< 0x46: orientation (left if equals 0, right otherwise). */ +} Struct_801E7374; + +typedef struct { + u8 pad000[0x28]; + s32 unk28; /**< 0x28: passed to drawColorByMenuPalette as 4th argument. */ +} Struct_801E7508; + +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 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 u8 D_801EB088[ITEM_PRICE_COUNT]; /**< Item quantities. */ +extern s32 g_menuColor; +extern s32 D_80077E70; +extern s32 func_801E8AB0; +extern void func_801E5E90(void*); +extern s32 func_801E79D4(void*, s32, s32); +extern s32 func_801EFBB4(s32, s32, s32); +extern void* func_801E6FD8(void); + +#endif /* MENUSHOP_H */ diff --git a/src/menu/menumain/menumain.c b/src/menu/menumain/menumain.c index 4b4d7180..2af0f13a 100644 --- a/src/menu/menumain/menumain.c +++ b/src/menu/menumain/menumain.c @@ -1693,7 +1693,7 @@ s32 func_801F5E0C(s32 ctx, s32 dl, s32 x, s32 y, s32 color, s32 val, s32 flag) { } /** @brief Render number right-aligned (last param = 1). */ -void func_801F5EFC(s32 a0, s32 a1, s32 a2, s32 a3, s32 a4, s32 a5) { +s32 func_801F5EFC(s32 a0, s32 a1, s32 a2, s32 a3, s32 a4, s32 a5) { func_801F5E0C(a0, a1, a2, a3, a4, a5, 1); } diff --git a/src/menu/menushop/menushop.c b/src/menu/menushop/menushop.c index c497e4c3..e45ec8f2 100644 --- a/src/menu/menushop/menushop.c +++ b/src/menu/menushop/menushop.c @@ -1,14 +1,8 @@ #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" +#include "menumain.h" /** * @brief Look up a shop item byte from a table or item data. @@ -95,28 +89,305 @@ void func_801E5BA4(s32 a0, s32 a1) { func_801F0A34(a0, 0, buf[a1] + 0x24, 0x22); } -INCLUDE_ASM("asm/ovl/menushop/nonmatchings/menushop", func_801E5C08); +/** + * @brief Updates the player's gil and synchronizes the shop inventory. + * + * Rebuilds item counts from the temporary purchase table, clears depleted + * slots, and adds any remaining items to the inventory. + * + * @param gil The updated gil amount. + */ +void func_801E5C08(s32 gil) { + ItemSlot *constPtr; + ItemSlot *p; + s32 i; + + if (g_gameState.mainData.partyLockFlag & 1) { + g_gameState.mainData.party.dreamGil = gil; + } else { + g_gameState.mainData.party.gil = gil; + } + + constPtr = D_80077EBC; + p = D_80077EBC; + + for (i = 0; i < ITEM_SLOT_COUNT; i++, p++) { + u8 itemId = p->id; + u8 itemCount = D_801EB088[itemId]; + + if (itemCount == 0) { + p->id = 0; + } + + p->count = itemCount; + D_801EB088[itemId] = 0; + } + + p = constPtr; + + for (i = 0; i < ITEM_PRICE_COUNT; i++) { + u8 itemCount = D_801EB088[i]; + + if (itemCount == 0) { + continue; + } + + while (1) { + if (p->id == 0 || p->count == 0) { + p->id = i; + p->count = itemCount; + func_800370AC(i); + break; + } + p++; + } + } +} + +/** + * @brief Loads the current gil amount and rebuilds the available item counts. + * + * Item counts are read from the shop inventory table and stored by item ID. + * + * @return The current gil amount (dream gil if party is locked, otherwise normal gil). + */ +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; + + for (i = 0; i < ITEM_PRICE_COUNT; i++) { + D_801EB088[i] = 0; + } + + for (i = 0; i < ITEM_SLOT_COUNT; i++) { + val1 = *ptr1; + ptr1++; + + val2 = *ptr1; + ptr1++; + + if (val1 != 0) { + D_801EB088[val1] = val2; + } + } + + 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[SHOP_ITEM_COUNT]; + s32 counter; + s32 i; + ShopItemVisibility *ptr; -INCLUDE_ASM("asm/ovl/menushop/nonmatchings/menushop", func_801E5D28); + ptr = D_801EAA28; + counter = 0; -INCLUDE_ASM("asm/ovl/menushop/nonmatchings/menushop", func_801E5DBC); + for (i = 0 ; i < SHOP_ITEM_COUNT; i++, ptr++) { + if (ptr->itemId != 0 && ptr->visible != 0) { + sp[counter] = i; + counter++; + } + } + + ptr = D_801EAA28; + + for (i = 0; i < counter; i++) { + if (i != sp[i]) { + ptr[i] = ptr[sp[i]]; + } + } + + for (; i < SHOP_ITEM_COUNT; i++) { + ptr[i].itemId = 0; + ptr[i].visible = 0; + } +} 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]; -INCLUDE_ASM("asm/ovl/menushop/nonmatchings/menushop", func_801E6ACC); + 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) { + ShopItemPrice *itemPrice; + s32 result; + s32 i; + s32 x; + s32 y; + + result = func_801F72B4(); + itemPrice = D_801EA3F0; + + for (i = 0; i < ITEM_PRICE_COUNT; i++) { + if (result & 1) { + D_801EAD68[i] = (itemPrice[i].basePrice * 15) / 2; + } else { + D_801EAD68[i] = itemPrice[i].basePrice * 10; + } + + if (result & 2) { + x = itemPrice[i].sellRate * 10; + y = itemPrice[i].basePrice * x; + D_801EAA48[i] = y * 3 / 40; + } else { + x = itemPrice[i].sellRate * 10; + y = itemPrice[i].basePrice * x; + D_801EAA48[i] = y / 20; + } + + if (D_801EAA48[i] == 0) { + D_801EAA48[i] = 1; + } + if (D_801EAD68[i] == 0) { + D_801EAD68[i] = 1; + } + } +} + +/** + * @brief Update shop item visibility based on rarity and flags. + * + * For each item in the shop, computes a value based on the item's rarity. + * If the computed value exceeds 0x80, the item is marked as visible; + * otherwise, it is hidden. The visibility flags are stored in both the shared + * D_801EAA28 table and the shop's own inventory. + * + * @param shopId Index of the shop to update. + */ +void func_801E6C3C(s32 shopId) { + ShopItemRarity* rarity; + ShopItemVisibility* p; + ShopData *shop; + s32 i; + s32 bitMask; + + p = D_801EAA28; + rarity = D_801EA170[0]; + rarity += shopId * 16; + shop = &D_80077CC8[shopId]; + bitMask = (func_801F72B4() << 6) & 0x100; + + for (i = 0; i< 16; i++, p++) { + if (p->itemId != 0) { + s32 aux = rarity[i].rarity; + s32 val = bitMask + aux; + + aux = 0xFF; + if (val == aux) { + val = 0x100; + } + + func_801F6A5C(); + + aux = 0x80; + if (val > aux) { + aux = 1; + p->visible = 1; + } else { + p->visible = 0; + } + + if (val == 0) { + p->visible = 0; + } + + shop->items[i] = p->visible; + } + } +} -INCLUDE_ASM("asm/ovl/menushop/nonmatchings/menushop", func_801E6C3C); INCLUDE_ASM("asm/ovl/menushop/nonmatchings/menushop", func_801E6D54); -INCLUDE_ASM("asm/ovl/menushop/nonmatchings/menushop", func_801E6E0C); +void func_801E6E0C(s32 arg0, s32 arg1, s32 arg2, s32 arg3) { + s32 result; + + result = func_801E5A8C(arg0, arg1, arg2 + 0xC, arg3 + 5, 3, D_801E9B64, 7); + g_menuDisplayCfg.iconType = 0; + g_menuDisplayCfg.iconSubType = 0; + g_menuDisplayCfg.x = arg2; + g_menuDisplayCfg.y = arg3; + g_menuDisplayCfg.w = 0x150; + g_menuDisplayCfg.h = 0x15; + func_801EF9AC(arg0, result, 0x1000, g_menuColor); +} -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, (s32)buffer, 7); + } + return result; +} /** * @brief Configure display parameters and invoke callback for shop list rendering. @@ -133,18 +404,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); } @@ -154,19 +424,104 @@ INCLUDE_ASM("asm/ovl/menushop/nonmatchings/menushop", func_801E6FD8); INCLUDE_ASM("asm/ovl/menushop/nonmatchings/menushop", func_801E722C); -INCLUDE_ASM("asm/ovl/menushop/nonmatchings/menushop", func_801E7374); +s32 func_801E7374(Struct_801E7374* arg0, void *arg1, void* arg2, s32 arg3, s32 arg4) { + g_menuDisplayCfg.iconType = 0x4C; + g_menuDisplayCfg.iconSubType = 0; + g_menuDisplayCfg.x = arg3; + g_menuDisplayCfg.w = 0x100; + g_menuDisplayCfg.h = 0x77; + g_menuDisplayCfg.columnCount = 8; + g_menuDisplayCfg.y = arg4; + g_menuDisplayCfg.pageStart = arg0->unk40; + g_menuDisplayCfg.pageEnd = arg0->unk41; + g_menuDisplayCfg.scrollOffset = arg0->unk3A; + g_menuDisplayCfg.dataPtr = (s32)arg0; + + if (arg0->unk46 == 0) { + arg2 = (void *)func_8002FF34(arg1, arg2, 0x47, arg3 + 0xA8, arg4, g_menuColor); + arg2 = (void *)func_801F5F30((s32)arg1, (s32)arg2, arg3 + 0x1C, arg4, g_menuColor, (s32) (s8) arg0->unk40); + } + else { + arg2 = (void *)func_8002FF34(arg1, arg2, 0x47, arg3 + 0x80, arg4, g_menuColor); + arg2 = (void *)func_8002FF34(arg1, arg2, 0x4D, arg3 + 0xD6, arg4, g_menuColor); + arg2 = (void *)func_801F5EFC((s32)arg1, (s32)arg2, arg3 + 0x1C, arg4, g_menuColor, (s32) (s8) arg0->unk40); + } + + arg2 = (void *)func_801F5F60((s32)arg1, (s32)arg2, g_menuColor, 3); + return func_801EFBB4((s32)arg1, (s32)arg2, (s32)func_801E6FD8); +} + +void func_801E7508(Struct_801E7508 *arg0, s32 arg1, s32 arg2, s32 arg3, s32 arg4) { + s32 s6; + s32 s5; + s32 v0; -INCLUDE_ASM("asm/ovl/menushop/nonmatchings/menushop", func_801E7508); + s6 = arg4 + 6; + s5 = arg3 + 0xD0; + arg2 = func_801F0FEC(arg1, arg2, s5, s6, func_801F6AA4(0x33), 7); + + v0 = s6 << 0x10; + s5 = arg3 + 0x142; + arg2 = drawColorByMenuPalette(arg1, arg2, v0 | (s5 & 0xFFFF), arg0->unk28, 7); + + s6 = arg4 + 8; + arg2 = func_8002FF34(arg1, arg2, 0xB, arg3 + 0x143, s6, g_menuColor); + + g_menuDisplayCfg.iconType = 0x57; + g_menuDisplayCfg.iconSubType = 0; + g_menuDisplayCfg.x = arg3; + g_menuDisplayCfg.w = 0x150; + g_menuDisplayCfg.y = arg4; + g_menuDisplayCfg.h = 0x17; + + func_801EF9AC(arg1, arg2, 0x1000, g_menuColor); +} 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); -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, "shop.bin", (s32)D_801EA170); + func_801F1D2C(0, "price.bin", (s32)D_801EA3F0); + func_801F1D2C(0, "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. @@ -265,19 +620,18 @@ 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) { - 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); +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; + 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 = a0->unk36; + g_menuDisplayCfg.dataPtr = (s32)&a0->unk20; { func_801EFBB4(a1, a2, (s32)&func_801E8AB0); } @@ -326,16 +680,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); }