pokeemerald/src/pokenav.c

2901 lines
72 KiB
C
Raw Normal View History

2019-02-11 20:59:44 +01:00
#include "global.h"
#include "alloc.h"
#include "task.h"
#include "main.h"
#include "overworld.h"
2019-02-12 07:39:27 +01:00
#include "field_weather.h"
2019-02-12 08:23:08 +01:00
#include "palette.h"
2019-02-12 09:48:32 +01:00
#include "pokemon_storage_system.h"
2019-02-13 06:07:48 +01:00
#include "sound.h"
#include "constants/songs.h"
#include "window.h"
2019-02-13 08:31:24 +01:00
#include "gpu_regs.h"
#include "bg.h"
#include "menu.h"
#include "graphics.h"
2019-02-23 13:34:01 +01:00
#include "dma3.h"
#include "gba/macro.h"
2019-02-14 23:26:34 +01:00
#include "decompress.h"
#include "strings.h"
#include "constants/rgb.h"
2019-02-12 08:23:08 +01:00
2019-02-23 13:34:01 +01:00
enum
{
MODE_NORMAL, // Chosen from Start menu.
MODE_FORCE_CALL_1, // Used for the script's special. Has to choose Match Call and make a call.
MODE_FORCE_CALL_2, // Set after making a call, has to exit Pokenav.
};
enum
{
NAVMENU_CB_UNK_0,
NAVMENU_CB_UNK_1,
NAVMENU_CB_UNK_2,
NAVMENU_CB_UNK_3,
NAVMENU_CB_UNK_4,
NAVMENU_CB_UNK_5,
NAVMENU_CB_UNK_6
};
2019-04-07 07:32:42 +02:00
enum
{
NAVGEAR_GFX_MAIN_MENU,
NAVGEAR_GFX_CONDITION_MENU,
NAVGEAR_GFX_RIBBONS_MENU,
NAVGEAR_GFX_MATCH_CALL_MENU,
// One of these is for the zoomed-in map, and the other is for the
// zoomed-out map. Don't know which is which yet.
NAVGEAR_GFX_MAP_MENU_UNK0,
NAVGEAR_GFX_MAP_MENU_UNK1,
NAVGEAR_GFX_PARTY_MENU,
NAVGEAR_GFX_SEARCH_MENU,
NAVGEAR_GFX_COOL_MENU,
NAVGEAR_GFX_BEAUTY_MENU,
NAVGEAR_GFX_CUTE_MENU,
NAVGEAR_GFX_SMART_MENU,
NAVGEAR_GFX_TOUGH_MENU,
NAVGEAR_GFX_MENUS_END
};
#define NAVGEAR_GFX_SUBMENUS_START NAVGEAR_GFX_PARTY_MENU
2019-04-06 22:15:52 +02:00
// Return values of LoopedTask functions.
#define LT_INC_AND_PAUSE 0
2019-04-06 22:15:52 +02:00
#define LT_INC_AND_CONTINUE 1
#define LT_PAUSE 2
2019-04-06 22:15:52 +02:00
#define LT_CONTINUE 3
#define LT_FINISH 4
#define LT_SET_STATE(newState) (newState + 5)
#define LOOPED_TASK_DECODE_STATE(action) (action - 5)
#define LOOPED_TASK_ID(primary, secondary) (((secondary) << 16) |(primary))
#define LOOPED_TASK_PRIMARY_ID(taskId) (taskId & 0xFFFF)
#define LOOPED_TASK_SECONDARY_ID(taskId) (taskId >> 16)
#define UNKNOWN_OFFSET 100000
2019-04-06 22:15:52 +02:00
typedef u32 (*LoopedTask)(s32 state);
2019-02-24 05:17:26 +01:00
struct UnknownSubSubStruct_0203CF40 {
u8 bg;
u8 unk1;
u8 unk2;
u8 unk3;
2019-02-24 10:33:58 +01:00
u8 unk4;
u8 fontId;
2019-02-24 05:17:26 +01:00
u16 unk6;
2019-03-15 07:33:55 +01:00
u16 windowId;
2019-02-24 05:17:26 +01:00
u16 unkA;
u16 unkC;
u16 unkE;
2019-02-24 05:17:26 +01:00
};
2019-04-06 22:15:52 +02:00
struct MatchCallWindowState {
// The index of the element at the top of the window.
u16 windowTopIndex;
u16 listLength;
u16 unk4;
2019-04-06 22:15:52 +02:00
// The index of the cursor, relative to the top of the window.
u16 selectedIndexOffset;
u16 visibleEntries;
u16 unkA;
u32 unkC;
u32 unk10;
};
// Generally at index 0.
struct PokenavMainMenuResources
2019-02-23 13:34:01 +01:00
{
void (*unk0)(u32);
u32 (*unk4)(void);
u32 unk8;
2019-04-06 22:15:52 +02:00
u32 currentTaskId;
2019-02-23 13:34:01 +01:00
u32 unk10;
u32 unk14;
struct Sprite *spinningNavgear;
2019-04-07 07:32:42 +02:00
struct Sprite *leftHeaderSprites[2];
struct Sprite *submenuLeftHeaderSprites[2];
2019-02-24 05:17:26 +01:00
u8 tilemapBuffer[0x800];
};
struct UnknownInnerStruct_81C81D4
2019-02-24 05:17:26 +01:00
{
struct UnknownSubSubStruct_0203CF40 unk0;
u32 unk10;
u32 unk14;
u32 unk18;
u32 unk1C;
2019-02-25 07:02:16 +01:00
s32 unk20;
2019-02-27 08:11:45 +01:00
s32 unk24;
2019-02-24 10:33:58 +01:00
u32 unk28;
2019-02-25 07:02:16 +01:00
s32 unk2C;
2019-02-24 10:33:58 +01:00
u32 unk30;
void (*unk34)(u32, u8*);
2019-02-24 10:33:58 +01:00
void (*unk38)(u16, u32, u32);
struct Sprite *rightArrow;
struct Sprite *upArrow;
struct Sprite *downArrow;
u8 unkTextBuffer[0x40];
};
// Generally at index 0x11 (17)
struct UnknownSubStruct_81C81D4
{
struct UnknownInnerStruct_81C81D4 unk0;
u8 tilemapBuffer[0x800];
2019-04-06 22:15:52 +02:00
struct MatchCallWindowState unk888;
2019-02-27 08:11:45 +01:00
u32 unk89C;
u32 unk8A0;
2019-02-23 13:34:01 +01:00
};
#define SUBSTRUCT_COUNT 19
2019-04-06 22:15:52 +02:00
struct PokenavResources
2019-02-15 06:07:57 +01:00
{
u32 (*currentMenuCb1)(void);
u32 currentMenuIndex;
2019-02-23 13:34:01 +01:00
u16 mode;
2019-02-15 06:29:32 +01:00
u16 fieldA;
2019-02-23 13:34:01 +01:00
bool32 hasAnyRibbons;
2019-02-24 05:17:26 +01:00
void *field10[SUBSTRUCT_COUNT];
2019-02-13 04:35:07 +01:00
};
2019-04-07 07:32:42 +02:00
// This struct uses a 32bit tag, and doesn't have a size field.
// Needed to match LoadLeftHeaderGfxForSubMenu.
struct CompressedSpriteSheetNoSize
2019-03-16 00:33:30 +01:00
{
const u32 *data; // LZ77 compressed palette data
u32 tag;
};
2019-04-06 22:15:52 +02:00
struct MatchCallListTemplate
{
u32 unk0;
u16 unk4;
u16 unk6;
u8 unk8;
u8 unk9;
u8 unkA;
u8 unkB;
u8 unkC;
u8 unkD;
u8 unkE;
void (*unk10)(u32, u8 *a1);
void (*unk14)(u16 a0, u32 a1, u32 a2);
};
extern u32 sub_81C9430(void);
2019-02-13 06:07:48 +01:00
extern void sub_81CAADC(void);
extern u32 sub_81C99D4(void);
extern void InitHoenMapHeaderSprites(void);
extern u32 sub_81C9298(void);
extern u32 sub_81C941C(void);
extern u32 sub_81C9924(void);
extern u32 sub_81C99C0(void);
extern u32 sub_81C9990(void);
extern u32 sub_81C9940(void);
extern u32 sub_81C9338(void);
extern u32 sub_81C9368(void);
extern u32 sub_81C92CC(void);
extern u32 sub_81C9304(void);
extern u32 sub_81CC4D4(void);
extern u32 sub_81CC554(void);
extern u32 sub_81CC5F4(void);
extern u32 sub_81CC62C(void);
extern u32 sub_81CC65C(void);
extern u32 sub_81CC524(void);
extern u32 sub_81CC670(void);
extern u32 sub_81CCFD8(void);
extern u32 sub_81CD070(void);
extern u32 sub_81CDDD4(void);
extern u32 sub_81CDE2C(void);
extern u32 sub_81CDE64(void);
extern u32 sub_81CD1C0(void);
extern u32 sub_81CECA0(void);
extern u32 sub_81CEF3C(void);
extern u32 sub_81CEFDC(void);
extern u32 sub_81CF330(void);
extern u32 sub_81CF3A0(void);
extern u32 sub_81CF3D0(void);
extern u32 sub_81CEFF0(void);
extern u32 sub_81CF3F8(void);
extern u32 sub_81CD024(void);
extern u32 sub_81CEF98(void);
extern u32 sub_81CF368(void);
extern u32 sub_81CAAE8(void);
extern u32 sub_81CAB24(void);
extern u32 sub_81CB260(void);
extern u32 sub_81CB29C(void);
extern u32 sub_81CB2CC(void);
extern u32 sub_81CAB38(void);
extern u32 sub_81CB2E0(void);
extern u32 sub_81CF9BC(void);
extern u32 sub_81CFA34(void);
extern u32 sub_81CFDD0(void);
extern u32 sub_81CFE40(void);
extern u32 sub_81CFE70(void);
extern u32 sub_81CFA48(void);
extern u32 sub_81CFE98(void);
extern u32 sub_81D0450(void);
extern u32 sub_81D04A0(void);
extern u32 sub_81D0978(void);
extern u32 sub_81D09B0(void);
extern u32 sub_81D09E0(void);
extern u32 sub_81D04B8(void);
extern u32 sub_81D09F4(void);
extern u32 sub_81CFA04(void);
extern u32 sub_81CFE08(void);
extern void SpriteCB_SpinningNavgear(struct Sprite* sprite);
extern void sub_81CBD48(u16 windowId, u32 a1);
extern u8 *sub_81CAFD8(u16 a0, u32 a1);
extern void sub_81DB620(u32 windowId, u32 a1, u32 a2, u32 a3, u32 a4);
2019-04-06 22:15:52 +02:00
u32 sub_81C91AC(struct UnknownInnerStruct_81C81D4 *a0, const struct BgTemplate *a1, struct MatchCallListTemplate *a2, s32 a3);
void sub_81C9160(struct MatchCallWindowState *a0, struct MatchCallListTemplate *a1);
void SpriteCB_MatchCallUpArrow(struct Sprite *sprite);
void SpriteCB_MatchCallDownArrow(struct Sprite *sprite);
void SpriteCB_MatchCallRightArrow(struct Sprite *sprite);
void ToggleMatchCallArrows(struct UnknownInnerStruct_81C81D4 *a0, u32 a1);
void sub_81C8FE0(struct UnknownInnerStruct_81C81D4 *a0);
2019-04-06 22:15:52 +02:00
void sub_81C8EF8(struct MatchCallWindowState *a0, struct UnknownInnerStruct_81C81D4 *a1);
void sub_81C8ED0(void);
2019-04-06 22:15:52 +02:00
void sub_81C8E54(struct MatchCallWindowState *a0, struct UnknownInnerStruct_81C81D4 *a1, u32 a2);
void PrintMatchCallFieldNames(struct UnknownInnerStruct_81C81D4 *a0, u32 a1);
2019-04-06 22:15:52 +02:00
void sub_81C8D4C(struct MatchCallWindowState *a0, struct UnknownInnerStruct_81C81D4 *a1);
void sub_81C8CB4(struct MatchCallWindowState *a0, struct UnknownInnerStruct_81C81D4 *a1);
void sub_81C8B70(struct UnknownSubSubStruct_0203CF40 *a0, u32 a1, u32 a2);
2019-04-06 22:15:52 +02:00
u32 LoopedTask_sub_81C8A28(s32 a0);
u32 LoopedTask_sub_81C8958(s32 a0);
u32 LoopedTask_sub_81C8870(s32 a0);
u32 LoopedTask_sub_81C85A0(s32 a0);
void sub_81C8568(s32 a0, struct UnknownInnerStruct_81C81D4 *a1);
2019-04-06 22:15:52 +02:00
u32 LoopedTask_sub_81C83F0(s32 a0);
2019-02-27 08:11:45 +01:00
bool32 sub_81C83E0(void);
void sub_81C83AC(u32 a0, u32 a1, u32 a2, u32 a3, u32 a4, struct UnknownInnerStruct_81C81D4 *a5);
2019-04-06 22:15:52 +02:00
void sub_81C837C(struct MatchCallWindowState *a0, struct UnknownInnerStruct_81C81D4 *a1);
void sub_81C835C(struct UnknownSubSubStruct_0203CF40 *a0);
void sub_81C82E4(struct UnknownSubStruct_81C81D4 *a0);
2019-04-06 22:15:52 +02:00
u32 LoopedTask_sub_81C8254(s32 a0);
u32 LoopedTask_ScrollMenuHeaderUp(s32 a0);
bool32 SetActivePokenavMenu(u32 a0);
bool32 InitPokenavMainMenu(void);
2019-02-23 13:34:01 +01:00
static bool32 AnyMonHasRibbon(void);
2019-02-13 03:33:15 +01:00
u32 sub_81C75E0(void);
u32 sub_81C75D4(void);
u32 PokenavMainMenuLoopedTaskIsActive(void);
u32 sub_81C786C(void);
u32 LoopedTask_InitPokenavMenu(s32 a0);
u32 LoopedTask_ScrollMenuHeaderDown(s32 a0);
bool32 WaitForPokenavShutdownFade(void);
2019-02-15 06:00:01 +01:00
void CopyPaletteIntoBufferUnfaded(const u16 *palette, u32 a1, u32 a2);
2019-02-23 13:34:01 +01:00
void sub_81C7834(void *func1, void *func2);
static void InitPokenavResources(struct PokenavResources *a0);
void FreePokenavSubstruct(u32 index);
void sub_81C7850(u32 a0);
2019-02-14 23:26:34 +01:00
void sub_81C7BF8(u32 a0);
2019-04-06 22:15:52 +02:00
void Task_RunLoopedTask_LinkMode(u8 a0);
void Task_RunLoopedTask(u8 taskId);
2019-02-13 04:18:12 +01:00
void sub_81C742C(u8 taskId);
void ShutdownPokenav(void);
2019-02-23 13:34:01 +01:00
static void InitKeys_(void);
static void FreePokenavResources(void);
2019-04-06 22:15:52 +02:00
static void VBlankCB_Pokenav(void);
2019-03-02 09:18:08 +01:00
static void CB2_Pokenav(void);
void InitPokenavMainMenuResources(void);
2019-02-12 08:23:08 +01:00
void sub_81C72BC(void);
void sub_81C7B74(void);
void CleanupPokenavMainMenuResources(void);
2019-04-07 07:32:42 +02:00
void LoadLeftHeaderGfxForSubMenu(u32 arg0);
void LoadLeftHeaderGfxForMenu(u32 arg0);
void HideLeftHeaderSubmenuSprites(bool32 arg0);
void HideLeftHeaderSprites(bool32 arg0);
void ShowLeftHeaderSprites(u32 arg0, bool32 arg1);
void ShowLeftHeaderSubmenuSprites(u32 arg0, bool32 arg1);
void MoveLeftHeader(struct Sprite *sprite, s32 arg1, s32 arg2, s32 arg3);
void SpriteCB_MoveLeftHeader(struct Sprite *sprite);
2019-02-23 13:34:01 +01:00
// Const rom data.
u32 (*const PokenavMenuCallbacks[15][7])(void) =
{
2019-02-15 06:29:32 +01:00
{
sub_81C9298,
2019-02-15 06:29:32 +01:00
sub_81C941C,
sub_81C9924,
sub_81C9990,
sub_81C99C0,
sub_81C9430,
sub_81C99D4,
},
{
sub_81C9298,
sub_81C941C,
sub_81C9940,
sub_81C9990,
sub_81C99C0,
sub_81C9430,
sub_81C99D4,
},
{
sub_81C9338,
sub_81C941C,
sub_81C9940,
sub_81C9990,
sub_81C99C0,
sub_81C9430,
sub_81C99D4,
},
{
sub_81C9368,
sub_81C941C,
sub_81C9940,
sub_81C9990,
sub_81C99C0,
sub_81C9430,
sub_81C99D4,
},
{
sub_81C92CC,
sub_81C941C,
sub_81C9940,
sub_81C9990,
sub_81C99C0,
sub_81C9430,
sub_81C99D4,
},
{
sub_81C9304,
sub_81C941C,
sub_81C9940,
sub_81C9990,
sub_81C99C0,
sub_81C9430,
sub_81C99D4,
},
{
sub_81CC4D4,
sub_81CC554,
sub_81CC5F4,
sub_81CC62C,
sub_81CC65C,
sub_81CC524,
sub_81CC670,
},
{
sub_81CCFD8,
sub_81CD070,
sub_81CDDD4,
sub_81CDE2C,
sub_81CDE64,
sub_81CD1C0,
sub_81CECA0,
},
{
sub_81CEF3C,
sub_81CEFDC,
sub_81CF330,
sub_81CF3A0,
sub_81CF3D0,
sub_81CEFF0,
sub_81CF3F8,
},
{
sub_81CD024,
sub_81CD070,
sub_81CDDD4,
sub_81CDE2C,
sub_81CDE64,
sub_81CD1C0,
sub_81CECA0,
},
{
sub_81CEF98,
sub_81CEFDC,
sub_81CF368,
sub_81CF3A0,
sub_81CF3D0,
sub_81CEFF0,
sub_81CF3F8,
},
{
sub_81CAAE8,
sub_81CAB24,
sub_81CB260,
sub_81CB29C,
sub_81CB2CC,
sub_81CAB38,
sub_81CB2E0,
},
{
sub_81CF9BC,
sub_81CFA34,
sub_81CFDD0,
sub_81CFE40,
sub_81CFE70,
sub_81CFA48,
sub_81CFE98,
},
{
sub_81D0450,
sub_81D04A0,
sub_81D0978,
sub_81D09B0,
sub_81D09E0,
sub_81D04B8,
sub_81D09F4,
},
{
sub_81CFA04,
sub_81CFA34,
sub_81CFE08,
sub_81CFE40,
sub_81CFE70,
sub_81CFA48,
sub_81CFE98,
},
};
const u16 gSpinningNavgearPaletteData[] = INCBIN_U16("graphics/pokenav/icon2.gbapal");
const u32 gSpinningNavgearGfx[] = INCBIN_U32("graphics/pokenav/icon2.4bpp.lz");
const u32 gUnused_SpinningNavgearGfx2[] = INCBIN_U32("graphics/pokenav/icon2_unused.4bpp.lz");
const struct BgTemplate gPokenavMainMenuBgTemplates[] =
2019-02-15 06:07:57 +01:00
{
2019-02-23 13:34:01 +01:00
{
.bg = 0,
.charBaseIndex = 0,
.mapBaseIndex = 5,
.screenSize = 0,
.paletteMode = 0,
.priority = 0,
.baseTile = 0,
}
};
2019-02-15 06:07:57 +01:00
const struct WindowTemplate gUnknown_0861FA08[2] =
{
2019-02-15 06:29:32 +01:00
{
.bg = 0,
.tilemapLeft = 1,
.tilemapTop = 22,
.width = 16,
.height = 2,
2019-02-15 06:29:32 +01:00
.paletteNum = 0,
.baseBlock = 0x36,
},
{
.bg = 0xFF,
.tilemapLeft = 0,
.tilemapTop = 0,
.width = 0,
.height = 0,
.paletteNum = 0,
.baseBlock = 0,
},
};
2019-02-23 13:34:01 +01:00
const u8 *const (sMenuButtonReminders[12]) =
2019-02-15 06:07:57 +01:00
{
2019-02-15 06:29:32 +01:00
gText_Navgear_ClearButtonList,
gText_NavgearMap_ZoomedOutButtons,
gText_NavgearMap_ZoomedInButtons,
gText_NavgearCondition_MonListButtons,
gText_NavgearCondition_MonStatusButtons,
gText_NavgearCondition_MarkingButtons,
gText_NavgearMatchCall_TrainerListButtons,
gText_NavgearMatchCall_CallMenuButtons,
gText_NavgearMatchCall_CheckTrainerButtons,
gText_NavgearRibbons_MonListButtons,
gText_NavgearRibbons_RibbonListButtons,
gText_NavgearRibbons_RibbonCheckButtons,
};
2019-02-15 06:07:57 +01:00
const u8 gMenuButtonReminderColor[4] =
{
2019-02-15 06:29:32 +01:00
4, 1, 2, 0
};
static const struct CompressedSpriteSheet gSpinningNavgearSpriteSheet[] =
2019-02-15 06:07:57 +01:00
{
2019-02-15 06:29:32 +01:00
{
.data = gSpinningNavgearGfx,
2019-02-15 06:29:32 +01:00
.size = 0x1000,
.tag = 0,
}
};
static const struct SpritePalette gSpinningNavgearPalette[] =
2019-02-15 06:07:57 +01:00
{
2019-02-15 06:29:32 +01:00
{
.data = gSpinningNavgearPaletteData,
2019-02-15 06:29:32 +01:00
.tag = 0,
},
2019-03-16 00:33:30 +01:00
{}
2019-02-15 06:00:01 +01:00
};
static const struct CompressedSpriteSheet sPokenavHoenMapLeftHeaderSpriteSheet =
2019-02-15 06:07:57 +01:00
{
2019-02-15 06:29:32 +01:00
.data = gPokenavLeftHeaderHoennMap_Gfx,
.size = 0xC00,
.tag = 2
2019-02-15 06:00:01 +01:00
};
2019-04-07 07:32:42 +02:00
static const struct CompressedSpriteSheet sPokenavMenuLeftHeaderSpriteSheets[] =
2019-03-16 00:33:30 +01:00
{
2019-04-07 07:32:42 +02:00
[NAVGEAR_GFX_MAIN_MENU] = {
2019-03-16 00:33:30 +01:00
.data = gPokenavLeftHeaderMainMenu_Gfx,
.size = 0x20,
.tag = 3
},
2019-04-07 07:32:42 +02:00
[NAVGEAR_GFX_CONDITION_MENU] = {
2019-03-16 00:33:30 +01:00
.data = gPokenavLeftHeaderCondition_Gfx,
.size = 0x20,
.tag = 1
},
2019-04-07 07:32:42 +02:00
[NAVGEAR_GFX_RIBBONS_MENU] = {
2019-03-16 00:33:30 +01:00
.data = gPokenavLeftHeaderRibbons_Gfx,
.size = 0x20,
.tag = 2
},
2019-04-07 07:32:42 +02:00
[NAVGEAR_GFX_MATCH_CALL_MENU] = {
2019-03-16 00:33:30 +01:00
.data = gPokenavLeftHeaderMatchCall_Gfx,
.size = 0x20,
.tag = 4
},
2019-04-07 07:32:42 +02:00
[NAVGEAR_GFX_MAP_MENU_UNK0] = {
2019-03-16 00:33:30 +01:00
.data = gPokenavLeftHeaderHoennMap_Gfx,
.size = 0x20,
.tag = 0
},
2019-04-07 07:32:42 +02:00
[NAVGEAR_GFX_MAP_MENU_UNK1] = {
2019-03-16 00:33:30 +01:00
.data = gPokenavLeftHeaderHoennMap_Gfx,
.size = 0x40,
.tag = 0
}
};
2019-04-07 07:32:42 +02:00
static const struct CompressedSpriteSheetNoSize sPokenavSubMenuLeftHeaderSpriteSheets[] =
2019-03-16 00:33:30 +01:00
{
2019-04-07 07:32:42 +02:00
[NAVGEAR_GFX_PARTY_MENU - NAVGEAR_GFX_SUBMENUS_START] = {
2019-03-16 00:33:30 +01:00
.data = gPokenavLeftHeaderParty_Gfx,
.tag = 1
},
2019-04-07 07:32:42 +02:00
[NAVGEAR_GFX_SEARCH_MENU - NAVGEAR_GFX_SUBMENUS_START] = {
2019-03-16 00:33:30 +01:00
.data = gPokenavLeftHeaderSearch_Gfx,
.tag = 1
},
2019-04-07 07:32:42 +02:00
[NAVGEAR_GFX_COOL_MENU - NAVGEAR_GFX_SUBMENUS_START] = {
2019-03-16 00:33:30 +01:00
.data = gPokenavLeftHeaderCool_Gfx,
.tag = 4
},
2019-04-07 07:32:42 +02:00
[NAVGEAR_GFX_BEAUTY_MENU - NAVGEAR_GFX_SUBMENUS_START] = {
2019-03-16 00:33:30 +01:00
.data = gPokenavLeftHeaderBeauty_Gfx,
.tag = 1
},
2019-04-07 07:32:42 +02:00
[NAVGEAR_GFX_CUTE_MENU - NAVGEAR_GFX_SUBMENUS_START] = {
2019-03-16 00:33:30 +01:00
.data = gPokenavLeftHeaderCute_Gfx,
.tag = 2
},
2019-04-07 07:32:42 +02:00
[NAVGEAR_GFX_SMART_MENU - NAVGEAR_GFX_SUBMENUS_START] = {
2019-03-16 00:33:30 +01:00
.data = gPokenavLeftHeaderSmart_Gfx,
.tag = 0
},
2019-04-07 07:32:42 +02:00
[NAVGEAR_GFX_TOUGH_MENU - NAVGEAR_GFX_SUBMENUS_START] = {
2019-03-16 00:33:30 +01:00
.data = gPokenavLeftHeaderTough_Gfx,
.tag = 0
}
};
static const struct OamData sSpinningNavgearSpriteOam =
2019-03-16 00:33:30 +01:00
{
.y = 0,
.affineMode = 0,
.objMode = 0,
.mosaic = 0,
.bpp = 0,
.shape = 0, // FIXME: Use SPRITE_SHAPE
.x = 0,
.matrixNum = 0,
.size = 2, // FIXME: Use SPRITE_SIZE
.tileNum = 0,
.priority = 0,
.paletteNum = 0,
.affineParam = 0
};
2019-04-07 07:32:42 +02:00
static const union AnimCmd sSpinningNavgearAnims[] =
2019-03-16 00:33:30 +01:00
{
ANIMCMD_FRAME(0, 8),
ANIMCMD_FRAME(16, 8),
ANIMCMD_FRAME(32, 8),
ANIMCMD_FRAME(48, 8),
ANIMCMD_FRAME(64, 8),
ANIMCMD_FRAME(80, 8),
ANIMCMD_FRAME(96, 8),
ANIMCMD_FRAME(112, 8),
ANIMCMD_JUMP(0)
};
2019-04-07 07:32:42 +02:00
static const union AnimCmd *const sSpinningNavgearAnimTable[] =
2019-03-16 00:33:30 +01:00
{
2019-04-07 07:32:42 +02:00
sSpinningNavgearAnims
2019-03-16 00:33:30 +01:00
};
static const struct SpriteTemplate sSpinningNavgearSpriteTemplate =
2019-03-16 00:33:30 +01:00
{
.tileTag = 0,
.paletteTag = 0,
.oam = &sSpinningNavgearSpriteOam,
2019-04-07 07:32:42 +02:00
.anims = sSpinningNavgearAnimTable,
2019-03-16 00:33:30 +01:00
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = SpriteCB_SpinningNavgear
2019-03-16 00:33:30 +01:00
};
static const struct OamData sPokenavLeftHeaderHoenMapSpriteOam =
2019-03-16 00:33:30 +01:00
{
.y = 0,
.affineMode = 0,
.objMode = 0,
.mosaic = 0,
.bpp = 0,
.shape = 1,
.x = 0,
.matrixNum = 0,
.size = 3,
.tileNum = 0,
.priority = 1,
.paletteNum = 0,
.affineParam = 0
};
static const struct OamData sUnknown_0861FB24 =
{
.y = 0,
.affineMode = 0,
.objMode = 0,
.mosaic = 0,
.bpp = 0,
.shape = 1,
.x = 0,
.matrixNum = 0,
.size = 2,
.tileNum = 0,
.priority = 1,
.paletteNum = 0,
.affineParam = 0
};
static const struct SpriteTemplate sPokenavLeftHeaderHoenMapSpriteTemplate =
2019-03-16 00:33:30 +01:00
{
.tileTag = 2,
.paletteTag = 1,
.oam = &sPokenavLeftHeaderHoenMapSpriteOam,
2019-03-16 00:33:30 +01:00
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = SpriteCallbackDummy
};
static const struct SpriteTemplate sUnknown_0861FB44 =
{
.tileTag = 2,
.paletteTag = 2,
.oam = &sUnknown_0861FB24,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = SpriteCallbackDummy
};
static const u16 sMatchcallArrowPaletteData[] = INCBIN_U16("graphics/pokenav/arrows_matchcall.gbapal");
static const u32 sMatchcallArrowSpriteSheetData[] = INCBIN_U32("graphics/pokenav/arrows_matchcall.4bpp.lz");
static const u8 sPokenavColors_0861FBE4[] =
{
0, 2, 5
};
static const u8 *const sMatchCallFieldNames[] =
{
gText_NavgearMatchCall_Strategy,
gText_NavgearMatchCall_TrainerPokemon,
gText_NavgearMatchCall_SelfIntroduction
};
static const u8 sMatchCallFieldColors[] =
{
1, 4, 5
};
static const u8 sUnknown_0861FBF7[] =
{
2, 4, 6, 7, 0
};
static const struct CompressedSpriteSheet sMatchcallArrowSpriteSheet[] =
{
{
.data = sMatchcallArrowSpriteSheetData,
.size = 192,
.tag = 0xA
}
};
static const struct SpritePalette sMatchcallArrowPalette[] =
{
{
.data = sMatchcallArrowPaletteData,
.tag = 0x14
},
{}
};
static const struct OamData sMatchCallRightArrowSpriteOam =
{
.y = 0,
.affineMode = ST_OAM_AFFINE_OFF,
.objMode = ST_OAM_OBJ_NORMAL,
.bpp = ST_OAM_4BPP,
.shape = 2, //SPRITE_SHAPE(16x8),
.x = 0,
.size = 0, //SPRITE_SIZE(16x8),
.tileNum = 0,
.priority = 2,
.paletteNum = 0
};
static const struct SpriteTemplate sMatchCallRightArrowSprite =
{
.tileTag = 0xA,
.paletteTag = 0x14,
.oam = &sMatchCallRightArrowSpriteOam,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = SpriteCB_MatchCallRightArrow
};
static const struct OamData sMatchCallUpDownArrowSpriteOam =
{
.y = 0,
.affineMode = ST_OAM_AFFINE_OFF,
.objMode = ST_OAM_OBJ_NORMAL,
.bpp = ST_OAM_4BPP,
.shape = 1, //SPRITE_SHAPE(8x16),
.x = 0,
.size = 0, //SPRITE_SIZE(8x16),
.tileNum = 0,
.priority = 2,
.paletteNum = 0
};
static const struct SpriteTemplate sMatchCallUpDownArrowSprite =
{
.tileTag = 0xA,
.paletteTag = 0x14,
.oam = &sMatchCallUpDownArrowSpriteOam,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = SpriteCallbackDummy
};
2019-04-06 22:15:52 +02:00
EWRAM_DATA u8 gNextLoopedTaskId = 0;
EWRAM_DATA struct PokenavResources *gPokenavResources = NULL;
2019-03-16 00:33:30 +01:00
EWRAM_DATA u32 gUnknown_0203CF44 = 0;
2019-02-23 13:34:01 +01:00
// code
2019-04-06 22:15:52 +02:00
u32 CreateLoopedTask(LoopedTask loopedTask, u32 priority)
2019-02-11 20:59:44 +01:00
{
u16 taskId;
if (!IsUpdateLinkStateCBActive())
2019-04-06 22:15:52 +02:00
taskId = CreateTask(Task_RunLoopedTask, priority);
2019-02-15 06:29:32 +01:00
else
2019-04-06 22:15:52 +02:00
taskId = CreateTask(Task_RunLoopedTask_LinkMode, priority);
2019-02-11 20:59:44 +01:00
2019-04-06 22:15:52 +02:00
SetWordTaskArg(taskId, 1, (u32)loopedTask);
2019-02-11 20:59:44 +01:00
2019-04-06 22:15:52 +02:00
gTasks[taskId].data[3] = gNextLoopedTaskId;
return LOOPED_TASK_ID(taskId, gNextLoopedTaskId++);
2019-02-11 20:59:44 +01:00
}
2019-04-06 22:15:52 +02:00
bool32 IsLoopedTaskActive(u32 taskId)
2019-02-11 22:35:02 +01:00
{
2019-04-06 22:15:52 +02:00
u32 primaryId = LOOPED_TASK_PRIMARY_ID(taskId);
u32 secondaryId = LOOPED_TASK_SECONDARY_ID(taskId);
2019-02-23 13:34:01 +01:00
2019-04-06 22:15:52 +02:00
if (gTasks[primaryId].isActive
&& (gTasks[primaryId].func == Task_RunLoopedTask || gTasks[primaryId].func == Task_RunLoopedTask_LinkMode)
&& gTasks[primaryId].data[3] == secondaryId)
2019-02-15 06:29:32 +01:00
return TRUE;
else
return FALSE;
2019-02-11 22:06:46 +01:00
}
2019-04-06 22:15:52 +02:00
bool32 FuncIsActiveLoopedTask(LoopedTask func)
2019-02-11 22:35:02 +01:00
{
2019-02-15 06:29:32 +01:00
s32 i;
2019-02-23 13:34:01 +01:00
for (i = 0; i < NUM_TASKS; i++)
2019-02-15 06:29:32 +01:00
{
if (gTasks[i].isActive
2019-04-06 22:15:52 +02:00
&& (gTasks[i].func == Task_RunLoopedTask || gTasks[i].func == Task_RunLoopedTask_LinkMode)
&& (LoopedTask)GetWordTaskArg(i, 1) == func)
2019-02-23 13:34:01 +01:00
return TRUE;
2019-02-15 06:29:32 +01:00
}
return FALSE;
2019-02-12 06:51:54 +01:00
}
2019-04-06 22:15:52 +02:00
void Task_RunLoopedTask(u8 taskId)
2019-02-12 06:51:54 +01:00
{
2019-04-06 22:15:52 +02:00
LoopedTask loopedTask = (LoopedTask)GetWordTaskArg(taskId, 1);
s16 *state = &gTasks[taskId].data[0];
2019-02-23 13:34:01 +01:00
bool32 exitLoop = FALSE;
2019-02-15 06:29:32 +01:00
while (!exitLoop)
{
2019-04-06 22:15:52 +02:00
u32 action = loopedTask(*state);
switch (action)
2019-02-16 18:09:27 +01:00
{
2019-04-06 22:15:52 +02:00
case LT_INC_AND_CONTINUE:
(*state)++;
2019-02-15 06:29:32 +01:00
break;
case LT_INC_AND_PAUSE:
2019-04-06 22:15:52 +02:00
(*state)++;
2019-02-15 06:29:32 +01:00
return;
2019-04-06 22:15:52 +02:00
case LT_FINISH:
2019-02-15 06:29:32 +01:00
DestroyTask(taskId);
return;
2019-04-06 22:15:52 +02:00
// case LT_SET_STATE:
2019-02-15 06:29:32 +01:00
default:
2019-04-06 22:15:52 +02:00
*state = LOOPED_TASK_DECODE_STATE(action);
2019-02-15 06:29:32 +01:00
break;
2019-04-06 22:15:52 +02:00
case LT_CONTINUE:
2019-02-15 06:29:32 +01:00
break;
case LT_PAUSE:
2019-02-15 06:29:32 +01:00
return;
}
}
2019-02-12 07:30:39 +01:00
}
// Every "Continue" action pauses instead.
2019-04-06 22:15:52 +02:00
void Task_RunLoopedTask_LinkMode(u8 taskId)
2019-02-15 06:07:57 +01:00
{
2019-04-06 22:15:52 +02:00
LoopedTask task;
s16 *state;
u32 action;
2019-02-15 06:29:32 +01:00
if (sub_8087598())
return;
2019-04-06 22:15:52 +02:00
task = (LoopedTask)GetWordTaskArg(taskId, 1);
state = &gTasks[taskId].data[0];
action = task(*state);
switch (action)
{
case LT_INC_AND_PAUSE:
2019-04-06 22:15:52 +02:00
case LT_INC_AND_CONTINUE:
(*state)++;
2019-02-16 18:09:27 +01:00
break;
2019-04-06 22:15:52 +02:00
case LT_FINISH:
2019-02-16 18:09:27 +01:00
DestroyTask(taskId);
break;
2019-04-06 22:15:52 +02:00
// case: LT_SET_STATE:
2019-02-16 18:09:27 +01:00
default:
2019-04-06 22:15:52 +02:00
*state = LOOPED_TASK_DECODE_STATE(action);
2019-02-16 18:09:27 +01:00
break;
case LT_PAUSE:
2019-04-06 22:15:52 +02:00
case LT_CONTINUE:
break;
2019-02-15 06:29:32 +01:00
}
2019-02-12 07:34:43 +01:00
}
2019-03-02 09:18:08 +01:00
void CB2_InitPokeNav(void)
2019-02-12 07:34:43 +01:00
{
2019-04-06 22:15:52 +02:00
gPokenavResources = Alloc(sizeof(*gPokenavResources));
if (gPokenavResources == NULL)
{
2019-02-12 07:34:43 +01:00
SetMainCallback2(CB2_ReturnToFieldWithOpenMenu);
}
2019-02-16 18:09:27 +01:00
else
{
InitPokenavResources(gPokenavResources);
2019-02-12 07:34:43 +01:00
ResetTasks();
SetVBlankCallback(NULL);
CreateTask(sub_81C742C, 0);
2019-03-02 09:18:08 +01:00
SetMainCallback2(CB2_Pokenav);
2019-04-06 22:15:52 +02:00
SetVBlankCallback(VBlankCB_Pokenav);
2019-02-12 07:34:43 +01:00
}
2019-02-12 07:39:27 +01:00
}
2019-02-23 13:34:01 +01:00
void sub_81C72A4(void)
2019-02-15 06:07:57 +01:00
{
2019-02-15 06:29:32 +01:00
SetMainCallback2(sub_81C72BC);
FadeScreen(1, 0);
2019-02-12 08:23:08 +01:00
}
2019-02-23 13:34:01 +01:00
void sub_81C72BC(void)
2019-02-15 06:07:57 +01:00
{
2019-02-15 06:29:32 +01:00
UpdatePaletteFade();
2019-02-23 13:34:01 +01:00
if (gPaletteFade.active)
return;
2019-04-06 22:15:52 +02:00
gPokenavResources = Alloc(sizeof(*gPokenavResources));
if (gPokenavResources == NULL)
2019-02-15 06:29:32 +01:00
{
2019-02-23 13:34:01 +01:00
SetMainCallback2(CB2_ReturnToFieldContinueScriptPlayMapMusic);
}
else
{
InitPokenavResources(gPokenavResources);
2019-04-06 22:15:52 +02:00
gPokenavResources->mode = MODE_FORCE_CALL_1;
2019-02-23 13:34:01 +01:00
ResetTasks();
ResetSpriteData();
FreeAllSpritePalettes();
SetVBlankCallback(NULL);
CreateTask(sub_81C742C, 0);
2019-03-02 09:18:08 +01:00
SetMainCallback2(CB2_Pokenav);
2019-04-06 22:15:52 +02:00
SetVBlankCallback(VBlankCB_Pokenav);
2019-02-15 06:29:32 +01:00
}
2019-02-12 08:28:46 +01:00
}
static void FreePokenavResources(void)
2019-02-15 06:07:57 +01:00
{
2019-02-15 06:29:32 +01:00
s32 i;
2019-02-12 08:28:46 +01:00
2019-02-23 13:34:01 +01:00
for (i = 0; i < SUBSTRUCT_COUNT; i++)
FreePokenavSubstruct(i);
2019-02-23 13:34:01 +01:00
2019-04-06 22:15:52 +02:00
FREE_AND_SET_NULL(gPokenavResources);
2019-02-15 06:29:32 +01:00
InitKeys();
2019-02-12 08:59:17 +01:00
}
static void InitPokenavResources(struct PokenavResources *a0)
2019-02-15 06:07:57 +01:00
{
2019-02-15 06:29:32 +01:00
s32 i;
2019-02-23 13:34:01 +01:00
for (i = 0; i < SUBSTRUCT_COUNT; i++)
a0->field10[i] = NULL;
a0->mode = MODE_NORMAL;
a0->currentMenuIndex = 0;
2019-02-23 13:34:01 +01:00
a0->hasAnyRibbons = AnyMonHasRibbon();
a0->currentMenuCb1 = NULL;
2019-02-12 09:48:32 +01:00
}
2019-02-23 13:34:01 +01:00
static bool32 AnyMonHasRibbon(void)
2019-02-15 06:07:57 +01:00
{
2019-02-23 13:34:01 +01:00
s32 i, j;
2019-02-15 06:29:32 +01:00
for (i = 0; i < PARTY_SIZE; i++)
2019-02-15 06:29:32 +01:00
{
if (GetMonData(&gPlayerParty[i], MON_DATA_SANITY_HAS_SPECIES)
&& !GetMonData(&gPlayerParty[i], MON_DATA_SANITY_IS_EGG)
&& GetMonData(&gPlayerParty[i], MON_DATA_RIBBON_COUNT) != 0)
{
return TRUE;
}
}
for (j = 0; j < TOTAL_BOXES_COUNT; j++)
2019-02-15 06:29:32 +01:00
{
2019-02-23 13:34:01 +01:00
for (i = 0; i < IN_BOX_COUNT; i++)
2019-02-15 06:29:32 +01:00
{
if (CheckBoxMonSanityAt(j, i)
&& GetBoxMonDataAt(j, i, MON_DATA_RIBBON_COUNT) != 0)
{
return TRUE;
}
}
}
return FALSE;
2019-02-12 09:51:48 +01:00
}
2019-03-02 09:18:08 +01:00
static void CB2_Pokenav(void)
2019-02-15 06:07:57 +01:00
{
2019-02-15 06:29:32 +01:00
RunTasks();
AnimateSprites();
BuildOamBuffer();
UpdatePaletteFade();
2019-02-12 09:54:35 +01:00
}
2019-04-06 22:15:52 +02:00
static void VBlankCB_Pokenav(void)
2019-02-15 06:07:57 +01:00
{
2019-02-15 06:29:32 +01:00
TransferPlttBuffer();
LoadOam();
ProcessSpriteCopyRequests();
2019-02-13 02:20:15 +01:00
}
2019-02-15 06:07:57 +01:00
void sub_81C742C(u8 taskId)
{
2019-02-15 06:29:32 +01:00
u32 v1;
2019-02-23 13:34:01 +01:00
s16 *data = gTasks[taskId].data;
2019-02-15 06:29:32 +01:00
2019-02-23 13:34:01 +01:00
switch (data[0])
2019-02-15 06:29:32 +01:00
{
case 0:
InitPokenavMainMenu();
2019-02-23 13:34:01 +01:00
data[0] = 1;
2019-02-15 06:29:32 +01:00
break;
case 1:
// Wait for LoopedTask_InitPokenavMenu to finish
if (PokenavMainMenuLoopedTaskIsActive())
2019-02-15 06:29:32 +01:00
break;
SetActivePokenavMenu(0 + UNKNOWN_OFFSET);
2019-02-23 13:34:01 +01:00
data[0] = 4;
2019-02-15 06:29:32 +01:00
break;
case 2:
if (sub_81C786C())
break;
2019-02-23 13:34:01 +01:00
data[0] = 3;
2019-02-15 06:29:32 +01:00
case 3:
v1 = sub_81C75E0();
if (v1 == -1)
{
ShutdownPokenav();
2019-02-23 13:34:01 +01:00
data[0] = 5;
2019-02-15 06:29:32 +01:00
}
else if (v1 >= UNKNOWN_OFFSET)
{
PokenavMenuCallbacks[gPokenavResources->currentMenuIndex][NAVMENU_CB_UNK_6]();
PokenavMenuCallbacks[gPokenavResources->currentMenuIndex][NAVMENU_CB_UNK_5]();
if (SetActivePokenavMenu(v1))
{
2019-02-23 13:34:01 +01:00
data[0] = 4;
}
2019-02-15 06:29:32 +01:00
else
{
ShutdownPokenav();
2019-02-23 13:34:01 +01:00
data[0] = 5;
2019-02-15 06:29:32 +01:00
}
}
else if (v1 != 0)
{
sub_81C7850(v1);
if (sub_81C786C())
2019-02-23 13:34:01 +01:00
data[0] = 2;
2019-02-15 06:29:32 +01:00
}
break;
case 4:
if (!sub_81C75D4())
2019-02-23 13:34:01 +01:00
data[0] = 3;
2019-02-15 06:29:32 +01:00
break;
case 5:
if (!WaitForPokenavShutdownFade())
2019-02-15 06:29:32 +01:00
{
2019-04-06 22:15:52 +02:00
bool32 calledFromScript = (gPokenavResources->mode != MODE_NORMAL);
2019-02-23 13:34:01 +01:00
2019-02-15 06:29:32 +01:00
sub_81C9430();
FreePokenavResources();
2019-02-23 13:34:01 +01:00
if (calledFromScript)
2019-02-15 06:29:32 +01:00
SetMainCallback2(CB2_ReturnToFieldContinueScriptPlayMapMusic);
else
SetMainCallback2(CB2_ReturnToFieldWithOpenMenu);
}
break;
2019-02-15 06:29:32 +01:00
}
}
bool32 SetActivePokenavMenu(u32 indexWithOffset)
2019-02-15 06:07:57 +01:00
{
u32 index = indexWithOffset - UNKNOWN_OFFSET;
2019-02-15 06:29:32 +01:00
2019-02-23 13:34:01 +01:00
InitKeys_();
if (!PokenavMenuCallbacks[index][NAVMENU_CB_UNK_0]())
2019-02-15 06:29:32 +01:00
return FALSE;
if (!PokenavMenuCallbacks[index][NAVMENU_CB_UNK_2]())
2019-02-15 06:29:32 +01:00
return FALSE;
2019-02-23 13:34:01 +01:00
sub_81C7834(PokenavMenuCallbacks[index][NAVMENU_CB_UNK_3], PokenavMenuCallbacks[index][NAVMENU_CB_UNK_4]);
gPokenavResources->currentMenuCb1 = PokenavMenuCallbacks[index][NAVMENU_CB_UNK_1];
gPokenavResources->currentMenuIndex = index;
2019-02-15 06:29:32 +01:00
return TRUE;
2019-02-13 03:33:15 +01:00
}
2019-02-15 06:07:57 +01:00
u32 sub_81C75D4(void)
{
2019-02-15 06:29:32 +01:00
return sub_81C786C();
2019-02-13 03:33:15 +01:00
}
2019-02-15 06:07:57 +01:00
u32 sub_81C75E0(void)
{
return gPokenavResources->currentMenuCb1();
2019-02-13 03:33:15 +01:00
}
2019-02-23 13:34:01 +01:00
static void InitKeys_(void)
2019-02-15 06:07:57 +01:00
{
2019-02-15 06:29:32 +01:00
InitKeys();
2019-02-13 03:33:15 +01:00
}
2019-02-23 13:34:01 +01:00
void SetVBlankCallback_(IntrCallback callback)
2019-02-15 06:07:57 +01:00
{
2019-02-15 06:29:32 +01:00
SetVBlankCallback(callback);
2019-02-13 03:33:15 +01:00
}
2019-02-23 13:34:01 +01:00
void SetPokenavVBlankCallback(void)
2019-02-15 06:07:57 +01:00
{
2019-04-06 22:15:52 +02:00
SetVBlankCallback(VBlankCB_Pokenav);
2019-02-13 03:33:15 +01:00
}
2019-02-23 13:34:01 +01:00
void *AllocSubstruct(u32 index, u32 size)
2019-02-15 06:07:57 +01:00
{
2019-04-06 22:15:52 +02:00
return gPokenavResources->field10[index] = Alloc(size);
2019-02-13 04:18:12 +01:00
}
void *GetSubstructPtr(u32 index)
2019-02-15 06:07:57 +01:00
{
2019-04-06 22:15:52 +02:00
return gPokenavResources->field10[index];
2019-02-13 04:18:12 +01:00
}
void FreePokenavSubstruct(u32 index)
2019-02-15 06:07:57 +01:00
{
2019-04-06 22:15:52 +02:00
if (gPokenavResources->field10[index] != NULL)
FREE_AND_SET_NULL(gPokenavResources->field10[index]);
2019-02-13 04:18:12 +01:00
}
2019-02-23 13:34:01 +01:00
u16 GetPokenavMode(void)
2019-02-15 06:07:57 +01:00
{
2019-04-06 22:15:52 +02:00
return gPokenavResources->mode;
2019-02-13 04:18:12 +01:00
}
2019-02-23 13:34:01 +01:00
void SetPokenavMode(u16 mode)
2019-02-15 06:07:57 +01:00
{
2019-04-06 22:15:52 +02:00
gPokenavResources->mode = mode;
2019-02-13 04:18:12 +01:00
}
2019-02-15 06:07:57 +01:00
void sub_81C7694(u32 a0)
{
2019-02-23 13:34:01 +01:00
u32 value = a0;
if (value > 4)
2019-02-15 06:29:32 +01:00
value = 0;
2019-04-06 22:15:52 +02:00
gPokenavResources->fieldA = value;
2019-02-13 04:18:12 +01:00
}
2019-02-15 06:07:57 +01:00
u16 sub_81C76AC(void)
{
2019-04-06 22:15:52 +02:00
return gPokenavResources->fieldA;
2019-02-13 04:18:12 +01:00
}
2019-02-23 13:34:01 +01:00
bool32 CanViewRibbonsMenu(void)
2019-02-15 06:07:57 +01:00
{
2019-04-06 22:15:52 +02:00
return gPokenavResources->hasAnyRibbons;
2019-02-13 04:18:12 +01:00
}
bool32 InitPokenavMainMenu(void)
2019-02-15 06:07:57 +01:00
{
struct PokenavMainMenuResources *structPtr;
2019-02-24 05:17:26 +01:00
structPtr = AllocSubstruct(0, sizeof(struct PokenavMainMenuResources));
2019-02-23 13:34:01 +01:00
if (structPtr == NULL)
2019-02-15 06:29:32 +01:00
return FALSE;
2019-02-23 13:34:01 +01:00
ResetSpriteData();
FreeAllSpritePalettes();
structPtr->currentTaskId = CreateLoopedTask(LoopedTask_InitPokenavMenu, 1);
2019-02-23 13:34:01 +01:00
return TRUE;
2019-02-13 06:07:48 +01:00
}
u32 PokenavMainMenuLoopedTaskIsActive(void)
2019-02-15 06:07:57 +01:00
{
struct PokenavMainMenuResources *structPtr = GetSubstructPtr(0);
2019-04-06 22:15:52 +02:00
return IsLoopedTaskActive(structPtr->currentTaskId);
2019-02-13 06:07:48 +01:00
}
void ShutdownPokenav(void)
2019-02-15 06:07:57 +01:00
{
2019-02-15 06:29:32 +01:00
PlaySE(SE_PN_OFF);
sub_81CAADC();
BeginNormalPaletteFade(0xFFFFFFFF, -1, 0, 16, RGB_BLACK);
2019-02-13 06:07:48 +01:00
}
bool32 WaitForPokenavShutdownFade(void)
2019-02-15 06:07:57 +01:00
{
2019-02-15 06:29:32 +01:00
if (!gPaletteFade.active)
{
sub_81C99D4();
CleanupPokenavMainMenuResources();
2019-02-15 06:29:32 +01:00
FreeAllWindowBuffers();
return FALSE;
}
2019-02-23 13:34:01 +01:00
return TRUE;
2019-02-13 08:31:24 +01:00
}
u32 LoopedTask_InitPokenavMenu(s32 a0)
2019-02-15 06:07:57 +01:00
{
struct PokenavMainMenuResources *structPtr;
2019-02-15 06:29:32 +01:00
switch (a0)
{
case 0:
SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_ON | DISPCNT_OBJ_1D_MAP);
2019-02-15 06:29:32 +01:00
FreeAllWindowBuffers();
ResetBgsAndClearDma3BusyFlags(0);
InitBgsFromTemplates(0, gPokenavMainMenuBgTemplates, ARRAY_COUNT(gPokenavMainMenuBgTemplates));
ResetBgPositions();
2019-02-15 06:29:32 +01:00
reset_temp_tile_data_buffers();
return LT_INC_AND_CONTINUE;
2019-02-15 06:29:32 +01:00
case 1:
2019-02-23 13:34:01 +01:00
structPtr = GetSubstructPtr(0);
2019-02-15 06:29:32 +01:00
decompress_and_copy_tile_data_to_vram(0, &gPokenavHeader_Gfx, 0, 0, 0);
2019-02-23 13:34:01 +01:00
SetBgTilemapBuffer(0, structPtr->tilemapBuffer);
2019-02-15 06:29:32 +01:00
CopyToBgTilemapBuffer(0, &gPokenavHeader_Tilemap, 0, 0);
CopyPaletteIntoBufferUnfaded(gPokenavHeader_Pal, 0, 0x20);
CopyBgTilemapBufferToVram(0);
return LT_INC_AND_PAUSE;
2019-02-15 06:29:32 +01:00
case 2:
if (free_temp_tile_data_buffers_if_possible())
return LT_PAUSE;
2019-02-23 13:34:01 +01:00
2019-02-15 06:29:32 +01:00
sub_81C7B74();
return LT_INC_AND_PAUSE;
2019-02-15 06:29:32 +01:00
case 3:
if (IsDma3ManagerBusyWithBgCopy())
return LT_PAUSE;
2019-02-15 06:29:32 +01:00
InitPokenavMainMenuResources();
InitHoenMapHeaderSprites();
2019-02-15 06:29:32 +01:00
ShowBg(0);
return LT_FINISH;
2019-02-15 06:29:32 +01:00
default:
return LT_FINISH;
2019-02-15 06:29:32 +01:00
}
}
2019-02-23 13:34:01 +01:00
void sub_81C7834(void *func1, void *func2) // Fix types later.
2019-02-15 06:07:57 +01:00
{
struct PokenavMainMenuResources *structPtr = GetSubstructPtr(0);
2019-02-23 13:34:01 +01:00
structPtr->unk0 = func1;
structPtr->unk4 = func2;
structPtr->unk8 = 0;
}
2019-02-15 06:07:57 +01:00
void sub_81C7850(u32 a0)
{
struct PokenavMainMenuResources *structPtr = GetSubstructPtr(0);
2019-02-23 13:34:01 +01:00
structPtr->unk8 = 0;
structPtr->unk0(a0);
}
2019-02-15 06:07:57 +01:00
u32 sub_81C786C(void)
{
struct PokenavMainMenuResources *structPtr = GetSubstructPtr(0);
2019-02-23 13:34:01 +01:00
return structPtr->unk4();
}
2019-02-15 06:07:57 +01:00
void sub_81C7880(void)
{
struct PokenavMainMenuResources *structPtr = GetSubstructPtr(0);
structPtr->currentTaskId = CreateLoopedTask(LoopedTask_ScrollMenuHeaderDown, 4);
}
2019-02-15 06:07:57 +01:00
void sub_81C78A0(void)
{
struct PokenavMainMenuResources *structPtr = GetSubstructPtr(0);
structPtr->currentTaskId = CreateLoopedTask(LoopedTask_ScrollMenuHeaderUp, 4);
}
bool32 MainMenuLoopedTaskIsBusy(void)
2019-02-15 06:07:57 +01:00
{
struct PokenavMainMenuResources *structPtr = GetSubstructPtr(0);
2019-04-06 22:15:52 +02:00
return IsLoopedTaskActive(structPtr->currentTaskId);
}
u32 LoopedTask_ScrollMenuHeaderDown(s32 a0)
2019-02-15 06:07:57 +01:00
{
2019-02-15 06:29:32 +01:00
switch (a0)
{
default:
return LT_FINISH;
2019-02-15 06:29:32 +01:00
case 1:
return LT_INC_AND_PAUSE;
2019-02-15 06:29:32 +01:00
case 0:
return LT_INC_AND_PAUSE;
2019-02-15 06:29:32 +01:00
case 2:
2019-02-23 13:34:01 +01:00
if (ChangeBgY(0, 384, 1) >= 0x2000u)
2019-02-15 06:29:32 +01:00
{
ChangeBgY(0, 0x2000, 0);
return LT_FINISH;
2019-02-15 06:29:32 +01:00
}
2019-02-23 13:34:01 +01:00
return LT_PAUSE;
2019-02-15 06:29:32 +01:00
}
}
u32 LoopedTask_ScrollMenuHeaderUp(s32 a0)
2019-02-16 18:09:27 +01:00
{
if (ChangeBgY(0, 384, 2) <= 0)
{
2019-02-15 06:29:32 +01:00
ChangeBgY(0, 0, 0);
return 4;
}
return 2;
}
2019-02-23 13:34:01 +01:00
void CopyPaletteIntoBufferUnfaded(const u16 *palette, u32 bufferOffset, u32 size)
{
2019-02-15 06:29:32 +01:00
CpuCopy16(palette, gPlttBufferUnfaded + bufferOffset, size);
}
void Pokenav_AllocAndLoadPalettes(const struct SpritePalette *palettes)
2019-02-15 06:07:57 +01:00
{
2019-02-15 06:29:32 +01:00
const struct SpritePalette *current;
u32 index;
2019-02-23 13:34:01 +01:00
for (current = palettes; current->data != NULL; current++)
{
index = AllocSpritePalette(current->tag);
if (index == 0xFF)
{
break;
}
else
{
index = (index * 16) + 0x100;
2019-02-15 06:00:01 +01:00
CopyPaletteIntoBufferUnfaded(current->data, index, 0x20);
}
}
2019-02-14 17:55:58 +01:00
}
2019-02-15 06:07:57 +01:00
void sub_81C7990(u32 a0, u16 a1)
{
2019-02-15 06:29:32 +01:00
CpuFill16(a1, gPlttBufferFaded + 0x100 + (a0 * 16), 16 * sizeof(u16));
2019-02-14 17:55:58 +01:00
}
__attribute__((naked))
2019-02-23 13:34:01 +01:00
void sub_81C79BC(u16 *a0, u16 *a1, u32 a2, u32 a3, u32 a4, u32 a5)
2019-02-15 06:07:57 +01:00
{
2019-02-15 06:29:32 +01:00
asm(".syntax unified\n\
push {r4-r7,lr}\n\
mov r7, r10\n\
mov r6, r9\n\
mov r5, r8\n\
push {r5-r7}\n\
sub sp, 0xC\n\
str r0, [sp]\n\
str r1, [sp, 0x4]\n\
mov r10, r2\n\
str r3, [sp, 0x8]\n\
ldr r0, [sp, 0x2C]\n\
cmp r0, 0\n\
bne _081C79E4\n\
ldr r2, =0x001fffff\n\
mov r1, r10\n\
ands r2, r1\n\
ldr r0, [sp]\n\
b _081C79F4\n\
.pool\n\
_081C79E4:\n\
2019-02-15 06:29:32 +01:00
ldr r2, [sp, 0x2C]\n\
ldr r0, [sp, 0x8]\n\
cmp r2, r0\n\
blt _081C7A00\n\
ldr r2, =0x001fffff\n\
mov r1, r10\n\
ands r2, r1\n\
ldr r0, [sp, 0x4]\n\
_081C79F4:\n\
2019-02-15 06:29:32 +01:00
ldr r1, [sp, 0x30]\n\
bl CpuSet\n\
b _081C7AAE\n\
.pool\n\
_081C7A00:\n\
2019-02-15 06:29:32 +01:00
movs r2, 0x1\n\
negs r2, r2\n\
add r10, r2\n\
b _081C7AA6\n\
_081C7A08:\n\
2019-02-15 06:29:32 +01:00
ldr r1, [sp]\n\
ldrh r0, [r1]\n\
movs r2, 0x1F\n\
mov r9, r2\n\
mov r1, r9\n\
ands r1, r0\n\
mov r9, r1\n\
lsls r0, 16\n\
lsrs r2, r0, 21\n\
movs r1, 0x1F\n\
ands r1, r2\n\
mov r8, r1\n\
lsrs r7, r0, 26\n\
movs r2, 0x1F\n\
ands r7, r2\n\
ldr r0, [sp, 0x4]\n\
ldrh r4, [r0]\n\
movs r0, 0x1F\n\
ands r0, r4\n\
mov r1, r9\n\
subs r0, r1\n\
lsls r0, 8\n\
ldr r1, [sp, 0x8]\n\
bl __divsi3\n\
ldr r2, [sp, 0x2C]\n\
adds r6, r0, 0\n\
muls r6, r2\n\
asrs r6, 8\n\
lsls r4, 16\n\
lsrs r0, r4, 21\n\
movs r1, 0x1F\n\
ands r0, r1\n\
mov r2, r8\n\
subs r0, r2\n\
lsls r0, 8\n\
ldr r1, [sp, 0x8]\n\
bl __divsi3\n\
ldr r1, [sp, 0x2C]\n\
adds r5, r0, 0\n\
muls r5, r1\n\
asrs r5, 8\n\
lsrs r4, 26\n\
movs r2, 0x1F\n\
ands r4, r2\n\
subs r4, r7\n\
lsls r4, 8\n\
adds r0, r4, 0\n\
ldr r1, [sp, 0x8]\n\
bl __divsi3\n\
ldr r1, [sp, 0x2C]\n\
muls r0, r1\n\
asrs r0, 8\n\
add r6, r9\n\
movs r2, 0x1F\n\
ands r6, r2\n\
add r5, r8\n\
ands r5, r2\n\
adds r0, r7, r0\n\
ands r0, r2\n\
lsls r0, 10\n\
lsls r5, 5\n\
orrs r0, r5\n\
orrs r0, r6\n\
ldr r1, [sp, 0x30]\n\
strh r0, [r1]\n\
ldr r2, [sp]\n\
adds r2, 0x2\n\
str r2, [sp]\n\
ldr r0, [sp, 0x4]\n\
adds r0, 0x2\n\
str r0, [sp, 0x4]\n\
adds r1, 0x2\n\
str r1, [sp, 0x30]\n\
movs r1, 0x1\n\
negs r1, r1\n\
add r10, r1\n\
_081C7AA6:\n\
2019-02-15 06:29:32 +01:00
movs r0, 0x1\n\
negs r0, r0\n\
cmp r10, r0\n\
bne _081C7A08\n\
_081C7AAE:\n\
2019-02-15 06:29:32 +01:00
add sp, 0xC\n\
pop {r3-r5}\n\
mov r8, r3\n\
mov r9, r4\n\
mov r10, r5\n\
pop {r4-r7}\n\
pop {r0}\n\
bx r0\n\
.syntax divided");
}
2019-02-15 06:07:57 +01:00
void sub_81C7AC0(s32 a0)
{
struct PokenavMainMenuResources *structPtr = GetSubstructPtr(0);
2019-02-23 13:34:01 +01:00
2019-02-15 06:29:32 +01:00
switch (a0)
{
2019-02-16 18:09:27 +01:00
case 0:
2019-02-23 13:34:01 +01:00
BeginNormalPaletteFade(structPtr->unk14, -2, 0, 16, RGB_BLACK);
2019-02-16 18:09:27 +01:00
break;
case 1:
2019-02-23 13:34:01 +01:00
BeginNormalPaletteFade(structPtr->unk14, -2, 16, 0, RGB_BLACK);
2019-02-16 18:09:27 +01:00
break;
case 2:
BeginNormalPaletteFade(0xFFFFFFFF, -2, 0, 16, RGB_BLACK);
2019-02-16 18:09:27 +01:00
break;
case 3:
BeginNormalPaletteFade(0xFFFFFFFF, -2, 16, 0, RGB_BLACK);
2019-02-16 18:09:27 +01:00
break;
2019-02-15 06:29:32 +01:00
}
}
2019-02-15 06:07:57 +01:00
bool32 IsPaletteFadeActive(void)
{
2019-02-15 06:29:32 +01:00
return gPaletteFade.active;
}
2019-02-15 06:07:57 +01:00
void sub_81C7B40(void)
{
BlendPalettes(0xFFFEFFFE, 16, RGB_BLACK);
}
2019-02-23 13:34:01 +01:00
void InitBgTemplates(const struct BgTemplate *templates, s32 count)
2019-02-15 06:07:57 +01:00
{
2019-02-15 06:29:32 +01:00
s32 i;
2019-02-23 13:34:01 +01:00
for (i = 0; i < count; i++)
InitBgFromTemplate(templates++);
}
2019-02-15 06:07:57 +01:00
void sub_81C7B74(void)
{
struct PokenavMainMenuResources *structPtr = GetSubstructPtr(0);
2019-02-15 06:29:32 +01:00
InitWindows(&gUnknown_0861FA08[0]);
2019-02-23 13:34:01 +01:00
structPtr->unk10 = 0;
sub_81C7BF8(structPtr->unk10);
PutWindowTilemap(structPtr->unk10);
CopyWindowToVram(structPtr->unk10, 3); // TODO: Use a defined constant here.
2019-02-14 23:26:34 +01:00
}
2019-02-15 06:07:57 +01:00
void sub_81C7BA4(u32 a0)
{
struct PokenavMainMenuResources *structPtr = GetSubstructPtr(0);
2019-02-14 23:26:34 +01:00
2019-02-23 13:34:01 +01:00
sub_81C7BF8(structPtr->unk10);
AddTextPrinterParameterized3(structPtr->unk10, 1, 0, 1, gMenuButtonReminderColor, 0, sMenuButtonReminders[a0]);
2019-02-14 23:26:34 +01:00
}
2019-02-23 13:34:01 +01:00
bool32 IsDma3ManagerBusyWithBgCopy_(void)
2019-02-15 06:07:57 +01:00
{
2019-02-15 06:29:32 +01:00
return IsDma3ManagerBusyWithBgCopy();
2019-02-14 23:26:34 +01:00
}
2019-02-23 13:34:01 +01:00
void sub_81C7BF8(u32 windowId)
2019-02-15 06:07:57 +01:00
{
FillWindowPixelBuffer(windowId, PIXEL_FILL(4));
FillWindowPixelRect(windowId, PIXEL_FILL(5), 0, 0, 0x80, 1);
2019-02-14 23:26:34 +01:00
}
void InitPokenavMainMenuResources(void)
2019-02-15 06:07:57 +01:00
{
2019-02-23 13:34:01 +01:00
s32 i;
2019-02-15 06:29:32 +01:00
u8 spriteId;
struct PokenavMainMenuResources *structPtr = GetSubstructPtr(0);
2019-02-15 06:29:32 +01:00
for (i = 0; i < ARRAY_COUNT(gSpinningNavgearSpriteSheet); i++)
LoadCompressedSpriteSheet(&gSpinningNavgearSpriteSheet[i]);
2019-02-15 06:29:32 +01:00
Pokenav_AllocAndLoadPalettes(gSpinningNavgearPalette);
2019-02-23 13:34:01 +01:00
structPtr->unk14 = ~1 & ~(0x10000 << IndexOfSpritePaletteTag(0));
spriteId = CreateSprite(&sSpinningNavgearSpriteTemplate, 220, 12, 0);
structPtr->spinningNavgear = &gSprites[spriteId];
2019-02-15 03:03:52 +01:00
}
void CleanupPokenavMainMenuResources(void)
2019-02-15 06:07:57 +01:00
{
struct PokenavMainMenuResources *structPtr = GetSubstructPtr(0);
2019-02-23 13:34:01 +01:00
DestroySprite(structPtr->spinningNavgear);
2019-02-15 06:29:32 +01:00
FreeSpriteTilesByTag(0);
FreeSpritePaletteByTag(0);
2019-02-15 03:03:52 +01:00
}
void SpriteCB_SpinningNavgear(struct Sprite *sprite)
2019-02-15 06:07:57 +01:00
{
2019-04-07 07:32:42 +02:00
// If the background starts scrolling, follow it.
2019-02-23 13:34:01 +01:00
sprite->pos2.y = (GetBgY(0) / 256u) * -1;
2019-02-15 03:03:52 +01:00
}
2019-04-07 07:32:42 +02:00
struct Sprite *PauseSpinningNavgearSprite(void)
2019-02-15 06:07:57 +01:00
{
struct PokenavMainMenuResources *structPtr = GetSubstructPtr(0);
2019-02-23 13:34:01 +01:00
structPtr->spinningNavgear->callback = SpriteCallbackDummy;
return structPtr->spinningNavgear;
2019-02-23 13:34:01 +01:00
}
2019-04-07 07:32:42 +02:00
void ResumeSpinningNavgearSprite(void)
2019-02-23 13:34:01 +01:00
{
struct PokenavMainMenuResources *structPtr = GetSubstructPtr(0);
2019-02-23 13:34:01 +01:00
structPtr->spinningNavgear->pos1.x = 220;
structPtr->spinningNavgear->pos1.y = 12;
structPtr->spinningNavgear->callback = SpriteCB_SpinningNavgear;
structPtr->spinningNavgear->invisible = FALSE;
structPtr->spinningNavgear->oam.priority = 0;
structPtr->spinningNavgear->subpriority = 0;
2019-02-23 13:34:01 +01:00
}
void InitHoenMapHeaderSprites(void)
2019-02-23 13:34:01 +01:00
{
s32 i, spriteId;
struct PokenavMainMenuResources *structPtr = GetSubstructPtr(0);
2019-02-23 13:34:01 +01:00
LoadCompressedSpriteSheet(&sPokenavHoenMapLeftHeaderSpriteSheet);
2019-02-23 13:34:01 +01:00
AllocSpritePalette(1);
AllocSpritePalette(2);
2019-04-07 07:32:42 +02:00
for (i = 0; i < (s32)ARRAY_COUNT(structPtr->leftHeaderSprites); i++)
2019-02-23 13:34:01 +01:00
{
spriteId = CreateSprite(&sPokenavLeftHeaderHoenMapSpriteTemplate, 0, 0, 1);
2019-04-07 07:32:42 +02:00
structPtr->leftHeaderSprites[i] = &gSprites[spriteId];
structPtr->leftHeaderSprites[i]->invisible = TRUE;
structPtr->leftHeaderSprites[i]->pos2.x = i * 64;
2019-02-23 13:34:01 +01:00
2019-03-16 00:33:30 +01:00
spriteId = CreateSprite(&sUnknown_0861FB44, 0, 0, 2);
2019-04-07 07:32:42 +02:00
structPtr->submenuLeftHeaderSprites[i] = &gSprites[spriteId];
structPtr->submenuLeftHeaderSprites[i]->invisible = TRUE;
structPtr->submenuLeftHeaderSprites[i]->pos2.x = i * 32;
structPtr->submenuLeftHeaderSprites[i]->pos2.y = 18;
structPtr->submenuLeftHeaderSprites[i]->oam.tileNum += (i * 8) + 64;
2019-02-23 13:34:01 +01:00
}
}
2019-04-07 07:32:42 +02:00
void LoadLeftHeaderGfxForIndex(u32 arg0)
2019-02-23 13:34:01 +01:00
{
2019-04-07 07:32:42 +02:00
if (arg0 < NAVGEAR_GFX_SUBMENUS_START)
LoadLeftHeaderGfxForMenu(arg0);
2019-02-23 13:34:01 +01:00
else
2019-04-07 07:32:42 +02:00
LoadLeftHeaderGfxForSubMenu(arg0 - NAVGEAR_GFX_SUBMENUS_START);
2019-02-23 13:34:01 +01:00
}
void sub_81C7E14(u32 arg0)
{
struct PokenavMainMenuResources *structPtr = GetSubstructPtr(0);
2019-02-23 13:34:01 +01:00
if (arg0 == 4)
2019-04-07 07:32:42 +02:00
structPtr->leftHeaderSprites[1]->oam.tileNum = GetSpriteTileStartByTag(2) + 32;
2019-02-23 13:34:01 +01:00
else
2019-04-07 07:32:42 +02:00
structPtr->leftHeaderSprites[1]->oam.tileNum = GetSpriteTileStartByTag(2) + 64;
2019-02-23 13:34:01 +01:00
}
2019-04-07 07:32:42 +02:00
void LoadLeftHeaderGfxForMenu(u32 index)
2019-02-23 13:34:01 +01:00
{
struct PokenavMainMenuResources *structPtr;
2019-02-23 13:34:01 +01:00
u32 size, tag;
2019-04-07 07:32:42 +02:00
if (index >= NAVGEAR_GFX_SUBMENUS_START)
2019-02-23 13:34:01 +01:00
return;
structPtr = GetSubstructPtr(0);
2019-04-07 07:32:42 +02:00
tag = sPokenavMenuLeftHeaderSpriteSheets[index].tag;
size = GetDecompressedDataSize(sPokenavMenuLeftHeaderSpriteSheets[index].data);
2019-02-23 13:34:01 +01:00
LoadPalette(&gPokenavLeftHeader_Pal[tag * 16], (IndexOfSpritePaletteTag(1) * 16) + 0x100, 0x20);
2019-04-07 07:32:42 +02:00
LZ77UnCompWram(sPokenavMenuLeftHeaderSpriteSheets[index].data, gDecompressionBuffer);
2019-02-23 13:34:01 +01:00
RequestDma3Copy(gDecompressionBuffer, (void *)VRAM + 0x10000 + (GetSpriteTileStartByTag(2) * 32), size, 1);
2019-04-07 07:32:42 +02:00
structPtr->leftHeaderSprites[1]->oam.tileNum = GetSpriteTileStartByTag(2) + sPokenavMenuLeftHeaderSpriteSheets[index].size;
2019-02-23 13:34:01 +01:00
2019-04-07 07:32:42 +02:00
if (index == NAVGEAR_GFX_MAP_MENU_UNK0 || index == NAVGEAR_GFX_MAP_MENU_UNK1)
structPtr->leftHeaderSprites[1]->pos2.x = 56;
2019-02-23 13:34:01 +01:00
else
2019-04-07 07:32:42 +02:00
structPtr->leftHeaderSprites[1]->pos2.x = 64;
2019-02-23 13:34:01 +01:00
}
2019-04-07 07:32:42 +02:00
void LoadLeftHeaderGfxForSubMenu(u32 arg0)
2019-02-23 13:34:01 +01:00
{
u32 size, tag;
2019-04-07 07:32:42 +02:00
if (arg0 >= NAVGEAR_GFX_MENUS_END - NAVGEAR_GFX_SUBMENUS_START)
2019-02-23 13:34:01 +01:00
return;
2019-04-07 07:32:42 +02:00
tag = sPokenavSubMenuLeftHeaderSpriteSheets[arg0].tag;
size = GetDecompressedDataSize(sPokenavSubMenuLeftHeaderSpriteSheets[arg0].data);
2019-02-23 13:34:01 +01:00
LoadPalette(&gPokenavLeftHeader_Pal[tag * 16], (IndexOfSpritePaletteTag(2) * 16) + 0x100, 0x20);
2019-04-07 07:32:42 +02:00
LZ77UnCompWram(sPokenavSubMenuLeftHeaderSpriteSheets[arg0].data, &gDecompressionBuffer[0x1000]);
2019-02-23 13:34:01 +01:00
RequestDma3Copy(&gDecompressionBuffer[0x1000], (void *)VRAM + 0x10800 + (GetSpriteTileStartByTag(2) * 32), size, 1);
}
void sub_81C7FA0(u32 arg0, bool32 arg1, bool32 arg2)
{
u32 var;
if (!arg1)
var = 0x30;
else
var = 0x10;
if (arg0 < 6)
2019-04-07 07:32:42 +02:00
ShowLeftHeaderSprites(var, arg2);
2019-02-23 13:34:01 +01:00
else
2019-04-07 07:32:42 +02:00
ShowLeftHeaderSubmenuSprites(var, arg2);
2019-02-23 13:34:01 +01:00
}
void sub_81C7FC4(u32 arg0, bool32 arg1)
{
if (arg0 < 6)
2019-04-07 07:32:42 +02:00
HideLeftHeaderSprites(arg1);
2019-02-23 13:34:01 +01:00
else
2019-04-07 07:32:42 +02:00
HideLeftHeaderSubmenuSprites(arg1);
2019-02-23 13:34:01 +01:00
}
void sub_81C7FDC(void)
{
s32 i;
struct PokenavMainMenuResources *structPtr = GetSubstructPtr(0);
2019-02-23 13:34:01 +01:00
2019-04-07 07:32:42 +02:00
for (i = 0; i < (s32)ARRAY_COUNT(structPtr->leftHeaderSprites); i++)
2019-02-23 13:34:01 +01:00
{
2019-04-07 07:32:42 +02:00
structPtr->leftHeaderSprites[i]->invisible = TRUE;
structPtr->submenuLeftHeaderSprites[i]->invisible = TRUE;
2019-02-23 13:34:01 +01:00
}
}
bool32 sub_81C8010(void)
{
struct PokenavMainMenuResources *structPtr = GetSubstructPtr(0);
2019-02-23 13:34:01 +01:00
2019-04-07 07:32:42 +02:00
if (structPtr->leftHeaderSprites[0]->callback == SpriteCallbackDummy && structPtr->submenuLeftHeaderSprites[0]->callback == SpriteCallbackDummy)
2019-02-23 13:34:01 +01:00
return FALSE;
else
return TRUE;
}
2019-04-07 07:32:42 +02:00
void ShowLeftHeaderSprites(u32 startY, bool32 isOnRightSide)
2019-02-23 13:34:01 +01:00
{
2019-04-07 07:32:42 +02:00
s32 start, end, i;
struct PokenavMainMenuResources *structPtr = GetSubstructPtr(0);
2019-02-23 13:34:01 +01:00
2019-04-07 07:32:42 +02:00
if (!isOnRightSide)
start = -96, end = 32;
2019-02-23 13:34:01 +01:00
else
2019-04-07 07:32:42 +02:00
start = 256, end = 160;
2019-02-23 13:34:01 +01:00
2019-04-07 07:32:42 +02:00
for (i = 0; i < (s32)ARRAY_COUNT(structPtr->leftHeaderSprites); i++)
2019-02-23 13:34:01 +01:00
{
2019-04-07 07:32:42 +02:00
structPtr->leftHeaderSprites[i]->pos1.y = startY;
MoveLeftHeader(structPtr->leftHeaderSprites[i], start, end, 12);
2019-02-23 13:34:01 +01:00
}
}
2019-04-07 07:32:42 +02:00
void ShowLeftHeaderSubmenuSprites(u32 startY, bool32 isOnRightSide)
2019-02-23 13:34:01 +01:00
{
2019-04-07 07:32:42 +02:00
s32 start, end, i;
struct PokenavMainMenuResources *structPtr = GetSubstructPtr(0);
2019-02-23 13:34:01 +01:00
2019-04-07 07:32:42 +02:00
if (!isOnRightSide)
start = -96, end = 16;
2019-02-23 13:34:01 +01:00
else
2019-04-07 07:32:42 +02:00
start = 256, end = 192;
2019-02-23 13:34:01 +01:00
2019-04-07 07:32:42 +02:00
for (i = 0; i < (s32)ARRAY_COUNT(structPtr->submenuLeftHeaderSprites); i++)
2019-02-23 13:34:01 +01:00
{
2019-04-07 07:32:42 +02:00
structPtr->submenuLeftHeaderSprites[i]->pos1.y = startY;
MoveLeftHeader(structPtr->submenuLeftHeaderSprites[i], start, end, 12);
2019-02-23 13:34:01 +01:00
}
}
2019-04-07 07:32:42 +02:00
void HideLeftHeaderSprites(bool32 isOnRightSide)
2019-02-23 13:34:01 +01:00
{
2019-04-07 07:32:42 +02:00
s32 start, end, i;
struct PokenavMainMenuResources *structPtr = GetSubstructPtr(0);
2019-02-23 13:34:01 +01:00
2019-04-07 07:32:42 +02:00
if (!isOnRightSide)
start = 32, end = -96;
2019-02-23 13:34:01 +01:00
else
2019-04-07 07:32:42 +02:00
start = 192, end = 256;
2019-02-23 13:34:01 +01:00
2019-04-07 07:32:42 +02:00
for (i = 0; i < (s32)ARRAY_COUNT(structPtr->leftHeaderSprites); i++)
2019-02-23 13:34:01 +01:00
{
2019-04-07 07:32:42 +02:00
MoveLeftHeader(structPtr->leftHeaderSprites[i], start, end, 12);
2019-02-23 13:34:01 +01:00
}
}
2019-04-07 07:32:42 +02:00
void HideLeftHeaderSubmenuSprites(bool32 isOnRightSide)
2019-02-23 13:34:01 +01:00
{
2019-04-07 07:32:42 +02:00
s32 start, end, i;
struct PokenavMainMenuResources *structPtr = GetSubstructPtr(0);
2019-02-23 13:34:01 +01:00
2019-04-07 07:32:42 +02:00
if (!isOnRightSide)
start = 16, end = -96;
2019-02-23 13:34:01 +01:00
else
2019-04-07 07:32:42 +02:00
start = 192, end = 256;
2019-02-23 13:34:01 +01:00
2019-04-07 07:32:42 +02:00
for (i = 0; i < (s32)ARRAY_COUNT(structPtr->submenuLeftHeaderSprites); i++)
2019-02-23 13:34:01 +01:00
{
2019-04-07 07:32:42 +02:00
MoveLeftHeader(structPtr->submenuLeftHeaderSprites[i], start, end, 12);
2019-02-23 13:34:01 +01:00
}
}
2019-04-07 07:32:42 +02:00
void MoveLeftHeader(struct Sprite *sprite, s32 startX, s32 endX, s32 duration)
2019-02-23 13:34:01 +01:00
{
2019-04-07 07:32:42 +02:00
sprite->pos1.x = startX;
sprite->data[0] = startX * 16;
sprite->data[1] = (endX - startX) * 16 / duration;
sprite->data[2] = duration;
sprite->data[7] = endX;
sprite->callback = SpriteCB_MoveLeftHeader;
2019-02-23 13:34:01 +01:00
}
2019-04-07 07:32:42 +02:00
void SpriteCB_MoveLeftHeader(struct Sprite *sprite)
2019-02-23 13:34:01 +01:00
{
if (sprite->data[2] != 0)
{
sprite->data[2]--;
sprite->data[0] += sprite->data[1];
sprite->pos1.x = sprite->data[0] >> 4;
if (sprite->pos1.x < -16 || sprite->pos1.x > 256)
sprite->invisible = TRUE;
else
sprite->invisible = FALSE;
}
else
{
sprite->pos1.x = sprite->data[7];
sprite->callback = SpriteCallbackDummy;
}
}
2019-04-06 22:15:52 +02:00
bool32 sub_81C81D4(const struct BgTemplate *arg0, struct MatchCallListTemplate *arg1, s32 arg2)
2019-02-23 13:34:01 +01:00
{
2019-02-24 05:17:26 +01:00
u32 v1;
struct UnknownSubStruct_81C81D4 *structPtr;
structPtr = AllocSubstruct(0x11, sizeof(struct UnknownSubStruct_81C81D4));
2019-02-23 13:34:01 +01:00
if (structPtr == NULL)
return FALSE;
2019-02-24 05:17:26 +01:00
sub_81C9160(&structPtr->unk888, arg1);
v1 = sub_81C91AC(&structPtr->unk0, arg0, arg1, arg2);
2019-02-24 05:17:26 +01:00
if (v1 == 0)
return FALSE;
2019-04-06 22:15:52 +02:00
CreateLoopedTask(LoopedTask_sub_81C8254, 6);
2019-02-24 05:17:26 +01:00
return TRUE;
}
2019-02-24 05:17:26 +01:00
bool32 sub_81C8224(void)
{
2019-04-06 22:15:52 +02:00
return FuncIsActiveLoopedTask(LoopedTask_sub_81C8254);
}
void sub_81C8234(void)
{
struct UnknownSubStruct_81C81D4 *structPtr;
structPtr = GetSubstructPtr(0x11);
sub_81C8FE0(&structPtr->unk0);
RemoveWindow(structPtr->unk0.unk0.windowId);
FreePokenavSubstruct(0x11);
}
2019-04-06 22:15:52 +02:00
u32 LoopedTask_sub_81C8254(s32 a0)
{
struct UnknownSubStruct_81C81D4 *structPtr;
if (IsDma3ManagerBusyWithBgCopy())
return 2;
structPtr = GetSubstructPtr(0x11);
switch (a0)
{
case 0:
sub_81C82E4(structPtr);
return 0;
case 1:
sub_81C835C(&structPtr->unk0.unk0);
return 0;
case 2:
sub_81C837C(&structPtr->unk888, &structPtr->unk0);
return 0;
case 3:
if (sub_81C83E0())
{
return 2;
}
else
{
sub_81C8ED0();
return 1;
}
case 4:
sub_81C8EF8(&structPtr->unk888, &structPtr->unk0);
return 4;
default:
return 4;
}
}
void sub_81C82E4(struct UnknownSubStruct_81C81D4 *a0)
{
u16 v1 = (a0->unk0.unk0.unk1 << 12) | a0->unk0.unk0.unk6;
// TODO: When #553 is merged, use a PALETTE_NUM_TO_FILL_VALUE(1) macro here...
sub_8199DF0(a0->unk0.unk0.bg, 0x11, a0->unk0.unk0.unk6, 1);
// ...and PALETTE_NUM_TO_FILL_VALUE(4) here.
sub_8199DF0(a0->unk0.unk0.bg, 0x44, a0->unk0.unk0.unk6 + 1, 1);
SetBgTilemapBuffer(a0->unk0.unk0.bg, a0->tilemapBuffer);
FillBgTilemapBufferRect_Palette0(a0->unk0.unk0.bg, v1, 0, 0, 32, 32);
ChangeBgY(a0->unk0.unk0.bg, 0, 0);
ChangeBgX(a0->unk0.unk0.bg, 0, 0);
ChangeBgY(a0->unk0.unk0.bg, a0->unk0.unk0.unk3 << 11, 2);
CopyBgTilemapBufferToVram(a0->unk0.unk0.bg);
}
void sub_81C835C(struct UnknownSubSubStruct_0203CF40 *a0)
{
FillWindowPixelBuffer(a0->windowId, PIXEL_FILL(1));
PutWindowTilemap(a0->windowId);
CopyWindowToVram(a0->windowId, 1);
}
2019-04-06 22:15:52 +02:00
void sub_81C837C(struct MatchCallWindowState *a0, struct UnknownInnerStruct_81C81D4 *a1)
{
s32 v1;
s32 v2;
// TODO: Clean this up.
2019-04-06 22:15:52 +02:00
v1 = a0->listLength - a0->windowTopIndex;
v2 = a0->visibleEntries;
if (v1 > a0->visibleEntries)
v1 = v2;
2019-04-06 22:15:52 +02:00
sub_81C83AC(a0->unk10, a0->windowTopIndex, v1, a0->unkC, 0, a1);
}
void sub_81C83AC(u32 a0, u32 a1, u32 a2, u32 a3, u32 a4, struct UnknownInnerStruct_81C81D4 *a5)
{
if (a2 == 0)
return;
a5->unk1C = a0 + a1 * a3;
a5->unk18 = a3;
a5->unk0.unkC = 0;
a5->unk0.unkE = a2;
a5->unk14 = a1;
a5->unk10 = a4;
2019-04-06 22:15:52 +02:00
CreateLoopedTask(LoopedTask_sub_81C83F0, 5);
2019-02-24 10:33:58 +01:00
}
2019-02-27 08:11:45 +01:00
bool32 sub_81C83E0(void)
2019-02-24 10:33:58 +01:00
{
2019-04-06 22:15:52 +02:00
return FuncIsActiveLoopedTask(LoopedTask_sub_81C83F0);
2019-02-24 10:33:58 +01:00
}
2019-04-06 22:15:52 +02:00
u32 LoopedTask_sub_81C83F0(s32 a0)
2019-02-24 10:33:58 +01:00
{
struct UnknownInnerStruct_81C81D4 *structPtr;
2019-02-24 10:33:58 +01:00
u32 v1;
structPtr = &((struct UnknownSubStruct_81C81D4*)GetSubstructPtr(0x11))->unk0;
2019-02-24 10:33:58 +01:00
switch (a0)
{
case 0:
v1 = (structPtr->unk0.unkA + structPtr->unk0.unkC + structPtr->unk10) & 0xF;
structPtr->unk34(structPtr->unk1C, structPtr->unkTextBuffer);
2019-02-24 10:33:58 +01:00
if (structPtr->unk38 != NULL)
// Accessing unk0.windowId as if it were a u16...?
// It's accessed as a u8 again in the very next line...
structPtr->unk38(*(u16*)(&structPtr->unk0.windowId), structPtr->unk14, v1);
AddTextPrinterParameterized(structPtr->unk0.windowId, structPtr->unk0.fontId, structPtr->unkTextBuffer, 8, (v1 << 4) + 1, 255, NULL);
2019-02-24 10:33:58 +01:00
if (++structPtr->unk0.unkC >= structPtr->unk0.unkE)
{
if (structPtr->unk38 != NULL)
CopyWindowToVram(structPtr->unk0.windowId, 3);
else
CopyWindowToVram(structPtr->unk0.windowId, 2);
return 0;
}
else
{
structPtr->unk1C += structPtr->unk18;
structPtr->unk14++;
return 3;
}
case 1:
if (IsDma3ManagerBusyWithBgCopy())
return 2;
else
return 4;
default:
return 4;
}
2019-02-25 07:02:16 +01:00
}
2019-04-06 22:15:52 +02:00
bool32 ShouldShowUpArrow(void)
2019-02-25 07:02:16 +01:00
{
u16 v1;
s32 v2;
struct UnknownSubStruct_81C81D4 *structPtr;
structPtr = GetSubstructPtr(0x11);
2019-04-06 22:15:52 +02:00
return structPtr->unk888.windowTopIndex != 0;
2019-02-25 07:02:16 +01:00
}
2019-04-06 22:15:52 +02:00
bool32 ShouldShowDownArrow(void)
2019-02-25 07:02:16 +01:00
{
2019-04-06 22:15:52 +02:00
struct MatchCallWindowState *subPtr;
2019-02-25 07:02:16 +01:00
struct UnknownSubStruct_81C81D4 *structPtr;
structPtr = GetSubstructPtr(0x11);
subPtr = &structPtr->unk888;
2019-04-06 22:15:52 +02:00
return subPtr->windowTopIndex + subPtr->visibleEntries < subPtr->listLength;
2019-02-25 07:02:16 +01:00
}
#ifdef NONMATCHING
// This has some register renaming issues (r4, r5, and r6 are all switched around), and
// for some reason it's creating two copies of subPtr->unk0.
// TODO: Now I know why it's making two copies - one of them is UnknownInnerStruct_81C81D4.
2019-04-06 22:15:52 +02:00
void MatchCall_MoveWindow(s32 a0, bool32 a1)
2019-02-25 07:02:16 +01:00
{
s32 v1;
2019-04-06 22:15:52 +02:00
struct MatchCallWindowState *subPtr;
2019-02-25 07:02:16 +01:00
struct UnknownSubStruct_81C81D4 *structPtr;
structPtr = GetSubstructPtr(0x11);
subPtr = &structPtr->unk888;
if (a0 < 0)
{
2019-04-06 22:15:52 +02:00
// This is where the issue is. subPtr->windowTopIndex is being stored in r1 and then copied to
2019-02-25 07:02:16 +01:00
// r2... and then r2 is read for the if statement, r1 is read for the function call,
// and then both are clobbered as expected. Between those two uses, no writes to r1/r2
// happen; it doesn't need to be duplicated/moved at all.
2019-04-06 22:15:52 +02:00
if (subPtr->windowTopIndex + a0 < 0)
v1 = -1 * subPtr->windowTopIndex;
2019-02-25 07:02:16 +01:00
else
v1 = a0;
2019-04-06 22:15:52 +02:00
if (a1)
sub_81C83AC(subPtr->unk10, subPtr->windowTopIndex + v1, v1 * -1, subPtr->unkC, v1, structPtr);
2019-02-25 07:02:16 +01:00
}
2019-04-06 22:15:52 +02:00
else if (a1)
2019-02-25 07:02:16 +01:00
{
2019-04-06 22:15:52 +02:00
gUnknown_0203CF44 = subPtr->windowTopIndex + subPtr->visibleEntries;
if ((s32)(gUnknown_0203CF44) + a0 >= (s32)subPtr->listLength)
v1 = subPtr->listLength - gUnknown_0203CF44;
2019-02-25 07:02:16 +01:00
else
v1 = a0;
2019-04-06 22:15:52 +02:00
sub_81C83AC(subPtr->unk10, gUnknown_0203CF44, v1, subPtr->unkC, subPtr->visibleEntries, structPtr);
2019-02-25 07:02:16 +01:00
// Needed to prevent GCC from combining the two sub_81C83AC calls.
asm("");
}
else
{
v1 = a0;
}
sub_81C8568(v1, structPtr);
2019-04-06 22:15:52 +02:00
subPtr->windowTopIndex++;
2019-02-25 07:02:16 +01:00
}
#else
NAKED
2019-04-06 22:15:52 +02:00
void MatchCall_MoveWindow(s32 a0, bool32 a1)
2019-02-25 07:02:16 +01:00
{
asm(".syntax unified\n\
push {r4-r7,lr}\n\
sub sp, 0x8\n\
adds r6, r0, 0\n\
adds r4, r1, 0\n\
movs r0, 0x11\n\
bl GetSubstructPtr\n\
adds r7, r0, 0\n\
ldr r0, =0x00000888\n\
adds r5, r7, r0\n\
cmp r6, 0\n\
bge _081C8524\n\
ldrh r1, [r5]\n\
adds r0, r1, r6\n\
cmp r0, 0\n\
bge _081C850A\n\
negs r6, r1\n\
_081C850A:\n\
cmp r4, 0\n\
beq _081C854E\n\
ldr r0, [r5, 0x10]\n\
adds r1, r6\n\
negs r2, r6\n\
ldr r3, [r5, 0xC]\n\
str r6, [sp]\n\
str r7, [sp, 0x4]\n\
bl sub_81C83AC\n\
b _081C854E\n\
.pool\n\
_081C8524:\n\
cmp r4, 0\n\
beq _081C854E\n\
ldr r2, =gUnknown_0203CF44\n\
ldrh r1, [r5]\n\
ldrh r0, [r5, 0x8]\n\
adds r4, r1, r0\n\
str r4, [r2]\n\
adds r0, r4, r6\n\
ldrh r1, [r5, 0x2]\n\
cmp r0, r1\n\
blt _081C853C\n\
subs r6, r1, r4\n\
_081C853C:\n\
ldr r0, [r5, 0x10]\n\
ldr r3, [r5, 0xC]\n\
ldrh r1, [r5, 0x8]\n\
str r1, [sp]\n\
str r7, [sp, 0x4]\n\
adds r1, r4, 0\n\
adds r2, r6, 0\n\
bl sub_81C83AC\n\
_081C854E:\n\
adds r0, r6, 0\n\
adds r1, r7, 0\n\
bl sub_81C8568\n\
ldrh r0, [r5]\n\
adds r0, r6\n\
strh r0, [r5]\n\
add sp, 0x8\n\
pop {r4-r7}\n\
pop {r0}\n\
bx r0\n\
.pool\n\
.syntax divided");
}
#endif
void sub_81C8568(s32 a0, struct UnknownInnerStruct_81C81D4 *a1)
2019-02-25 07:02:16 +01:00
{
a1->unk20 = GetBgY(a1->unk0.bg);
a1->unk24 = a1->unk20 + (a0 << 12);
if (a0 > 0)
a1->unk30 = 1;
else
a1->unk30 = 2;
a1->unk2C = a0;
2019-04-06 22:15:52 +02:00
a1->unk28 = CreateLoopedTask(LoopedTask_sub_81C85A0, 6);
2019-02-27 08:11:45 +01:00
}
2019-04-06 22:15:52 +02:00
u32 LoopedTask_sub_81C85A0(s32 a0)
2019-02-27 08:11:45 +01:00
{
s32 y;
s32 v1;
bool32 flag;
struct UnknownInnerStruct_81C81D4 *structPtr;
structPtr = &((struct UnknownSubStruct_81C81D4 *)GetSubstructPtr(0x11))->unk0;
2019-02-27 08:11:45 +01:00
switch (a0)
{
case 0:
if (sub_81C83E0() == FALSE)
return 1;
else
return 2;
case 1:
flag = FALSE;
y = GetBgY(structPtr->unk0.bg);
v1 = ChangeBgY(structPtr->unk0.bg, 0x1000, structPtr->unk30);
if (structPtr->unk30 == 2)
{
if ((y > structPtr->unk24 || y <= structPtr->unk20) && v1 <= structPtr->unk24)
{
flag = TRUE;
}
}
else
{
if ((y < structPtr->unk24 || y >= structPtr->unk20) && v1 >= structPtr->unk24)
{
flag = TRUE;
}
}
if (flag)
{
structPtr->unk0.unkA = (structPtr->unk0.unkA + structPtr->unk2C) & 0xF;
ChangeBgY(structPtr->unk0.bg, structPtr->unk24, 0);
return 4;
}
else
{
return 2;
}
default:
return 4;
}
}
bool32 sub_81C8630(void)
{
struct UnknownSubStruct_81C81D4 *structPtr;
structPtr = GetSubstructPtr(0x11);
2019-04-06 22:15:52 +02:00
return IsLoopedTaskActive(structPtr->unk0.unk28);
2019-02-27 08:11:45 +01:00
}
2019-04-06 22:15:52 +02:00
struct MatchCallWindowState *GetMatchCallWindowStruct(void)
2019-02-27 08:11:45 +01:00
{
struct UnknownSubStruct_81C81D4 *structPtr;
structPtr = GetSubstructPtr(0x11);
return &structPtr->unk888;
}
2019-04-06 22:15:52 +02:00
u32 MatchCall_MoveCursorUp(void)
2019-02-27 08:11:45 +01:00
{
2019-04-06 22:15:52 +02:00
struct MatchCallWindowState *structPtr;
structPtr = GetMatchCallWindowStruct();
2019-02-27 08:11:45 +01:00
2019-04-06 22:15:52 +02:00
if (structPtr->selectedIndexOffset != 0)
2019-02-27 08:11:45 +01:00
{
2019-04-06 22:15:52 +02:00
structPtr->selectedIndexOffset--;
2019-02-27 08:11:45 +01:00
return 1;
}
else
{
2019-04-06 22:15:52 +02:00
if (ShouldShowUpArrow())
2019-02-27 08:11:45 +01:00
{
2019-04-06 22:15:52 +02:00
MatchCall_MoveWindow(-1, TRUE);
2019-02-27 08:11:45 +01:00
return 2;
}
else
{
return 0;
}
}
}
2019-04-06 22:15:52 +02:00
u32 MatchCall_MoveCursorDown(void)
2019-02-27 08:11:45 +01:00
{
2019-04-06 22:15:52 +02:00
struct MatchCallWindowState *structPtr;
structPtr = GetMatchCallWindowStruct();
2019-02-27 08:11:45 +01:00
2019-04-06 22:15:52 +02:00
if (structPtr->windowTopIndex + structPtr->selectedIndexOffset < structPtr->listLength - 1)
2019-02-27 08:11:45 +01:00
{
2019-04-06 22:15:52 +02:00
if (structPtr->selectedIndexOffset < structPtr->visibleEntries - 1)
2019-02-27 08:11:45 +01:00
{
2019-04-06 22:15:52 +02:00
structPtr->selectedIndexOffset++;
2019-02-27 08:11:45 +01:00
return 1;
}
2019-04-06 22:15:52 +02:00
else if (!ShouldShowDownArrow())
2019-02-27 08:11:45 +01:00
{
return 0;
}
}
else
{
return 0;
}
2019-04-06 22:15:52 +02:00
MatchCall_MoveWindow(1, TRUE);
2019-02-27 08:11:45 +01:00
return 2;
}
2019-04-06 22:15:52 +02:00
u32 MatchCall_PageUp(void)
2019-02-27 08:11:45 +01:00
{
2019-04-06 22:15:52 +02:00
struct MatchCallWindowState *structPtr;
s32 scroll;
2019-02-27 08:11:45 +01:00
2019-04-06 22:15:52 +02:00
structPtr = GetMatchCallWindowStruct();
if (ShouldShowUpArrow())
2019-02-27 08:11:45 +01:00
{
2019-04-06 22:15:52 +02:00
if (structPtr->windowTopIndex >= structPtr->visibleEntries)
scroll = structPtr->visibleEntries;
2019-02-27 08:11:45 +01:00
else
2019-04-06 22:15:52 +02:00
scroll = structPtr->windowTopIndex;
MatchCall_MoveWindow(scroll * -1, TRUE);
2019-02-27 08:11:45 +01:00
return 2;
}
2019-04-06 22:15:52 +02:00
else if (structPtr->selectedIndexOffset != 0)
2019-02-27 08:11:45 +01:00
{
2019-04-06 22:15:52 +02:00
structPtr->selectedIndexOffset = 0;
2019-02-27 08:11:45 +01:00
return 1;
}
else
{
return 0;
}
}
2019-04-06 22:15:52 +02:00
u32 MatchCall_PageDown(void)
2019-02-27 08:11:45 +01:00
{
2019-04-06 22:15:52 +02:00
struct MatchCallWindowState *structPtr;
structPtr = GetMatchCallWindowStruct();
2019-02-27 08:11:45 +01:00
2019-04-06 22:15:52 +02:00
if (ShouldShowDownArrow())
2019-02-27 08:11:45 +01:00
{
2019-04-06 22:15:52 +02:00
s32 scroll;
s32 windowBottomIndex;
2019-02-27 08:11:45 +01:00
s32 v3;
2019-04-06 22:15:52 +02:00
windowBottomIndex = structPtr->windowTopIndex + structPtr->visibleEntries;
scroll = structPtr->unk4 - structPtr->windowTopIndex;
if (windowBottomIndex <= structPtr->unk4)
scroll = structPtr->visibleEntries;
MatchCall_MoveWindow(scroll, TRUE);
2019-02-27 08:11:45 +01:00
return 2;
}
else
{
2019-04-06 22:15:52 +02:00
s32 cursor;
s32 lastVisibleIndex;
if (structPtr->listLength >= structPtr->visibleEntries)
2019-02-27 08:11:45 +01:00
{
2019-04-06 22:15:52 +02:00
cursor = structPtr->selectedIndexOffset;
lastVisibleIndex = structPtr->visibleEntries;
2019-02-27 08:11:45 +01:00
}
else
{
2019-04-06 22:15:52 +02:00
cursor = structPtr->selectedIndexOffset;
lastVisibleIndex = structPtr->listLength;
2019-02-27 08:11:45 +01:00
}
2019-04-06 22:15:52 +02:00
lastVisibleIndex -= 1;
if (cursor >= lastVisibleIndex)
2019-02-27 08:11:45 +01:00
{
return 0;
}
else
{
2019-04-06 22:15:52 +02:00
structPtr->selectedIndexOffset = lastVisibleIndex;
2019-02-27 08:11:45 +01:00
return 1;
}
}
}
2019-04-06 22:15:52 +02:00
u32 GetSelectedMatchCall(void)
2019-02-27 08:11:45 +01:00
{
2019-04-06 22:15:52 +02:00
struct MatchCallWindowState *structPtr;
structPtr = GetMatchCallWindowStruct();
2019-02-27 08:11:45 +01:00
2019-04-06 22:15:52 +02:00
return structPtr->windowTopIndex + structPtr->selectedIndexOffset;
2019-02-27 08:11:45 +01:00
}
2019-04-06 22:15:52 +02:00
u32 GetMatchCallListTopIndex(void)
2019-02-27 08:11:45 +01:00
{
2019-04-06 22:15:52 +02:00
struct MatchCallWindowState *structPtr;
structPtr = GetMatchCallWindowStruct();
2019-02-27 08:11:45 +01:00
2019-04-06 22:15:52 +02:00
return structPtr->windowTopIndex;
2019-02-27 08:11:45 +01:00
}
void sub_81C877C(void)
{
struct UnknownSubStruct_81C81D4 *structPtr;
structPtr = GetSubstructPtr(0x11);
structPtr->unk89C = 0;
2019-04-06 22:15:52 +02:00
structPtr->unk8A0 = CreateLoopedTask(LoopedTask_sub_81C8870, 6);
2019-02-27 08:11:45 +01:00
}
void sub_81C87AC(u16 a0)
{
u16 temp;
struct UnknownSubStruct_81C81D4 *structPtr;
structPtr = GetSubstructPtr(0x11);
2019-04-06 22:15:52 +02:00
temp = structPtr->unk888.windowTopIndex;
2019-02-27 08:11:45 +01:00
temp += a0;
2019-04-06 22:15:52 +02:00
structPtr->unk888.windowTopIndex = temp;
2019-02-27 08:11:45 +01:00
structPtr->unk89C = 0;
2019-04-06 22:15:52 +02:00
structPtr->unk8A0 = CreateLoopedTask(LoopedTask_sub_81C8958, 6);
2019-03-15 07:33:55 +01:00
}
void sub_81C87F0(void)
{
struct UnknownSubStruct_81C81D4 *structPtr;
structPtr = GetSubstructPtr(0x11);
structPtr->unk89C = 0;
2019-04-06 22:15:52 +02:00
structPtr->unk8A0 = CreateLoopedTask(LoopedTask_sub_81C8A28, 6);
2019-03-15 07:33:55 +01:00
}
bool32 sub_81C8820(void)
{
struct UnknownSubStruct_81C81D4 *structPtr;
structPtr = GetSubstructPtr(0x11);
2019-04-06 22:15:52 +02:00
return IsLoopedTaskActive(structPtr->unk8A0);
2019-03-15 07:33:55 +01:00
}
void sub_81C8838(void)
{
struct UnknownSubStruct_81C81D4 *structPtr;
2019-04-06 22:15:52 +02:00
struct MatchCallWindowState *subStr;
2019-03-15 07:33:55 +01:00
structPtr = GetSubstructPtr(0x11);
subStr = &structPtr->unk888;
2019-04-06 22:15:52 +02:00
structPtr->unk0.unk38(structPtr->unk0.unk0.windowId, subStr->windowTopIndex + subStr->selectedIndexOffset, (structPtr->unk0.unk0.unkA + subStr->selectedIndexOffset) & 0xF);
CopyWindowToVram(structPtr->unk0.unk0.windowId, 1);
2019-03-15 07:33:55 +01:00
}
2019-04-06 22:15:52 +02:00
u32 LoopedTask_sub_81C8870(s32 a0)
2019-03-15 07:33:55 +01:00
{
struct UnknownSubStruct_81C81D4 *structPtr;
u16 v1;
u32 v2;
// Needed to fix a register renaming issue.
register u16* temp asm("r1");
structPtr = GetSubstructPtr(0x11);
switch (a0)
{
case 0:
ToggleMatchCallArrows(&structPtr->unk0, 1);
2019-03-15 07:33:55 +01:00
// fall-through
case 1:
2019-04-06 22:15:52 +02:00
if (structPtr->unk89C != structPtr->unk888.selectedIndexOffset)
sub_81C8B70(&structPtr->unk0.unk0, structPtr->unk89C, 1);
2019-03-15 07:33:55 +01:00
structPtr->unk89C++;
return 0;
case 2:
if (IsDma3ManagerBusyWithBgCopy())
return 2;
2019-04-06 22:15:52 +02:00
if (structPtr->unk89C != structPtr->unk888.visibleEntries)
2019-03-15 07:33:55 +01:00
return 6;
2019-04-06 22:15:52 +02:00
if (structPtr->unk888.selectedIndexOffset != 0)
sub_81C8B70(&structPtr->unk0.unk0, structPtr->unk89C, structPtr->unk888.selectedIndexOffset);
2019-03-15 07:33:55 +01:00
return 0;
case 3:
if (IsDma3ManagerBusyWithBgCopy())
return 2;
2019-04-06 22:15:52 +02:00
temp = &structPtr->unk888.selectedIndexOffset;
2019-03-15 07:33:55 +01:00
v1 = *temp;
if (v1 == 0)
return 4;
2019-04-06 22:15:52 +02:00
MatchCall_MoveWindow(v1, FALSE);
2019-03-15 07:33:55 +01:00
return 0;
case 4:
v2 = sub_81C8630();
if (v2)
return 2;
2019-04-06 22:15:52 +02:00
structPtr->unk888.selectedIndexOffset = v2;
2019-03-15 07:33:55 +01:00
return 4;
default:
return 4;
}
}
2019-04-06 22:15:52 +02:00
u32 LoopedTask_sub_81C8958(s32 a0)
{
struct UnknownSubStruct_81C81D4 *structPtr;
structPtr = GetSubstructPtr(0x11);
if (IsDma3ManagerBusyWithBgCopy())
return 2;
switch (a0)
{
case 0:
sub_81C8CB4(&structPtr->unk888, &structPtr->unk0);
break;
case 1:
PrintMatchCallFieldNames(&structPtr->unk0, 0);
break;
case 2:
sub_81C8E54(&structPtr->unk888, &structPtr->unk0, 0);
break;
case 3:
PrintMatchCallFieldNames(&structPtr->unk0, 1);
break;
case 4:
sub_81C8E54(&structPtr->unk888, &structPtr->unk0, 1);
break;
case 5:
PrintMatchCallFieldNames(&structPtr->unk0, 2);
break;
case 6:
sub_81C8E54(&structPtr->unk888, &structPtr->unk0, 2);
break;
case 7:
sub_81C8E54(&structPtr->unk888, &structPtr->unk0, 3);
break;
default:
return 4;
}
return 0;
}
2019-04-06 22:15:52 +02:00
u32 LoopedTask_sub_81C8A28(s32 a0)
{
struct UnknownSubStruct_81C81D4 *structPtr;
2019-04-06 22:15:52 +02:00
struct MatchCallWindowState *subPtr888;
register struct UnknownInnerStruct_81C81D4 *subPtr0 asm("r2");
s32 v4;
if (IsDma3ManagerBusyWithBgCopy())
{
return 2;
}
structPtr = GetSubstructPtr(0x11);
subPtr888 = &structPtr->unk888;
subPtr0 = &structPtr->unk0;
switch (a0)
{
default:
return 4;
case 0:
sub_81C8D4C(subPtr888, subPtr0);
return 0;
case 1:
{
s32 v1;
s32 v2;
u32 *v3;
register s32 v4 asm("r5");
v3 = &structPtr->unk89C;
v1 = *v3 + 1;
*v3 = v1;
2019-04-06 22:15:52 +02:00
if (v1 < structPtr->unk888.visibleEntries)
{
sub_81C8B70(&subPtr0->unk0, v1, 1);
return 2;
}
*v3 = 0;
2019-04-06 22:15:52 +02:00
if (subPtr888->listLength <= subPtr888->visibleEntries)
{
register u32 temp asm("r0");
2019-04-06 22:15:52 +02:00
temp = subPtr888->windowTopIndex;
if (temp == 0)
return 9;
v2 = temp;
}
else
{
register s32 temp asm("r1");
2019-04-06 22:15:52 +02:00
v2 = subPtr888->windowTopIndex + subPtr888->visibleEntries;
temp = (s32)subPtr888->listLength;
if (v2 <= temp)
return 9;
v2 -= temp;
}
v4 = v2 * -1;
sub_81C8B70(&subPtr0->unk0, v4, v2);
2019-04-06 22:15:52 +02:00
subPtr888->selectedIndexOffset = v2;
*v3 = v4;
return 0;
}
case 2:
2019-04-06 22:15:52 +02:00
MatchCall_MoveWindow(structPtr->unk89C, FALSE);
return 0;
case 3:
if (sub_81C8630())
return 2;
structPtr->unk89C = 0;
return 1;
case 4:
2019-04-06 22:15:52 +02:00
sub_81C83AC(subPtr888->unk10, subPtr888->windowTopIndex + structPtr->unk89C, 1, subPtr888->unkC, structPtr->unk89C, &structPtr->unk0);
return 0;
case 5:
if (sub_81C83E0())
return 2;
v4 = ++structPtr->unk89C;
2019-04-06 22:15:52 +02:00
if (v4 >= subPtr888->listLength || v4 >= subPtr888->visibleEntries)
return 1;
return 9;
case 6:
ToggleMatchCallArrows(subPtr0, 0);
return 4;
}
}
void sub_81C8B70(struct UnknownSubSubStruct_0203CF40 *a0, u32 a1, u32 a2)
{
u8 *v1;
u32 v2;
v1 = (u8*)GetWindowAttribute(a0->windowId, WINDOW_TILE_DATA);
v2 = a0->unk4 * 64;
a1 = (a0->unkA + a1) & 0xF;
if ((s32)(a1 + a2) <= 16)
{
CpuFastFill8(PIXEL_FILL(1), v1 + a1 * v2, a2 * v2);
CopyWindowToVram(a0->windowId, 2);
}
else
{
u32 v3;
u32 v4;
v3 = 16 - a1;
v4 = a2 - v3;
CpuFastFill8(PIXEL_FILL(1), v1 + a1 * v2, v3 * v2);
CpuFastFill8(PIXEL_FILL(1), v1, v4 * v2);
CopyWindowToVram(a0->windowId, 2);
}
a2 -= 1;
for (a2; a2 != -1; a1 = (a1 + 1) & 0xF, a2--)
{
sub_81CBD48(a0->windowId, a1);
}
CopyWindowToVram(a0->windowId, 1);
}
void sub_81C8C64(struct UnknownSubSubStruct_0203CF40 *a0, u32 a1)
{
u16 *v1;
register u32 v2 asm("r0");
u32 v3;
v1 = (u16*)GetBgTilemapBuffer(GetWindowAttribute(a0->windowId, WINDOW_BG));
v1 = &v1[(a0->unkA << 6) + a0->unk2 - 1];
if (a1 != 0)
{
v2 = a0->unk1 << 12;
v3 = a0->unk6 + 1;
}
else
{
v2 = a0->unk1 << 12;
v3 = a0->unk6;
}
{
register u16 v5 asm("r1");
register u32 v6 asm("r0");
v6 = (v3 | v2);
v6 = v6 << 16;
v5 = v6 >> 16;
v1[0] = v5;
v1[0x20] = v5;
}
}
2019-04-06 22:15:52 +02:00
void sub_81C8CB4(struct MatchCallWindowState *a0, struct UnknownInnerStruct_81C81D4 *a1)
{
u8 colors[3];
memcpy(colors, sPokenavColors_0861FBE4, ARRAY_COUNT(sPokenavColors_0861FBE4));
2019-04-06 22:15:52 +02:00
a1->unk34(a0->unk10 + a0->unkC * a0->windowTopIndex, a1->unkTextBuffer);
a1->unk38(a1->unk0.windowId, a0->windowTopIndex, a1->unk0.unkA);
FillWindowPixelRect(a1->unk0.windowId, PIXEL_FILL(4), 0, a1->unk0.unkA * 16, a1->unk0.unk4 * 8, 16);
AddTextPrinterParameterized3(a1->unk0.windowId, a1->unk0.fontId, 8, (a1->unk0.unkA * 16) + 1, colors, TEXT_SPEED_FF, a1->unkTextBuffer);
sub_81C8C64(&a1->unk0, 1);
CopyWindowRectToVram(a1->unk0.windowId, 3, 0, a1->unk0.unkA * 2, a1->unk0.unk4, 2);
}
2019-04-06 22:15:52 +02:00
void sub_81C8D4C(struct MatchCallWindowState *a0, struct UnknownInnerStruct_81C81D4 *a1)
{
2019-04-06 22:15:52 +02:00
a1->unk34(a0->unk10 + a0->unkC * a0->windowTopIndex, a1->unkTextBuffer);
FillWindowPixelRect(a1->unk0.windowId, PIXEL_FILL(1), 0, a1->unk0.unkA * 16, a1->unk0.unk4 * 8, 16);
AddTextPrinterParameterized(a1->unk0.windowId, a1->unk0.fontId, a1->unkTextBuffer, 8, a1->unk0.unkA * 16 + 1, TEXT_SPEED_FF, NULL);
sub_81C8C64(&a1->unk0, 0);
CopyWindowToVram(a1->unk0.windowId, 3);
}
void PrintMatchCallFieldNames(struct UnknownInnerStruct_81C81D4 *a0, u32 fieldId)
{
const u8 *fieldNames[3];
u8 colors[3];
u32 r4;
u32 r5;
u32 tmp;
u32 one;
memcpy(fieldNames, sMatchCallFieldNames, sizeof(sMatchCallFieldNames));
memcpy(colors, sMatchCallFieldColors, sizeof(sMatchCallFieldColors));
r4 = a0->unk0.unkA;
tmp = fieldId * 2 + 1;
r4 += tmp;
r4 &= 0xF;
FillWindowPixelRect(a0->unk0.windowId, PIXEL_FILL(1), 0, r4 << 4, a0->unk0.unk4, 16);
// This is a fake match. It should be this:
// AddTextPrinterParameterized3(a0->unk0.windowId, 7, 2, r4 << 4 + 1, colors, TEXT_SPEED_FF, fieldNames[fieldId]);
// But the original GCC does some clever reuse of the `1` constant that the current GCC doesn't.
one = 1;
AddTextPrinterParameterized3(a0->unk0.windowId, 7, 2, (r4 << 4) + one, colors, one - 2, fieldNames[fieldId]);
CopyWindowRectToVram(a0->unk0.windowId, 2, 0, r4 << 1, a0->unk0.unk4, 2);
}
2019-04-06 22:15:52 +02:00
void sub_81C8E54(struct MatchCallWindowState *a0, struct UnknownInnerStruct_81C81D4 *a1, u32 a2)
{
const u8 *str;
u32 r6;
r6 = (a1->unk0.unkA + sUnknown_0861FBF7[a2]) & 0xF;
2019-04-06 22:15:52 +02:00
str = sub_81CAFD8(a0->windowTopIndex, a2);
if (str != NULL) {
sub_81DB620(a1->unk0.windowId, 1, r6 * 2, a1->unk0.unk4 - 1, 2);
AddTextPrinterParameterized(a1->unk0.windowId, 7, str, 2, (r6 << 4) + 1, TEXT_SPEED_FF, NULL);
CopyWindowRectToVram(a1->unk0.windowId, 2, 0, r6 * 2, a1->unk0.unk4, 2);
}
}
void sub_81C8ED0(void)
{
u32 i;
const struct CompressedSpriteSheet *ptr;
for (i = 0, ptr = sMatchcallArrowSpriteSheet; i < ARRAY_COUNT(sMatchcallArrowSpriteSheet); ptr++, i++)
{
LoadCompressedSpriteSheet(ptr);
}
Pokenav_AllocAndLoadPalettes(sMatchcallArrowPalette);
}
2019-04-06 22:15:52 +02:00
void sub_81C8EF8(struct MatchCallWindowState *a0, struct UnknownInnerStruct_81C81D4 *a1)
{
register u32 spriteId asm("r3");
s16 temp;
spriteId = (u8)CreateSprite(&sMatchCallRightArrowSprite, a1->unk0.unk2 * 8 + 3, (a1->unk0.unk3 + 1) * 8, 7);
a1->rightArrow = &gSprites[spriteId];
temp = a1->unk0.unk2 * 8 + (a1->unk0.unk4 - 1) * 4;
2019-04-06 22:15:52 +02:00
spriteId = (u8)CreateSprite(&sMatchCallUpDownArrowSprite, temp, a1->unk0.unk3 * 8 + a0->visibleEntries * 16, 7);
a1->downArrow = &gSprites[spriteId];
a1->downArrow->oam.tileNum += 2;
a1->downArrow->callback = SpriteCB_MatchCallDownArrow;
spriteId = (u8)CreateSprite(&sMatchCallUpDownArrowSprite, temp, a1->unk0.unk3 * 8, 7);
a1->upArrow = &gSprites[spriteId];
a1->upArrow->oam.tileNum += 4;
a1->upArrow->callback = SpriteCB_MatchCallUpArrow;
}
void sub_81C8FE0(struct UnknownInnerStruct_81C81D4 *a0)
{
DestroySprite(a0->rightArrow);
DestroySprite(a0->upArrow);
DestroySprite(a0->downArrow);
FreeSpriteTilesByTag(0xA);
FreeSpritePaletteByTag(0x14);
}
void ToggleMatchCallArrows(struct UnknownInnerStruct_81C81D4 *a0, bool32 shouldHide)
{
if (shouldHide)
{
a0->rightArrow->callback = SpriteCallbackDummy;
a0->upArrow->callback = SpriteCallbackDummy;
a0->downArrow->callback = SpriteCallbackDummy;
}
else
{
a0->rightArrow->callback = SpriteCB_MatchCallRightArrow;
a0->upArrow->callback = SpriteCB_MatchCallUpArrow;
a0->downArrow->callback = SpriteCB_MatchCallDownArrow;
}
a0->rightArrow->invisible = shouldHide;
a0->upArrow->invisible = shouldHide;
a0->downArrow->invisible = shouldHide;
}
void SpriteCB_MatchCallRightArrow(struct Sprite *sprite)
{
struct UnknownSubStruct_81C81D4 *structPtr;
structPtr = GetSubstructPtr(0x11);
2019-04-06 22:15:52 +02:00
sprite->pos2.y = structPtr->unk888.selectedIndexOffset << 4;
}
void SpriteCB_MatchCallDownArrow(struct Sprite *sprite)
{
2019-04-06 22:15:52 +02:00
if (sprite->data[7] == 0 && ShouldShowDownArrow())
sprite->invisible = FALSE;
else
sprite->invisible = TRUE;
if (++sprite->data[0] > 3)
{
s16 offset;
sprite->data[0] = 0;
offset = (sprite->data[1] + 1) & 7;
sprite->data[1] = offset;
sprite->pos2.y = offset;
}
}
void SpriteCB_MatchCallUpArrow(struct Sprite *sprite)
{
2019-04-06 22:15:52 +02:00
if (sprite->data[7] == 0 && ShouldShowUpArrow())
sprite->invisible = FALSE;
else
sprite->invisible = TRUE;
if (++sprite->data[0] > 3)
{
s16 offset;
sprite->data[0] = 0;
offset = (sprite->data[1] + 1) & 7;
sprite->data[1] = offset;
sprite->pos2.y = -1 * offset;
}
}
void ToggleMatchCallVerticalArrows(bool32 shouldHide)
{
struct UnknownSubStruct_81C81D4 *structPtr;
structPtr = GetSubstructPtr(0x11);
structPtr->unk0.upArrow->data[7] = shouldHide;
structPtr->unk0.downArrow->data[7] = shouldHide;
}
2019-04-06 22:15:52 +02:00
void sub_81C9160(struct MatchCallWindowState *a0, struct MatchCallListTemplate *a1)
{
u32 unused1 = a0->unk10 = a1->unk0;
u32 v0 = a1->unk6;
u32 zero = 0;
2019-04-06 22:15:52 +02:00
u32 unused2 = a0->windowTopIndex = v0;
u32 v1 = a0->listLength = a1->unk4;
a0->unkC = a1->unk8;
2019-04-06 22:15:52 +02:00
a0->visibleEntries = a1->unkC;
if (a0->visibleEntries >= (u16)v1)
{
2019-04-06 22:15:52 +02:00
a0->windowTopIndex = 0;
a0->unk4 = 0;
2019-04-06 22:15:52 +02:00
a0->selectedIndexOffset = v0;
}
else
{
s32 v2;
2019-04-06 22:15:52 +02:00
a0->unk4 = a0->listLength - a0->visibleEntries;
v2 = a0->windowTopIndex + a0->visibleEntries;
if (v2 > a0->listLength) {
a0->selectedIndexOffset = v2 - a0->listLength;
a0->windowTopIndex = v0 - a0->selectedIndexOffset;
}
else
{
2019-04-06 22:15:52 +02:00
a0->selectedIndexOffset = 0;
}
}
}
2019-04-06 22:15:52 +02:00
u32 sub_81C91AC(struct UnknownInnerStruct_81C81D4 *a0, const struct BgTemplate *a1, struct MatchCallListTemplate *a2, s32 a3)
{
register u32 raw_bg asm("r4") = ((a1->bg) << 30);
u8 bg = raw_bg >> 30;
u32 unknown = 0;
2019-04-06 22:15:52 +02:00
struct WindowTemplate window;
u8 bg_again;
a0->unk0.bg = bg;
a0->unk0.unk6 = a3;
a0->unk34 = a2->unk10;
a0->unk38 = a2->unk14;
a0->unk0.unk1 = a2->unkD;
a0->unk0.unk2 = a2->unk9;
a0->unk0.unk3 = a2->unkB;
a0->unk0.unk4 = a2->unkA;
a0->unk0.fontId = a2->unkE;
2019-04-06 22:15:52 +02:00
window.bg = raw_bg >> 30;
window.tilemapLeft = a2->unk9;
window.tilemapTop = 0;
window.width = a2->unkA;
window.height = 32;
window.paletteNum = a2->unkD;
window.baseBlock = a3 + 2;
a0->unk0.windowId = AddWindow(&window);
if (a0->unk0.windowId == 0xFF)
{
return 0;
}
else
{
a0->unk0.unkA = unknown;
a0->rightArrow = NULL;
a0->upArrow = NULL;
a0->downArrow = NULL;
return 1;
}
}