summaryrefslogtreecommitdiff
path: root/arm9/src
diff options
context:
space:
mode:
Diffstat (limited to 'arm9/src')
-rw-r--r--arm9/src/bag.c25
-rw-r--r--arm9/src/bag_view.c211
-rw-r--r--arm9/src/render_text.c502
-rw-r--r--arm9/src/scrcmd_18_c.c22
-rw-r--r--arm9/src/scrcmd_party.c815
-rw-r--r--arm9/src/scrcmd_sound.c5
-rw-r--r--arm9/src/text_02054590.c11
-rw-r--r--arm9/src/unk_0201B8B8.c4
-rw-r--r--arm9/src/unk_0206015C.c6
-rw-r--r--arm9/src/unk_020851B8.c2
-rw-r--r--arm9/src/unk_02088AAC.c185
11 files changed, 1736 insertions, 52 deletions
diff --git a/arm9/src/bag.c b/arm9/src/bag.c
index 57609a8f..506f3ec1 100644
--- a/arm9/src/bag.c
+++ b/arm9/src/bag.c
@@ -296,40 +296,37 @@ void SortPocket(struct ItemSlot * slots, u32 count)
}
}
-extern struct BagView * BagView_new(u8 heap_id);
-extern void BagView_setitem(struct BagView * view, struct ItemSlot * slot, u8 pocket, u8 idx);
-
struct BagView * CreateBagView(struct Bag * bag, const u8 * pockets, u32 heap_id)
{
- struct BagView * view = BagView_new((u8)heap_id);
- int i;
- for (i = 0; pockets[i] != 0xFF; i++)
+ struct BagView * view = BagView_New((u8)heap_id);
+
+ for (u32 i = 0; pockets[i] != 0xFF; i++)
{
switch (pockets[i])
{
case POCKET_KEY_ITEMS:
- BagView_setitem(view, bag->keyItems, POCKET_KEY_ITEMS, (u8)i);
+ BagView_SetItem(view, bag->keyItems, POCKET_KEY_ITEMS, (u8)i);
break;
case POCKET_ITEMS:
- BagView_setitem(view, bag->items, POCKET_ITEMS, (u8)i);
+ BagView_SetItem(view, bag->items, POCKET_ITEMS, (u8)i);
break;
case POCKET_BERRIES:
- BagView_setitem(view, bag->berries, POCKET_BERRIES, (u8)i);
+ BagView_SetItem(view, bag->berries, POCKET_BERRIES, (u8)i);
break;
case POCKET_MEDICINE:
- BagView_setitem(view, bag->medicine, POCKET_MEDICINE, (u8)i);
+ BagView_SetItem(view, bag->medicine, POCKET_MEDICINE, (u8)i);
break;
case POCKET_BALLS:
- BagView_setitem(view, bag->balls, POCKET_BALLS, (u8)i);
+ BagView_SetItem(view, bag->balls, POCKET_BALLS, (u8)i);
break;
case POCKET_BATTLE_ITEMS:
- BagView_setitem(view, bag->battleItems, POCKET_BATTLE_ITEMS, (u8)i);
+ BagView_SetItem(view, bag->battleItems, POCKET_BATTLE_ITEMS, (u8)i);
break;
case POCKET_MAIL:
- BagView_setitem(view, bag->mail, POCKET_MAIL, (u8)i);
+ BagView_SetItem(view, bag->mail, POCKET_MAIL, (u8)i);
break;
case POCKET_TMHMS:
- BagView_setitem(view, bag->TMsHMs, POCKET_TMHMS, (u8)i);
+ BagView_SetItem(view, bag->TMsHMs, POCKET_TMHMS, (u8)i);
break;
}
}
diff --git a/arm9/src/bag_view.c b/arm9/src/bag_view.c
new file mode 100644
index 00000000..91bbafd2
--- /dev/null
+++ b/arm9/src/bag_view.c
@@ -0,0 +1,211 @@
+#include "global.h"
+#include "bag_view.h"
+#include "coins.h"
+#include "constants/items.h"
+#include "heap.h"
+#include "msgdata.h"
+#include "player_data.h"
+#include "script_buffers.h"
+#include "seal.h"
+
+extern u32 *FUN_0202708C(u32 *);
+extern u32 FUN_02027168(u32 *);
+extern u16 FUN_02027184(u32 *);
+extern u32 *FUN_02027E24(struct SaveBlock2 *sav2);
+extern u8 FUN_02029E2C(struct SealCase *, u32);
+extern u32 FUN_0202A8D8(struct SaveBlock2 *);
+extern u16 FUN_0202A3B4(u32, u32, u32);
+
+THUMB_FUNC struct BagView *BagView_New(u8 heap_id)
+{
+ struct BagView *ptr = AllocFromHeap(heap_id, sizeof(struct BagView));
+
+ memset(ptr, 0, sizeof(struct BagView));
+
+ return ptr;
+}
+
+THUMB_FUNC u32 BagView_sizeof()
+{
+ return sizeof(struct BagView);
+}
+
+THUMB_FUNC void FUN_0206E30C(struct BagView *bag_view, u8 r1)
+{
+ bag_view->unk65 = r1;
+}
+
+THUMB_FUNC void FUN_0206E314(
+ struct BagView *bag_view, struct SaveBlock2 *sav2, u8 r2, struct UnkStruct_0206F164 *r3)
+{
+ FUN_0206E30C(bag_view, r2);
+
+ bag_view->sav2 = sav2;
+ bag_view->unk6C = r3;
+ bag_view->unk66 = 0;
+}
+
+THUMB_FUNC void BagView_SetItem(struct BagView *bag_view, struct ItemSlot *slot, u8 pocket, u8 idx)
+{
+ bag_view->slots[idx].slot = slot;
+ bag_view->slots[idx].pocket = pocket;
+}
+
+THUMB_FUNC void FUN_0206E340(struct BagView *bag_view)
+{
+ bag_view->unk76 = 1;
+}
+
+THUMB_FUNC void FUN_0206E354(struct BagView *bag_view, u32 r1)
+{
+ bag_view->unk70 = r1;
+}
+
+THUMB_FUNC void FUN_0206E358(struct BagView *bag_view, u8 r1)
+{
+ bag_view->unk74 = r1;
+}
+
+THUMB_FUNC void FUN_0206E360(struct BagView *bag_view, u16 r1)
+{
+ bag_view->unk76_2 = r1;
+}
+
+THUMB_FUNC u16 FUN_0206E37C(struct BagView *bag_view)
+{
+ return bag_view->unk66;
+}
+
+THUMB_FUNC u16 FUN_0206E384(struct BagView *bag_view)
+{
+ return bag_view->unk68;
+}
+
+THUMB_FUNC u8 FUN_0206E38C(struct BagView *bag_view)
+{
+ return bag_view->unk74;
+}
+
+THUMB_FUNC u8 FUN_0206E394(struct BagView *bag_view)
+{
+ return bag_view->unk75;
+}
+
+THUMB_FUNC u32 FUN_0206E39C(struct SaveBlock2 *sav2)
+{
+ return (u32)CheckCoins(Sav2_PlayerData_GetCoinsAddr(sav2));
+}
+
+THUMB_FUNC u32 FUN_0206E3A8(struct SaveBlock2 *sav2)
+{
+ struct SealCase *seal_case = Sav2_SealCase_get(sav2);
+ u32 i;
+ u32 count = 0;
+
+ for (i = 1; i <= 0x50; ++i)
+ {
+ count += FUN_02029E2C(seal_case, i);
+ }
+
+ return count;
+}
+
+THUMB_FUNC u32 FUN_0206E3C8(struct SaveBlock2 *sav2)
+{
+ return FUN_02027168(FUN_0202708C(FUN_02027E24(sav2)));
+}
+
+THUMB_FUNC u32 FUN_0206E3D8(struct SaveBlock2 *sav2)
+{
+ return FUN_02027184(FUN_0202708C(FUN_02027E24(sav2)));
+}
+
+THUMB_FUNC u32 FUN_0206E3E8(struct SaveBlock2 *sav2)
+{
+ return FUN_0202A3B4(FUN_0202A8D8(sav2), 0, 0);
+}
+
+THUMB_FUNC BOOL FUN_0206E3F8(struct SaveBlock2 *sav2, struct String *dest, u32 item_id, u32 heap_id)
+{
+ struct MsgData *msgData = NewMsgDataFromNarc(0, NARC_MSGDATA_MSG, 7, heap_id);
+ struct ScrStrBufs *scrStrBufs = ScrStrBufs_new(heap_id);
+ struct String *string;
+
+ if (item_id == ITEM_NONE)
+ {
+ string = NewString_ReadMsgData(msgData, 0x63);
+ }
+ else if (item_id == ITEM_POINT_CARD)
+ {
+ string = NewString_ReadMsgData(msgData, 0x61);
+
+ BufferIntegerAsString(scrStrBufs, 0, FUN_0206E3E8(sav2), 4, 0, TRUE);
+ }
+ else if (item_id == ITEM_SEAL_CASE)
+ {
+ string = NewString_ReadMsgData(msgData, 0x5C);
+
+ BufferIntegerAsString(scrStrBufs, 0, FUN_0206E3A8(sav2), 4, 0, TRUE);
+ }
+ else if (item_id == ITEM_FASHION_CASE)
+ {
+ string = NewString_ReadMsgData(msgData, 0x5D);
+
+ BufferIntegerAsString(scrStrBufs, 0, FUN_0206E3C8(sav2), 3, 0, TRUE);
+ BufferIntegerAsString(scrStrBufs, 1, FUN_0206E3D8(sav2), 2, 0, TRUE);
+ }
+ else if (item_id == ITEM_COIN_CASE)
+ {
+ string = NewString_ReadMsgData(msgData, 0x39);
+
+ BufferIntegerAsString(scrStrBufs, 0, FUN_0206E39C(sav2), 5, 0, TRUE);
+ }
+ else
+ {
+ ScrStrBufs_delete(scrStrBufs);
+ DestroyMsgData(msgData);
+
+ return FALSE;
+ }
+
+ StringExpandPlaceholders(scrStrBufs, dest, string);
+ String_dtor(string);
+ ScrStrBufs_delete(scrStrBufs);
+ DestroyMsgData(msgData);
+
+ return TRUE;
+}
+
+THUMB_FUNC void FUN_0206E51C(
+ struct PlayerData *playerData, struct String *dest, u32 r2, u32 r3, u32 heap_id)
+{
+#pragma unused(r2)
+ struct MsgData *msgData;
+
+ switch (r3)
+ {
+ case 1:
+ msgData = NewMsgDataFromNarc(1, NARC_MSGDATA_MSG, 7, heap_id);
+
+ ReadMsgDataIntoString(msgData, 0x38, dest);
+ DestroyMsgData(msgData);
+ return;
+ case 2:
+ msgData = NewMsgDataFromNarc(1, NARC_MSGDATA_MSG, 7, heap_id);
+
+ ReadMsgDataIntoString(msgData, 0x6F, dest);
+ DestroyMsgData(msgData);
+ return;
+ default:
+ msgData = NewMsgDataFromNarc(1, NARC_MSGDATA_MSG, 0xC7, heap_id);
+ struct ScrStrBufs *scrStrBufs = ScrStrBufs_new(heap_id);
+ struct String *src = NewString_ReadMsgData(msgData, 0x24);
+
+ BufferPlayersName(scrStrBufs, 0, playerData);
+ StringExpandPlaceholders(scrStrBufs, dest, src);
+ String_dtor(src);
+ ScrStrBufs_delete(scrStrBufs);
+ DestroyMsgData(msgData);
+ return;
+ }
+}
diff --git a/arm9/src/render_text.c b/arm9/src/render_text.c
new file mode 100644
index 00000000..af0218c8
--- /dev/null
+++ b/arm9/src/render_text.c
@@ -0,0 +1,502 @@
+#include "global.h"
+#include "render_text.h"
+#include "game_init.h"
+#include "string_util.h"
+#include "text.h"
+#include "unk_0201B8B8.h"
+
+u16 unk00;
+
+TextFlags gTextFlags;
+
+const u8 UNK_020ECB50[] = { 0, 1, 2, 1 };
+
+extern const char *FUN_02002D94(u8, u16);
+extern void PlaySE(u16);
+
+THUMB_FUNC u32 RenderText(struct TextPrinter *printer)
+{
+
+ struct TextPrinterSubStruct *subStruct =
+ (struct TextPrinterSubStruct *)(&printer->subStructFields);
+ u16 currentChar;
+
+ switch (printer->state)
+ {
+ case 0:
+ if (((gMain.heldKeys & 3) != 0 && subStruct->hasPrintBeenSpedUp != 0) ||
+ (gMain.touchHeld != 0 && gTextFlags.unk0_4 != 0))
+ {
+ printer->delayCounter = 0;
+ if (printer->textSpeedBottom != 0)
+ {
+ gTextFlags.unk0_6 = 1;
+ }
+ }
+
+ if (printer->delayCounter && printer->textSpeedBottom)
+ {
+ printer->delayCounter--;
+
+ if (gTextFlags.canABSpeedUpPrint != 0)
+ {
+ if ((gMain.newKeys & 3) || (gMain.touchNew != 0 && gTextFlags.unk0_4))
+ {
+ subStruct->hasPrintBeenSpedUp = 1;
+ printer->delayCounter = 0;
+ }
+ }
+
+ return 3;
+ }
+
+ printer->delayCounter = printer->textSpeedBottom;
+ currentChar = *printer->printerTemplate.currentChar.raw;
+ printer->printerTemplate.currentChar.raw++;
+
+ GF_ASSERT(currentChar != 0xF100);
+
+ switch (currentChar)
+ {
+ case EOS:
+ return 1;
+ case 0xE000:
+ printer->printerTemplate.currentX = printer->printerTemplate.x;
+ s32 fontAttribute = GetFontAttribute(printer->printerTemplate.fontId, 1);
+
+ printer->printerTemplate.currentY +=
+ printer->printerTemplate.lineSpacing + fontAttribute;
+
+ return 2;
+
+ case 0xF0FD:
+ printer->printerTemplate.currentChar.raw++;
+ return 2;
+ case 0xFFFE:
+ printer->printerTemplate.currentChar.raw--;
+ switch ((u16)MsgArray_GetControlCode(printer->printerTemplate.currentChar.raw))
+ {
+ case 0xFF00:
+ u16 field = (u16)MsgArray_ControlCodeGetField(
+ printer->printerTemplate.currentChar.raw, 0);
+ if (field == 0xff)
+ {
+ u8 r2 = printer->printerTemplate.unk4;
+ printer->printerTemplate.unk4 =
+ (u8)((printer->printerTemplate.fgColor - 1) / 2 + 100);
+
+ if (!(r2 >= 100 && r2 < 107))
+ {
+ break;
+ }
+
+ field = (u16)(r2 - 100);
+ }
+ else
+ {
+ if (field >= 0x64)
+ {
+ printer->printerTemplate.unk4 = (u8)field;
+ break;
+ }
+ }
+
+ printer->printerTemplate.fgColor = (u8)(field * 2 + 1);
+ printer->printerTemplate.shadowColor = (u8)(field * 2 + 2);
+
+ GenerateFontHalfRowLookupTable(printer->printerTemplate.fgColor,
+ printer->printerTemplate.bgColor,
+ printer->printerTemplate.shadowColor);
+
+ break;
+
+ case 0x200:
+ field = (u16)MsgArray_ControlCodeGetField(
+ printer->printerTemplate.currentChar.raw, 0);
+
+ FUN_0201C1EC(printer,
+ printer->printerTemplate.currentX,
+ printer->printerTemplate.currentY,
+ field);
+ if (printer->textSpeedTop != 0)
+ {
+ CopyWindowToVram(printer->printerTemplate.window);
+ }
+
+ break;
+ case 0x201:
+ printer->delayCounter = (u8)MsgArray_ControlCodeGetField(
+ printer->printerTemplate.currentChar.raw, 0);
+ printer->printerTemplate.currentChar.raw =
+ MsgArray_SkipControlCode(printer->printerTemplate.currentChar.raw);
+ printer->state = 6;
+
+ return 3;
+ case 0x202:
+ printer->Unk2A = (u16)MsgArray_ControlCodeGetField(
+ printer->printerTemplate.currentChar.raw, 0);
+ printer->printerTemplate.currentChar.raw =
+ MsgArray_SkipControlCode(printer->printerTemplate.currentChar.raw);
+
+ return 3;
+ case 0x203:
+ printer->printerTemplate.currentX = (u8)MsgArray_ControlCodeGetField(
+ printer->printerTemplate.currentChar.raw, 0);
+ break;
+ case 0x204:
+ printer->printerTemplate.currentY = (u8)MsgArray_ControlCodeGetField(
+ printer->printerTemplate.currentChar.raw, 0);
+ break;
+
+ case 0xFF01:
+ field = (u16)MsgArray_ControlCodeGetField(
+ printer->printerTemplate.currentChar.raw, 0);
+
+ switch (field)
+ {
+ case 100:
+ printer->printerTemplate.unk2 = 0;
+ printer->printerTemplate.unk3 = 0;
+ break;
+ case 200:
+ printer->printerTemplate.unk2 = 0xFFFC;
+ printer->printerTemplate.unk3 = 0;
+ break;
+ }
+
+ break;
+
+ case 0xFE06:
+ field = (u16)MsgArray_ControlCodeGetField(
+ printer->printerTemplate.currentChar.raw, 0);
+ if (field != 0xFE00)
+ {
+ if (field != 0xFE01)
+ {
+ break;
+ }
+
+ printer->state = 2;
+ TextPrinterInitDownArrowCounters(printer);
+ printer->printerTemplate.currentChar.raw = MsgArray_SkipControlCode(
+ printer->printerTemplate.currentChar.raw);
+
+ return 3;
+ }
+
+ printer->state = 3;
+ TextPrinterInitDownArrowCounters(printer);
+ printer->printerTemplate.currentChar.raw =
+ MsgArray_SkipControlCode(printer->printerTemplate.currentChar.raw);
+
+ return 3;
+ }
+
+ printer->printerTemplate.currentChar.raw =
+ MsgArray_SkipControlCode(printer->printerTemplate.currentChar.raw);
+ return 2;
+
+ case 0x25BC:
+ printer->state = 2;
+ TextPrinterInitDownArrowCounters(printer);
+ return 3;
+
+ case 0x25BD:
+ printer->state = 3;
+ TextPrinterInitDownArrowCounters(printer);
+ return 3;
+ }
+
+ const char *r5 = FUN_02002D94(subStruct->glyphId, currentChar);
+ CopyGlyphToWindow(printer->printerTemplate.window,
+ r5,
+ r5[0x80],
+ r5[0x81],
+ printer->printerTemplate.currentX,
+ printer->printerTemplate.currentY,
+ printer->printerTemplate.unk2);
+
+ printer->printerTemplate.currentX += r5[0x80] + printer->printerTemplate.letterSpacing;
+
+ return 0;
+ case 1:
+ if (TextPrinterWait(printer) != 0)
+ {
+ TextPrinterClearDownArrow(printer);
+
+ printer->state = 0;
+ }
+
+ return 3;
+ case 2:
+ if (TextPrinterWaitWithDownArrow(printer) != 0)
+ {
+ TextPrinterClearDownArrow(printer);
+ FillWindowPixelBuffer(
+ printer->printerTemplate.window, printer->printerTemplate.bgColor);
+ printer->printerTemplate.currentX = printer->printerTemplate.x;
+ printer->printerTemplate.currentY = printer->printerTemplate.y;
+ printer->state = 0;
+ }
+
+ return 3;
+ case 3:
+ if (TextPrinterWaitWithDownArrow(printer) != 0)
+ {
+ TextPrinterClearDownArrow(printer);
+ printer->scrollDistance =
+ (u8)(GetFontAttribute(printer->printerTemplate.fontId, 1) +
+ printer->printerTemplate.lineSpacing);
+ printer->printerTemplate.currentX = printer->printerTemplate.x;
+ printer->state = 4;
+ }
+
+ return 3;
+ case 4:
+ if (printer->scrollDistance != 0)
+ {
+ if ((int)printer->scrollDistance < 4)
+ {
+ ScrollWindow(printer->printerTemplate.window,
+ 0,
+ printer->scrollDistance,
+ (u8)(printer->printerTemplate.bgColor |
+ (printer->printerTemplate.bgColor << 4)));
+ printer->scrollDistance = 0;
+ }
+ else
+ {
+ ScrollWindow(printer->printerTemplate.window,
+ 0,
+ 4,
+ (u8)(printer->printerTemplate.bgColor |
+ (printer->printerTemplate.bgColor << 4)));
+
+ printer->scrollDistance -= 4;
+ }
+
+ CopyWindowToVram(printer->printerTemplate.window);
+ }
+ else
+ {
+ printer->state = 0;
+ }
+
+ return 3;
+ case 5:
+ printer->state = 0;
+ return 3;
+ case 6:
+ if (printer->delayCounter != 0)
+ {
+ printer->delayCounter--;
+ }
+ else
+ {
+ printer->state = 0;
+ }
+
+ return 3;
+ }
+
+ return 1;
+}
+
+THUMB_FUNC void FUN_02002840(u16 flag)
+{
+ unk00 = flag;
+}
+
+THUMB_FUNC void TextPrinterInitDownArrowCounters(struct TextPrinter *printer)
+{
+ struct TextPrinterSubStruct *subStruct =
+ (struct TextPrinterSubStruct *)(&printer->subStructFields);
+
+ if (gTextFlags.autoScroll)
+ {
+ subStruct->autoScrollDelay = 0;
+ return;
+ }
+
+ subStruct->downArrowYPosIdx = 0;
+ subStruct->downArrowDelay = 0;
+}
+
+THUMB_FUNC void TextPrinterDrawDownArrow(struct TextPrinter *printer)
+{
+ struct TextPrinterSubStruct *subStruct =
+ (struct TextPrinterSubStruct *)(&printer->subStructFields);
+
+ if (gTextFlags.autoScroll)
+ {
+ return;
+ }
+
+ if (subStruct->downArrowDelay != 0)
+ {
+ subStruct->downArrowDelay--;
+ return;
+ }
+
+ u8 bg_id = GetWindowBgId(printer->printerTemplate.window);
+ u8 x = GetWindowX(printer->printerTemplate.window);
+ u8 y = GetWindowY(printer->printerTemplate.window);
+ u8 width = GetWindowWidth(printer->printerTemplate.window);
+ u16 r6 = unk00;
+
+ FillBgTilemapRect(printer->printerTemplate.window->bgConfig,
+ bg_id,
+ (u16)(r6 + 18 + UNK_020ECB50[subStruct->downArrowYPosIdx] * 4),
+ (u8)(x + width + 1),
+ (u8)(y + 2),
+ 1,
+ 1,
+ 0x10);
+
+ FillBgTilemapRect(printer->printerTemplate.window->bgConfig,
+ bg_id,
+ (u16)(r6 + 19 + UNK_020ECB50[subStruct->downArrowYPosIdx] * 4),
+ (u8)(x + width + 2),
+ (u8)(y + 2),
+ 1,
+ 1,
+ 0x10);
+ FillBgTilemapRect(printer->printerTemplate.window->bgConfig,
+ bg_id,
+ (u16)(r6 + 20 + UNK_020ECB50[subStruct->downArrowYPosIdx] * 4),
+ (u8)(x + width + 1),
+ (u8)(y + 3),
+ 1,
+ 1,
+ 0x10);
+ FillBgTilemapRect(printer->printerTemplate.window->bgConfig,
+ bg_id,
+ (u16)(r6 + 21 + UNK_020ECB50[subStruct->downArrowYPosIdx] * 4),
+ (u8)(x + width + 2),
+ (u8)(y + 3),
+ 1,
+ 1,
+ 0x10);
+
+ BgCommitTilemapBufferToVram(printer->printerTemplate.window->bgConfig, bg_id);
+ subStruct->downArrowDelay = 8;
+ subStruct->downArrowYPosIdx++;
+}
+
+THUMB_FUNC void TextPrinterClearDownArrow(struct TextPrinter *printer)
+{
+ u8 bg_id = GetWindowBgId(printer->printerTemplate.window);
+ u8 x = GetWindowX(printer->printerTemplate.window);
+ u8 y = GetWindowY(printer->printerTemplate.window);
+ u8 width = GetWindowWidth(printer->printerTemplate.window);
+ u16 r6 = unk00;
+
+ FillBgTilemapRect(printer->printerTemplate.window->bgConfig,
+ bg_id,
+ (u16)(r6 + 10),
+ (u8)(x + width + 1),
+ (u8)(y + 2),
+ 1,
+ 2,
+ 0x10);
+ FillBgTilemapRect(printer->printerTemplate.window->bgConfig,
+ bg_id,
+ (u16)(r6 + 11),
+ (u8)(x + width + 2),
+ (u8)(y + 2),
+ 1,
+ 2,
+ 0x10);
+ BgCommitTilemapBufferToVram(printer->printerTemplate.window->bgConfig, bg_id);
+}
+
+THUMB_FUNC BOOL TextPrinterContinue(struct TextPrinter *printer)
+{
+#pragma unused(printer)
+ if ((gMain.newKeys & 3) != 0 || (gMain.touchNew != 0 && gTextFlags.unk0_4 != 0))
+ {
+ PlaySE(0x5DC);
+
+ gTextFlags.unk0_7 = 1;
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+THUMB_FUNC BOOL TextPrinterWaitAutoMode(struct TextPrinter *printer)
+{
+ struct TextPrinterSubStruct *subStruct =
+ (struct TextPrinterSubStruct *)(&printer->subStructFields);
+
+ if (subStruct->autoScrollDelay == 100)
+ {
+ return TRUE;
+ }
+
+ subStruct->autoScrollDelay++;
+ if (gTextFlags.unk0_5)
+ {
+ return TextPrinterContinue(printer);
+ }
+
+ return FALSE;
+}
+
+THUMB_FUNC BOOL TextPrinterWaitWithDownArrow(struct TextPrinter *printer)
+{
+ if (gTextFlags.autoScroll)
+ {
+ return TextPrinterWaitAutoMode(printer);
+ }
+ TextPrinterDrawDownArrow(printer);
+
+ return TextPrinterContinue(printer);
+}
+
+THUMB_FUNC u8 TextPrinterWait(struct TextPrinter *printer)
+{
+ if (gTextFlags.autoScroll)
+ {
+ return (u8)TextPrinterWaitAutoMode(printer);
+ }
+
+ return (u8)TextPrinterContinue(printer);
+}
+
+THUMB_FUNC void TextFlags_SetCanABSpeedUpPrint(BOOL param0)
+{
+ gTextFlags.canABSpeedUpPrint = param0;
+}
+
+THUMB_FUNC void FUN_02002B7C(s32 param0)
+{
+ gTextFlags.autoScroll = param0 & 1;
+ gTextFlags.unk0_5 = (param0 >> 1) & 1;
+}
+
+THUMB_FUNC void FUN_02002BB8(u32 param0)
+{
+ gTextFlags.unk0_4 = param0;
+}
+
+THUMB_FUNC u8 FUN_02002BD4()
+{
+ return gTextFlags.unk0_6;
+}
+
+THUMB_FUNC void FUN_02002BE4()
+{
+ gTextFlags.unk0_6 = 0;
+}
+
+THUMB_FUNC u8 FUN_02002BF4()
+{
+ return gTextFlags.unk0_7;
+}
+
+THUMB_FUNC void FUN_02002C04()
+{
+ gTextFlags.unk0_7 = 0;
+}
diff --git a/arm9/src/scrcmd_18_c.c b/arm9/src/scrcmd_18_c.c
deleted file mode 100644
index d4437c5f..00000000
--- a/arm9/src/scrcmd_18_c.c
+++ /dev/null
@@ -1,22 +0,0 @@
-#include "global.h"
-#include "script.h"
-#include "party.h"
-#include "save_block_2.h"
-#include "unk_0204639C.h"
-#include "map_header.h"
-#include "scrcmd.h"
-
-extern BOOL GiveMon(u32 heap_id, struct SaveBlock2 * sav2, u16 species, u8 level, u16 item, u32 mapSec, u8 encounterType);
-
-THUMB_FUNC BOOL ScrCmd_GiveMon(struct ScriptContext* ctx)
-{
- u32 mapSec = MapHeader_GetMapSec(*(ctx->unk80->mapId));
- struct UnkSavStruct80 *savePtr = ctx->unk80;
- u16 species = VarGet(ctx->unk80, ScriptReadHalfword(ctx));
- u16 level = VarGet(ctx->unk80, ScriptReadHalfword(ctx));
- u16 item = VarGet(ctx->unk80, ScriptReadHalfword(ctx));
- u16 * varPtr = GetVarPointer(ctx->unk80, ScriptReadHalfword(ctx));
- struct PlayerParty * party = SavArray_PlayerParty_get(savePtr->saveBlock2);
- *varPtr = (u16)GiveMon(11, savePtr->saveBlock2, species, (u8)level, item, mapSec, 12);
- return FALSE;
-}
diff --git a/arm9/src/scrcmd_party.c b/arm9/src/scrcmd_party.c
new file mode 100644
index 00000000..48d558c9
--- /dev/null
+++ b/arm9/src/scrcmd_party.c
@@ -0,0 +1,815 @@
+#include "scrcmd.h"
+#include "constants/moves.h"
+#include "itemtool.h"
+#include "map_header.h"
+#include "module_05.h"
+#include "party.h"
+#include "save_block_2.h"
+#include "script_pokemon_util.h"
+#include "unk_02015CC0.h"
+#include "unk_02022504.h"
+#include "unk_0204639C.h"
+#include "unk_0207FC5C.h"
+
+extern u16 FUN_02054DEC(struct SaveBlock2* sav2);
+
+THUMB_FUNC BOOL ScrCmd_GiveMon(struct ScriptContext* ctx)
+{
+ u32 mapSec = MapHeader_GetMapSec(*(ctx->unk80->mapId));
+ struct UnkSavStruct80 *savePtr = ctx->unk80;
+ u16 species = VarGet(ctx->unk80, ScriptReadHalfword(ctx));
+ u16 level = VarGet(ctx->unk80, ScriptReadHalfword(ctx));
+ u16 item = VarGet(ctx->unk80, ScriptReadHalfword(ctx));
+ u16 * varPtr = GetVarPointer(ctx->unk80, ScriptReadHalfword(ctx));
+ struct PlayerParty * party = SavArray_PlayerParty_get(savePtr->saveBlock2);
+ *varPtr = (u16)GiveMon(11, savePtr->saveBlock2, species, (u8)level, item, mapSec, 12);
+ return FALSE;
+}
+
+THUMB_FUNC BOOL ScrCmd_GetPartyMonSpecies(struct ScriptContext* ctx)
+{
+ u32 species;
+ u16* ret_ptr;
+
+ struct UnkSavStruct80* sav_ptr = ctx->unk80;
+ u16* mon_slot = GetVarPointer(ctx->unk80, ScriptReadHalfword(ctx));
+ ret_ptr = GetVarPointer(ctx->unk80, ScriptReadHalfword(ctx));
+ struct PlayerParty* party = SavArray_PlayerParty_get(sav_ptr->saveBlock2);
+ struct Pokemon* party_mon = GetPartyMonByIndex(party, *mon_slot);
+
+ BOOL party_mon_is_egg = (BOOL)GetMonData(party_mon, MON_DATA_IS_EGG, NULL);
+ if (party_mon_is_egg == FALSE)
+ {
+ species = GetMonData(party_mon, MON_DATA_SPECIES, NULL);
+ }
+ else
+ {
+ species = SPECIES_NONE;
+ }
+
+ *ret_ptr = (u16)species;
+ return FALSE;
+}
+
+THUMB_FUNC BOOL ScrCmd_CheckPartyMonOTID(struct ScriptContext* ctx)
+{
+ struct UnkSavStruct80* sav_ptr = ctx->unk80;
+ struct SaveBlock2* sav2 = ScriptEnvironment_GetSav2Ptr(sav_ptr);
+ struct PlayerData* player = Sav2_PlayerData_GetProfileAddr(sav2);
+
+ u16* mon_slot = GetVarPointer(ctx->unk80, ScriptReadHalfword(ctx));
+ u16* ret_ptr = GetVarPointer(ctx->unk80, ScriptReadHalfword(ctx));
+
+ struct PlayerParty* party = SavArray_PlayerParty_get(sav_ptr->saveBlock2);
+ struct Pokemon* party_mon = GetPartyMonByIndex(party, *mon_slot);
+
+ u16 party_mon_otid = (u16)GetMonData(party_mon, MON_DATA_OTID, NULL);
+ u16 player_otid = (u16)PlayerProfile_GetTrainerID(player);
+ if (party_mon_otid == player_otid)
+ {
+ *ret_ptr = 0;
+ }
+ else
+ {
+ *ret_ptr = 1;
+ }
+
+ return FALSE;
+}
+
+THUMB_FUNC BOOL ScrCmd_GiveEgg(struct ScriptContext* ctx)
+{
+ struct UnkSavStruct80* sav_ptr = ctx->unk80;
+ struct PlayerData* player = Sav2_PlayerData_GetProfileAddr(sav_ptr->saveBlock2);
+ u16 species = VarGet(ctx->unk80, ScriptReadHalfword(ctx));
+ u16 unk = VarGet(ctx->unk80, ScriptReadHalfword(ctx));
+ struct PlayerParty* party = SavArray_PlayerParty_get(sav_ptr->saveBlock2);
+ u8 party_count = (u8)GetPartyCount(party);
+
+ if (party_count < PARTY_SIZE)
+ {
+ struct Pokemon* egg = AllocMonZeroed(11);
+ ZeroMonData(egg);
+
+ s32 met_loc = FUN_02015CF8(1, unk);
+ MOD05_SetEggStats(egg, species, 1, player, 3, met_loc);
+
+ AddMonToParty(party, egg);
+ FreeToHeap(egg);
+ }
+
+ return FALSE;
+}
+
+THUMB_FUNC BOOL ScrCmd_SetPartyMonMove(struct ScriptContext* ctx)
+{
+ u16 mon_slot = VarGet(ctx->unk80, ScriptReadHalfword(ctx));
+ u16 move_slot = VarGet(ctx->unk80, ScriptReadHalfword(ctx));
+ u16 move = VarGet(ctx->unk80, ScriptReadHalfword(ctx));
+ struct PlayerParty* party = SavArray_PlayerParty_get(ctx->unk80->saveBlock2);
+
+ PartyMonSetMoveInSlot(party, mon_slot, move_slot, move);
+
+ return FALSE;
+}
+
+THUMB_FUNC BOOL ScrCmd_PartyMonHasMove(struct ScriptContext* ctx)
+{
+ struct UnkSavStruct80* sav_ptr = ctx->unk80;
+ u16* ret_ptr = GetVarPointer(ctx->unk80, ScriptReadHalfword(ctx));
+ u16 required_move = VarGet(ctx->unk80, ScriptReadHalfword(ctx));
+ u16 mon_slot = VarGet(ctx->unk80, ScriptReadHalfword(ctx));
+ struct PlayerParty* party = SavArray_PlayerParty_get(sav_ptr->saveBlock2);
+ struct Pokemon* party_mon = GetPartyMonByIndex(party, mon_slot);
+
+ *ret_ptr = 0;
+
+ BOOL party_mon_is_egg = (BOOL)GetMonData(party_mon, MON_DATA_IS_EGG, NULL);
+ if (party_mon_is_egg)
+ {
+ return FALSE;
+ }
+
+ if (required_move == GetMonData(party_mon, MON_DATA_MOVE1, NULL) ||
+ required_move == GetMonData(party_mon, MON_DATA_MOVE2, NULL) ||
+ required_move == GetMonData(party_mon, MON_DATA_MOVE3, NULL) ||
+ required_move == GetMonData(party_mon, MON_DATA_MOVE4, NULL))
+ {
+ *ret_ptr = 1;
+ }
+
+ return FALSE;
+}
+
+THUMB_FUNC BOOL ScrCmd_FindPartyMonWithMove(struct ScriptContext* ctx)
+{
+ struct UnkSavStruct80* sav_ptr = ctx->unk80;
+ u16* ret_ptr = GetVarPointer(ctx->unk80, ScriptReadHalfword(ctx));
+ u16 required_move = VarGet(ctx->unk80, ScriptReadHalfword(ctx));
+ u8 party_count = (u8)GetPartyCount(SavArray_PlayerParty_get(sav_ptr->saveBlock2));
+
+ u8 i;
+ for (i = 0, *ret_ptr = PARTY_SIZE; i < party_count; i++)
+ {
+ struct PlayerParty* party = SavArray_PlayerParty_get(sav_ptr->saveBlock2);
+ struct Pokemon* party_mon = GetPartyMonByIndex(party, i);
+
+ BOOL party_mon_is_egg = (BOOL)GetMonData(party_mon, MON_DATA_IS_EGG, NULL);
+ if (party_mon_is_egg == FALSE)
+ {
+ if (required_move == GetMonData(party_mon, MON_DATA_MOVE1, NULL) ||
+ required_move == GetMonData(party_mon, MON_DATA_MOVE2, NULL) ||
+ required_move == GetMonData(party_mon, MON_DATA_MOVE3, NULL) ||
+ required_move == GetMonData(party_mon, MON_DATA_MOVE4, NULL))
+ {
+ *ret_ptr = i;
+ break;
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+THUMB_FUNC BOOL ScrCmd_SurvivePsn(struct ScriptContext* ctx)
+{
+ u16* ret_ptr = GetVarPointer(ctx->unk80, ScriptReadHalfword(ctx));
+ u16 mon_slot = VarGet(ctx->unk80, ScriptReadHalfword(ctx));
+ struct PlayerParty* party = SavArray_PlayerParty_get(ctx->unk80->saveBlock2);
+ struct Pokemon* party_mon = GetPartyMonByIndex(party, mon_slot);
+
+ *ret_ptr = (u16)SurvivePoisoning(party_mon);
+ return FALSE;
+}
+
+THUMB_FUNC BOOL ScrCmd_CountPartyMonsAtOrBelowLevel(struct ScriptContext* ctx)
+{
+ u8 party_count;
+ u8 i;
+
+ struct UnkSavStruct80* sav_ptr = ctx->unk80;
+ u16* ret_ptr = GetVarPointer(ctx->unk80, ScriptReadHalfword(ctx));
+ u16 highest_level = VarGet(ctx->unk80, ScriptReadHalfword(ctx));
+ party_count = (u8)GetPartyCount(SavArray_PlayerParty_get(sav_ptr->saveBlock2));
+
+ u8 mons;
+ for (i = 0, mons = 0, *ret_ptr = 0; i < party_count; i++)
+ {
+ struct PlayerParty* party = SavArray_PlayerParty_get(sav_ptr->saveBlock2);
+ struct Pokemon* party_mon = GetPartyMonByIndex(party, i);
+
+ BOOL party_mon_is_egg = (BOOL)GetMonData(party_mon, MON_DATA_IS_EGG, NULL);
+ if (party_mon_is_egg == FALSE)
+ {
+ u32 party_mon_level = GetMonData(party_mon, MON_DATA_LEVEL, NULL);
+ if (party_mon_level <= highest_level)
+ {
+ mons++;
+ }
+ }
+ }
+
+ *ret_ptr = mons;
+ return FALSE;
+}
+
+THUMB_FUNC BOOL ScrCmd_GetPartyMonLevel(struct ScriptContext* ctx)
+{
+ struct UnkSavStruct80* sav_ptr = ctx->unk80;
+ u16* ret_ptr = GetVarPointer(ctx->unk80, ScriptReadHalfword(ctx));
+ u16 mon_slot = VarGet(ctx->unk80, ScriptReadHalfword(ctx));
+ struct PlayerParty* party = SavArray_PlayerParty_get(sav_ptr->saveBlock2);
+ struct Pokemon* party_mon = GetPartyMonByIndex(party, mon_slot);
+
+ *ret_ptr = 0;
+
+ BOOL party_mon_is_egg = (BOOL)GetMonData(party_mon, MON_DATA_IS_EGG, NULL);
+ if (party_mon_is_egg == FALSE)
+ {
+ *ret_ptr = (u16)GetMonData(party_mon, MON_DATA_LEVEL, NULL);
+ }
+
+ return FALSE;
+}
+
+THUMB_FUNC BOOL ScrCmd_GetPartyMonNature(struct ScriptContext* ctx)
+{
+ struct UnkSavStruct80* sav_ptr = ctx->unk80;
+ u16* ret_ptr = GetVarPointer(ctx->unk80, ScriptReadHalfword(ctx));
+ u16 mon_slot = VarGet(ctx->unk80, ScriptReadHalfword(ctx));
+ u8 party_count = (u8)GetPartyCount(SavArray_PlayerParty_get(sav_ptr->saveBlock2));
+
+ if (mon_slot >= party_count)
+ {
+ *ret_ptr = 0;
+ return FALSE;
+ }
+
+ struct PlayerParty* party = SavArray_PlayerParty_get(sav_ptr->saveBlock2);
+ struct Pokemon* party_mon = GetPartyMonByIndex(party, mon_slot);
+
+ BOOL party_mon_is_egg = (BOOL)GetMonData(party_mon, MON_DATA_IS_EGG, NULL);
+ if (party_mon_is_egg)
+ {
+ *ret_ptr = 0;
+ return FALSE;
+ }
+
+ *ret_ptr = GetMonNature(party_mon);
+ return FALSE;
+}
+
+THUMB_FUNC BOOL ScrCmd_FindPartyMonWithNature(struct ScriptContext* ctx)
+{
+ struct UnkSavStruct80* sav_ptr = ctx->unk80;
+ u16* ret_ptr = GetVarPointer(ctx->unk80, ScriptReadHalfword(ctx));
+ u16 required_nature = VarGet(ctx->unk80, ScriptReadHalfword(ctx));
+ u8 party_count = (u8)GetPartyCount(SavArray_PlayerParty_get(sav_ptr->saveBlock2));
+
+ u8 i;
+ for (i = 0, *ret_ptr = 0xFF; i < party_count; i++)
+ {
+ struct PlayerParty* party = SavArray_PlayerParty_get(sav_ptr->saveBlock2);
+ struct Pokemon* party_mon = GetPartyMonByIndex(party, i);
+
+ BOOL party_mon_is_egg = (BOOL)GetMonData(party_mon, MON_DATA_IS_EGG, NULL);
+ if (party_mon_is_egg == FALSE)
+ {
+ u8 party_mon_nature = GetMonNature(party_mon);
+ if (required_nature == party_mon_nature)
+ {
+ *ret_ptr = i;
+ break;
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+THUMB_FUNC BOOL ScrCmd_GetPartyMonFriendship(struct ScriptContext* ctx)
+{
+ struct UnkSavStruct80* sav_ptr = ctx->unk80;
+ u16* ret_ptr = GetVarPointer(ctx->unk80, ScriptReadHalfword(ctx));
+ u16 mon_slot = VarGet(ctx->unk80, ScriptReadHalfword(ctx));
+ struct PlayerParty* party = SavArray_PlayerParty_get(sav_ptr->saveBlock2);
+ struct Pokemon* party_mon = GetPartyMonByIndex(party, mon_slot);
+
+ *ret_ptr = (u16)GetMonData(party_mon, MON_DATA_FRIENDSHIP, NULL);
+ return FALSE;
+}
+
+THUMB_FUNC BOOL ScrCmd_AddPartyMonFriendship(struct ScriptContext* ctx)
+{
+ struct UnkSavStruct80* sav_ptr = ctx->unk80;
+ u16 friendship_to_add = VarGet(ctx->unk80, ScriptReadHalfword(ctx));
+ u16 mon_slot = VarGet(ctx->unk80, ScriptReadHalfword(ctx));
+ u16 map_sec = MapHeader_GetMapSec(*ctx->unk80->mapId);
+ struct PlayerParty* party = SavArray_PlayerParty_get(sav_ptr->saveBlock2);
+ struct Pokemon* party_mon = GetPartyMonByIndex(party, mon_slot);
+
+ u16 friendship = (u16)GetMonData(party_mon, MON_DATA_FRIENDSHIP, NULL);
+
+ if (friendship_to_add != 0)
+ {
+ u16 party_mon_held_item = (u16)GetMonData(party_mon, MON_DATA_HELD_ITEM, NULL);
+ u32 held_item_hold_effect = GetItemAttr(party_mon_held_item, ITEMATTR_HOLD_EFFECT, 11);
+ if (held_item_hold_effect == HOLD_EFFECT_FRIENDSHIP_UP)
+ {
+ friendship_to_add = (u16)((friendship_to_add * 150) / 100);
+ }
+
+ u32 party_mon_pokeball = GetMonData(party_mon, MON_DATA_POKEBALL, NULL);
+ if (party_mon_pokeball == ITEM_LUXURY_BALL)
+ {
+ friendship_to_add++;
+ }
+
+ u32 party_mon_egg_met_location = GetMonData(party_mon, MON_DATA_EGG_MET_LOCATION, NULL);
+ if (map_sec == party_mon_egg_met_location)
+ {
+ friendship_to_add++;
+ }
+ }
+
+ friendship += friendship_to_add;
+ if (friendship > 0xFF)
+ {
+ friendship = 0xFF;
+ }
+
+ SetMonData(party_mon, MON_DATA_FRIENDSHIP, &friendship);
+
+ return FALSE;
+}
+
+THUMB_FUNC BOOL ScrCmd_SubtractPartyMonFriendship(struct ScriptContext* ctx)
+{
+ struct UnkSavStruct80* sav_ptr = ctx->unk80;
+ u16 friendship_to_deplete = VarGet(ctx->unk80, ScriptReadHalfword(ctx));
+ u16 mon_slot = VarGet(ctx->unk80, ScriptReadHalfword(ctx));
+ struct PlayerParty* party = SavArray_PlayerParty_get(sav_ptr->saveBlock2);
+ struct Pokemon* party_mon = GetPartyMonByIndex(party, mon_slot);
+
+ u16 friendship = (u16)GetMonData(party_mon, MON_DATA_FRIENDSHIP, NULL);
+ if (friendship_to_deplete > friendship)
+ {
+ friendship = 0;
+ }
+ else
+ {
+ friendship -= friendship_to_deplete;
+ }
+
+ SetMonData(party_mon, MON_DATA_FRIENDSHIP, &friendship);
+
+ return FALSE;
+}
+
+THUMB_FUNC BOOL ScrCmd_GetPartyMonContestCondition(struct ScriptContext* ctx)
+{
+ u16 mon_slot = VarGet(ctx->unk80, ScriptReadHalfword(ctx));
+ u16 contest_condition_id = VarGet(ctx->unk80, ScriptReadHalfword(ctx));
+ u16* ret_ptr = GetVarPointer(ctx->unk80, ScriptReadHalfword(ctx));
+ struct PlayerParty* party = SavArray_PlayerParty_get(ctx->unk80->saveBlock2);
+ struct Pokemon* party_mon = GetPartyMonByIndex(party, mon_slot);
+
+ *ret_ptr = (u16)GetMonData(party_mon, MON_DATA_COOL + contest_condition_id, NULL);
+ return FALSE;
+}
+
+THUMB_FUNC BOOL ScrCmd_GetLeadingPartyMonSlot(struct ScriptContext* ctx)
+{
+ u16* ret_ptr = GetVarPointer(ctx->unk80, ScriptReadHalfword(ctx));
+
+ *ret_ptr = FUN_02054DEC(ctx->unk80->saveBlock2);
+ return FALSE;
+}
+
+THUMB_FUNC BOOL ScrCmd_GetPartyMonTypes(struct ScriptContext* ctx)
+{
+ struct UnkSavStruct80* sav_ptr = ctx->unk80;
+ u16* type1 = GetVarPointer(ctx->unk80, ScriptReadHalfword(ctx));
+ u16* type2 = GetVarPointer(ctx->unk80, ScriptReadHalfword(ctx));
+ u16 mon_slot = VarGet(ctx->unk80, ScriptReadHalfword(ctx));
+ struct PlayerParty* party = SavArray_PlayerParty_get(sav_ptr->saveBlock2);
+ struct Pokemon* party_mon = GetPartyMonByIndex(party, mon_slot);
+
+ *type1 = (u16)GetMonData(party_mon, MON_DATA_TYPE_1, NULL);
+ *type2 = (u16)GetMonData(party_mon, MON_DATA_TYPE_2, NULL);
+ return FALSE;
+}
+
+THUMB_FUNC BOOL ScrCmd_CountPartyMons(struct ScriptContext* ctx)
+{
+ struct UnkSavStruct80* sav_ptr = ctx->unk80;
+ u16* ret_ptr = GetVarPointer(ctx->unk80, ScriptReadHalfword(ctx));
+ struct PlayerParty* party = SavArray_PlayerParty_get(sav_ptr->saveBlock2);
+
+ *ret_ptr = (u16)GetPartyCount(party);
+ return FALSE;
+}
+
+THUMB_FUNC BOOL ScrCmd_CountPartyMons_OmitEggs(struct ScriptContext* ctx)
+{
+ u32 non_egg_mons;
+ s32 i;
+
+ struct UnkSavStruct80* sav_ptr = ctx->unk80;
+ u16* ret_ptr = GetVarPointer(ctx->unk80, ScriptReadHalfword(ctx));
+ s32 party_count = GetPartyCount(SavArray_PlayerParty_get(sav_ptr->saveBlock2));
+
+ for (i = 0, non_egg_mons = 0; i < party_count; i++)
+ {
+ struct PlayerParty* party = SavArray_PlayerParty_get(sav_ptr->saveBlock2);
+ struct Pokemon* party_mon = GetPartyMonByIndex(party, i);
+
+ BOOL party_mon_is_egg = (BOOL)GetMonData(party_mon, MON_DATA_IS_EGG, NULL);
+ if (party_mon_is_egg == FALSE)
+ {
+ non_egg_mons++;
+ }
+
+ }
+
+ *ret_ptr = (u16)non_egg_mons;
+ return FALSE;
+}
+
+THUMB_FUNC BOOL ScrCmd_CountAvailablePartyMons_IgnoreSlot(struct ScriptContext* ctx)
+{
+ u16 slot_to_ignore;
+ s32 party_count;
+
+ struct UnkSavStruct80* sav_ptr = ctx->unk80;
+ u16* ret_ptr = GetVarPointer(ctx->unk80, ScriptReadHalfword(ctx));
+ slot_to_ignore = VarGet(ctx->unk80, ScriptReadHalfword(ctx));
+ party_count = GetPartyCount(SavArray_PlayerParty_get(sav_ptr->saveBlock2));
+
+ u32 available_mons;
+ s32 i;
+ for (i = 0, available_mons = 0; i < party_count; i++)
+ {
+ if (i != slot_to_ignore)
+ {
+ struct PlayerParty* party = SavArray_PlayerParty_get(sav_ptr->saveBlock2);
+ struct Pokemon* party_mon = GetPartyMonByIndex(party, i);
+
+ BOOL party_mon_is_egg = (BOOL)GetMonData(party_mon, MON_DATA_IS_EGG, NULL);
+ if (party_mon_is_egg == FALSE)
+ {
+ u32 party_mon_hp = GetMonData(party_mon, MON_DATA_HP, NULL);
+ if (party_mon_hp != 0)
+ {
+ available_mons++;
+ }
+ }
+ }
+ }
+
+ *ret_ptr = (u16)available_mons;
+ return FALSE;
+}
+
+THUMB_FUNC BOOL ScrCmd_CountAvailablePartyAndPCMons(struct ScriptContext* ctx)
+{
+ s32 party_count;
+ struct PCStorage* pc;
+
+ struct UnkSavStruct80* sav_ptr = ctx->unk80;
+ u16* ret_ptr = GetVarPointer(ctx->unk80, ScriptReadHalfword(ctx));
+ pc = GetStoragePCPointer(sav_ptr->saveBlock2);
+ party_count = GetPartyCount(SavArray_PlayerParty_get(sav_ptr->saveBlock2));
+
+ u32 mons;
+ s32 i;
+ for (i = 0, mons = 0; i < party_count; i++)
+ {
+ struct PlayerParty* party = SavArray_PlayerParty_get(sav_ptr->saveBlock2);
+ struct Pokemon* party_mon = GetPartyMonByIndex(party, i);
+
+ BOOL party_mon_is_egg = (BOOL)GetMonData(party_mon, MON_DATA_IS_EGG, NULL);
+ if (party_mon_is_egg == FALSE)
+ {
+ u32 party_mon_hp = GetMonData(party_mon, MON_DATA_HP, NULL);
+ if (party_mon_hp != 0)
+ {
+ mons++;
+ }
+ }
+ }
+
+ *ret_ptr = (u16)(mons + PCStorage_CountMonsInAllBoxes(pc));
+ return FALSE;
+}
+
+THUMB_FUNC BOOL ScrCmd_GetPartyEggCount(struct ScriptContext* ctx)
+{
+ s32 party_count;
+ u32 eggs_in_party;
+
+ struct UnkSavStruct80* sav_ptr = ctx->unk80;
+ u16* ret_ptr = GetVarPointer(ctx->unk80, ScriptReadHalfword(ctx));
+ party_count = GetPartyCount(SavArray_PlayerParty_get(sav_ptr->saveBlock2));
+
+ s32 i;
+ for (i = 0, eggs_in_party = 0; i < party_count; i++)
+ {
+ struct PlayerParty* party = SavArray_PlayerParty_get(sav_ptr->saveBlock2);
+ struct Pokemon* party_mon = GetPartyMonByIndex(party, i);
+
+ BOOL party_mon_is_egg = (BOOL)GetMonData(party_mon, MON_DATA_IS_EGG, NULL);
+ if (party_mon_is_egg)
+ {
+ eggs_in_party++;
+ }
+ }
+
+ *ret_ptr = (u16)eggs_in_party;
+ return FALSE;
+}
+
+THUMB_FUNC BOOL ScrCmd_CheckPartyForPokerus(struct ScriptContext* ctx)
+{
+ u16 party_count;
+ u16 i;
+
+ struct UnkSavStruct80* sav_ptr = ctx->unk80;
+ u16* ret_ptr = GetVarPointer(ctx->unk80, ScriptReadHalfword(ctx));
+ party_count = (u16)GetPartyCount(SavArray_PlayerParty_get(sav_ptr->saveBlock2));
+
+ for (i = 0, *ret_ptr = 0; i < party_count; i++)
+ {
+ struct PlayerParty* party = SavArray_PlayerParty_get(sav_ptr->saveBlock2);
+ struct Pokemon* party_mon = GetPartyMonByIndex(party, i);
+
+ BOOL party_mon_has_pokerus = (BOOL)GetMonData(party_mon, MON_DATA_POKERUS, NULL);
+ if (party_mon_has_pokerus)
+ {
+ *ret_ptr = 1;
+ break;
+ }
+ }
+
+ return FALSE;
+}
+
+THUMB_FUNC BOOL ScrCmd_GetPartyMonGender(struct ScriptContext* ctx)
+{
+ u16 mon_slot = VarGet(ctx->unk80, ScriptReadHalfword(ctx));
+ u16* ret_ptr = GetVarPointer(ctx->unk80, ScriptReadHalfword(ctx));
+ struct PlayerParty* party = SavArray_PlayerParty_get(ctx->unk80->saveBlock2);
+ struct Pokemon* party_mon = GetPartyMonByIndex(party, mon_slot);
+
+ *ret_ptr = (u16)GetMonData(party_mon, MON_DATA_GENDER, NULL);
+ return FALSE;
+}
+
+THUMB_FUNC BOOL ScrCmd_CountPartyMonMoves(struct ScriptContext* ctx)
+{
+ struct Pokemon* party_mon;
+ u8 moves;
+
+ struct UnkSavStruct80* sav_ptr = ctx->unk80;
+ u16* ret_ptr = GetVarPointer(ctx->unk80, ScriptReadHalfword(ctx));
+ u16 mon_slot = VarGet(ctx->unk80, ScriptReadHalfword(ctx));
+ struct PlayerParty* party = SavArray_PlayerParty_get(sav_ptr->saveBlock2);
+ party_mon = GetPartyMonByIndex(party, mon_slot);
+
+ BOOL party_mon_is_egg = (BOOL)GetMonData(party_mon, MON_DATA_IS_EGG, NULL);
+ if (party_mon_is_egg)
+ {
+ *ret_ptr = 0;
+ return FALSE;
+ }
+
+ moves = 0;
+
+ u32 move1 = GetMonData(party_mon, MON_DATA_MOVE1, NULL);
+ if (move1 != MOVE_NONE)
+ {
+ moves++;
+ }
+
+ u32 move2 = GetMonData(party_mon, MON_DATA_MOVE2, NULL);
+ if (move2 != MOVE_NONE)
+ {
+ moves++;
+ }
+
+ u32 move3 = GetMonData(party_mon, MON_DATA_MOVE3, NULL);
+ if (move3 != MOVE_NONE)
+ {
+ moves++;
+ }
+
+ u32 move4 = GetMonData(party_mon, MON_DATA_MOVE4, NULL);
+ if (move4 != MOVE_NONE)
+ {
+ moves++;
+ }
+
+ *ret_ptr = moves;
+ return FALSE;
+}
+
+THUMB_FUNC BOOL ScrCmd_ForgetPartyMonMove(struct ScriptContext* ctx)
+{
+ struct UnkSavStruct80* sav_ptr = ctx->unk80;
+ u16 mon_slot = VarGet(ctx->unk80, ScriptReadHalfword(ctx));
+ u16 move_slot = VarGet(ctx->unk80, ScriptReadHalfword(ctx));
+ struct PlayerParty* party = SavArray_PlayerParty_get(sav_ptr->saveBlock2);
+ struct Pokemon* party_mon = GetPartyMonByIndex(party, mon_slot);
+
+ FUN_020699A4(party_mon, move_slot);
+
+ return FALSE;
+}
+
+THUMB_FUNC BOOL ScrCmd_GetPartyMonMove(struct ScriptContext* ctx)
+{
+ struct UnkSavStruct80* sav_ptr = ctx->unk80;
+ u16* ret_ptr = GetVarPointer(ctx->unk80, ScriptReadHalfword(ctx));
+ u16 mon_slot = VarGet(ctx->unk80, ScriptReadHalfword(ctx));
+ u16 move_slot = VarGet(ctx->unk80, ScriptReadHalfword(ctx));
+ struct PlayerParty* party = SavArray_PlayerParty_get(sav_ptr->saveBlock2);
+ struct Pokemon* party_mon = GetPartyMonByIndex(party, mon_slot);
+
+ *ret_ptr = (u16)GetMonData(party_mon, MON_DATA_MOVE1 + move_slot, NULL);
+ return FALSE;
+}
+
+THUMB_FUNC BOOL ScrCmd_GetPartyMonHeldItem(struct ScriptContext* ctx)
+{
+ struct UnkSavStruct80* sav_ptr = ctx->unk80;
+ u16* ret_ptr = GetVarPointer(ctx->unk80, ScriptReadHalfword(ctx));
+ u16 mon_slot = VarGet(ctx->unk80, ScriptReadHalfword(ctx));
+ struct PlayerParty* party = SavArray_PlayerParty_get(sav_ptr->saveBlock2);
+ struct Pokemon* party_mon = GetPartyMonByIndex(party, mon_slot);
+
+ *ret_ptr = (u16)GetMonData(party_mon, MON_DATA_HELD_ITEM, NULL);
+ return FALSE;
+}
+
+THUMB_FUNC BOOL ScrCmd_ResetPartyMonHeldItem(struct ScriptContext* ctx)
+{
+ struct UnkSavStruct80* sav_ptr = ctx->unk80;
+ u16 mon_slot = VarGet(ctx->unk80, ScriptReadHalfword(ctx));
+ struct PlayerParty* party = SavArray_PlayerParty_get(sav_ptr->saveBlock2);
+ struct Pokemon* party_mon = GetPartyMonByIndex(party, mon_slot);
+
+ u16 party_mon_held_item = ITEM_NONE;
+ SetMonData(party_mon, MON_DATA_HELD_ITEM, &party_mon_held_item);
+
+ return FALSE;
+}
+
+THUMB_FUNC BOOL ScrCmd_CheckPartyForSpecies(struct ScriptContext* ctx)
+{
+ struct UnkSavStruct80* sav_ptr = ctx->unk80;
+ u16* ret_ptr = GetVarPointer(ctx->unk80, ScriptReadHalfword(ctx));
+ u16 species = VarGet(ctx->unk80, ScriptReadHalfword(ctx));
+ u8 party_count = (u8)GetPartyCount(SavArray_PlayerParty_get(sav_ptr->saveBlock2));
+
+ u8 i;
+ for (i = 0, *ret_ptr = 0; i < party_count; i++)
+ {
+ struct PlayerParty* party = SavArray_PlayerParty_get(sav_ptr->saveBlock2);
+ struct Pokemon* party_mon = GetPartyMonByIndex(party, i);
+
+ BOOL party_mon_is_egg = (BOOL)GetMonData(party_mon, MON_DATA_IS_EGG, NULL);
+ if (party_mon_is_egg == FALSE)
+ {
+ u16 party_mon_species = (u16)GetMonData(party_mon, MON_DATA_SPECIES, NULL);
+ if (species == party_mon_species)
+ {
+ *ret_ptr = 1;
+ break;
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+THUMB_FUNC BOOL ScrCmd_CountPartyMonRibbons(struct ScriptContext* ctx)
+{
+ u16* ret_ptr = GetVarPointer(ctx->unk80, ScriptReadHalfword(ctx));
+ u16 mon_slot = VarGet(ctx->unk80, ScriptReadHalfword(ctx));
+ struct PlayerParty* party = SavArray_PlayerParty_get(ctx->unk80->saveBlock2);
+ struct Pokemon* party_mon = GetPartyMonByIndex(party, mon_slot);
+
+ u16 ribbon_idx;
+ u16 ribbons;
+ for (ribbon_idx = 0, ribbons = 0; ribbon_idx < 80; ribbon_idx++)
+ {
+ BOOL party_mon_has_ribbon = (BOOL)GetMonData(party_mon, FUN_0207FC5C((u8)ribbon_idx, 0), NULL);
+ if (party_mon_has_ribbon)
+ {
+ ribbons++;
+ }
+ }
+
+ *ret_ptr = ribbons;
+ return FALSE;
+}
+
+THUMB_FUNC BOOL ScrCmd_CountTotalPartyRibbons(struct ScriptContext* ctx)
+{
+ struct PlayerParty* party;
+ u16 ribbon_idx;
+ u16 ribbons;
+
+ u16* ret_ptr = GetVarPointer(ctx->unk80, ScriptReadHalfword(ctx));
+ u16 party_count = (u16)GetPartyCount(SavArray_PlayerParty_get(ctx->unk80->saveBlock2));
+ party = SavArray_PlayerParty_get(ctx->unk80->saveBlock2);
+
+ for (ribbon_idx = 0, ribbons = 0; ribbon_idx < 80; ribbon_idx++)
+ {
+ for (u16 i = 0; i < party_count; i++)
+ {
+ struct Pokemon* party_mon = GetPartyMonByIndex(party, i);
+
+ BOOL party_mon_is_egg = (BOOL)GetMonData(party_mon, MON_DATA_IS_EGG, NULL);
+ if (party_mon_is_egg)
+ {
+ // BUG: This `break` should be a `continue`, as any party mons after a detected
+ // egg would have their ribbons ignored.
+ break;
+ }
+
+ BOOL party_mon_has_ribbon = (BOOL)GetMonData(party_mon, FUN_0207FC5C((u8)ribbon_idx, 0), NULL);
+ if (party_mon_has_ribbon)
+ {
+ ribbons++;
+ break;
+ }
+ }
+ }
+
+ *ret_ptr = ribbons;
+ return FALSE;
+}
+
+THUMB_FUNC BOOL ScrCmd_PartyMonHasRibbon(struct ScriptContext* ctx)
+{
+ u16* ret_ptr = GetVarPointer(ctx->unk80, ScriptReadHalfword(ctx));
+ u16 mon_slot = VarGet(ctx->unk80, ScriptReadHalfword(ctx));
+ u16 ribbon_idx = VarGet(ctx->unk80, ScriptReadHalfword(ctx));
+ struct PlayerParty* party = SavArray_PlayerParty_get(ctx->unk80->saveBlock2);
+ struct Pokemon* party_mon = GetPartyMonByIndex(party, mon_slot);
+
+ *ret_ptr = (u16)GetMonData(party_mon, FUN_0207FC5C((u8)ribbon_idx, 0), NULL);
+ return FALSE;
+}
+
+THUMB_FUNC BOOL ScrCmd_GivePartyMonRibbon(struct ScriptContext* ctx)
+{
+ u16 mon_slot = VarGet(ctx->unk80, ScriptReadHalfword(ctx));
+ u16 ribbon_idx = VarGet(ctx->unk80, ScriptReadHalfword(ctx));
+ u8 mon_has_ribbon = TRUE;
+ struct PlayerParty* party = SavArray_PlayerParty_get(ctx->unk80->saveBlock2);
+ struct Pokemon* party_mon = GetPartyMonByIndex(party, mon_slot);
+
+ SetMonData(party_mon, (s32)FUN_0207FC5C((u8)ribbon_idx, 0), &mon_has_ribbon);
+
+ return FALSE;
+}
+
+THUMB_FUNC BOOL ScrCmd_CheckPartyForBadEgg(struct ScriptContext* ctx)
+{
+ u16 ribbon_idx;
+
+ u16* ret_ptr = GetVarPointer(ctx->unk80, ScriptReadHalfword(ctx));
+ u16 party_count = (u16)GetPartyCount(SavArray_PlayerParty_get(ctx->unk80->saveBlock2));
+ struct PlayerParty* party = SavArray_PlayerParty_get(ctx->unk80->saveBlock2);
+
+ // BUG: Probably a copy-paste fail. Checks if your party has a Bad Egg in it,
+ // 80 times.
+ for (ribbon_idx = 0; ribbon_idx < 80; ribbon_idx++)
+ {
+ for (u16 i = 0; i < party_count; i++)
+ {
+ struct Pokemon* party_mon = GetPartyMonByIndex(party, i);
+ BOOL party_mon_is_egg = (BOOL)GetMonData(party_mon, MON_DATA_IS_EGG, NULL);
+ if (party_mon_is_egg)
+ {
+ BOOL party_mon_is_bad_egg = (BOOL)GetMonData(party_mon, MON_DATA_CHECKSUM_FAILED, NULL);
+ if (party_mon_is_bad_egg)
+ {
+ *ret_ptr = 1;
+ return FALSE;
+ }
+ }
+ }
+ }
+
+ *ret_ptr = 0;
+ return FALSE;
+}
+
+THUMB_FUNC BOOL ScrCmd_Unk00A0(struct ScriptContext* ctx)
+{
+#pragma unused(ctx)
+ return FALSE;
+}
diff --git a/arm9/src/scrcmd_sound.c b/arm9/src/scrcmd_sound.c
index ec5ab7f8..1251c612 100644
--- a/arm9/src/scrcmd_sound.c
+++ b/arm9/src/scrcmd_sound.c
@@ -18,7 +18,7 @@ extern void FUN_0200538C(u32, u16, u32);
extern void FUN_020053CC(u16, u16);
extern BOOL FUN_02005404(void);
extern u16 FUN_02005410(u16);
-extern void FUN_020054C8(u16);
+extern void PlaySE(u16);
extern void FUN_020054F0(u16, u32);
extern void FUN_020047C8(u8, u8);
extern void FUN_020040F4(u8);
@@ -123,7 +123,7 @@ THUMB_FUNC BOOL ScrCmd_Unk0058(struct ScriptContext* ctx)
THUMB_FUNC BOOL ScrCmd_PlayFanfare(struct ScriptContext* ctx)
{
u16 unk = VarGet(ctx->unk80, ScriptReadHalfword(ctx));
- FUN_020054C8(unk);
+ PlaySE(unk);
return FALSE;
}
@@ -263,4 +263,3 @@ THUMB_FUNC BOOL ScrCmd_SetVolume(struct ScriptContext* ctx)
return FALSE;
}
-
diff --git a/arm9/src/text_02054590.c b/arm9/src/text_02054590.c
index d4984f78..f5527257 100644
--- a/arm9/src/text_02054590.c
+++ b/arm9/src/text_02054590.c
@@ -1,6 +1,7 @@
#include "text_02054590.h"
#include "text.h"
#include "bg_window.h"
+#include "render_text.h"
extern void FUN_0201BD5C(void);
extern void FUN_02002ED0(u32 param0, u32 param1, u32 param2);
@@ -10,10 +11,6 @@ extern void FUN_0200CD68(
struct BgConfig *param0, u32 param1, u32 param2, u32 param3, u8 param4, u32 param5);
extern void FUN_0200D0BC(struct Window *param0, u32 param1, u32 param2, u32 param3);
-extern void FUN_02002B60(u8 param0);
-extern void FUN_02002B7C(u32 param0);
-extern void FUN_02002BB8(u32 param0);
-
extern void FUN_0200D300(struct BgConfig *param0,
u32 param1,
u32 param2,
@@ -59,15 +56,15 @@ THUMB_FUNC void FUN_0205464C(struct Window *param0)
THUMB_FUNC u16 FUN_02054658(struct Window * window, struct String *str, struct Options *options, u8 param3)
{
- FUN_02002B60(param3);
+ TextFlags_SetCanABSpeedUpPrint(param3);
FUN_02002B7C(0);
FUN_02002BB8(0);
return AddTextPrinterParameterized(window, 1, str, 0, 0, (u32)Options_GetTextFrameDelay(options), NULL);
}
-THUMB_FUNC u16 DrawFieldMessage(struct Window * window, struct String *str, u8 fontId, u32 speed, u8 a4, u32 a5)
+THUMB_FUNC u16 DrawFieldMessage(struct Window * window, struct String *str, u8 fontId, u32 speed, u8 a4, s32 a5)
{
- FUN_02002B60(a4);
+ TextFlags_SetCanABSpeedUpPrint(a4);
FUN_02002B7C(a5);
FUN_02002BB8(0);
return AddTextPrinterParameterized(window, fontId, str, 0, 0, speed, NULL);
diff --git a/arm9/src/unk_0201B8B8.c b/arm9/src/unk_0201B8B8.c
index c7f77f87..b8e978f2 100644
--- a/arm9/src/unk_0201B8B8.c
+++ b/arm9/src/unk_0201B8B8.c
@@ -14,7 +14,7 @@ const u16 * MsgArray_SkipControlCode(const u16 * r4)
return r4;
}
-u16 MsgArray_GetControlCode(const u16 * r4)
+u32 MsgArray_GetControlCode(const u16 * r4)
{
GF_ASSERT(*r4 == 0xFFFE);
return r4[1];
@@ -25,7 +25,7 @@ BOOL MsgArray_ControlCodeIsStrVar(const u16 * r4)
return (MsgArray_GetControlCode(r4) & 0xFF00) == 0x100;
}
-u16 MsgArray_ControlCodeGetField(const u16 * r5, u32 r4)
+u32 MsgArray_ControlCodeGetField(const u16 * r5, u32 r4)
{
GF_ASSERT(*r5 == 0xFFFE);
GF_ASSERT(r4 < r5[2]);
diff --git a/arm9/src/unk_0206015C.c b/arm9/src/unk_0206015C.c
index a217f52c..0bf3a15a 100644
--- a/arm9/src/unk_0206015C.c
+++ b/arm9/src/unk_0206015C.c
@@ -21,7 +21,7 @@ extern THUMB_FUNC void MOD06_02245190(u32);
extern THUMB_FUNC void MOD06_02245198(u8, u32);
extern THUMB_FUNC u32 MOD06_022451F0(u32);
-extern THUMB_FUNC void FUN_020054C8(u32);
+extern THUMB_FUNC void PlaySE(u32);
extern THUMB_FUNC void FUN_02049160(struct UnkStruct_0204639C*, u32);
extern THUMB_FUNC void FUN_0204AF84(struct UnkStruct_0204639C*);
extern THUMB_FUNC void FUN_0204AF3C(struct UnkStruct_0204639C *);
@@ -97,7 +97,7 @@ THUMB_FUNC BOOL FUN_02060194(struct UnkStruct_0204639C *unkStruct0)
MOD06_02244DC4(unkStruct1->unk0, unkAddr);
MOD06_02244EF8(unkStruct1->unk0);
unkStruct1->unkE = 0;
- FUN_020054C8(1657);
+ PlaySE(1657);
FUN_0204C1B4(unkStruct0, 0x3, 0x11, 0x0000FFFF, 0, 6, 1, 0xb);
unkStruct1->action = 5;
}
@@ -117,7 +117,7 @@ THUMB_FUNC BOOL FUN_02060194(struct UnkStruct_0204639C *unkStruct0)
MOD06_02245198(unkStruct1->unkD, unkStruct1->unk4);
unkStruct1->unk8 = MOD06_022451F0(unkStruct1->unk4);
- FUN_020054C8(1657);
+ PlaySE(1657);
FUN_0204C1B4(unkStruct0, 0x3, 0x10, 0x0000FFFF, 0, 6, 1, 0xb);
unkStruct1->action = 6;
break;
diff --git a/arm9/src/unk_020851B8.c b/arm9/src/unk_020851B8.c
index 592d16d6..922ca2e4 100644
--- a/arm9/src/unk_020851B8.c
+++ b/arm9/src/unk_020851B8.c
@@ -10,7 +10,7 @@ THUMB_FUNC struct UnkStruct_020851B8 *FUN_020851B8(u32 heap_id)
return ptr;
}
-THUMB_FUNC void FUN_020851DC(struct UnkStruct_020851B8 *param0, u32 item_id, BOOL param2)
+THUMB_FUNC void FUN_020851DC(struct UnkStruct_020851B8 *param0, u16 item_id, BOOL param2)
{
u16 berry_id = item_id - FIRST_BERRY_IDX;
FUN_02085200(param0, berry_id);
diff --git a/arm9/src/unk_02088AAC.c b/arm9/src/unk_02088AAC.c
new file mode 100644
index 00000000..c0419e09
--- /dev/null
+++ b/arm9/src/unk_02088AAC.c
@@ -0,0 +1,185 @@
+#include "global.h"
+#include "unk_02088AAC.h"
+#include "heap.h"
+#include "overlay_manager.h"
+#include "unk_020851B8.h"
+
+extern BOOL MOD68_021D74E0(struct UnkStruct_02006234 *, u32 *);
+extern BOOL MOD68_021D75D8(struct UnkStruct_02006234 *, u32 *);
+extern BOOL MOD68_021D762C(struct UnkStruct_02006234 *, u32 *);
+extern BOOL MOD73_021D74F0(struct UnkStruct_02006234 *, u32 *);
+extern BOOL MOD73_021D758C(struct UnkStruct_02006234 *, u32 *);
+extern BOOL MOD73_021D7640(struct UnkStruct_02006234 *, u32 *);
+extern BOOL MOD75_021E6BA0(struct UnkStruct_02006234 *, u32 *);
+extern BOOL MOD75_021E6D6C(struct UnkStruct_02006234 *, u32 *);
+extern BOOL MOD75_021E6F00(struct UnkStruct_02006234 *, u32 *);
+
+extern BOOL FUN_0208898C(struct UnkStruct_02006234 **r0);
+
+THUMB_FUNC u32 FUN_02088AAC(struct UnkStruct_02088AAC *r0, u32 *r1)
+{
+ switch (*r1)
+ {
+ case 0:
+ *r1 = FUN_02088B4C(r0);
+ break;
+ case 1:
+ *r1 = FUN_02088BA8(r0);
+ break;
+ case 2:
+ *r1 = FUN_02088C3C(r0);
+ break;
+ case 3:
+ *r1 = FUN_02088CDC(r0);
+ break;
+ case 4:
+ return 1;
+ case 5:
+ return 4;
+ }
+
+ return 0;
+}
+
+THUMB_FUNC u32 FUN_02088AFC(struct UnkStruct_02088AAC *r0)
+{
+ FS_EXTERN_OVERLAY(MODULE_73);
+
+ const struct Unk21DBE18 OVERLAY_73_MANAGER = { .unk0 = MOD73_021D74F0,
+ .unk4 = MOD73_021D758C,
+ .unk8 = MOD73_021D7640,
+ .ovly = FS_OVERLAY_ID(MODULE_73) };
+ r0->ovly_data = OverlayManager_new(&OVERLAY_73_MANAGER, (s32 *)r0, r0->heap_id);
+
+ return 2;
+}
+
+THUMB_FUNC u32 FUN_02088B28(struct UnkStruct_02088AAC *r0)
+{
+ if (!FUN_0208898C(&r0->ovly_data))
+ {
+ return 2;
+ }
+
+ if (r0->unk20 == TRUE)
+ {
+ return 0;
+ }
+
+ return 3;
+}
+
+THUMB_FUNC u32 FUN_02088B48()
+{
+ return 4;
+}
+
+THUMB_FUNC u32 FUN_02088B4C(struct UnkStruct_02088AAC *r0)
+{
+ FS_EXTERN_OVERLAY(MODULE_75);
+
+ static const u8 UNK_020FD6F4[] = { 0x04, 0xFF };
+ const struct Unk21DBE18 OVERLAY_75_MANAGER = { .unk0 = MOD75_021E6BA0,
+ .unk4 = MOD75_021E6D6C,
+ .unk8 = MOD75_021E6F00,
+ .ovly = FS_OVERLAY_ID(MODULE_75) };
+ struct BagView *bag_view = CreateBagView(r0->unk10->bag, UNK_020FD6F4, r0->heap_id);
+
+ FUN_0206E314(bag_view, r0->unk10->sav2, (u8)((u8)r0->unk06 == 1 ? 5 : 4), r0->unk0C);
+
+ r0->ovly_data = OverlayManager_new(&OVERLAY_75_MANAGER, (s32 *)bag_view, r0->heap_id);
+ r0->ovly_param = bag_view;
+
+ return 1;
+}
+
+THUMB_FUNC u32 FUN_02088BA8(struct UnkStruct_02088AAC *r0)
+{
+ if (!FUN_0208898C(&r0->ovly_data))
+ {
+ return 1;
+ }
+
+ struct BagView *bag_view = BagView_New((u8)r0->heap_id);
+
+ memcpy(bag_view, r0->ovly_param, BagView_sizeof());
+ FreeToHeap(r0->ovly_param);
+
+ r0->ovly_param = NULL;
+ r0->item = FUN_0206E37C(bag_view);
+
+ FreeToHeap(bag_view);
+
+ switch (FUN_0206E384(bag_view))
+ {
+ case 1:
+ return 2;
+ case 5:
+ return 5;
+ default:
+ GF_AssertFail();
+ r0->item = FIRST_BERRY_IDX;
+ case 0:
+ case 2:
+ case 3:
+ case 4:
+ GF_ASSERT(Bag_TakeItem(r0->unk10->bag, (u16)r0->item, 1, r0->heap_id));
+ return 4;
+ }
+}
+
+THUMB_FUNC u32 FUN_02088C3C(struct UnkStruct_02088AAC *r0)
+{
+ FS_EXTERN_OVERLAY(MODULE_68);
+
+ struct Bag *bag = r0->unk10->bag;
+ const struct Unk21DBE18 OVERLAY_68_MANAGER = { .unk0 = MOD68_021D74E0,
+ .unk4 = MOD68_021D75D8,
+ .unk8 = MOD68_021D762C,
+ .ovly = FS_OVERLAY_ID(MODULE_68) };
+
+ r0->ovly_param = FUN_020851B8((u8)r0->heap_id);
+
+ FUN_020851DC(r0->ovly_param, (u16)r0->item, TRUE);
+
+ u8 berry_count = 0;
+ for (u8 berry_id = 0; berry_id < (u8)NUM_BERRIES; berry_id++)
+ {
+ u8 item_id = (u8)BerryToItemId(berry_id);
+ if (Bag_HasItem(bag, item_id, 1, r0->heap_id) == TRUE)
+ {
+ FUN_020851DC(r0->ovly_param, item_id, 0);
+
+ berry_count++;
+ }
+ }
+
+ u8 sp5;
+ u8 sp6;
+
+ FUN_0206F17C(r0->unk0C, 4, &sp6, &sp5);
+ FUN_020851F8(r0->ovly_param, sp5, sp6, (u8)(berry_count + 2));
+
+ r0->ovly_data = OverlayManager_new(&OVERLAY_68_MANAGER, (s32 *)r0->ovly_param, r0->heap_id);
+
+ return 3;
+}
+
+THUMB_FUNC u32 FUN_02088CDC(struct UnkStruct_02088AAC *r0)
+{
+ if (!FUN_0208898C(&r0->ovly_data))
+ {
+ return 3;
+ }
+
+ u8 sp0;
+ u8 sp1;
+
+ FUN_0208524C(r0->ovly_param, &sp0, &sp1);
+ FUN_0206F190(r0->unk0C, 4, sp1, sp0);
+ FreeToHeap(r0->ovly_param);
+
+ r0->ovly_param = NULL;
+
+ return 0;
+}