Document Poketch Matchup Checker (Overlay 44) (#806)
Some checks failed
build / build (push) Has been cancelled

This commit is contained in:
VicSevenT 2025-10-26 17:28:52 -05:00 committed by GitHub
parent 073cb57f43
commit b5d2aa56a7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 877 additions and 890 deletions

View File

@ -0,0 +1,66 @@
#ifndef POKEPLATINUM_POKETCH_MATCHUP_CHECKER_GRAPHICS_H
#define POKEPLATINUM_POKETCH_MATCHUP_CHECKER_GRAPHICS_H
#include "constants/pokemon.h"
#include "applications/poketch/poketch_animation.h"
#include "applications/poketch/poketch_task.h"
#include "bg_window.h"
#define MATCHUP_CHECKER_TASK_SLOTS 4
#define NUM_SPRITES 6
#define SPRITE_BUTTON 0
#define SPRITE_HEART_METER 1
#define SPRITE_LUVDISC_LEFT 2
#define SPRITE_LUVDISC_RIGHT 3
#define SPRITE_MON_ICON_LEFT 4
#define SPRITE_MON_ICON_RIGHT 5
typedef struct MatchupCheckerData {
u32 spriteIndices[MAX_PARTY_SIZE];
u16 species[MAX_PARTY_SIZE];
u16 forms[MAX_PARTY_SIZE];
u8 partySize;
u8 compatibility;
u8 leftMonIdx;
u8 rightMonIdx;
} MatchupCheckerData;
typedef struct MatchupCheckerGraphics {
const MatchupCheckerData *matchupData;
BgConfig *bgConfig;
u32 activeTasks[POKETCH_TASK_SLOT_BASE + MATCHUP_CHECKER_TASK_SLOTS];
PoketchAnimation_AnimationManager *animMan;
PoketchAnimation_AnimatedSpriteData *sprites[NUM_SPRITES];
PoketchAnimation_SpriteData indicatorSpriteData;
PoketchAnimation_SpriteData monIconData;
u32 monIconTileOffset;
BOOL killIndicatorTask;
const int *animationCommands;
u32 commandState;
u32 commandIdx;
fx32 luvdiscOffset;
fx32 offsetStep;
fx32 commandEndOffset;
u32 commandTimer;
} MatchupCheckerGraphics;
enum MatchupCheckerGraphicsTask {
MATCHUP_CHECKER_GRAPHICS_INIT = 0,
MATCHUP_CHECKER_GRAPHICS_FREE,
MATCHUP_CHECKER_GRAPHICS_PRESS_BUTTON,
MATCHUP_CHECKER_GRAPHICS_RELEASE_BUTTON,
MATCHUP_CHECKER_GRAPHICS_UPDATE_LEFT,
MATCHUP_CHECKER_GRAPHICS_UPDATE_RIGHT,
MATCHUP_CHECKER_GRAPHICS_CHECK_MATCHUP,
};
BOOL PoketchMatchupCheckerGraphics_New(MatchupCheckerGraphics **graphics, const MatchupCheckerData *matchupData, BgConfig *bgConfig);
void PoketchMatchupCheckerGraphics_Free(MatchupCheckerGraphics *graphics);
void PoketchMatchupCheckerGraphics_StartTask(MatchupCheckerGraphics *graphics, enum MatchupCheckerGraphicsTask taskID);
BOOL PoketchMatchupCheckerGraphics_TaskIsNotActive(MatchupCheckerGraphics *graphics, enum MatchupCheckerGraphicsTask taskID);
BOOL PoketchMatchupCheckerGraphics_NoActiveTasks(MatchupCheckerGraphics *graphics);
#endif // POKEPLATINUM_POKETCH_MATCHUP_CHECKER_GRAPHICS_H

View File

@ -1,15 +0,0 @@
#ifndef POKEPLATINUM_OV44_022565BC_H
#define POKEPLATINUM_OV44_022565BC_H
#include "overlay044/struct_ov44_022565BC_1.h"
#include "overlay044/struct_ov44_022565BC_decl.h"
#include "bg_window.h"
BOOL ov44_022565BC(UnkStruct_ov44_022565BC **param0, const UnkStruct_ov44_022565BC_1 *param1, BgConfig *param2);
void ov44_022565F8(UnkStruct_ov44_022565BC *param0);
void ov44_02256744(UnkStruct_ov44_022565BC *param0, u32 param1);
BOOL ov44_02256768(UnkStruct_ov44_022565BC *param0, u32 param1);
BOOL ov44_02256774(UnkStruct_ov44_022565BC *param0);
#endif // POKEPLATINUM_OV44_022565BC_H

View File

@ -1,14 +0,0 @@
#ifndef POKEPLATINUM_STRUCT_OV44_022565BC_1_H
#define POKEPLATINUM_STRUCT_OV44_022565BC_1_H
typedef struct {
u32 unk_00[6];
u16 unk_18[6];
u16 unk_24[6];
u8 unk_30;
u8 unk_31;
u8 unk_32;
u8 unk_33;
} UnkStruct_ov44_022565BC_1;
#endif // POKEPLATINUM_STRUCT_OV44_022565BC_1_H

View File

@ -1,6 +0,0 @@
#ifndef POKEPLATINUM_STRUCT_OV44_022565BC_DECL_H
#define POKEPLATINUM_STRUCT_OV44_022565BC_DECL_H
typedef struct UnkStruct_ov44_022565BC_t UnkStruct_ov44_022565BC;
#endif // POKEPLATINUM_STRUCT_OV44_022565BC_DECL_H

View File

@ -1005,11 +1005,11 @@ Overlay poketch_move_tester
Object main.nef.p/src_applications_poketch_move_tester_graphics.c.o
}
Overlay overlay44
Overlay poketch_matchup_checker
{
After overlay25
Object main.nef.p/src_overlay044_ov44_022561C0.c.o
Object main.nef.p/src_overlay044_ov44_022565BC.c.o
Object main.nef.p/src_applications_poketch_matchup_checker_main.c.o
Object main.nef.p/src_applications_poketch_matchup_checker_graphics.c.o
}
Overlay poketch_alarm_clock

View File

@ -43,7 +43,7 @@ f8a583401a3a614cc88ee6dc7f3b3cdbf00f22cb *poketch_daycare_checker.sbin
a5b13f54d5303140b3169c794db0fd04c9c2dc22 *poketch_roulette.sbin
ba5baba0ff38e940d333dbea89e4c510b6998922 *poketch_coin_toss.sbin
261b64d5fd09a304a5d7e78a18b44a6ecfe7ec93 *poketch_move_tester.sbin
5dd962600f238f162c0999dcb8a134c9df134293 *overlay44.sbin
5dd962600f238f162c0999dcb8a134c9df134293 *poketch_matchup_checker.sbin
e722ce81a98e1d78011e179f008a4cac37e20610 *poketch_alarm_clock.sbin
87cd3ac2574737177d399a8cf8a8374c9599e38b *overlay46.sbin
b38da9fe733a6a1213ff217f4e2788e3ae2011a4 *poketch_marking_map.sbin

View File

