summaryrefslogtreecommitdiff
path: root/src/pokemon_storage_system.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pokemon_storage_system.c')
-rw-r--r--src/pokemon_storage_system.c523
1 files changed, 504 insertions, 19 deletions
diff --git a/src/pokemon_storage_system.c b/src/pokemon_storage_system.c
index 7f8c24ab7..031f704a4 100644
--- a/src/pokemon_storage_system.c
+++ b/src/pokemon_storage_system.c
@@ -7,17 +7,49 @@
#include "text.h"
#include "strings.h"
#include "window.h"
+#include "menu.h"
+#include "bg.h"
+#include "main.h"
+#include "palette.h"
+#include "overworld.h"
+#include "field_screen.h"
+#include "field_weather.h"
+#include "script.h"
+#include "international_string_util.h"
+#include "walda_phrase.h"
+#include "sound.h"
+#include "gpu_regs.h"
+#include "constants/songs.h"
IWRAM_DATA u8 gUnknown_03000F78[0x188];
-struct OptionAndDescription
-{
- const u8 *optionTxt;
- const u8 *descriptionTxt;
-};
+extern const u8 gText_PartyFull[];
+extern const u8 gText_Box[];
+extern const u8 gText_JustOnePkmn[];
+
+extern u8 gUnknown_02039D00;
+
+// This file's functions.
+void StorageSystemCreatePrimaryMenu(u8 whichMenu, s16 *windowIdPtr);
+void sub_80C7D74(u8);
+u8 sub_80CAEA0(void);
+void SetBoxWallpaper(u8 boxId, u8 wallpaperId);
+void SetCurrentBox(u8 boxId);
+void ClearMonInBox(u8 boxId, u8 boxPos);
+void ResetWaldaWallpaper(void);
+void sub_80C7958(u8 curBox);
+void sub_80C7B14(void);
+void sub_80C7BB4(void);
+void sub_80CA028(void);
+void sub_80C7B80(void);
+void sub_80D2AA4(void);
+void sub_80C7BE4(void);
+void sub_80CAA14(void);
+void sub_80C7CF4(struct Sprite *sprite);
+struct Sprite *sub_80CD2E8(u16 x, u16 y, u8 animId, u8 priority, u8 subpriority);
// const rom data
-const struct OptionAndDescription gUnknown_085716C0[] =
+const struct PSS_MenuStringPtrs gUnknown_085716C0[] =
{
{gText_WithdrawPokemon, gText_WithdrawMonDescription},
{gText_DepositPokemon, gText_DepositMonDescription},
@@ -74,6 +106,10 @@ static const union AffineAnimCmd *const sSpriteAffineAnimTable_8571730[] =
const u8 gUnknown_08571734[] = {4, 0xF, 0xE};
const u8 gUnknown_08571737[] = _("/30");
+const u16 gBoxSelectionPopupPalette[] = INCBIN_U16("graphics/unknown/unknown_57173C.gbapal");
+const u8 gBoxSelectionPopupCenterTiles[] = INCBIN_U8("graphics/pokemon_storage/box_selection_popup_center.4bpp");
+const u8 gBoxSelectionPopupSidesTiles[] = INCBIN_U8("graphics/pokemon_storage/box_selection_popup_sides.4bpp");
+
// code
u8 CountMonsInBox(u8 boxId)
{
@@ -166,24 +202,473 @@ static u8 *StringCopyAndFillWithSpaces(u8 *dst, const u8 *src, u16 n)
return str;
}
-/* can't match
-static void sub_80C7128(u16 *dst, u16 dstToAdd, u16 dstToMul, const u16 *src, u16 srcToAdd, u16 srcToMul, u32 size, u16 count, u16 srcBy)
+static void sub_80C7128(u16 *dest, u16 dest_left, u16 dest_top, const u16 *src, u16 src_left, u16 src_top, u16 dest_width, u16 dest_height, u16 src_width)
+{
+ u16 i;
+
+ dest_width *= 2;
+ dest += dest_top * 0x20 + dest_left;
+ src += src_top * src_width + src_left;
+ for (i = 0; i < dest_height; i++)
+ {
+ CpuCopy16(src, dest, dest_width);
+ dest += 0x20;
+ src += src_width;
+ }
+}
+
+#define MAX_DMA_BLOCK_SIZE 0x1000
+#define Dma3FillLarge_(value, dest, size, bit) \
+{ \
+ void *_dest = dest; \
+ u32 _size = size; \
+ while (1) \
+ { \
+ if (_size <= MAX_DMA_BLOCK_SIZE) \
+ { \
+ DmaFill##bit(3, value, _dest, _size); \
+ break; \
+ } \
+ DmaFill##bit(3, value, _dest, MAX_DMA_BLOCK_SIZE); \
+ _dest += MAX_DMA_BLOCK_SIZE; \
+ _size -= MAX_DMA_BLOCK_SIZE; \
+ } \
+}
+
+#define Dma3FillLarge16_(value, dest, size) Dma3FillLarge_(value, dest, size, 16)
+#define Dma3FillLarge32_(value, dest, size) Dma3FillLarge_(value, dest, size, 32)
+
+void sub_80C71A4(u16 *dest, u16 dest_left, u16 dest_top, u16 width, u16 height)
+{
+ u16 i;
+
+ dest += dest_top * 0x20 + dest_left;
+ width *= 2;
+ for (i = 0; i < height; dest += 0x20, i++)
+ Dma3FillLarge16_(0, dest, width);
+}
+
+void Task_PokemonStorageSystem(u8 taskId)
+{
+ struct Task *task = gTasks + taskId;
+ switch (task->data[0])
+ {
+ case 0:
+ StorageSystemCreatePrimaryMenu(task->data[1], &task->data[15]);
+ sub_81973A4();
+ NewMenuHelpers_DrawDialogueFrame(0, 0);
+ FillWindowPixelBuffer(0, 0x11);
+ AddTextPrinterParameterized2(0, 1, gUnknown_085716C0[task->data[1]].desc, TEXT_SPEED_FF, NULL, 2, 1, 3);
+ CopyWindowToVram(0, 3);
+ CopyWindowToVram(task->data[15], 3);
+ task->data[0]++;
+ break;
+ case 1:
+ if (IsWeatherNotFadingIn())
+ {
+ task->data[0]++;
+ }
+ break;
+ case 2:
+ task->data[2] = ProcessMenuInput();
+ switch(task->data[2])
+ {
+ case -2:
+ task->data[3] = task->data[1];
+ if (gMain.newKeys & DPAD_UP && --task->data[3] < 0)
+ task->data[3] = 4;
+
+ if (gMain.newKeys & DPAD_DOWN && ++task->data[3] > 4)
+ task->data[3] = 0;
+ if (task->data[1] != task->data[3])
+ {
+ task->data[1] = task->data[3];
+ FillWindowPixelBuffer(0, 0x11);
+ AddTextPrinterParameterized2(0, 1, gUnknown_085716C0[task->data[1]].desc, 0, NULL, 2, 1, 3);
+ }
+ break;
+ case -1:
+ case 4:
+ sub_819746C(task->data[15], TRUE);
+ ScriptContext2_Disable();
+ EnableBothScriptContexts();
+ RemoveWindow(task->data[15]);
+ DestroyTask(taskId);
+ break;
+ default:
+ if (task->data[2] == 0 && CountPartyMons() == PARTY_SIZE)
+ {
+ FillWindowPixelBuffer(0, 0x11);
+ AddTextPrinterParameterized2(0, 1, gText_PartyFull, 0, NULL, 2, 1, 3);
+ task->data[0] = 3;
+ }
+ else if (task->data[2] == 1 && CountPartyMons() == 1)
+ {
+ FillWindowPixelBuffer(0, 0x11);
+ AddTextPrinterParameterized2(0, 1, gText_JustOnePkmn, 0, NULL, 2, 1, 3);
+ task->data[0] = 3;
+ }
+ else
+ {
+ FadeScreen(1, 0);
+ task->data[0] = 4;
+ }
+ break;
+ }
+ break;
+ case 3:
+ if (gMain.newKeys & (A_BUTTON | B_BUTTON))
+ {
+ FillWindowPixelBuffer(0, 0x11);
+ AddTextPrinterParameterized2(0, 1, gUnknown_085716C0[task->data[1]].desc, 0, NULL, 2, 1, 3);
+ task->data[0] = 2;
+ }
+ else if (gMain.newKeys & DPAD_UP)
+ {
+ if (--task->data[1] < 0)
+ task->data[1] = 4;
+ MoveMenuCursor(-1);
+ task->data[1] = GetMenuCursorPos();
+ FillWindowPixelBuffer(0, 0x11);
+ AddTextPrinterParameterized2(0, 1, gUnknown_085716C0[task->data[1]].desc, 0, NULL, 2, 1, 3);
+ task->data[0] = 2;
+ }
+ else if (gMain.newKeys & DPAD_DOWN)
+ {
+ if (++task->data[1] > 3)
+ task->data[1] = 0;
+ MoveMenuCursor(1);
+ task->data[1] = GetMenuCursorPos();
+ FillWindowPixelBuffer(0, 0x11);
+ AddTextPrinterParameterized2(0, 1, gUnknown_085716C0[task->data[1]].desc, 0, NULL, 2, 1, 3);
+ task->data[0] = 2;
+ }
+ break;
+ case 4:
+ if (!gPaletteFade.active)
+ {
+ overworld_free_bg_tilemaps();
+ sub_80C7D74(task->data[2]);
+ RemoveWindow(task->data[15]);
+ DestroyTask(taskId);
+ }
+ break;
+ }
+}
+
+void ShowPokemonStorageSystem(void)
+{
+ u8 taskId = CreateTask(Task_PokemonStorageSystem, 80);
+ gTasks[taskId].data[0] = 0;
+ gTasks[taskId].data[1] = 0;
+ ScriptContext2_Enable();
+}
+
+void mapldr_0808C6D8(void)
+{
+ u8 taskId;
+ MainCallback vblankCb = gMain.vblankCallback;
+
+ SetVBlankCallback(NULL);
+ taskId = CreateTask(Task_PokemonStorageSystem, 80);
+ gTasks[taskId].data[0] = 0;
+ gTasks[taskId].data[1] = gUnknown_02039D00;
+ Task_PokemonStorageSystem(taskId);
+ SetVBlankCallback(vblankCb);
+ pal_fill_black();
+}
+
+void StorageSystemCreatePrimaryMenu(u8 whichMenu, s16 *windowIdPtr)
+{
+ s16 windowId;
+ struct WindowTemplate winTemplate = gUnknown_085716E8;
+ winTemplate.width = GetMaxWidthInMenuTable((void *)gUnknown_085716C0, ARRAY_COUNT(gUnknown_085716C0));
+ windowId = AddWindow(&winTemplate);
+
+ NewMenuHelpers_DrawStdWindowFrame(windowId, FALSE);
+ PrintMenuTable(windowId, ARRAY_COUNT(gUnknown_085716C0), (void *)gUnknown_085716C0);
+ InitMenuInUpperLeftCornerPlaySoundWhenAPressed(windowId, ARRAY_COUNT(gUnknown_085716C0), whichMenu);
+ *windowIdPtr = windowId;
+}
+
+void sub_80C7678(void)
+{
+ gUnknown_02039D00 = sub_80CAEA0();
+ gFieldCallback = mapldr_0808C6D8;
+ SetMainCallback2(CB2_ReturnToField);
+}
+
+s16 StorageSystemGetNextMonIndex(struct BoxPokemon *box, s8 startIdx, u8 stopIdx, u8 mode)
+{
+ s16 i;
+ s16 direction;
+ if (mode == 0 || mode == 1)
+ {
+ direction = 1;
+ }
+ else
+ {
+ direction = -1;
+ }
+ if (mode == 1 || mode == 3)
+ {
+ for (i = startIdx + direction; i >= 0 && i <= stopIdx; i += direction)
+ {
+ if (GetBoxMonData(box + i, MON_DATA_SPECIES) != 0)
+ return i;
+ }
+ }
+ else
+ {
+ for (i = startIdx + direction; i >= 0 && i <= stopIdx; i += direction)
+ {
+ if (GetBoxMonData(box + i, MON_DATA_SPECIES) != 0 && !GetBoxMonData(box + i, MON_DATA_IS_EGG))
+ return i;
+ }
+ }
+ return -1;
+}
+
+void ResetPokemonStorageSystem(void)
+{
+ u16 boxId;
+ u16 boxMon;
+
+ SetCurrentBox(0);
+ for (boxId = 0; boxId < TOTAL_BOXES_COUNT; boxId++)
+ {
+ for (boxMon = 0; boxMon < IN_BOX_COUNT; boxMon++)
+ ClearMonInBox(boxId, boxMon);
+ }
+ for (boxId = 0; boxId < TOTAL_BOXES_COUNT; boxId++)
+ {
+ u8 *dest = StringCopy(GetBoxNamePtr(boxId), gText_Box);
+ ConvertIntToDecimalStringN(dest, boxId + 1, STR_CONV_MODE_LEFT_ALIGN, 2);
+ }
+ for (boxId = 0; boxId < TOTAL_BOXES_COUNT; boxId++)
+ {
+ SetBoxWallpaper(boxId, boxId % 4);
+ }
+ ResetWaldaWallpaper();
+}
+
+void sub_80C77E8(struct UnkPSSStruct_2002370 *a0, u16 tileTag, u16 palTag, u8 a3, bool32 loadPal)
+{
+ struct SpritePalette palette =
+ {
+ gBoxSelectionPopupPalette, palTag
+ };
+ struct SpriteSheet sheets[] =
+ {
+ {gBoxSelectionPopupCenterTiles, 0x800, tileTag},
+ {gBoxSelectionPopupSidesTiles, 0x180, tileTag + 1},
+ {}
+ };
+
+ if (loadPal)
+ LoadSpritePalette(&palette);
+
+ LoadSpriteSheets(sheets);
+ gUnknown_02039D04 = a0;
+ a0->unk_0240 = tileTag;
+ a0->unk_0242 = palTag;
+ a0->unk_0246 = a3;
+ a0->unk_023c = loadPal;
+}
+
+void sub_80C7890(void)
+{
+ if (gUnknown_02039D04->unk_023c)
+ FreeSpritePaletteByTag(gUnknown_02039D04->unk_0242);
+ FreeSpriteTilesByTag(gUnknown_02039D04->unk_0240);
+ FreeSpriteTilesByTag(gUnknown_02039D04->unk_0240 + 1);
+}
+
+void sub_80C78D4(u8 curBox)
+{
+ sub_80C7958(curBox);
+}
+
+void sub_80C78E4(void)
+{
+ sub_80C7B14();
+}
+
+u8 sub_80C78F0(void)
+{
+ if (gMain.newKeys & B_BUTTON)
+ {
+ PlaySE(SE_SELECT);
+ return 201;
+ }
+ if (gMain.newKeys & A_BUTTON)
+ {
+ PlaySE(SE_SELECT);
+ return gUnknown_02039D04->curBox;
+ }
+ if (gMain.newKeys & DPAD_LEFT)
+ {
+ PlaySE(SE_SELECT);
+ sub_80C7BB4();
+ }
+ else if (gMain.newKeys & DPAD_RIGHT)
+ {
+ PlaySE(SE_SELECT);
+ sub_80C7B80();
+ }
+ return 200;
+}
+
+void sub_80C7958(u8 curBox)
{
u16 i;
+ u8 spriteId;
+ struct SpriteTemplate template;
+ struct OamData oamData = {};
+ oamData.size = 3;
+ oamData.paletteNum = 1;
+ template = (struct SpriteTemplate){
+ 0, 0, &oamData, gDummySpriteAnimTable, NULL, gDummySpriteAffineAnimTable, SpriteCallbackDummy
+ };
+
+ gUnknown_02039D04->curBox = curBox;
+ template.tileTag = gUnknown_02039D04->unk_0240;
+ template.paletteTag = gUnknown_02039D04->unk_0242;
+
+ spriteId = CreateSprite(&template, 0xA0, 0x60, 0);
+ gUnknown_02039D04->unk_0000 = gSprites + spriteId;
+
+ oamData.shape = ST_OAM_V_RECTANGLE;
+ oamData.size = 1;
+ template.tileTag = gUnknown_02039D04->unk_0240 + 1;
+ template.anims = sSpriteAnimTable_8571710;
+ for (i = 0; i < 4; i++)
+ {
+ u16 r5;
+ spriteId = CreateSprite(&template, 0x7c, 0x50, gUnknown_02039D04->unk_0246);
+ gUnknown_02039D04->unk_0004[i] = gSprites + spriteId;
+ r5 = 0;
+ if (i & 2)
+ {
+ gUnknown_02039D04->unk_0004[i]->pos1.x = 0xc4;
+ r5 = 2;
+ }
+ if (i & 1)
+ {
+ gUnknown_02039D04->unk_0004[i]->pos1.y = 0x70;
+ gUnknown_02039D04->unk_0004[i]->oam.size = 0;
+ r5++;
+ }
+ StartSpriteAnim(gUnknown_02039D04->unk_0004[i], r5);
+ }
+ for (i = 0; i < 2; i++)
+ {
+ gUnknown_02039D04->unk_0020[i] = sub_80CD2E8(72 * i + 0x7c, 0x58, i, 0, gUnknown_02039D04->unk_0246);
+ if (gUnknown_02039D04->unk_0020[i])
+ {
+ gUnknown_02039D04->unk_0020[i]->data[0] = (i == 0 ? -1 : 1);
+ gUnknown_02039D04->unk_0020[i]->callback = sub_80C7CF4;
+ }
+ }
+ sub_80C7BE4();
+}
+
+void sub_80C7B14(void)
+{
+ u16 i;
+ if (gUnknown_02039D04->unk_0000)
+ {
+ DestroySprite(gUnknown_02039D04->unk_0000);
+ gUnknown_02039D04->unk_0000 = NULL;
+ }
+ for (i = 0; i < 4; i++)
+ {
+ if (gUnknown_02039D04->unk_0004[i])
+ {
+ DestroySprite(gUnknown_02039D04->unk_0004[i]);
+ gUnknown_02039D04->unk_0004[i] = NULL;
+ }
+ }
+ for (i = 0; i < 2; i++)
+ {
+ if (gUnknown_02039D04->unk_0020[i])
+ DestroySprite(gUnknown_02039D04->unk_0020[i]);
+ }
+}
- size <<= 0x11;
- dst += (dstToMul * 32) + dstToAdd;
- src += (srcToMul * srcBy) + srcToAdd;
+void sub_80C7B80(void)
+{
+ if (++gUnknown_02039D04->curBox >= TOTAL_BOXES_COUNT)
+ gUnknown_02039D04->curBox = 0;
+ sub_80C7BE4();
+}
+
+void sub_80C7BB4(void)
+{
+ gUnknown_02039D04->curBox = (gUnknown_02039D04->curBox == 0 ? TOTAL_BOXES_COUNT - 1 : gUnknown_02039D04->curBox - 1);
+ sub_80C7BE4();
+}
- i = 0;
- if (i < count)
+void sub_80C7BE4(void)
+{
+ u8 text[16];
+ struct WindowTemplate winTemplate;
+ u8 windowId;
+ u8 *boxName = GetBoxNamePtr(gUnknown_02039D04->curBox);
+ u8 nPokemonInBox = CountMonsInBox(gUnknown_02039D04->curBox);
+ u32 winTileData;
+ s32 center;
+
+ memset(&winTemplate, 0, sizeof(winTemplate));
+ winTemplate.width = 8;
+ winTemplate.height = 4;
+
+ windowId = AddWindow(&winTemplate);
+ FillWindowPixelBuffer(windowId, 0x44);
+
+ center = GetStringCenterAlignXOffset(1, boxName, 0x40);
+ AddTextPrinterParameterized3(windowId, 1, center, 1, gUnknown_08571734, TEXT_SPEED_FF, boxName);
+
+ ConvertIntToDecimalStringN(text, nPokemonInBox, 1, 2);
+ StringAppend(text, gUnknown_08571737);
+ center = GetStringCenterAlignXOffset(1, text, 0x40);
+ AddTextPrinterParameterized3(windowId, 1, center, 0x11, gUnknown_08571734, TEXT_SPEED_FF, text);
+
+ winTileData = GetWindowAttribute(windowId, WINDOW_TILE_DATA);
+ CpuCopy32((void *)winTileData, (void *)OBJ_VRAM0 + 0x100 + (GetSpriteTileStartByTag(gUnknown_02039D04->unk_0240) * 32), 0x400);
+
+ RemoveWindow(windowId);
+}
+
+void sub_80C7CF4(struct Sprite *sprite)
+{
+ if (++sprite->data[1] > 3)
{
- size >>= 1;
- for (i = 0; i < count; i++)
+ sprite->data[1] = 0;
+ sprite->pos2.x += sprite->data[0];
+ if (++sprite->data[2] > 5)
{
- CpuSet(src, dst, size >> 0x10);
- dst += 0x20;
- src += srcBy;
+ sprite->data[2] = 0;
+ sprite->pos2.x = 0;
}
}
-}*/
+}
+
+void sub_80C7D28(void)
+{
+ LoadOam();
+ ProcessSpriteCopyRequests();
+ sub_80D2AA4();
+ TransferPlttBuffer();
+ SetGpuReg(REG_OFFSET_BG2HOFS, gUnknown_02039D08->bg2_X);
+}
+
+void c2_Box(void)
+{
+ RunTasks();
+ do_scheduled_bg_tilemap_copies_to_vram();
+ sub_80CA028();
+ sub_80CAA14();
+ AnimateSprites();
+ BuildOamBuffer();
+}