@ -0,0 +1,490 @@
#include "applications/poketch/matchup_checker/graphics.h"
#include <nitro.h>
#include "generated/sdat.h"
#include "applications/poketch/poketch_animation.h"
#include "applications/poketch/poketch_graphics.h"
#include "applications/poketch/poketch_system.h"
#include "applications/poketch/poketch_task.h"
#include "bg_window.h"
#include "graphics.h"
#include "heap.h"
#include "pokemon.h"
#include "pokemon_icon.h"
#include "sys_task_manager.h"
#define ANIM_COMMAND_END -1
#define ANIM_COMMAND_MOVE_FORWARD -2
#define ANIM_COMMAND_MOVE_BACKWARD -3
#define ANIM_COMMAND_WAIT -4
#define ANIM_COMMAND_PLAY_SOUND -5
#define ANIM_COMMAND_FLIP_LUVDISCS -6
#define ANIM_COMMAND_UPDATE_SPRITE -7
static void SetupSprites(MatchupCheckerGraphics *graphics, const MatchupCheckerData *matchupData);
static void UnloadSprites(MatchupCheckerGraphics *graphics);
static void EndTask(PoketchTaskManager *taskMan);
static void Task_DrawBackground(SysTask *task, void *taskMan);
static void Task_FreeBackground(SysTask *task, void *taskMan);
static void Task_PressButton(SysTask *task, void *taskMan);
static void Task_ReleaseButton(SysTask *task, void *taskMan);
static void Task_UpdateLeftMonIcon(SysTask *task, void *taskMan);
static void Task_UpdateRightMonIcon(SysTask *task, void *taskMan);
static void Task_RunMatchupAnimation(SysTask *task, void *taskMan);
static void UpdateMonIcon(MatchupCheckerGraphics *graphics, u32 spriteIdx, u32 partyIdx, u16 species, u16 form);
static void ResetIndicatorPositions(MatchupCheckerGraphics *graphics);
static void InitAnimationSequence(MatchupCheckerGraphics *graphics, const MatchupCheckerData *matchupData);
static BOOL RunAnimationSequence(MatchupCheckerGraphics *graphics, const MatchupCheckerData *matchupData);
BOOL PoketchMatchupCheckerGraphics_New(MatchupCheckerGraphics **dest, const MatchupCheckerData *matchupData, BgConfig *bgConfig)
{
MatchupCheckerGraphics *graphics = Heap_Alloc(HEAP_ID_POKETCH_APP, sizeof(MatchupCheckerGraphics));
if (graphics != NULL) {
PoketchTask_InitActiveTaskList(graphics->activeTasks, MATCHUP_CHECKER_TASK_SLOTS);
graphics->matchupData = matchupData;
graphics->bgConfig = PoketchGraphics_GetBgConfig();
graphics->animMan = PoketchGraphics_GetAnimationManager();
SetupSprites(graphics, matchupData);
*dest = graphics;
return TRUE;
}
return FALSE;
}
void PoketchMatchupCheckerGraphics_Free(MatchupCheckerGraphics *graphics)
{
if (graphics != NULL) {
UnloadSprites(graphics);
Heap_Free(graphics);
}
}
static void SetupSprites(MatchupCheckerGraphics *graphics, const MatchupCheckerData *matchupData)
{
static const PoketchAnimation_AnimationData sAnimData[] = {
[SPRITE_BUTTON] = {
.translation = { FX32_CONST(112), FX32_CONST(148) },
.animIdx = 9,
.flip = NNS_G2D_RENDERERFLIP_NONE,
.oamPriority = 2,
.priority = 0,
.hasAffineTransform = FALSE,
},
[SPRITE_HEART_METER] = {
.translation = { FX32_CONST(112), FX32_CONST(32) },
.animIdx = 0,
.flip = NNS_G2D_RENDERERFLIP_NONE,
.oamPriority = 2,
.priority = 1,
.hasAffineTransform = FALSE,
},
[SPRITE_LUVDISC_LEFT] = {
.translation = { FX32_CONST(48), FX32_CONST(88) },
.animIdx = 5,
.flip = NNS_G2D_RENDERERFLIP_NONE,
.oamPriority = 2,
.priority = 0,
.hasAffineTransform = FALSE,
},
[SPRITE_LUVDISC_RIGHT] = {
.translation = { FX32_CONST(176), FX32_CONST(88) },
.animIdx = 6,
.flip = NNS_G2D_RENDERERFLIP_NONE,
.oamPriority = 2,
.priority = 0,
.hasAffineTransform = FALSE,
},
[SPRITE_MON_ICON_LEFT] = {
.translation = { FX32_CONST(48), FX32_CONST(140) },
.animIdx = 5,
.flip = NNS_G2D_RENDERERFLIP_NONE,
.oamPriority = 2,
.priority = 0,
.hasAffineTransform = TRUE,
},
[SPRITE_MON_ICON_RIGHT] = {
.translation = { FX32_CONST(176), FX32_CONST(140) },
.animIdx = 4,
.flip = NNS_G2D_RENDERERFLIP_NONE,
.oamPriority = 2,
.priority = 0,
.hasAffineTransform = TRUE,
},
};
PoketchTask_LoadPokemonIconLuminancePalette(1);
u32 indicatorsTileCount = Graphics_LoadObjectTiles(NARC_INDEX_GRAPHIC__POKETCH, 74, DS_SCREEN_SUB, 0, 0, TRUE, HEAP_ID_POKETCH_APP);
indicatorsTileCount /= 20;
graphics->monIconTileOffset = indicatorsTileCount;
PoketchTask_LoadPokemonIcons(indicatorsTileCount, matchupData->spriteIndices, matchupData->partySize, FALSE);
PoketchAnimation_LoadSpriteFromNARC(&graphics->indicatorSpriteData, NARC_INDEX_GRAPHIC__POKETCH, 72, 73, HEAP_ID_POKETCH_APP);
PoketchAnimation_LoadSpriteFromNARC(&graphics->monIconData, NARC_INDEX_GRAPHIC__POKETCH, 5, 6, HEAP_ID_POKETCH_APP);
int i;
for (i = 0; i < NUM_SPRITES - 2; i++) {
graphics->sprites[i] = PoketchAnimation_SetupNewAnimatedSprite(graphics->animMan, &sAnimData[i], &graphics->indicatorSpriteData);
}
for (; i < NUM_SPRITES; i++) {
graphics->sprites[i] = PoketchAnimation_SetupNewAnimatedSprite(graphics->animMan, &sAnimData[i], &graphics->monIconData);
}
UpdateMonIcon(graphics, SPRITE_MON_ICON_LEFT, matchupData->leftMonIdx, matchupData->species[matchupData->leftMonIdx], matchupData->forms[matchupData->leftMonIdx]);
UpdateMonIcon(graphics, SPRITE_MON_ICON_RIGHT, matchupData->rightMonIdx, matchupData->species[matchupData->rightMonIdx], matchupData->forms[matchupData->rightMonIdx]);
if (matchupData->partySize <= 1) {
PoketchAnimation_HideSprite(graphics->sprites[SPRITE_MON_ICON_RIGHT], TRUE);
PoketchAnimation_HideSprite(graphics->sprites[SPRITE_LUVDISC_RIGHT], TRUE);
PoketchAnimation_UpdateAnimationIdx(graphics->sprites[SPRITE_BUTTON], 10);
}
}
static void UnloadSprites(MatchupCheckerGraphics *graphics)
{
PoketchAnimation_FreeSpriteData(&graphics->monIconData);
PoketchAnimation_FreeSpriteData(&graphics->indicatorSpriteData);
for (int i = 0; i < NUM_SPRITES; i++) {
if (graphics->sprites[i]) {
PoketchAnimation_RemoveAnimatedSprite(graphics->animMan, graphics->sprites[i]);
}
}
}
static const PoketchTask sMatchupCheckerTasks[] = {
{ MATCHUP_CHECKER_GRAPHICS_INIT, Task_DrawBackground, 0 },
{ MATCHUP_CHECKER_GRAPHICS_FREE, Task_FreeBackground, 0 },
{ MATCHUP_CHECKER_GRAPHICS_PRESS_BUTTON, Task_PressButton, 0 },
{ MATCHUP_CHECKER_GRAPHICS_RELEASE_BUTTON, Task_ReleaseButton, 0 },
{ MATCHUP_CHECKER_GRAPHICS_UPDATE_LEFT, Task_UpdateLeftMonIcon, 0 },
{ MATCHUP_CHECKER_GRAPHICS_UPDATE_RIGHT, Task_UpdateRightMonIcon, 0 },
{ MATCHUP_CHECKER_GRAPHICS_CHECK_MATCHUP, Task_RunMatchupAnimation, 0 },
{ 0 }
};
void PoketchMatchupCheckerGraphics_StartTask(MatchupCheckerGraphics *graphics, enum MatchupCheckerGraphicsTask taskID)
{
PoketchTask_Start(sMatchupCheckerTasks, taskID, graphics, graphics->matchupData, graphics->activeTasks, 2, HEAP_ID_POKETCH_APP);
}
BOOL PoketchMatchupCheckerGraphics_TaskIsNotActive(MatchupCheckerGraphics *graphics, enum MatchupCheckerGraphicsTask taskID)
{
return PoketchTask_TaskIsNotActive(graphics->activeTasks, taskID);
}
BOOL PoketchMatchupCheckerGraphics_NoActiveTasks(MatchupCheckerGraphics *graphics)
{
return PoketchTask_NoActiveTasks(graphics->activeTasks);
}
static void EndTask(PoketchTaskManager *taskMan)
{
MatchupCheckerGraphics *graphics = PoketchTask_GetTaskData(taskMan);
PoketchTask_EndTask(graphics->activeTasks, taskMan);
}
static void Task_DrawBackground(SysTask *task, void *taskMan)
{
static const BgTemplate bgTemplate = {
.x = 0,
.y = 0,
.bufferSize = 0x800,
.baseTile = 0,
.screenSize = BG_SCREEN_SIZE_256x256,
.colorMode = GX_BG_COLORMODE_16,
.screenBase = GX_BG_SCRBASE_0x7000,
.charBase = GX_BG_CHARBASE_0x00000,
.bgExtPltt = GX_BG_EXTPLTT_01,
.priority = 2,
.areaOver = 0,
.mosaic = FALSE,
};
MatchupCheckerGraphics *graphics = PoketchTask_GetTaskData(taskMan);
const MatchupCheckerData *matchupData = PoketchTask_GetConstTaskData(taskMan);
Bg_InitFromTemplate(graphics->bgConfig, BG_LAYER_SUB_2, &bgTemplate, BG_TYPE_STATIC);
Graphics_LoadTilesToBgLayer(NARC_INDEX_GRAPHIC__POKETCH, 71, graphics->bgConfig, BG_LAYER_SUB_2, 0, 0, TRUE, HEAP_ID_POKETCH_APP);
Graphics_LoadTilemapToBgLayer(NARC_INDEX_GRAPHIC__POKETCH, 70, graphics->bgConfig, BG_LAYER_SUB_2, 0, 0, TRUE, HEAP_ID_POKETCH_APP);
PoketchGraphics_LoadActivePalette(0, 0);
Bg_CopyTilemapBufferToVRAM(graphics->bgConfig, BG_LAYER_SUB_2);
GXSDispCnt dispCnt = GXS_GetDispCnt();
GXS_SetVisiblePlane(dispCnt.visiblePlane | GX_PLANEMASK_BG2);
EndTask(taskMan);
}
static void Task_FreeBackground(SysTask *task, void *taskMan)
{
MatchupCheckerGraphics *graphics = PoketchTask_GetTaskData(taskMan);
switch (PoketchTask_GetState(taskMan)) {
case 0:
graphics->killIndicatorTask = TRUE;
PoketchTask_IncrementState(taskMan);
break;
case 1:
if (PoketchMatchupCheckerGraphics_TaskIsNotActive(graphics, MATCHUP_CHECKER_GRAPHICS_CHECK_MATCHUP)) {
Bg_FreeTilemapBuffer(graphics->bgConfig, BG_LAYER_SUB_2);
EndTask(taskMan);
}
break;
}
}
static void Task_PressButton(SysTask *task, void *taskMan)
{
MatchupCheckerGraphics *graphics = PoketchTask_GetTaskData(taskMan);
const MatchupCheckerData *matchupData = PoketchTask_GetConstTaskData(taskMan);
PoketchSystem_PlaySoundEffect(SEQ_SE_DP_POKETCH_010);
PoketchAnimation_UpdateAnimationIdx(graphics->sprites[SPRITE_BUTTON], 10);
EndTask(taskMan);
}
static void Task_ReleaseButton(SysTask *task, void *taskMan)
{
MatchupCheckerGraphics *graphics = PoketchTask_GetTaskData(taskMan);
const MatchupCheckerData *matchupData = PoketchTask_GetConstTaskData(taskMan);
PoketchAnimation_UpdateAnimationIdx(graphics->sprites[SPRITE_BUTTON], 9);
EndTask(taskMan);
}
static void Task_UpdateLeftMonIcon(SysTask *task, void *taskMan)
{
MatchupCheckerGraphics *graphics = PoketchTask_GetTaskData(taskMan);
const MatchupCheckerData *matchupData = PoketchTask_GetConstTaskData(taskMan);
int idx = matchupData->leftMonIdx;
PoketchSystem_PlayCry(matchupData->species[idx], matchupData->forms[idx]);
UpdateMonIcon(graphics, SPRITE_MON_ICON_LEFT, idx, matchupData->species[idx], matchupData->forms[idx]);
ResetIndicatorPositions(graphics);
EndTask(taskMan);
}
static void Task_UpdateRightMonIcon(SysTask *task, void *taskMan)
{
MatchupCheckerGraphics *graphics = PoketchTask_GetTaskData(taskMan);
const MatchupCheckerData *matchupData = PoketchTask_GetConstTaskData(taskMan);
int idx = matchupData->rightMonIdx;
PoketchSystem_PlayCry(matchupData->species[idx], matchupData->forms[idx]);
UpdateMonIcon(graphics, SPRITE_MON_ICON_RIGHT, idx, matchupData->species[idx], matchupData->forms[idx]);
ResetIndicatorPositions(graphics);
EndTask(taskMan);
}
static void UpdateMonIcon(MatchupCheckerGraphics *graphics, u32 spriteIdx, u32 partyIdx, u16 species, u16 form)
{
PoketchAnimation_AnimatedSpriteData *sprite = graphics->sprites[spriteIdx];
u32 animIdx;
if (spriteIdx == SPRITE_MON_ICON_RIGHT) {
animIdx = 4;
} else {
if (SpeciesData_GetFormValue(species, form, SPECIES_DATA_FLIP_SPRITE)) {
animIdx = 4;
} else {
animIdx = 5;
}
}
PoketchAnimation_UpdateAnimationIdx(sprite, animIdx);
PoketchAnimation_SetSpriteCharNo(sprite, graphics->monIconTileOffset + partyIdx * 16);
PoketchAnimation_SetCParam(sprite, 1 + PokeIconPaletteIndex(species, form, 0));
}
static void ResetIndicatorPositions(MatchupCheckerGraphics *graphics)
{
PoketchAnimation_SetSpritePosition(graphics->sprites[SPRITE_LUVDISC_LEFT], FX32_CONST(48), FX32_CONST(88));
PoketchAnimation_SetSpritePosition(graphics->sprites[SPRITE_LUVDISC_RIGHT], FX32_CONST(176), FX32_CONST(88));
PoketchAnimation_UpdateAnimationIdx(graphics->sprites[SPRITE_LUVDISC_LEFT], 5);
PoketchAnimation_UpdateAnimationIdx(graphics->sprites[SPRITE_LUVDISC_RIGHT], 6);
PoketchAnimation_UpdateAnimationIdx(graphics->sprites[SPRITE_HEART_METER], 0);
}
static void Task_RunMatchupAnimation(SysTask *task, void *taskMan)
{
MatchupCheckerGraphics *graphics = PoketchTask_GetTaskData(taskMan);
const MatchupCheckerData *matchupData = PoketchTask_GetConstTaskData(taskMan);
u32 indicatorState = PoketchTask_GetState(taskMan);
if (indicatorState != 0 && graphics->killIndicatorTask) {
EndTask(taskMan);
return;
}
switch (PoketchTask_GetState(taskMan)) {
case 0:
graphics->killIndicatorTask = FALSE;
ResetIndicatorPositions(graphics);
InitAnimationSequence(graphics, matchupData);
PoketchTask_IncrementState(taskMan);
break;
case 1:
if (RunAnimationSequence(graphics, matchupData)) {
EndTask(taskMan);
}
break;
}
}
// clang-format off
static const int sCommandsIncompatible[] = {
ANIM_COMMAND_MOVE_FORWARD, 16, 16,
ANIM_COMMAND_WAIT, 16,
ANIM_COMMAND_FLIP_LUVDISCS,
ANIM_COMMAND_PLAY_SOUND, SEQ_SE_DP_POKETCH_013,
ANIM_COMMAND_MOVE_BACKWARD, 16, 16,
ANIM_COMMAND_END
};
static const int sCommandsLowCompatibility[] = {
ANIM_COMMAND_MOVE_FORWARD, 16, 16,
ANIM_COMMAND_PLAY_SOUND, SEQ_SE_DP_POKETCH_012,
ANIM_COMMAND_END
};
static const int sCommandsMedCompatibility[] = {
ANIM_COMMAND_MOVE_FORWARD, 16, 16,
ANIM_COMMAND_PLAY_SOUND, SEQ_SE_DP_POKETCH_012,
ANIM_COMMAND_MOVE_FORWARD, 16, 16,
ANIM_COMMAND_PLAY_SOUND, SEQ_SE_DP_POKETCH_012,
ANIM_COMMAND_END
};
static const int sCommandsMaxCompatibility[] = {
ANIM_COMMAND_MOVE_FORWARD, 16, 16,
ANIM_COMMAND_PLAY_SOUND, SEQ_SE_DP_POKETCH_012,
ANIM_COMMAND_MOVE_FORWARD, 16, 16,
ANIM_COMMAND_PLAY_SOUND, SEQ_SE_DP_POKETCH_012,
ANIM_COMMAND_MOVE_FORWARD, 16, 16,
ANIM_COMMAND_PLAY_SOUND, SEQ_SE_DP_POKETCH_012,
ANIM_COMMAND_WAIT, 16,
ANIM_COMMAND_PLAY_SOUND, SEQ_SE_DP_POKETCH_014,
ANIM_COMMAND_UPDATE_SPRITE, SPRITE_LUVDISC_LEFT, 7,
ANIM_COMMAND_UPDATE_SPRITE, SPRITE_LUVDISC_RIGHT, 8,
ANIM_COMMAND_UPDATE_SPRITE, SPRITE_HEART_METER, 4,
ANIM_COMMAND_WAIT, 16,
ANIM_COMMAND_END
};
// clang-format on
static void InitAnimationSequence(MatchupCheckerGraphics *graphics, const MatchupCheckerData *matchupData)
{
graphics->commandState = 0;
graphics->commandIdx = 0;
graphics->luvdiscOffset = 0;
graphics->commandTimer = 0;
switch (matchupData->compatibility) {
case 3:
graphics->animationCommands = sCommandsIncompatible;
break;
case 2:
graphics->animationCommands = sCommandsLowCompatibility;
PoketchAnimation_UpdateAnimationIdx(graphics->sprites[SPRITE_HEART_METER], 1);
break;
case 1:
graphics->animationCommands = sCommandsMedCompatibility;
PoketchAnimation_UpdateAnimationIdx(graphics->sprites[SPRITE_HEART_METER], 2);
break;
case 0:
graphics->animationCommands = sCommandsMaxCompatibility;
PoketchAnimation_UpdateAnimationIdx(graphics->sprites[SPRITE_HEART_METER], 3);
break;
}
RunAnimationSequence(graphics, matchupData);
}
static BOOL RunAnimationSequence(MatchupCheckerGraphics *graphics, const MatchupCheckerData *matchupData)
{
func_start:
switch (graphics->commandState) {
case 0:
while (graphics->commandState == 0) {
switch (graphics->animationCommands[graphics->commandIdx++]) {
case ANIM_COMMAND_END:
return TRUE;
case ANIM_COMMAND_MOVE_FORWARD:
graphics->commandTimer = graphics->animationCommands[graphics->commandIdx++];
graphics->offsetStep = graphics->animationCommands[graphics->commandIdx++];
graphics->offsetStep *= FX32_ONE;
graphics->commandEndOffset = graphics->luvdiscOffset + graphics->offsetStep;
graphics->offsetStep /= graphics->commandTimer;
graphics->commandState = 1;
break;
case ANIM_COMMAND_MOVE_BACKWARD:
graphics->commandTimer = graphics->animationCommands[graphics->commandIdx++];
graphics->offsetStep = graphics->animationCommands[graphics->commandIdx++];
graphics->offsetStep *= FX32_ONE;
graphics->offsetStep *= -1;
graphics->commandEndOffset = graphics->luvdiscOffset + graphics->offsetStep;
graphics->offsetStep /= graphics->commandTimer;
graphics->commandState = 1;
break;
case ANIM_COMMAND_WAIT:
graphics->commandTimer = graphics->animationCommands[graphics->commandIdx++];
graphics->commandState = 2;
break;
case ANIM_COMMAND_PLAY_SOUND:
PoketchSystem_PlaySoundEffect(graphics->animationCommands[graphics->commandIdx++]);
break;
case ANIM_COMMAND_FLIP_LUVDISCS:
PoketchAnimation_UpdateAnimationIdx(graphics->sprites[SPRITE_LUVDISC_LEFT], 6);
PoketchAnimation_UpdateAnimationIdx(graphics->sprites[SPRITE_LUVDISC_RIGHT], 5);
break;
case ANIM_COMMAND_UPDATE_SPRITE:
u32 sprite = graphics->animationCommands[graphics->commandIdx++];
u32 animIdx = graphics->animationCommands[graphics->commandIdx++];
PoketchAnimation_UpdateAnimationIdx(graphics->sprites[sprite], animIdx);
break;
}
}
break;
case 1:
if (graphics->commandTimer) {
graphics->commandTimer--;
if (graphics->commandTimer) {
graphics->luvdiscOffset += graphics->offsetStep;
} else {
graphics->luvdiscOffset = graphics->commandEndOffset;
}
PoketchAnimation_SetSpritePosition(graphics->sprites[SPRITE_LUVDISC_LEFT], FX32_CONST(48) + graphics->luvdiscOffset, FX32_CONST(88));
PoketchAnimation_SetSpritePosition(graphics->sprites[SPRITE_LUVDISC_RIGHT], FX32_CONST(176) - graphics->luvdiscOffset, FX32_CONST(88));
}
if (graphics->commandTimer == 0) {
graphics->commandState = 0;
goto func_start;
}
break;
case 2:
if (graphics->commandTimer) {
graphics->commandTimer--;
} else {
graphics->commandState = 0;
goto func_start;
}
break;
}
return FALSE;
}

View File

@ -0,0 +1,313 @@
#include <nitro.h>
#include <nitro/sinit.h>
#include "constants/pokemon.h"
#include "generated/sdat.h"
#include "applications/poketch/matchup_checker/graphics.h"
#include "applications/poketch/poketch_button.h"
#include "applications/poketch/poketch_system.h"
#include "overlay005/daycare.h"
#include "bg_window.h"
#include "heap.h"
#include "party.h"
#include "pokemon.h"
#include "pokemon_icon.h"
#include "sys_task.h"
#include "sys_task_manager.h"
#include "touch_screen.h"
#define BUTTON_CHECK_MATCHUP 0
#define BUTTON_CHANGE_LEFT_MON 1
#define BUTTON_CHANGE_RIGHT_MON 2
typedef struct PoketchMatchupChecker {
u8 state;
u8 subState;
u8 shouldExit;
MatchupCheckerData matchupData;
MatchupCheckerGraphics *graphics;
PoketchSystem *poketchSys;
PoketchButtonManager *buttonManager;
u16 pressedButton;
u16 buttonState;
BoxPokemon *pokemon[MAX_PARTY_SIZE];
BoxPokemon *boxMonPair[2];
} PoketchMatchupChecker;
typedef BOOL (*StateFunc)(PoketchMatchupChecker *);
enum MatchupCheckerState {
STATE_LOAD_APP = 0,
STATE_UPDATE_LOOP,
STATE_SHUTDOWN,
};
static void NitroStaticInit(void);
static BOOL New(void **appData, PoketchSystem *poketchSys, BgConfig *bgConfig, u32 appID);
static BOOL Init(PoketchMatchupChecker *appData, PoketchSystem *poketchSys, BgConfig *bgConfig, u32 appID);
static void Free(PoketchMatchupChecker *appData);
static void Exit(void *appData);
static void ButtonCallback(u32 buttonID, u32 buttonState, u32 touchState, void *appData);
static void Task_Main(SysTask *task, void *appData);
static void ChangeState(PoketchMatchupChecker *appData, enum MatchupCheckerState newState);
static BOOL State_LoadApp(PoketchMatchupChecker *appData);
static BOOL State_UpdateApp(PoketchMatchupChecker *appData);
static BOOL State_UnloadApp(PoketchMatchupChecker *appData);
static BOOL UpdateLeftMon(PoketchMatchupChecker *appData);
static BOOL UpdateRightMon(PoketchMatchupChecker *appData);
static void NitroStaticInit(void)
{
PoketchSystem_SetAppFunctions(New, Exit);
}
static BOOL New(void **appData, PoketchSystem *poketchSys, BgConfig *bgConfig, u32 appID)
{
PoketchMatchupChecker *matchupChecker = Heap_Alloc(HEAP_ID_POKETCH_APP, sizeof(PoketchMatchupChecker));
if (matchupChecker != NULL) {
if (Init(matchupChecker, poketchSys, bgConfig, appID)) {
if (SysTask_Start(Task_Main, matchupChecker, 1) != NULL) {
*appData = matchupChecker;
return TRUE;
}
}
Heap_Free(matchupChecker);
}
return FALSE;
}
static BOOL Init(PoketchMatchupChecker *appData, PoketchSystem *poketchSys, BgConfig *bgConfig, u32 appID)
{
Party *party = SaveData_GetParty(PoketchSystem_GetSaveData(poketchSys));
int nonEggMon = 0;
appData->matchupData.partySize = Party_GetCurrentCount(party);
for (int i = 0; i < appData->matchupData.partySize; i++) {
Pokemon *pokemon = Party_GetPokemonBySlotIndex(party, i);
if (Pokemon_GetValue(pokemon, MON_DATA_IS_EGG, NULL)) {
continue;
}
appData->matchupData.spriteIndices[nonEggMon] = BoxPokemon_IconSpriteIndex((const BoxPokemon *)pokemon);
appData->matchupData.species[nonEggMon] = Pokemon_GetValue(pokemon, MON_DATA_SPECIES, NULL);
appData->matchupData.forms[nonEggMon] = Pokemon_GetValue(pokemon, MON_DATA_FORM, NULL);
appData->pokemon[nonEggMon] = (BoxPokemon *)pokemon;
nonEggMon++;
}
appData->matchupData.partySize = nonEggMon;
appData->matchupData.leftMonIdx = 0;
appData->matchupData.rightMonIdx = appData->matchupData.partySize > 1 ? 1 : 0;
if (PoketchMatchupCheckerGraphics_New(&appData->graphics, &appData->matchupData, bgConfig)) {
static const TouchScreenRect sHitboxes[] = {
[BUTTON_CHECK_MATCHUP] = { .rect = { .top = 128, .bottom = 168, .left = 92, .right = 132 } },
[BUTTON_CHANGE_LEFT_MON] = { .rect = { .top = 130, .bottom = 164, .left = 24, .right = 72 } },
[BUTTON_CHANGE_RIGHT_MON] = { .rect = { .top = 130, .bottom = 164, .left = 152, .right = 200 } }
};
appData->state = STATE_LOAD_APP;
appData->subState = 0;
appData->shouldExit = FALSE;
appData->buttonManager = PoketchButtonManager_New(sHitboxes, NELEMS(sHitboxes), ButtonCallback, appData, HEAP_ID_POKETCH_APP);
appData->buttonState = BUTTON_MANAGER_STATE_NULL;
appData->poketchSys = poketchSys;
return TRUE;
}
return FALSE;
}
static void Free(PoketchMatchupChecker *appData)
{
PoketchButtonManager_Free(appData->buttonManager);
PoketchMatchupCheckerGraphics_Free(appData->graphics);
Heap_Free(appData);
}
static void ButtonCallback(u32 buttonID, u32 buttonState, u32 touchState, void *appData)
{
PoketchMatchupChecker *matchupChecker = appData;
matchupChecker->pressedButton = buttonID;
matchupChecker->buttonState = buttonState;
}
static void Task_Main(SysTask *task, void *appData)
{
static const StateFunc stateFuncs[] = {
State_LoadApp,
State_UpdateApp,
State_UnloadApp,
};
PoketchMatchupChecker *matchupChecker = appData;
if (matchupChecker->state < NELEMS(stateFuncs)) {
PoketechSystem_UpdateButtonManager(matchupChecker->poketchSys, matchupChecker->buttonManager);
if (stateFuncs[matchupChecker->state](matchupChecker)) {
Free(matchupChecker);
SysTask_Done(task);
PoketchSystem_NotifyAppUnloaded(matchupChecker->poketchSys);
}
}
}
static void Exit(void *appData)
{
((PoketchMatchupChecker *)appData)->shouldExit = TRUE;
}
static void ChangeState(PoketchMatchupChecker *appData, enum MatchupCheckerState newState)
{
if (appData->shouldExit == FALSE) {
appData->state = newState;
} else {
appData->state = STATE_SHUTDOWN;
}
appData->subState = 0;
}
static BOOL State_LoadApp(PoketchMatchupChecker *appData)
{
switch (appData->subState) {
case 0:
PoketchMatchupCheckerGraphics_StartTask(appData->graphics, MATCHUP_CHECKER_GRAPHICS_INIT);
appData->subState++;
break;
case 1:
if (PoketchMatchupCheckerGraphics_TaskIsNotActive(appData->graphics, MATCHUP_CHECKER_GRAPHICS_INIT)) {
PoketchSystem_NotifyAppLoaded(appData->poketchSys);
ChangeState(appData, STATE_UPDATE_LOOP);
}
break;
}
return FALSE;
}
static BOOL State_UpdateApp(PoketchMatchupChecker *appData)
{
if (appData->shouldExit) {
ChangeState(appData, STATE_SHUTDOWN);
return FALSE;
}
switch (appData->subState) {
case 0:
if (appData->buttonState == BUTTON_MANAGER_STATE_TOUCH) {
switch (appData->pressedButton) {
case BUTTON_CHANGE_LEFT_MON:
if (UpdateLeftMon(appData)) {
PoketchMatchupCheckerGraphics_StartTask(appData->graphics, MATCHUP_CHECKER_GRAPHICS_UPDATE_LEFT);
appData->subState = 1;
}
break;
case BUTTON_CHANGE_RIGHT_MON:
if (UpdateRightMon(appData)) {
PoketchMatchupCheckerGraphics_StartTask(appData->graphics, MATCHUP_CHECKER_GRAPHICS_UPDATE_RIGHT);
appData->subState = 1;
}
break;
case BUTTON_CHECK_MATCHUP:
if (appData->matchupData.partySize > 1) {
PoketchMatchupCheckerGraphics_StartTask(appData->graphics, MATCHUP_CHECKER_GRAPHICS_PRESS_BUTTON);
appData->subState = 2;
} else {
PoketchSystem_PlaySoundEffect(SEQ_SE_DP_BEEP);
}
break;
}
appData->buttonState = BUTTON_MANAGER_STATE_NULL;
}
break;
case 1:
if (PoketchMatchupCheckerGraphics_NoActiveTasks(appData->graphics)) {
appData->subState = 0;
}
break;
case 2:
if (appData->buttonState == BUTTON_MANAGER_STATE_DRAGGING) {
PoketchMatchupCheckerGraphics_StartTask(appData->graphics, MATCHUP_CHECKER_GRAPHICS_RELEASE_BUTTON);
appData->subState = 0;
break;
}
if (appData->buttonState == BUTTON_MANAGER_STATE_TAP) {
appData->boxMonPair[0] = appData->pokemon[appData->matchupData.leftMonIdx];
appData->boxMonPair[1] = appData->pokemon[appData->matchupData.rightMonIdx];
appData->matchupData.compatibility = BoxMon_GetPairDaycareCompatibilityLevel(appData->boxMonPair);
PoketchMatchupCheckerGraphics_StartTask(appData->graphics, MATCHUP_CHECKER_GRAPHICS_RELEASE_BUTTON);
PoketchMatchupCheckerGraphics_StartTask(appData->graphics, MATCHUP_CHECKER_GRAPHICS_CHECK_MATCHUP);
appData->subState++;
}
break;
case 3:
if (PoketchMatchupCheckerGraphics_TaskIsNotActive(appData->graphics, MATCHUP_CHECKER_GRAPHICS_CHECK_MATCHUP)) {
appData->subState = 0;
}
}
return FALSE;
}
static BOOL UpdateLeftMon(PoketchMatchupChecker *appData)
{
if (appData->matchupData.partySize > 2) {
do {
if (++appData->matchupData.leftMonIdx >= appData->matchupData.partySize) {
appData->matchupData.leftMonIdx = 0;
}
} while (appData->matchupData.leftMonIdx == appData->matchupData.rightMonIdx);
return TRUE;
}
return FALSE;
}
static BOOL UpdateRightMon(PoketchMatchupChecker *appData)
{
if (appData->matchupData.partySize > 2) {
do {
if (++appData->matchupData.rightMonIdx >= appData->matchupData.partySize) {
appData->matchupData.rightMonIdx = 0;
}
} while (appData->matchupData.rightMonIdx == appData->matchupData.leftMonIdx);
return TRUE;
}
return FALSE;
}
static BOOL State_UnloadApp(PoketchMatchupChecker *appData)
{
switch (appData->subState) {
case 0:
PoketchMatchupCheckerGraphics_StartTask(appData->graphics, MATCHUP_CHECKER_GRAPHICS_FREE);
appData->subState++;
break;
case 1:
if (PoketchMatchupCheckerGraphics_NoActiveTasks(appData->graphics)) {
return TRUE;
}
break;
}
return FALSE;
}

View File

@ -44,7 +44,7 @@ FS_EXTERN_OVERLAY(poketch_daycare_checker);
FS_EXTERN_OVERLAY(poketch_roulette);
FS_EXTERN_OVERLAY(poketch_coin_toss);
FS_EXTERN_OVERLAY(poketch_move_tester);
FS_EXTERN_OVERLAY(overlay44);
FS_EXTERN_OVERLAY(poketch_matchup_checker);
FS_EXTERN_OVERLAY(poketch_alarm_clock);
FS_EXTERN_OVERLAY(overlay46);
FS_EXTERN_OVERLAY(poketch_marking_map);
@ -99,7 +99,7 @@ static const struct {
{ POKETCH_APPID_ROULETTE, FS_OVERLAY_ID(poketch_roulette) },
{ POKETCH_APPID_COINTOSS, FS_OVERLAY_ID(poketch_coin_toss) },
{ POKETCH_APPID_MOVETESTER, FS_OVERLAY_ID(poketch_move_tester) },
{ POKETCH_APPID_MATCHUPCHECKER, FS_OVERLAY_ID(overlay44) },
{ POKETCH_APPID_MATCHUPCHECKER, FS_OVERLAY_ID(poketch_matchup_checker) },
{ POKETCH_APPID_UNUSED_ALARMCLOCK, FS_OVERLAY_ID(poketch_alarm_clock) },
{ POKETCH_APPID_KITCHENTIMER, FS_OVERLAY_ID(overlay46) },
{ POKETCH_APPID_MARKINGMAP, FS_OVERLAY_ID(poketch_marking_map) },

View File

@ -703,8 +703,8 @@ pokeplatinum_c = files(
'applications/poketch/coin_toss/graphics.c',
'applications/poketch/move_tester/main.c',
'applications/poketch/move_tester/graphics.c',
'overlay044/ov44_022561C0.c',
'overlay044/ov44_022565BC.c',
'applications/poketch/matchup_checker/main.c',
'applications/poketch/matchup_checker/graphics.c',
'applications/poketch/alarm_clock/main.c',
'applications/poketch/alarm_clock/graphics.c',
'overlay046/ov46_022561C0.c',

View File

@ -1,302 +0,0 @@
#include <nitro.h>
#include <nitro/sinit.h>
#include <string.h>
#include "applications/poketch/poketch_button.h"
#include "applications/poketch/poketch_system.h"
#include "overlay005/daycare.h"
#include "overlay044/ov44_022565BC.h"
#include "overlay044/struct_ov44_022565BC_1.h"
#include "overlay044/struct_ov44_022565BC_decl.h"
#include "bg_window.h"
#include "heap.h"
#include "party.h"
#include "pokemon.h"
#include "pokemon_icon.h"
#include "sys_task.h"
#include "sys_task_manager.h"
#include "touch_screen.h"
typedef struct {
u8 unk_00;
u8 unk_01;
u8 unk_02;
UnkStruct_ov44_022565BC_1 unk_04;
UnkStruct_ov44_022565BC *unk_38;
PoketchSystem *poketchSys;
PoketchButtonManager *buttonManager;
u16 unk_44;
u16 unk_46;
BoxPokemon *unk_48[6];
BoxPokemon *unk_60[2];
} UnkStruct_ov44_0225621C;
static void NitroStaticInit(void);
static BOOL ov44_022561D4(void **param0, PoketchSystem *poketchSys, BgConfig *param2, u32 param3);
static BOOL ov44_0225621C(UnkStruct_ov44_0225621C *param0, PoketchSystem *poketchSys, BgConfig *param2, u32 param3);
static void ov44_02256314(UnkStruct_ov44_0225621C *param0);
static void ov44_0225632C(u32 param0, u32 param1, u32 param2, void *param3);
static void ov44_02256338(SysTask *param0, void *param1);
static void ov44_02256374(void *param0);
static void ov44_0225637C(UnkStruct_ov44_0225621C *param0, u32 param1);
static BOOL ov44_02256390(UnkStruct_ov44_0225621C *param0);
static BOOL ov44_022563D0(UnkStruct_ov44_0225621C *param0);
static BOOL ov44_022564F0(UnkStruct_ov44_0225621C *param0);
static BOOL ov44_0225653C(UnkStruct_ov44_0225621C *param0);
static BOOL ov44_02256588(UnkStruct_ov44_0225621C *param0);
static void NitroStaticInit(void)
{
PoketchSystem_SetAppFunctions(ov44_022561D4, ov44_02256374);
}
static BOOL ov44_022561D4(void **param0, PoketchSystem *poketchSys, BgConfig *param2, u32 param3)
{
UnkStruct_ov44_0225621C *v0 = (UnkStruct_ov44_0225621C *)Heap_Alloc(HEAP_ID_POKETCH_APP, sizeof(UnkStruct_ov44_0225621C));
if (v0 != NULL) {
if (ov44_0225621C(v0, poketchSys, param2, param3)) {
if (SysTask_Start(ov44_02256338, v0, 1) != NULL) {
*param0 = v0;
return 1;
}
}
Heap_Free(v0);
}
return 0;
}
static BOOL ov44_0225621C(UnkStruct_ov44_0225621C *param0, PoketchSystem *poketchSys, BgConfig *param2, u32 param3)
{
Party *v0 = SaveData_GetParty(PoketchSystem_GetSaveData(poketchSys));
Pokemon *v1;
int v2;
int v3 = 0;
param0->unk_04.unk_30 = Party_GetCurrentCount(v0);
for (v2 = 0; v2 < param0->unk_04.unk_30; v2++) {
v1 = Party_GetPokemonBySlotIndex(v0, v2);
if (Pokemon_GetValue(v1, MON_DATA_IS_EGG, NULL)) {
continue;
}
param0->unk_04.unk_00[v3] = BoxPokemon_IconSpriteIndex((const BoxPokemon *)v1);
param0->unk_04.unk_18[v3] = Pokemon_GetValue(v1, MON_DATA_SPECIES, NULL);
param0->unk_04.unk_24[v3] = Pokemon_GetValue(v1, MON_DATA_FORM, NULL);
param0->unk_48[v3] = (BoxPokemon *)v1;
v3++;
}
param0->unk_04.unk_30 = v3;
param0->unk_04.unk_32 = 0;
param0->unk_04.unk_33 = (param0->unk_04.unk_30 > 1) ? 1 : 0;
if (ov44_022565BC(&(param0->unk_38), &(param0->unk_04), param2)) {
static const TouchScreenHitTable v4[] = {
{ 128, 168, 92, 132 },
{ 130, 164, 24, 72 },
{ 130, 164, 152, 200 }
};
param0->unk_00 = 0;
param0->unk_01 = 0;
param0->unk_02 = 0;
param0->buttonManager = PoketchButtonManager_New(v4, NELEMS(v4), ov44_0225632C, param0, HEAP_ID_POKETCH_APP);
param0->unk_46 = 0;
param0->poketchSys = poketchSys;
return 1;
}
return 0;
}
static void ov44_02256314(UnkStruct_ov44_0225621C *param0)
{
PoketchButtonManager_Free(param0->buttonManager);
ov44_022565F8(param0->unk_38);
Heap_Free(param0);
}
static void ov44_0225632C(u32 param0, u32 param1, u32 param2, void *param3)
{
UnkStruct_ov44_0225621C *v0 = (UnkStruct_ov44_0225621C *)param3;
v0->unk_44 = param0;
v0->unk_46 = param1;
}
static void ov44_02256338(SysTask *param0, void *param1)
{
static BOOL (*const v0[])(UnkStruct_ov44_0225621C *) = {
ov44_02256390,
ov44_022563D0,
ov44_02256588,
};
UnkStruct_ov44_0225621C *v1 = (UnkStruct_ov44_0225621C *)param1;
if (v1->unk_00 < NELEMS(v0)) {
PoketechSystem_UpdateButtonManager(v1->poketchSys, v1->buttonManager);
if (v0[v1->unk_00](v1)) {
ov44_02256314(v1);
SysTask_Done(param0);
PoketchSystem_NotifyAppUnloaded(v1->poketchSys);
}
} else {
}
}
static void ov44_02256374(void *param0)
{
((UnkStruct_ov44_0225621C *)param0)->unk_02 = 1;
}
static void ov44_0225637C(UnkStruct_ov44_0225621C *param0, u32 param1)
{
if (param0->unk_02 == 0) {
param0->unk_00 = param1;
} else {
param0->unk_00 = 2;
}
param0->unk_01 = 0;
}
static BOOL ov44_02256390(UnkStruct_ov44_0225621C *param0)
{
switch (param0->unk_01) {
case 0:
ov44_02256744(param0->unk_38, 0);
param0->unk_01++;
break;
case 1:
if (ov44_02256768(param0->unk_38, 0)) {
PoketchSystem_NotifyAppLoaded(param0->poketchSys);
ov44_0225637C(param0, 1);
}
break;
}
return 0;
}
static BOOL ov44_022563D0(UnkStruct_ov44_0225621C *param0)
{
if (param0->unk_02) {
ov44_0225637C(param0, 2);
return 0;
}
switch (param0->unk_01) {
case 0:
if (param0->unk_46 == 1) {
switch (param0->unk_44) {
case 1:
if (ov44_022564F0(param0)) {
ov44_02256744(param0->unk_38, 4);
param0->unk_01 = 1;
}
break;
case 2:
if (ov44_0225653C(param0)) {
ov44_02256744(param0->unk_38, 5);
param0->unk_01 = 1;
}
break;
case 0:
if (param0->unk_04.unk_30 > 1) {
ov44_02256744(param0->unk_38, 2);
param0->unk_01 = 2;
} else {
PoketchSystem_PlaySoundEffect(1646);
}
break;
}
param0->unk_46 = 0;
}
break;
case 1:
if (ov44_02256774(param0->unk_38)) {
param0->unk_01 = 0;
}
break;
case 2:
if (param0->unk_46 == 2) {
ov44_02256744(param0->unk_38, 3);
param0->unk_01 = 0;
break;
}
if (param0->unk_46 == 3) {
param0->unk_60[0] = param0->unk_48[param0->unk_04.unk_32];
param0->unk_60[1] = param0->unk_48[param0->unk_04.unk_33];
param0->unk_04.unk_31 = BoxMon_GetPairDaycareCompatibilityLevel(param0->unk_60);
ov44_02256744(param0->unk_38, 3);
ov44_02256744(param0->unk_38, 6);
param0->unk_01++;
}
break;
case 3:
if (ov44_02256768(param0->unk_38, 6)) {
param0->unk_01 = 0;
}
}
return 0;
}
static BOOL ov44_022564F0(UnkStruct_ov44_0225621C *param0)
{
if (param0->unk_04.unk_30 > 2) {
do {
if (++(param0->unk_04.unk_32) >= param0->unk_04.unk_30) {
param0->unk_04.unk_32 = 0;
}
} while (param0->unk_04.unk_32 == param0->unk_04.unk_33);
return 1;
}
return 0;
}
static BOOL ov44_0225653C(UnkStruct_ov44_0225621C *param0)
{
if (param0->unk_04.unk_30 > 2) {
do {
if (++(param0->unk_04.unk_33) >= param0->unk_04.unk_30) {
param0->unk_04.unk_33 = 0;
}
} while (param0->unk_04.unk_33 == param0->unk_04.unk_32);
return 1;
}
return 0;
}
static BOOL ov44_02256588(UnkStruct_ov44_0225621C *param0)
{
switch (param0->unk_01) {
case 0:
ov44_02256744(param0->unk_38, 1);
param0->unk_01++;
break;
case 1:
if (ov44_02256774(param0->unk_38)) {
return 1;
}
break;
}
return 0;
}

View File

@ -1,545 +0,0 @@
#include "overlay044/ov44_022565BC.h"
#include <nitro.h>
#include <string.h>
#include "applications/poketch/poketch_animation.h"
#include "applications/poketch/poketch_graphics.h"
#include "applications/poketch/poketch_system.h"
#include "applications/poketch/poketch_task.h"
#include "overlay044/struct_ov44_022565BC_1.h"
#include "overlay044/struct_ov44_022565BC_decl.h"
#include "bg_window.h"
#include "graphics.h"
#include "heap.h"
#include "pokemon.h"
#include "pokemon_icon.h"
#include "sys_task_manager.h"
struct UnkStruct_ov44_022565BC_t {
const UnkStruct_ov44_022565BC_1 *unk_00;
BgConfig *unk_04;
u32 unk_08[6];
PoketchAnimation_AnimationManager *unk_20;
PoketchAnimation_AnimatedSpriteData *unk_24[6];
PoketchAnimation_SpriteData unk_3C;
PoketchAnimation_SpriteData unk_50;
u32 unk_64;
BOOL unk_68;
const int *unk_6C;
u32 unk_70;
u32 unk_74;
fx32 unk_78;
fx32 unk_7C;
fx32 unk_80;
u32 unk_84;
};
static void ov44_0225660C(UnkStruct_ov44_022565BC *param0, const UnkStruct_ov44_022565BC_1 *param1);
static void ov44_02256718(UnkStruct_ov44_022565BC *param0);
static void ov44_02256780(PoketchTaskManager *param0);
static void ov44_02256794(SysTask *param0, void *param1);
static void ov44_02256828(SysTask *param0, void *param1);
static void ov44_0225686C(SysTask *param0, void *param1);
static void ov44_02256898(SysTask *param0, void *param1);
static void ov44_022568BC(SysTask *param0, void *param1);
static void ov44_02256908(SysTask *param0, void *param1);
static void ov44_02256954(UnkStruct_ov44_022565BC *param0, u32 param1, u32 param2, u16 param3, u16 param4);
static void ov44_022569AC(UnkStruct_ov44_022565BC *param0);
static void ov44_022569E4(SysTask *param0, void *param1);
static void ov44_02256A50(UnkStruct_ov44_022565BC *param0, const UnkStruct_ov44_022565BC_1 *param1);
static BOOL ov44_02256AC8(UnkStruct_ov44_022565BC *param0, const UnkStruct_ov44_022565BC_1 *param1);
BOOL ov44_022565BC(UnkStruct_ov44_022565BC **param0, const UnkStruct_ov44_022565BC_1 *param1, BgConfig *param2)
{
UnkStruct_ov44_022565BC *v0 = (UnkStruct_ov44_022565BC *)Heap_Alloc(HEAP_ID_POKETCH_APP, sizeof(UnkStruct_ov44_022565BC));
if (v0 != NULL) {
PoketchTask_InitActiveTaskList(v0->unk_08, 4);
v0->unk_00 = param1;
v0->unk_04 = PoketchGraphics_GetBgConfig();
v0->unk_20 = PoketchGraphics_GetAnimationManager();
ov44_0225660C(v0, param1);
*param0 = v0;
return 1;
}
return 0;
}
void ov44_022565F8(UnkStruct_ov44_022565BC *param0)
{
if (param0 != NULL) {
ov44_02256718(param0);
Heap_Free(param0);
}
}
static void ov44_0225660C(UnkStruct_ov44_022565BC *param0, const UnkStruct_ov44_022565BC_1 *param1)
{
static const PoketchAnimation_AnimationData v0[] = {
{
{ (112 << FX32_SHIFT), (148 << FX32_SHIFT) },
9,
0,
2,
0,
0,
},
{
{ (112 << FX32_SHIFT), (32 << FX32_SHIFT) },
0,
0,
2,
1,
0,
},
{
{ (48 << FX32_SHIFT), (88 << FX32_SHIFT) },
5,
0,
2,
0,
0,
},
{
{ (176 << FX32_SHIFT), (88 << FX32_SHIFT) },
6,
0,
2,
0,
0,
},
{
{ (48 << FX32_SHIFT), (140 << FX32_SHIFT) },
5,
0,
2,
0,
1,
},
{
{ (176 << FX32_SHIFT), (140 << FX32_SHIFT) },
4,
0,
2,
0,
1,
},
};
int v1;
u32 v2;
PoketchTask_LoadPokemonIconLuminancePalette(1);
v2 = Graphics_LoadObjectTiles(12, 74, 1, 0, 0, 1, HEAP_ID_POKETCH_APP);
v2 /= 20;
param0->unk_64 = v2;
PoketchTask_LoadPokemonIcons(v2, param1->unk_00, param1->unk_30, 0);
PoketchAnimation_LoadSpriteFromNARC(&param0->unk_3C, 12, 72, 73, 8);
PoketchAnimation_LoadSpriteFromNARC(&param0->unk_50, 12, 5, 6, 8);
for (v1 = 0; v1 < 4; v1++) {
param0->unk_24[v1] = PoketchAnimation_SetupNewAnimatedSprite(param0->unk_20, &v0[v1], &param0->unk_3C);
}
for (; v1 < 6; v1++) {
param0->unk_24[v1] = PoketchAnimation_SetupNewAnimatedSprite(param0->unk_20, &v0[v1], &param0->unk_50);
}
ov44_02256954(param0, 4, param1->unk_32, param1->unk_18[param1->unk_32], param1->unk_24[param1->unk_32]);
ov44_02256954(param0, 5, param1->unk_33, param1->unk_18[param1->unk_33], param1->unk_24[param1->unk_33]);
if (param1->unk_30 <= 1) {
PoketchAnimation_HideSprite(param0->unk_24[5], 1);
PoketchAnimation_HideSprite(param0->unk_24[3], 1);
PoketchAnimation_UpdateAnimationIdx(param0->unk_24[0], 10);
}
}
static void ov44_02256718(UnkStruct_ov44_022565BC *param0)
{
int v0;
PoketchAnimation_FreeSpriteData(&param0->unk_50);
PoketchAnimation_FreeSpriteData(&param0->unk_3C);
for (v0 = 0; v0 < 6; v0++) {
if (param0->unk_24[v0]) {
PoketchAnimation_RemoveAnimatedSprite(param0->unk_20, param0->unk_24[v0]);
}
}
}
static const PoketchTask Unk_ov44_02256D5C[] = {
{ 0x0, ov44_02256794, 0x0 },
{ 0x1, ov44_02256828, 0x0 },
{ 0x2, ov44_0225686C, 0x0 },
{ 0x3, ov44_02256898, 0x0 },
{ 0x4, ov44_022568BC, 0x0 },
{ 0x5, ov44_02256908, 0x0 },
{ 0x6, ov44_022569E4, 0x0 },
{ 0x0, NULL, 0x0 }
};
void ov44_02256744(UnkStruct_ov44_022565BC *param0, u32 param1)
{
PoketchTask_Start(Unk_ov44_02256D5C, param1, param0, param0->unk_00, param0->unk_08, 2, 8);
}
BOOL ov44_02256768(UnkStruct_ov44_022565BC *param0, u32 param1)
{
return PoketchTask_TaskIsNotActive(param0->unk_08, param1);
}
BOOL ov44_02256774(UnkStruct_ov44_022565BC *param0)
{
return PoketchTask_NoActiveTasks(param0->unk_08);
}
static void ov44_02256780(PoketchTaskManager *param0)
{
UnkStruct_ov44_022565BC *v0 = PoketchTask_GetTaskData(param0);
PoketchTask_EndTask(v0->unk_08, param0);
}
static void ov44_02256794(SysTask *param0, void *param1)
{
static const BgTemplate v0 = {
.x = 0,
.y = 0,
.bufferSize = 0x800,
.baseTile = 0,
.screenSize = BG_SCREEN_SIZE_256x256,
.colorMode = GX_BG_COLORMODE_16,
.screenBase = GX_BG_SCRBASE_0x7000,
.charBase = GX_BG_CHARBASE_0x00000,
.bgExtPltt = GX_BG_EXTPLTT_01,
.priority = 2,
.areaOver = 0,
.mosaic = FALSE,
};
GXSDispCnt v1;
UnkStruct_ov44_022565BC *v2;
const UnkStruct_ov44_022565BC_1 *v3;
void *v4;
NNSG2dPaletteData *v5;
v2 = PoketchTask_GetTaskData(param1);
v3 = PoketchTask_GetConstTaskData(param1);
Bg_InitFromTemplate(v2->unk_04, BG_LAYER_SUB_2, &v0, 0);
Graphics_LoadTilesToBgLayer(NARC_INDEX_GRAPHIC__POKETCH, 71, v2->unk_04, BG_LAYER_SUB_2, 0, 0, 1, HEAP_ID_POKETCH_APP);
Graphics_LoadTilemapToBgLayer(NARC_INDEX_GRAPHIC__POKETCH, 70, v2->unk_04, BG_LAYER_SUB_2, 0, 0, 1, HEAP_ID_POKETCH_APP);
PoketchGraphics_LoadActivePalette(0, 0);
Bg_CopyTilemapBufferToVRAM(v2->unk_04, 6);
v1 = GXS_GetDispCnt();
GXS_SetVisiblePlane(v1.visiblePlane | GX_PLANEMASK_BG2);
ov44_02256780(param1);
}
static void ov44_02256828(SysTask *param0, void *param1)
{
UnkStruct_ov44_022565BC *v0 = PoketchTask_GetTaskData(param1);
switch (PoketchTask_GetState(param1)) {
case 0:
v0->unk_68 = 1;
PoketchTask_IncrementState(param1);
break;
case 1:
if (ov44_02256768(v0, 6)) {
Bg_FreeTilemapBuffer(v0->unk_04, BG_LAYER_SUB_2);
ov44_02256780(param1);
}
break;
}
}
static void ov44_0225686C(SysTask *param0, void *param1)
{
UnkStruct_ov44_022565BC *v0;
const UnkStruct_ov44_022565BC_1 *v1;
v0 = PoketchTask_GetTaskData(param1);
v1 = PoketchTask_GetConstTaskData(param1);
PoketchSystem_PlaySoundEffect(1641);
PoketchAnimation_UpdateAnimationIdx(v0->unk_24[0], 10);
ov44_02256780(param1);
}
static void ov44_02256898(SysTask *param0, void *param1)
{
UnkStruct_ov44_022565BC *v0;
const UnkStruct_ov44_022565BC_1 *v1;
v0 = PoketchTask_GetTaskData(param1);
v1 = PoketchTask_GetConstTaskData(param1);
PoketchAnimation_UpdateAnimationIdx(v0->unk_24[0], 9);
ov44_02256780(param1);
}
static void ov44_022568BC(SysTask *param0, void *param1)
{
UnkStruct_ov44_022565BC *v0 = PoketchTask_GetTaskData(param1);
const UnkStruct_ov44_022565BC_1 *v1 = PoketchTask_GetConstTaskData(param1);
int v2 = v1->unk_32;
PoketchSystem_PlayCry(v1->unk_18[v2], v1->unk_24[v2]);
ov44_02256954(v0, 4, v2, v1->unk_18[v2], v1->unk_24[v2]);
ov44_022569AC(v0);
ov44_02256780(param1);
}
static void ov44_02256908(SysTask *param0, void *param1)
{
UnkStruct_ov44_022565BC *v0 = PoketchTask_GetTaskData(param1);
const UnkStruct_ov44_022565BC_1 *v1 = PoketchTask_GetConstTaskData(param1);
int v2 = v1->unk_33;
PoketchSystem_PlayCry(v1->unk_18[v2], v1->unk_24[v2]);
ov44_02256954(v0, 5, v2, v1->unk_18[v2], v1->unk_24[v2]);
ov44_022569AC(v0);
ov44_02256780(param1);
}
static void ov44_02256954(UnkStruct_ov44_022565BC *param0, u32 param1, u32 param2, u16 param3, u16 param4)
{
PoketchAnimation_AnimatedSpriteData *v0 = param0->unk_24[param1];
u32 v1;
if (param1 == 5) {
v1 = 4;
} else {
if (SpeciesData_GetFormValue(param3, param4, 28)) {
v1 = 4;
} else {
v1 = 5;
}
}
PoketchAnimation_UpdateAnimationIdx(v0, v1);
PoketchAnimation_SetSpriteCharNo(v0, param0->unk_64 + param2 * 16);
PoketchAnimation_SetCParam(v0, 1 + PokeIconPaletteIndex(param3, param4, 0));
}
static void ov44_022569AC(UnkStruct_ov44_022565BC *param0)
{
PoketchAnimation_SetSpritePosition(param0->unk_24[2], 48 << FX32_SHIFT, 88 << FX32_SHIFT);
PoketchAnimation_SetSpritePosition(param0->unk_24[3], 176 << FX32_SHIFT, 88 << FX32_SHIFT);
PoketchAnimation_UpdateAnimationIdx(param0->unk_24[2], 5);
PoketchAnimation_UpdateAnimationIdx(param0->unk_24[3], 6);
PoketchAnimation_UpdateAnimationIdx(param0->unk_24[1], 0);
}
static void ov44_022569E4(SysTask *param0, void *param1)
{
UnkStruct_ov44_022565BC *v0 = PoketchTask_GetTaskData(param1);
const UnkStruct_ov44_022565BC_1 *v1 = PoketchTask_GetConstTaskData(param1);
u32 v2 = PoketchTask_GetState(param1);
if ((v2 != 0) && v0->unk_68) {
ov44_02256780(param1);
return;
}
switch (PoketchTask_GetState(param1)) {
case 0:
v0->unk_68 = 0;
ov44_022569AC(v0);
ov44_02256A50(v0, v1);
PoketchTask_IncrementState(param1);
break;
case 1:
if (ov44_02256AC8(v0, v1)) {
ov44_02256780(param1);
}
break;
}
}
static const int Unk_ov44_02256D2C[] = {
-2,
0x10,
0x10,
-4,
0x10,
-6,
-5,
0x66C,
-3,
0x10,
0x10,
-1
};
static const int Unk_ov44_02256CCC[] = {
-2,
0x10,
0x10,
-5,
0x66B,
-1
};
static const int Unk_ov44_02256D00[] = {
-2,
0x10,
0x10,
-5,
0x66B,
-2,
0x10,
0x10,
-5,
0x66B,
-1
};
static const int Unk_ov44_02256E1C[] = {
-2,
0x10,
0x10,
-5,
0x66B,
-2,
0x10,
0x10,
-5,
0x66B,
-2,
0x10,
0x10,
-5,
0x66B,
-4,
0x10,
-5,
0x66D,
-7,
0x2,
0x7,
-7,
0x3,
0x8,
-7,
0x1,
0x4,
-4,
0x10,
-1
};
static void ov44_02256A50(UnkStruct_ov44_022565BC *param0, const UnkStruct_ov44_022565BC_1 *param1)
{
param0->unk_70 = 0;
param0->unk_74 = 0;
param0->unk_78 = 0;
param0->unk_84 = 0;
switch (param1->unk_31) {
case 3:
param0->unk_6C = Unk_ov44_02256D2C;
break;
case 2:
param0->unk_6C = Unk_ov44_02256CCC;
PoketchAnimation_UpdateAnimationIdx(param0->unk_24[1], 1);
break;
case 1:
param0->unk_6C = Unk_ov44_02256D00;
PoketchAnimation_UpdateAnimationIdx(param0->unk_24[1], 2);
break;
case 0:
param0->unk_6C = Unk_ov44_02256E1C;
PoketchAnimation_UpdateAnimationIdx(param0->unk_24[1], 3);
break;
}
ov44_02256AC8(param0, param1);
}
static BOOL ov44_02256AC8(UnkStruct_ov44_022565BC *param0, const UnkStruct_ov44_022565BC_1 *param1)
{
func_start:
switch (param0->unk_70) {
case 0:
while (param0->unk_70 == 0) {
switch (param0->unk_6C[param0->unk_74++]) {
case -1:
return 1;
case -2:
param0->unk_84 = param0->unk_6C[(param0->unk_74)++];
param0->unk_7C = param0->unk_6C[(param0->unk_74)++];
param0->unk_7C *= FX32_ONE;
param0->unk_80 = param0->unk_78 + param0->unk_7C;
param0->unk_7C /= param0->unk_84;
param0->unk_70 = 1;
break;
case -3:
param0->unk_84 = param0->unk_6C[(param0->unk_74)++];
param0->unk_7C = param0->unk_6C[(param0->unk_74)++];
param0->unk_7C *= FX32_ONE;
param0->unk_7C *= -1;
param0->unk_80 = param0->unk_78 + param0->unk_7C;
param0->unk_7C /= param0->unk_84;
param0->unk_70 = 1;
break;
case -4:
param0->unk_84 = param0->unk_6C[(param0->unk_74)++];
param0->unk_70 = 2;
break;
case -5:
PoketchSystem_PlaySoundEffect(param0->unk_6C[(param0->unk_74)++]);
break;
case -6:
PoketchAnimation_UpdateAnimationIdx(param0->unk_24[2], 6);
PoketchAnimation_UpdateAnimationIdx(param0->unk_24[3], 5);
break;
case -7: {
u32 v0 = param0->unk_6C[(param0->unk_74)++];
u32 v1 = param0->unk_6C[(param0->unk_74)++];
PoketchAnimation_UpdateAnimationIdx(param0->unk_24[v0], v1);
} break;
}
}
break;
case 1:
if (param0->unk_84) {
param0->unk_84--;
if (param0->unk_84) {
param0->unk_78 += param0->unk_7C;
} else {
param0->unk_78 = param0->unk_80;
}
PoketchAnimation_SetSpritePosition(param0->unk_24[2], (48 << FX32_SHIFT) + param0->unk_78, 88 << FX32_SHIFT);
PoketchAnimation_SetSpritePosition(param0->unk_24[3], (176 << FX32_SHIFT) - param0->unk_78, 88 << FX32_SHIFT);
}
if (param0->unk_84 == 0) {
param0->unk_70 = 0;
goto func_start;
}
break;
case 2:
if (param0->unk_84) {
param0->unk_84--;
} else {
param0->unk_70 = 0;
goto func_start;
}
break;
}
return 0;
}