Document Poketch Roulette (Overlay 41) (#794)

This commit is contained in:
VicSevenT
2025-10-08 11:09:14 -05:00
committed by GitHub
parent 83c7411509
commit ca7a4e09d6
25 changed files with 926 additions and 886 deletions

View File

@@ -0,0 +1,61 @@
#ifndef POKEPLATINUM_POKETCH_ROULETTE_GRAPHICS_H
#define POKEPLATINUM_POKETCH_ROULETTE_GRAPHICS_H
#include "applications/poketch/poketch_animation.h"
#include "applications/poketch/poketch_task.h"
#include "bg_window.h"
#define ROULETTE_TASK_SLOTS 4
#define NUM_SPRITES 4
#define DRAWING_REGION_WIDTH 156
#define DRAWING_REGION_HEIGHT 150
typedef struct RouletteData {
u32 x;
u32 y;
u32 appID;
u8 pixels[DRAWING_REGION_WIDTH][DRAWING_REGION_HEIGHT];
u8 playButtonPressed;
u8 stopButtonPressed;
u8 clearButtonPressed;
} RouletteData;
typedef struct RouletteGraphics {
const RouletteData *rouletteData;
BgConfig *bgConfig;
u32 activeTasks[POKETCH_TASK_SLOT_BASE + ROULETTE_TASK_SLOTS];
PoketchAnimation_AnimationManager *animMan;
PoketchAnimation_AnimatedSpriteData *sprites[NUM_SPRITES];
PoketchAnimation_SpriteData animData;
Window window;
u32 windowBaseTile;
BOOL killSpinnerTask;
BOOL stopSpinner;
BOOL spinnerUpToSpeed;
u16 spinnerAngle;
u16 rotationSpeed;
u32 stopDelay;
} RouletteGraphics;
enum RouletteGraphicsTask {
ROULETTE_GRAPHICS_INIT = 0,
ROULETTE_GRAPHICS_FREE,
ROULETTE_GRAPHICS_UNUSED,
ROULETTE_GRAPHICS_UPDATE_DRAWING,
ROULETTE_GRAPHICS_UNUSED2,
ROULETTE_GRAPHICS_UPDATE_BUTTONS,
ROULETTE_GRAPHICS_CLEAR_DRAWING,
ROULETTE_GRAPHICS_RUN_SPINNER,
ROULETTE_GRAPHICS_STOP_SPINNER,
};
BOOL PoketchRouletteGraphics_New(RouletteGraphics **dest, const RouletteData *rouletteData, BgConfig *bgConfig);
void PoketchRouletteGraphics_Free(RouletteGraphics *graphics);
void PoketchRouletteGraphics_StartTask(RouletteGraphics *graphics, enum RouletteGraphicsTask taskID);
BOOL PoketchRouletteGraphics_TaskIsNotActive(RouletteGraphics *graphics, enum RouletteGraphicsTask taskID);
BOOL PoketchRouletteGraphics_NoActiveTasks(RouletteGraphics *graphics);
#endif // POKEPLATINUM_POKETCH_ROULETTE_GRAPHICS_H

View File

@@ -1,15 +0,0 @@
#ifndef POKEPLATINUM_OV41_022567B0_H
#define POKEPLATINUM_OV41_022567B0_H
#include "overlay041/struct_ov41_022567B0_1.h"
#include "overlay041/struct_ov41_022567B0_decl.h"
#include "bg_window.h"
BOOL ov41_022567B0(UnkStruct_ov41_022567B0 **param0, const UnkStruct_ov41_022567B0_1 *param1, BgConfig *param2);
void ov41_022567F8(UnkStruct_ov41_022567B0 *param0);
void ov41_0225688C(UnkStruct_ov41_022567B0 *param0, u32 param1);
BOOL ov41_022568B0(UnkStruct_ov41_022567B0 *param0, u32 param1);
BOOL ov41_022568BC(UnkStruct_ov41_022567B0 *param0);
#endif // POKEPLATINUM_OV41_022567B0_H

View File

@@ -1,14 +0,0 @@
#ifndef POKEPLATINUM_STRUCT_OV41_022567B0_1_H
#define POKEPLATINUM_STRUCT_OV41_022567B0_1_H
typedef struct {
u32 unk_00;
u32 unk_04;
u32 unk_08;
u8 unk_0C[156][150];
u8 unk_5B74;
u8 unk_5B75;
u8 unk_5B76;
} UnkStruct_ov41_022567B0_1;
#endif // POKEPLATINUM_STRUCT_OV41_022567B0_1_H

View File

@@ -1,6 +0,0 @@
#ifndef POKEPLATINUM_STRUCT_OV41_022567B0_DECL_H
#define POKEPLATINUM_STRUCT_OV41_022567B0_DECL_H
typedef struct UnkStruct_ov41_022567B0_t UnkStruct_ov41_022567B0;
#endif // POKEPLATINUM_STRUCT_OV41_022567B0_DECL_H

View File

@@ -984,11 +984,11 @@ Overlay poketch_daycare_checker
Object main.nef.p/src_applications_poketch_daycare_checker_graphics.c.o
}
Overlay overlay41
Overlay poketch_roulette
{
After overlay25
Object main.nef.p/src_overlay041_ov41_022561C0.c.o
Object main.nef.p/src_overlay041_ov41_022567B0.c.o
Object main.nef.p/src_applications_poketch_roulette_main.c.o
Object main.nef.p/src_applications_poketch_roulette_graphics.c.o
}
Overlay overlay42

View File

@@ -40,7 +40,7 @@ cd5d643c3bf17d863db96640d7bfc100bda30b37 *poketch_dowsing_machine.sbin
3f15b19c0ca694b9942077a9c8eda0855c25450c *overlay38.sbin
da2f09fdfc788b4a6e6ada88db5176fcdc23c924 *overlay39.sbin
f8a583401a3a614cc88ee6dc7f3b3cdbf00f22cb *poketch_daycare_checker.sbin
a5b13f54d5303140b3169c794db0fd04c9c2dc22 *overlay41.sbin
a5b13f54d5303140b3169c794db0fd04c9c2dc22 *poketch_roulette.sbin
ba5baba0ff38e940d333dbea89e4c510b6998922 *overlay42.sbin
261b64d5fd09a304a5d7e78a18b44a6ecfe7ec93 *poketch_move_tester.sbin
5dd962600f238f162c0999dcb8a134c9df134293 *overlay44.sbin

View File

@@ -26,6 +26,8 @@ typedef struct PoketchAnalogWatch {
PoketchSystem *poketchSys;
} PoketchAnalogWatch;
typedef BOOL (*StateFunc)(PoketchAnalogWatch *);
enum AnalogWatchState {
STATE_LOAD_APP = 0,
STATE_UPDATE,
@@ -116,7 +118,7 @@ static void Free(PoketchAnalogWatch *appData)
static void Task_Main(SysTask *task, void *taskMan)
{
static BOOL (*const stateFuncs[])(PoketchAnalogWatch *) = {
static const StateFunc stateFuncs[] = {
State_LoadApp,
State_UpdateApp,
State_UnloadApp

View File

@@ -31,6 +31,8 @@ typedef struct PoketchCalculator {
CalculatorData calcData;
} PoketchCalculator;
typedef BOOL (*StateFunc)(PoketchCalculator *);
enum CalculatorState {
STATE_LOAD_APP = 0,
STATE_ENTER_OPERAND_1,
@@ -158,7 +160,7 @@ static void Free(PoketchCalculator *appData)
static void Task_Main(SysTask *task, void *appData)
{
static BOOL (*const stateFuncs[])(PoketchCalculator *) = {
static const StateFunc stateFuncs[] = {
State_LoadApp,
State_EnterOperand1,
State_EnterOperator,

View File

@@ -24,6 +24,8 @@ typedef struct PoketchCounter {
enum ButtonManagerState buttonState;
} PoketchCounter;
typedef BOOL (*StateFunc)(PoketchCounter *);
enum CounterState {
STATE_LOAD_APP = 0,
STATE_UPDATE_LOOP,
@@ -111,7 +113,7 @@ static void Free(PoketchCounter *appData)
static void Task_Main(SysTask *task, void *appData)
{
static BOOL (*const stateFuncs[])(PoketchCounter *) = {
static const StateFunc stateFuncs[] = {
State_LoadApp,
State_UpdateApp,
State_UnloadApp

View File

@@ -26,6 +26,8 @@ typedef struct PoketchDaycare {
Daycare *daycareSaveData;
} PoketchDaycareChecker;
typedef BOOL (*StateFunc)(PoketchDaycareChecker *);
enum DaycareCheckerState {
STATE_LOAD_APP = 0,
STATE_UPDATE_LOOP,
@@ -93,7 +95,7 @@ static void Free(PoketchDaycareChecker *appData)
static void Task_Main(SysTask *task, void *appData)
{
static BOOL (*const stateFuncs[])(PoketchDaycareChecker *) = {
static const StateFunc stateFuncs[] = {
State_LoadApp,
State_UpdateApp,
State_UnloadApp

View File

@@ -28,6 +28,8 @@ typedef struct PoketchDigitalWatch {
PoketchSystem *poketchSys;
} PoketchDigitalWatch;
typedef BOOL (*StateFunc)(PoketchDigitalWatch *);
enum DigitalWatchState {
STATE_LOAD_APP = 0,
STATE_UPDATE_LOOP,
@@ -120,7 +122,7 @@ static void Free(PoketchDigitalWatch *appData)
static void Task_Main(SysTask *task, void *callbackData)
{
static BOOL (*const stateFuncs[])(PoketchDigitalWatch *) = {
static const StateFunc stateFuncs[] = {
State_LoadApp,
State_UpdateApp,
State_UnloadApp,

View File

@@ -25,6 +25,8 @@ typedef struct PoketchDotArtist {
u8 packedData[PACKED_SIZE];
} PoketchDotArtist;
typedef BOOL (*StateFunc)(PoketchDotArtist *);
enum DotArtistState {
STATE_LOAD_APP = 0,
STATE_UPDATE_LOOP,
@@ -196,7 +198,7 @@ static void SaveCallback(void *appData)
static void Task_Main(SysTask *task, void *appData)
{
static BOOL (*const stateFuncs[])(PoketchDotArtist *) = {
static const StateFunc stateFuncs[] = {
State_LoadApp,
State_UpdateApp,
State_UnloadApp

View File

@@ -27,6 +27,8 @@ typedef struct PoketchDowsingMachine {
void *unused;
} PoketchDowsingMachine;
typedef BOOL (*StateFunc)(PoketchDowsingMachine *);
enum DowsingMachineState {
STATE_LOAD_APP = 0,
STATE_UPDATE_LOOP,
@@ -100,7 +102,7 @@ static void Free(PoketchDowsingMachine *appData)
static void Task_Main(SysTask *task, void *appData)
{
static BOOL (*const stateFuncs[])(PoketchDowsingMachine *) = {
static const StateFunc stateFuncs[] = {
State_LoadApp,
State_UpdateApp,
State_UnloadApp

View File

@@ -23,6 +23,8 @@ typedef struct PoketchFriendshipChecker {
PoketchSystem *poketchSys;
} PoketchFriendshipChecker;
typedef BOOL (*StateFunc)(PoketchFriendshipChecker *);
enum FriendshipCheckerState {
STATE_LOAD_APP = 0,
STATE_UPDATE_LOOP,
@@ -155,7 +157,7 @@ static void Free(PoketchFriendshipChecker *appData)
static void Task_Main(SysTask *task, void *appData)
{
static BOOL (*const stateFuncs[])(PoketchFriendshipChecker *) = {
static const StateFunc stateFuncs[] = {
State_LoadApp,
State_UpdateApp,
State_UnloadApp,

View File

@@ -24,6 +24,8 @@ typedef struct PoketchMemoPad {
PoketchButtonManager *buttonManager;
} PoketchMemoPad;
typedef BOOL (*StateFunc)(PoketchMemoPad *);
enum MemoPadState {
STATE_LOAD_APP = 0,
STATE_UPDATE_LOOP,
@@ -104,7 +106,7 @@ static void Free(PoketchMemoPad *appData)
static void Task_Main(SysTask *task, void *appData)
{
static BOOL (*const stateFuncs[])(PoketchMemoPad *) = {
static const StateFunc stateFuncs[] = {
State_LoadApp,
State_UpdateApp,
State_UnloadApp

View File

@@ -27,6 +27,8 @@ typedef struct PoketchMoveTester {
u32 buttonState;
} PoketchMoveTester;
typedef BOOL (*StateFunc)(PoketchMoveTester *);
enum MoveTesterState {
STATE_LOAD_APP = 0,
STATE_UPDATE_LOOP,
@@ -185,7 +187,7 @@ static void Free(PoketchMoveTester *appData)
static void Task_Main(SysTask *task, void *appData)
{
static BOOL (*const stateFuncs[])(PoketchMoveTester *) = {
static const StateFunc stateFuncs[] = {
State_LoadApp,
State_UpdateApp,
State_UnloadApp

View File

@@ -22,6 +22,8 @@ typedef struct PoketchPartyStatus {
PoketchSystem *poketchSys;
} PoketchPartyStatus;
typedef BOOL (*StateFunc)(PoketchPartyStatus *);
enum PartyStatusState {
STATE_LOAD_APP = 0,
STATE_UPDATE_LOOP,
@@ -93,7 +95,7 @@ static void Free(PoketchPartyStatus *appData)
static void Task_Main(SysTask *task, void *appData)
{
static BOOL (*const stateFuncs[])(PoketchPartyStatus *) = {
static const StateFunc stateFuncs[] = {
State_LoadApp,
State_UpdateApp,
State_UnloadApp

View File

@@ -24,6 +24,8 @@ typedef struct PoketchPedometer {
Poketch *poketch;
} PoketchPedometer;
typedef BOOL (*StateFunc)(PoketchPedometer *);
enum PedometerState {
STATE_LOAD_APP = 0,
STATE_UPDATE_LOOP,
@@ -109,7 +111,7 @@ static void Free(PoketchPedometer *appData)
static void Task_Main(SysTask *task, void *appData)
{
static BOOL (*const stateFuncs[])(PoketchPedometer *) = {
static const StateFunc stateFuncs[] = {
State_LoadApp,
State_UpdateApp,
State_UnloadApp

View File

@@ -41,7 +41,7 @@ FS_EXTERN_OVERLAY(overlay37);
FS_EXTERN_OVERLAY(overlay38);
FS_EXTERN_OVERLAY(overlay39);
FS_EXTERN_OVERLAY(poketch_daycare_checker);
FS_EXTERN_OVERLAY(overlay41);
FS_EXTERN_OVERLAY(poketch_roulette);
FS_EXTERN_OVERLAY(overlay42);
FS_EXTERN_OVERLAY(poketch_move_tester);
FS_EXTERN_OVERLAY(overlay44);
@@ -96,7 +96,7 @@ static const struct {
{ POKETCH_APPID_COUNTER, FS_OVERLAY_ID(poketch_counter) },
{ POKETCH_APPID_PEDOMETER, FS_OVERLAY_ID(poketch_pedometer) },
{ POKETCH_APPID_DAYCARECHECKER, FS_OVERLAY_ID(poketch_daycare_checker) },
{ POKETCH_APPID_ROULETTE, FS_OVERLAY_ID(overlay41) },
{ POKETCH_APPID_ROULETTE, FS_OVERLAY_ID(poketch_roulette) },
{ POKETCH_APPID_COINTOSS, FS_OVERLAY_ID(overlay42) },
{ POKETCH_APPID_MOVETESTER, FS_OVERLAY_ID(poketch_move_tester) },
{ POKETCH_APPID_MATCHUPCHECKER, FS_OVERLAY_ID(overlay44) },

View File

@@ -0,0 +1,391 @@
#include "applications/poketch/roulette/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 "math_util.h"
#include "poketch_memory.h"
#include "sys_task_manager.h"
#define WINDOW_WIDTH_TILES 20
#define WINDOW_HEIGHT_TILES 19
static void SetupSprites(RouletteGraphics *graphics, const RouletteData *rouletteData);
static void UnloadSprites(RouletteGraphics *graphics);
static void SetupWindow(RouletteGraphics *graphics, u32 baseTile);
static void EndTask(PoketchTaskManager *taskMan);
static void Task_DrawBackground(SysTask *task, void *taskMan);
static void Task_FreeBackground(SysTask *task, void *taskMan);
static void Task_Unused(SysTask *task, void *taskMan);
static void Task_UpdateDrawing(SysTask *task, void *taskMan);
static void Task_Unused2(SysTask *task, void *taskMan);
static void Task_UpdateButtonStates(SysTask *task, void *taskMan);
static void Task_ClearDrawing(SysTask *task, void *taskMan);
static void Task_RunSpinner(SysTask *task, void *taskMan);
static void Task_StopSpinner(SysTask *task, void *taskMan);
BOOL PoketchRouletteGraphics_New(RouletteGraphics **dest, const RouletteData *rouletteData, BgConfig *bgConfig)
{
RouletteGraphics *graphics = Heap_Alloc(HEAP_ID_POKETCH_APP, sizeof(RouletteGraphics));
if (graphics != NULL) {
PoketchTask_InitActiveTaskList(graphics->activeTasks, ROULETTE_TASK_SLOTS);
graphics->rouletteData = rouletteData;
graphics->bgConfig = PoketchGraphics_GetBgConfig();
graphics->animMan = PoketchGraphics_GetAnimationManager();
graphics->spinnerAngle = 0;
SetupSprites(graphics, rouletteData);
if (graphics->bgConfig != NULL) {
*dest = graphics;
return TRUE;
}
}
return FALSE;
}
void PoketchRouletteGraphics_Free(RouletteGraphics *graphics)
{
if (graphics != NULL) {
UnloadSprites(graphics);
Heap_Free(graphics);
}
}
static void SetupSprites(RouletteGraphics *graphics, const RouletteData *rouletteData)
{
static const PoketchAnimation_AnimationData animationData[] = {
{
.translation = { FX32_CONST(96), FX32_CONST(96) },
.animIdx = 0,
.flip = NNS_G2D_RENDERERFLIP_NONE,
.oamPriority = 2,
.priority = 0,
.hasAffineTransform = TRUE,
},
{
.translation = { FX32_CONST(187), FX32_CONST(50) },
.animIdx = 1,
.flip = NNS_G2D_RENDERERFLIP_NONE,
.oamPriority = 2,
.priority = 0,
.hasAffineTransform = FALSE,
},
{
.translation = { FX32_CONST(187), FX32_CONST(96) },
.animIdx = 4,
.flip = NNS_G2D_RENDERERFLIP_NONE,
.oamPriority = 2,
.priority = 0,
.hasAffineTransform = FALSE,
},
{
.translation = { FX32_CONST(187), FX32_CONST(142) },
.animIdx = 5,
.flip = NNS_G2D_RENDERERFLIP_NONE,
.oamPriority = 2,
.priority = 0,
.hasAffineTransform = FALSE,
},
};
Graphics_LoadObjectTiles(NARC_INDEX_GRAPHIC__POKETCH, 89, DS_SCREEN_SUB, 0, 0, TRUE, HEAP_ID_POKETCH_APP);
PoketchAnimation_LoadSpriteFromNARC(&graphics->animData, NARC_INDEX_GRAPHIC__POKETCH, 87, 88, HEAP_ID_POKETCH_APP);
for (int i = 0; i < NUM_SPRITES; i++) {
graphics->sprites[i] = PoketchAnimation_SetupNewAnimatedSprite(graphics->animMan, &animationData[i], &graphics->animData);
}
}
static void UnloadSprites(RouletteGraphics *graphics)
{
for (int i = 0; i < NUM_SPRITES; i++) {
if (graphics->sprites[i]) {
PoketchAnimation_RemoveAnimatedSprite(graphics->animMan, graphics->sprites[i]);
}
}
PoketchAnimation_FreeSpriteData(&graphics->animData);
}
static const PoketchTask sRouletteTasks[] = {
{ ROULETTE_GRAPHICS_INIT, Task_DrawBackground, 0 },
{ ROULETTE_GRAPHICS_FREE, Task_FreeBackground, 0 },
{ ROULETTE_GRAPHICS_UNUSED, Task_Unused, 0 },
{ ROULETTE_GRAPHICS_UPDATE_DRAWING, Task_UpdateDrawing, 0 },
{ ROULETTE_GRAPHICS_UNUSED2, Task_Unused2, 0 },
{ ROULETTE_GRAPHICS_UPDATE_BUTTONS, Task_UpdateButtonStates, 0 },
{ ROULETTE_GRAPHICS_CLEAR_DRAWING, Task_ClearDrawing, 0 },
{ ROULETTE_GRAPHICS_RUN_SPINNER, Task_RunSpinner, 0 },
{ ROULETTE_GRAPHICS_STOP_SPINNER, Task_StopSpinner, 0 },
{ 0 }
};
void PoketchRouletteGraphics_StartTask(RouletteGraphics *graphics, enum RouletteGraphicsTask taskID)
{
PoketchTask_Start(sRouletteTasks, taskID, graphics, graphics->rouletteData, graphics->activeTasks, 2, HEAP_ID_POKETCH_APP);
}
BOOL PoketchRouletteGraphics_TaskIsNotActive(RouletteGraphics *graphics, enum RouletteGraphicsTask taskID)
{
return PoketchTask_TaskIsNotActive(graphics->activeTasks, taskID);
}
BOOL PoketchRouletteGraphics_NoActiveTasks(RouletteGraphics *graphics)
{
return PoketchTask_NoActiveTasks(graphics->activeTasks);
}
static void EndTask(PoketchTaskManager *taskMan)
{
RouletteGraphics *graphics = PoketchTask_GetTaskData(taskMan);
PoketchTask_EndTask(graphics->activeTasks, taskMan);
}
static void Task_DrawBackground(SysTask *task, void *taskMan)
{
static const BgTemplate mainBgTemplate = {
.x = 0,
.y = 0,
.bufferSize = 0,
.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,
};
static const BgTemplate windowBgTemplate = {
.x = 0,
.y = 0,
.bufferSize = 0x800,
.baseTile = 0,
.screenSize = BG_SCREEN_SIZE_256x256,
.colorMode = GX_BG_COLORMODE_16,
.screenBase = GX_BG_SCRBASE_0x7800,
.charBase = GX_BG_CHARBASE_0x00000,
.bgExtPltt = GX_BG_EXTPLTT_01,
.priority = 3,
.areaOver = 0,
.mosaic = FALSE,
};
GF_ASSERT(GF_heap_c_dummy_return_true(HEAP_ID_POKETCH_APP));
RouletteGraphics *graphics = PoketchTask_GetTaskData(taskMan);
Bg_InitFromTemplate(graphics->bgConfig, BG_LAYER_SUB_2, &mainBgTemplate, BG_TYPE_STATIC);
Bg_InitFromTemplate(graphics->bgConfig, BG_LAYER_SUB_3, &windowBgTemplate, BG_TYPE_STATIC);
GF_ASSERT(GF_heap_c_dummy_return_true(HEAP_ID_POKETCH_APP));
u32 bgTileCount = Graphics_LoadTilesToBgLayer(NARC_INDEX_GRAPHIC__POKETCH, 86, graphics->bgConfig, BG_LAYER_SUB_2, 0, 0, TRUE, HEAP_ID_POKETCH_APP);
bgTileCount /= TILE_SIZE_4BPP;
Graphics_LoadTilemapToBgLayer(NARC_INDEX_GRAPHIC__POKETCH, 85, graphics->bgConfig, BG_LAYER_SUB_2, 0, 0, TRUE, HEAP_ID_POKETCH_APP);
PoketchGraphics_LoadActivePalette(0, 0);
GF_ASSERT(GF_heap_c_dummy_return_true(HEAP_ID_POKETCH_APP));
SetupWindow(graphics, bgTileCount);
Bg_CopyTilemapBufferToVRAM(graphics->bgConfig, BG_LAYER_SUB_3);
GXSDispCnt dispCnt = GXS_GetDispCnt();
GXS_SetVisiblePlane(dispCnt.visiblePlane | GX_PLANEMASK_BG2 | GX_PLANEMASK_OBJ);
EndTask(taskMan);
GF_ASSERT(GF_heap_c_dummy_return_true(HEAP_ID_POKETCH_APP));
}
static void SetupWindow(RouletteGraphics *graphics, u32 baseTile)
{
WindowTemplate windowTemplate = {
.bgLayer = BG_LAYER_SUB_3,
.tilemapLeft = POKETCH_SCREEN_TILE_OFFSET_X,
.tilemapTop = POKETCH_SCREEN_TILE_OFFSET_Y,
.width = WINDOW_WIDTH_TILES,
.height = WINDOW_HEIGHT_TILES,
.palette = 0,
.baseTile = 0
};
graphics->windowBaseTile = baseTile;
windowTemplate.baseTile = baseTile;
Window_AddFromTemplate(graphics->bgConfig, &graphics->window, &windowTemplate);
if (PoketchMemory_ReadFast(graphics->rouletteData->appID, graphics->window.pixels, WINDOW_WIDTH_TILES * WINDOW_HEIGHT_TILES * TILE_SIZE_4BPP) == FALSE) {
Window_FillTilemap(&graphics->window, 4);
}
Window_PutToTilemap(&graphics->window);
Window_LoadTiles(&graphics->window);
}
static void Task_FreeBackground(SysTask *task, void *taskMan)
{
RouletteGraphics *graphics = PoketchTask_GetTaskData(taskMan);
switch (PoketchTask_GetState(taskMan)) {
case 0:
graphics->killSpinnerTask = TRUE;
PoketchTask_IncrementState(taskMan);
break;
case 1:
PoketchMemory_WriteFast(graphics->rouletteData->appID, graphics->window.pixels, WINDOW_WIDTH_TILES * WINDOW_HEIGHT_TILES * TILE_SIZE_4BPP);
Window_Remove(&graphics->window);
Bg_FreeTilemapBuffer(graphics->bgConfig, BG_LAYER_SUB_2);
Bg_FreeTilemapBuffer(graphics->bgConfig, BG_LAYER_SUB_3);
EndTask(taskMan);
}
}
static void Task_Unused(SysTask *task, void *taskMan)
{
RouletteGraphics *graphics = PoketchTask_GetTaskData(taskMan);
Window_LoadTiles(&graphics->window);
EndTask(taskMan);
}
static void Task_UpdateDrawing(SysTask *task, void *taskMan)
{
RouletteGraphics *graphics = PoketchTask_GetTaskData(taskMan);
s32 x = graphics->rouletteData->x * 2;
s32 y = graphics->rouletteData->y * 2;
// Dividing x and y by 8 (TILE_WIDTH/HEIGHT_PIXELS) here
s32 tileIdx = ((y >> 3) * WINDOW_WIDTH_TILES) + (x >> 3);
Window_FillRectWithColor(&graphics->window, 1, x, y, 2, 2);
GXS_LoadBG3Char(graphics->window.pixels + (tileIdx * TILE_SIZE_4BPP), (graphics->windowBaseTile + tileIdx) * TILE_SIZE_4BPP, TILE_SIZE_4BPP);
EndTask(taskMan);
}
static void Task_Unused2(SysTask *task, void *taskMan)
{
RouletteGraphics *graphics = PoketchTask_GetTaskData(taskMan);
Window_LoadTiles(&graphics->window);
EndTask(taskMan);
}
static void Task_UpdateButtonStates(SysTask *task, void *taskMan)
{
RouletteGraphics *graphics = PoketchTask_GetTaskData(taskMan);
const RouletteData *rouletteData = PoketchTask_GetConstTaskData(taskMan);
PoketchAnimation_UpdateAnimationIdx(graphics->sprites[1], rouletteData->playButtonPressed ? 2 : 1);
PoketchAnimation_UpdateAnimationIdx(graphics->sprites[2], rouletteData->stopButtonPressed ? 4 : 3);
PoketchAnimation_UpdateAnimationIdx(graphics->sprites[3], rouletteData->clearButtonPressed ? 6 : 5);
EndTask(taskMan);
}
static void Task_ClearDrawing(SysTask *task, void *taskMan)
{
RouletteGraphics *graphics = PoketchTask_GetTaskData(taskMan);
const RouletteData *rouletteData = PoketchTask_GetConstTaskData(taskMan);
Window_FillTilemap(&graphics->window, 4);
Window_LoadTiles(&graphics->window);
EndTask(taskMan);
}
static void Task_RunSpinner(SysTask *task, void *taskMan)
{
RouletteGraphics *graphics = PoketchTask_GetTaskData(taskMan);
const RouletteData *rouletteData = PoketchTask_GetConstTaskData(taskMan);
u32 spinnerState = PoketchTask_GetState(taskMan);
if ((spinnerState != 0) && graphics->killSpinnerTask) {
EndTask(taskMan);
return;
}
switch (spinnerState) {
case 0:
graphics->spinnerAngle += 336;
graphics->rotationSpeed = 336;
PoketchAnimation_SetSpriteRotation(graphics->sprites[0], graphics->spinnerAngle);
graphics->spinnerUpToSpeed = FALSE;
graphics->stopSpinner = FALSE;
graphics->killSpinnerTask = FALSE;
PoketchTask_IncrementState(taskMan);
break;
case 1:
graphics->spinnerAngle += graphics->rotationSpeed;
PoketchAnimation_SetSpriteRotation(graphics->sprites[0], graphics->spinnerAngle);
graphics->rotationSpeed += 336;
if (graphics->rotationSpeed >= 12288) {
graphics->rotationSpeed = 12288;
graphics->spinnerUpToSpeed = TRUE;
PoketchTask_IncrementState(taskMan);
}
break;
case 2:
graphics->spinnerAngle += graphics->rotationSpeed;
PoketchAnimation_SetSpriteRotation(graphics->sprites[0], graphics->spinnerAngle);
if (graphics->stopSpinner) {
graphics->stopDelay = MTRNG_Next() % 8;
if (graphics->rotationSpeed > 6656) {
graphics->rotationSpeed = 6656;
}
PoketchTask_IncrementState(taskMan);
}
break;
case 3:
graphics->spinnerAngle += graphics->rotationSpeed;
PoketchAnimation_SetSpriteRotation(graphics->sprites[0], graphics->spinnerAngle);
if (graphics->stopDelay == 0) {
graphics->stopDelay--;
} else {
PoketchTask_IncrementState(taskMan);
}
break;
case 4:
if (graphics->rotationSpeed > 80) {
graphics->rotationSpeed -= 80;
graphics->spinnerAngle += graphics->rotationSpeed;
PoketchAnimation_SetSpriteRotation(graphics->sprites[0], graphics->spinnerAngle);
} else {
graphics->rotationSpeed = 0;
EndTask(taskMan);
}
break;
}
}
static void Task_StopSpinner(SysTask *task, void *taskMan)
{
RouletteGraphics *graphics = PoketchTask_GetTaskData(taskMan);
const RouletteData *rouletteData = PoketchTask_GetConstTaskData(taskMan);
switch (PoketchTask_GetState(taskMan)) {
case 0:
graphics->stopSpinner = TRUE;
PoketchTask_IncrementState(taskMan);
break;
case 1:
if (PoketchRouletteGraphics_TaskIsNotActive(graphics, ROULETTE_GRAPHICS_RUN_SPINNER)) {
PoketchSystem_PlaySoundEffect(SEQ_SE_DP_POKETCH_011);
EndTask(taskMan);
}
break;
}
}

View File

@@ -0,0 +1,427 @@
#include <nitro.h>
#include <nitro/sinit.h>
#include "generated/sdat.h"
#include "applications/poketch/poketch_button.h"
#include "applications/poketch/poketch_system.h"
#include "applications/poketch/roulette/graphics.h"
#include "bg_window.h"
#include "heap.h"
#include "sys_task.h"
#include "sys_task_manager.h"
#include "touch_screen.h"
#define ROULETTE_BUTTON_START 0
#define ROULETTE_BUTTON_STOP 1
#define ROULETTE_BUTTON_CLEAR 2
typedef struct Poketch_Roulette {
u8 state;
u8 subState;
u8 shouldExit;
u8 currentlyDrawing;
RouletteData rouletteData;
RouletteGraphics *graphics;
PoketchSystem *poketchSys;
PoketchButtonManager *buttonManager;
enum ButtonManagerState buttonState;
u32 button;
} PoketchRoulette;
typedef BOOL (*StateFunc)(PoketchRoulette *);
enum RouletteState {
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(PoketchRoulette *appData, PoketchSystem *poketchSys, BgConfig *bgConfig, u32 appID);
static void Free(PoketchRoulette *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(PoketchRoulette *appData, enum RouletteState newState);
static BOOL State_LoadApp(PoketchRoulette *appData);
static BOOL State_UpdateApp(PoketchRoulette *appData);
static BOOL State_UnloadApp(PoketchRoulette *appData);
static BOOL GetTouchStartPosition(PoketchRoulette *appData);
static BOOL GetTouchContinuePosition(PoketchRoulette *appData);
static void UpdatePixelsOnPath(PoketchRoulette *appData, u32 x, u32 y, u32 endX, u32 endY);
static void ClearPixelArray(RouletteData *rouletteData);
static void NitroStaticInit(void)
{
PoketchSystem_SetAppFunctions(New, Exit);
}
static BOOL New(void **appData, PoketchSystem *poketchSys, BgConfig *bgConfig, u32 appID)
{
PoketchRoulette *roulette = Heap_Alloc(HEAP_ID_POKETCH_APP, sizeof(PoketchRoulette));
if (roulette != NULL) {
if (Init(roulette, poketchSys, bgConfig, appID)) {
if (SysTask_Start(Task_Main, roulette, 1) != NULL) {
*appData = roulette;
return TRUE;
}
}
Heap_Free(roulette);
}
return FALSE;
}
static BOOL Init(PoketchRoulette *appData, PoketchSystem *poketchSys, BgConfig *bgConfig, u32 appID)
{
static const TouchScreenRect sButtonHitboxes[] = {
{ .rect = { .top = 34, .bottom = 66, .left = 167, .right = 207 } },
{ .rect = { .top = 80, .bottom = 112, .left = 167, .right = 207 } },
{ .rect = { .top = 126, .bottom = 158, .left = 167, .right = 207 } }
};
appData->rouletteData.appID = appID;
appData->rouletteData.playButtonPressed = FALSE;
appData->rouletteData.stopButtonPressed = TRUE;
appData->rouletteData.clearButtonPressed = FALSE;
if (PoketchRouletteGraphics_New(&appData->graphics, &appData->rouletteData, bgConfig)) {
appData->state = STATE_LOAD_APP;
appData->subState = 0;
appData->shouldExit = FALSE;
appData->currentlyDrawing = FALSE;
ClearPixelArray(&appData->rouletteData);
appData->buttonManager = PoketchButtonManager_New(sButtonHitboxes, NELEMS(sButtonHitboxes), ButtonCallback, appData, HEAP_ID_POKETCH_APP);
appData->buttonState = BUTTON_MANAGER_STATE_NULL;
appData->poketchSys = poketchSys;
return TRUE;
}
return FALSE;
}
static void Free(PoketchRoulette *appData)
{
PoketchButtonManager_Free(appData->buttonManager);
PoketchRouletteGraphics_Free(appData->graphics);
Heap_Free(appData);
}
static void Task_Main(SysTask *task, void *appData)
{
static const StateFunc stateFuncs[] = {
State_LoadApp,
State_UpdateApp,
State_UnloadApp
};
PoketchRoulette *roulette = appData;
if (roulette->state < NELEMS(stateFuncs)) {
PoketechSystem_UpdateButtonManager(roulette->poketchSys, roulette->buttonManager);
if (stateFuncs[roulette->state](roulette)) {
Free(roulette);
SysTask_Done(task);
PoketchSystem_NotifyAppUnloaded(roulette->poketchSys);
}
}
}
static void ButtonCallback(u32 buttonID, u32 buttonState, u32 touchState, void *appData)
{
PoketchRoulette *roulette = appData;
roulette->buttonState = buttonState;
roulette->button = buttonID;
}
static void Exit(void *appData)
{
((PoketchRoulette *)appData)->shouldExit = TRUE;
}
static void ChangeState(PoketchRoulette *appData, enum RouletteState newState)
{
if (appData->shouldExit == FALSE) {
appData->state = newState;
} else {
appData->state = STATE_SHUTDOWN;
}
appData->subState = 0;
}
static BOOL State_LoadApp(PoketchRoulette *appData)
{
switch (appData->subState) {
case 0:
PoketchRouletteGraphics_StartTask(appData->graphics, ROULETTE_GRAPHICS_INIT);
appData->subState++;
break;
case 1:
if (PoketchRouletteGraphics_TaskIsNotActive(appData->graphics, ROULETTE_GRAPHICS_INIT)) {
PoketchSystem_NotifyAppLoaded(appData->poketchSys);
ChangeState(appData, STATE_UPDATE_LOOP);
}
break;
}
return FALSE;
}
static BOOL State_UpdateApp(PoketchRoulette *appData)
{
if (appData->shouldExit) {
ChangeState(appData, STATE_SHUTDOWN);
}
switch (appData->subState) {
case 0:
if (PoketechSystem_IsRunningTask(appData->poketchSys)) {
break;
}
if (appData->buttonState == BUTTON_MANAGER_STATE_TOUCH) {
switch (appData->button) {
case ROULETTE_BUTTON_START:
appData->rouletteData.playButtonPressed = TRUE;
appData->rouletteData.stopButtonPressed = FALSE;
appData->rouletteData.clearButtonPressed = TRUE;
PoketchRouletteGraphics_StartTask(appData->graphics, ROULETTE_GRAPHICS_UPDATE_BUTTONS);
PoketchRouletteGraphics_StartTask(appData->graphics, ROULETTE_GRAPHICS_RUN_SPINNER);
PoketchSystem_PlaySoundEffect(SEQ_SE_DP_POKETCH_003);
appData->subState = 1;
break;
case ROULETTE_BUTTON_STOP:
PoketchSystem_PlaySoundEffect(SEQ_SE_DP_BEEP);
break;
case ROULETTE_BUTTON_CLEAR:
appData->rouletteData.clearButtonPressed = TRUE;
PoketchRouletteGraphics_StartTask(appData->graphics, ROULETTE_GRAPHICS_UPDATE_BUTTONS);
PoketchSystem_PlaySoundEffect(SEQ_SE_DP_POKETCH_003);
appData->subState = 3;
break;
}
appData->buttonState = BUTTON_MANAGER_STATE_NULL;
break;
}
if (appData->currentlyDrawing) {
u32 prevX = appData->rouletteData.x;
u32 prevY = appData->rouletteData.y;
if (GetTouchContinuePosition(appData)) {
UpdatePixelsOnPath(appData, prevX, prevY, appData->rouletteData.x, appData->rouletteData.y);
} else {
appData->currentlyDrawing = FALSE;
}
} else if (GetTouchStartPosition(appData)) {
PoketchRouletteGraphics_StartTask(appData->graphics, ROULETTE_GRAPHICS_UPDATE_DRAWING);
appData->currentlyDrawing = TRUE;
}
break;
case 1:
if (appData->buttonState == BUTTON_MANAGER_STATE_TOUCH) {
switch (appData->button) {
case ROULETTE_BUTTON_CLEAR:
case ROULETTE_BUTTON_START:
PoketchSystem_PlaySoundEffect(SEQ_SE_DP_BEEP);
break;
case ROULETTE_BUTTON_STOP:
appData->rouletteData.playButtonPressed = TRUE;
appData->rouletteData.stopButtonPressed = TRUE;
appData->rouletteData.clearButtonPressed = TRUE;
PoketchRouletteGraphics_StartTask(appData->graphics, ROULETTE_GRAPHICS_UPDATE_BUTTONS);
PoketchRouletteGraphics_StartTask(appData->graphics, ROULETTE_GRAPHICS_STOP_SPINNER);
PoketchSystem_PlaySoundEffect(SEQ_SE_DP_POKETCH_003);
appData->subState = 2;
break;
}
appData->buttonState = BUTTON_MANAGER_STATE_NULL;
break;
}
break;
case 2:
if (PoketchRouletteGraphics_TaskIsNotActive(appData->graphics, ROULETTE_GRAPHICS_STOP_SPINNER)) {
appData->rouletteData.playButtonPressed = FALSE;
appData->rouletteData.stopButtonPressed = TRUE;
appData->rouletteData.clearButtonPressed = FALSE;
PoketchRouletteGraphics_StartTask(appData->graphics, ROULETTE_GRAPHICS_UPDATE_BUTTONS);
appData->subState = 0;
}
break;
case 3:
if (appData->buttonState == BUTTON_MANAGER_STATE_DRAGGING) {
appData->rouletteData.clearButtonPressed = FALSE;
PoketchRouletteGraphics_StartTask(appData->graphics, ROULETTE_GRAPHICS_UPDATE_BUTTONS);
appData->subState = 0;
break;
}
if (appData->buttonState == BUTTON_MANAGER_STATE_TAP) {
appData->rouletteData.clearButtonPressed = FALSE;
ClearPixelArray(&appData->rouletteData);
PoketchRouletteGraphics_StartTask(appData->graphics, ROULETTE_GRAPHICS_UPDATE_BUTTONS);
PoketchRouletteGraphics_StartTask(appData->graphics, ROULETTE_GRAPHICS_CLEAR_DRAWING);
appData->subState = 0;
break;
}
break;
}
return FALSE;
}
static BOOL GetTouchStartPosition(PoketchRoulette *appData)
{
u32 x, y;
if (PoketchSystem_GetDisplayHeldCoords(&x, &y)) {
if ((x - POKETCH_SCREEN_MIN_X < DRAWING_REGION_WIDTH - 1) & (y - POKETCH_SCREEN_MIN_Y < DRAWING_REGION_HEIGHT - 1)) {
x = (x - POKETCH_SCREEN_MIN_X) / 2;
y = (y - POKETCH_SCREEN_MIN_Y) / 2;
if (appData->rouletteData.pixels[x][y] == 0) {
appData->rouletteData.pixels[x][y] = 1;
appData->rouletteData.x = x;
appData->rouletteData.y = y;
return TRUE;
}
}
}
return FALSE;
}
static BOOL GetTouchContinuePosition(PoketchRoulette *appData)
{
u32 x, y;
if (PoketchSystem_GetDisplayHeldCoords(&x, &y)) {
if ((x - POKETCH_SCREEN_MIN_X < DRAWING_REGION_WIDTH - 1) & (y - POKETCH_SCREEN_MIN_Y < DRAWING_REGION_HEIGHT - 1)) {
x = (x - POKETCH_SCREEN_MIN_X) / 2;
y = (y - POKETCH_SCREEN_MIN_Y) / 2;
appData->rouletteData.x = x;
appData->rouletteData.y = y;
return TRUE;
}
}
return FALSE;
}
static void UpdatePixelsOnPath(PoketchRoulette *appData, u32 x, u32 y, u32 endX, u32 endY)
{
fx32 minorAxisStep;
if ((y == endY) && (x == endX)) {
return;
}
u32 deltaX = endX > x ? endX - x : x - endX;
u32 deltaY = endY > y ? endY - y : y - endY;
if (deltaX > deltaY) {
u32 xStep = endX > x ? 1 : -1;
if (deltaX) {
minorAxisStep = (endY - y) * FX32_ONE;
minorAxisStep /= (s32)deltaX;
} else {
minorAxisStep = 0;
}
fx32 minorAxis = (y << FX32_SHIFT) + minorAxisStep;
x += xStep;
while (x != endX) {
u32 minorAxisRounded = minorAxis >> FX32_SHIFT;
if ((x < DRAWING_REGION_WIDTH) && (minorAxisRounded < DRAWING_REGION_HEIGHT)) {
if (appData->rouletteData.pixels[x][minorAxisRounded] == 0) {
appData->rouletteData.pixels[x][minorAxisRounded] = 0;
appData->rouletteData.x = x;
appData->rouletteData.y = minorAxisRounded;
PoketchRouletteGraphics_StartTask(appData->graphics, ROULETTE_GRAPHICS_UPDATE_DRAWING);
}
}
x += xStep;
minorAxis += minorAxisStep;
}
} else {
u32 yStep = endY > y ? 1 : -1;
if (deltaY) {
minorAxisStep = (endX - x) * FX32_ONE;
minorAxisStep /= (s32)deltaY;
} else {
minorAxisStep = 0;
}
fx32 minorAxis = (x << FX32_SHIFT) + minorAxisStep;
y += yStep;
while (y != endY) {
u32 minorAxisRounded = minorAxis >> FX32_SHIFT;
if ((y < DRAWING_REGION_HEIGHT) && (minorAxisRounded < DRAWING_REGION_WIDTH)) {
if (appData->rouletteData.pixels[minorAxisRounded][y] == 0) {
appData->rouletteData.pixels[minorAxisRounded][y] = 1;
appData->rouletteData.x = minorAxisRounded;
appData->rouletteData.y = y;
PoketchRouletteGraphics_StartTask(appData->graphics, ROULETTE_GRAPHICS_UPDATE_DRAWING);
}
}
y += yStep;
minorAxis += minorAxisStep;
}
}
if ((endY < DRAWING_REGION_HEIGHT) && (endX < DRAWING_REGION_WIDTH)) {
appData->rouletteData.x = endX;
appData->rouletteData.y = endY;
PoketchRouletteGraphics_StartTask(appData->graphics, ROULETTE_GRAPHICS_UPDATE_DRAWING);
}
}
static BOOL State_UnloadApp(PoketchRoulette *appData)
{
switch (appData->subState) {
case 0:
PoketchRouletteGraphics_StartTask(appData->graphics, ROULETTE_GRAPHICS_FREE);
appData->subState++;
break;
case 1:
if (PoketchRouletteGraphics_NoActiveTasks(appData->graphics)) {
return TRUE;
}
break;
}
return FALSE;
}
static void ClearPixelArray(RouletteData *rouletteData)
{
for (int x = 0; x < DRAWING_REGION_WIDTH; x++) {
for (int y = 0; y < DRAWING_REGION_HEIGHT; y++) {
rouletteData->pixels[x][y] = 0;
}
}
}

View File

@@ -40,6 +40,8 @@ typedef struct PoketchStopwatch {
PoketchSystem *poketchSys;
} PoketchStopwatch;
typedef BOOL (*StateFunc)(PoketchStopwatch *);
enum StopwatchTask {
STATE_LOAD_APP = 0,
STATE_INACTIVE_TIMER,
@@ -156,7 +158,7 @@ static void Free(PoketchStopwatch *appData)
static void Task_Main(SysTask *task, void *appData)
{
static BOOL (*const stateFuncs[])(PoketchStopwatch *) = {
static const StateFunc stateFuncs[] = {
State_LoadApp,
State_InactiveTimer,
State_ActiveTimer,

View File

@@ -697,8 +697,8 @@ pokeplatinum_c = files(
'overlay039/ov39_022563DC.c',
'applications/poketch/daycare_checker/main.c',
'applications/poketch/daycare_checker/graphics.c',
'overlay041/ov41_022561C0.c',
'overlay041/ov41_022567B0.c',
'applications/poketch/roulette/main.c',
'applications/poketch/roulette/graphics.c',
'overlay042/ov42_022561C0.c',
'overlay042/ov42_022563D4.c',
'applications/poketch/move_tester/main.c',

View File

@@ -1,424 +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 "overlay041/ov41_022567B0.h"
#include "overlay041/struct_ov41_022567B0_1.h"
#include "overlay041/struct_ov41_022567B0_decl.h"
#include "bg_window.h"
#include "heap.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;
u8 unk_03;
UnkStruct_ov41_022567B0_1 unk_04;
UnkStruct_ov41_022567B0 *unk_5B7C;
PoketchSystem *poketchSys;
PoketchButtonManager *buttonManager;
u32 unk_5B88;
u32 unk_5B8C;
} UnkStruct_ov41_02256220;
static void NitroStaticInit(void);
static BOOL ov41_022561D4(void **param0, PoketchSystem *poketchSys, BgConfig *param2, u32 param3);
static BOOL ov41_02256220(UnkStruct_ov41_02256220 *param0, PoketchSystem *poketchSys, BgConfig *param2, u32 param3);
static void ov41_02256294(UnkStruct_ov41_02256220 *param0);
static void ov41_022562B8(SysTask *param0, void *param1);
static void ov41_02256300(u32 param0, u32 param1, u32 param2, void *param3);
static void ov41_02256310(void *param0);
static void ov41_02256318(UnkStruct_ov41_02256220 *param0, u32 param1);
static BOOL ov41_0225632C(UnkStruct_ov41_02256220 *param0);
static BOOL ov41_02256378(UnkStruct_ov41_02256220 *param0);
static BOOL ov41_02256564(UnkStruct_ov41_02256220 *param0);
static BOOL ov41_022565C4(UnkStruct_ov41_02256220 *param0);
static void ov41_02256610(UnkStruct_ov41_02256220 *param0, u32 param1, u32 param2, u32 param3, u32 param4);
static BOOL ov41_02256754(UnkStruct_ov41_02256220 *param0);
static void ov41_02256790(UnkStruct_ov41_022567B0_1 *param0);
static void NitroStaticInit(void)
{
PoketchSystem_SetAppFunctions(ov41_022561D4, ov41_02256310);
}
static BOOL ov41_022561D4(void **param0, PoketchSystem *poketchSys, BgConfig *param2, u32 param3)
{
UnkStruct_ov41_02256220 *v0 = (UnkStruct_ov41_02256220 *)Heap_Alloc(HEAP_ID_POKETCH_APP, sizeof(UnkStruct_ov41_02256220));
if (v0 != NULL) {
if (ov41_02256220(v0, poketchSys, param2, param3)) {
if (SysTask_Start(ov41_022562B8, v0, 1) != NULL) {
*param0 = v0;
return 1;
}
}
Heap_Free(v0);
}
return 0;
}
static BOOL ov41_02256220(UnkStruct_ov41_02256220 *param0, PoketchSystem *poketchSys, BgConfig *param2, u32 param3)
{
static const TouchScreenHitTable v0[] = {
{ 34, 66, 167, 207 },
{ 80, 112, 167, 207 },
{ 126, 158, 167, 207 }
};
param0->unk_04.unk_08 = param3;
param0->unk_04.unk_5B74 = 0;
param0->unk_04.unk_5B75 = 1;
param0->unk_04.unk_5B76 = 0;
if (ov41_022567B0(&(param0->unk_5B7C), &(param0->unk_04), param2)) {
param0->unk_00 = 0;
param0->unk_01 = 0;
param0->unk_02 = 0;
param0->unk_03 = 0;
ov41_02256790(&param0->unk_04);
param0->buttonManager = PoketchButtonManager_New(v0, NELEMS(v0), ov41_02256300, param0, HEAP_ID_POKETCH_APP);
param0->unk_5B88 = 0;
param0->poketchSys = poketchSys;
return 1;
}
return 0;
}
static void ov41_02256294(UnkStruct_ov41_02256220 *param0)
{
PoketchButtonManager_Free(param0->buttonManager);
ov41_022567F8(param0->unk_5B7C);
Heap_Free(param0);
}
static void ov41_022562B8(SysTask *param0, void *param1)
{
static BOOL (*const v0[])(UnkStruct_ov41_02256220 *) = {
ov41_0225632C,
ov41_02256378,
ov41_02256754
};
UnkStruct_ov41_02256220 *v1 = (UnkStruct_ov41_02256220 *)param1;
if (v1->unk_00 < NELEMS(v0)) {
PoketechSystem_UpdateButtonManager(v1->poketchSys, v1->buttonManager);
if (v0[v1->unk_00](v1)) {
ov41_02256294(v1);
SysTask_Done(param0);
PoketchSystem_NotifyAppUnloaded(v1->poketchSys);
}
} else {
}
}
static void ov41_02256300(u32 param0, u32 param1, u32 param2, void *param3)
{
UnkStruct_ov41_02256220 *v0 = (UnkStruct_ov41_02256220 *)param3;
v0->unk_5B88 = param1;
v0->unk_5B8C = param0;
}
static void ov41_02256310(void *param0)
{
((UnkStruct_ov41_02256220 *)param0)->unk_02 = 1;
}
static void ov41_02256318(UnkStruct_ov41_02256220 *param0, u32 param1)
{
if (param0->unk_02 == 0) {
param0->unk_00 = param1;
} else {
param0->unk_00 = 2;
}
param0->unk_01 = 0;
}
static BOOL ov41_0225632C(UnkStruct_ov41_02256220 *param0)
{
switch (param0->unk_01) {
case 0:
ov41_0225688C(param0->unk_5B7C, 0);
param0->unk_01++;
break;
case 1:
if (ov41_022568B0(param0->unk_5B7C, 0)) {
PoketchSystem_NotifyAppLoaded(param0->poketchSys);
ov41_02256318(param0, 1);
}
break;
}
return 0;
}
static BOOL ov41_02256378(UnkStruct_ov41_02256220 *param0)
{
if (param0->unk_02) {
ov41_02256318(param0, 2);
}
switch (param0->unk_01) {
case 0:
if (PoketechSystem_IsRunningTask(param0->poketchSys)) {
break;
}
if (param0->unk_5B88 == 1) {
switch (param0->unk_5B8C) {
case 0:
param0->unk_04.unk_5B74 = 1;
param0->unk_04.unk_5B75 = 0;
param0->unk_04.unk_5B76 = 1;
ov41_0225688C(param0->unk_5B7C, 5);
ov41_0225688C(param0->unk_5B7C, 7);
PoketchSystem_PlaySoundEffect(1635);
param0->unk_01 = 1;
break;
case 1:
PoketchSystem_PlaySoundEffect(1646);
break;
case 2:
param0->unk_04.unk_5B76 = 1;
ov41_0225688C(param0->unk_5B7C, 5);
PoketchSystem_PlaySoundEffect(1635);
param0->unk_01 = 3;
break;
}
param0->unk_5B88 = 0;
break;
}
if (param0->unk_03) {
u32 v0, v1;
v0 = param0->unk_04.unk_00;
v1 = param0->unk_04.unk_04;
if (ov41_022565C4(param0)) {
ov41_02256610(param0, v0, v1, param0->unk_04.unk_00, param0->unk_04.unk_04);
} else {
param0->unk_03 = 0;
}
} else {
if (ov41_02256564(param0)) {
ov41_0225688C(param0->unk_5B7C, 3);
param0->unk_03 = 1;
}
}
break;
case 1:
if (param0->unk_5B88 == 1) {
switch (param0->unk_5B8C) {
case 2:
case 0:
PoketchSystem_PlaySoundEffect(1646);
break;
case 1:
param0->unk_04.unk_5B74 = 1;
param0->unk_04.unk_5B75 = 1;
param0->unk_04.unk_5B76 = 1;
ov41_0225688C(param0->unk_5B7C, 5);
ov41_0225688C(param0->unk_5B7C, 8);
PoketchSystem_PlaySoundEffect(1635);
param0->unk_01 = 2;
break;
}
param0->unk_5B88 = 0;
break;
}
break;
case 2:
if (ov41_022568B0(param0->unk_5B7C, 8)) {
param0->unk_04.unk_5B74 = 0;
param0->unk_04.unk_5B75 = 1;
param0->unk_04.unk_5B76 = 0;
ov41_0225688C(param0->unk_5B7C, 5);
param0->unk_01 = 0;
}
break;
case 3:
if (param0->unk_5B88 == 2) {
param0->unk_04.unk_5B76 = 0;
ov41_0225688C(param0->unk_5B7C, 5);
param0->unk_01 = 0;
break;
}
if (param0->unk_5B88 == 3) {
param0->unk_04.unk_5B76 = 0;
ov41_02256790(&param0->unk_04);
ov41_0225688C(param0->unk_5B7C, 5);
ov41_0225688C(param0->unk_5B7C, 6);
param0->unk_01 = 0;
break;
}
break;
}
return 0;
}
static BOOL ov41_02256564(UnkStruct_ov41_02256220 *param0)
{
u32 v0, v1;
if (PoketchSystem_GetDisplayHeldCoords(&v0, &v1)) {
if (((u32)(v0 - 16) < (u32)(171 - 16)) & ((u32)(v1 - 16) < (u32)(165 - 16))) {
v0 = (v0 - 16) >> 1;
v1 = (v1 - 16) >> 1;
if (param0->unk_04.unk_0C[v0][v1] == 0) {
param0->unk_04.unk_0C[v0][v1] = 1;
param0->unk_04.unk_00 = v0;
param0->unk_04.unk_04 = v1;
return 1;
}
}
}
return 0;
}
static BOOL ov41_022565C4(UnkStruct_ov41_02256220 *param0)
{
u32 v0, v1;
if (PoketchSystem_GetDisplayHeldCoords(&v0, &v1)) {
if (((u32)(v0 - 16) < (u32)(171 - 16)) & ((u32)(v1 - 16) < (u32)(165 - 16))) {
v0 = (v0 - 16) >> 1;
v1 = (v1 - 16) >> 1;
param0->unk_04.unk_00 = v0;
param0->unk_04.unk_04 = v1;
return 1;
}
}
return 0;
}
static void ov41_02256610(UnkStruct_ov41_02256220 *param0, u32 param1, u32 param2, u32 param3, u32 param4)
{
u32 v0, v1, v2, v3;
fx32 v4, v5;
if ((param2 == param4) && (param1 == param3)) {
return;
}
v0 = (param3 > param1) ? (param3 - param1) : (param1 - param3);
v1 = (param4 > param2) ? (param4 - param2) : (param2 - param4);
if (v0 > v1) {
v2 = (param3 > param1) ? 1 : -1;
if (v0) {
v5 = ((param4 - param2) * FX32_ONE);
v5 /= (s32)(v0);
} else {
v5 = 0;
}
v4 = (param2 << FX32_SHIFT) + v5;
param1 += v2;
while (param1 != param3) {
v3 = v4 >> FX32_SHIFT;
if ((param1 < 156) && (v3 < 150)) {
if (param0->unk_04.unk_0C[param1][v3] == 0) {
param0->unk_04.unk_0C[param1][v3] = 0;
param0->unk_04.unk_00 = param1;
param0->unk_04.unk_04 = v3;
ov41_0225688C(param0->unk_5B7C, 3);
}
}
param1 += v2;
v4 += v5;
}
} else {
v2 = (param4 > param2) ? 1 : -1;
if (v1) {
v5 = (param3 - param1) * FX32_ONE;
v5 /= (s32)v1;
} else {
v5 = 0;
}
v4 = (param1 << FX32_SHIFT) + v5;
param2 += v2;
while (param2 != param4) {
v3 = v4 >> FX32_SHIFT;
if ((param2 < 150) && (v3 < 156)) {
if (param0->unk_04.unk_0C[v3][param2] == 0) {
param0->unk_04.unk_0C[v3][param2] = 1;
param0->unk_04.unk_00 = v3;
param0->unk_04.unk_04 = param2;
ov41_0225688C(param0->unk_5B7C, 3);
}
}
param2 += v2;
v4 += v5;
}
}
if ((param4 < 150) && (param3 < 156)) {
param0->unk_04.unk_00 = param3;
param0->unk_04.unk_04 = param4;
ov41_0225688C(param0->unk_5B7C, 3);
}
}
static BOOL ov41_02256754(UnkStruct_ov41_02256220 *param0)
{
switch (param0->unk_01) {
case 0:
ov41_0225688C(param0->unk_5B7C, 1);
param0->unk_01++;
break;
case 1:
if (ov41_022568BC(param0->unk_5B7C)) {
return 1;
}
break;
}
return 0;
}
static void ov41_02256790(UnkStruct_ov41_022567B0_1 *param0)
{
int v0, v1;
for (v0 = 0; v0 < 156; v0++) {
for (v1 = 0; v1 < 150; v1++) {
param0->unk_0C[v0][v1] = 0;
}
}
}

View File

@@ -1,406 +0,0 @@
#include "overlay041/ov41_022567B0.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 "overlay041/struct_ov41_022567B0_1.h"
#include "overlay041/struct_ov41_022567B0_decl.h"
#include "bg_window.h"
#include "graphics.h"
#include "heap.h"
#include "math_util.h"
#include "poketch_memory.h"
#include "sys_task_manager.h"
struct UnkStruct_ov41_022567B0_t {
const UnkStruct_ov41_022567B0_1 *unk_00;
BgConfig *unk_04;
u32 unk_08[6];
PoketchAnimation_AnimationManager *unk_20;
PoketchAnimation_AnimatedSpriteData *unk_24[4];
PoketchAnimation_SpriteData unk_34;
Window unk_48;
u32 unk_58;
BOOL unk_5C;
BOOL unk_60;
BOOL unk_64;
u16 unk_68;
u16 unk_6A;
u32 unk_6C;
};
static void ov41_0225680C(UnkStruct_ov41_022567B0 *param0, const UnkStruct_ov41_022567B0_1 *param1);
static void ov41_02256864(UnkStruct_ov41_022567B0 *param0);
static void ov41_022568C8(PoketchTaskManager *param0);
static void ov41_022568DC(SysTask *param0, void *param1);
static void ov41_022569BC(UnkStruct_ov41_022567B0 *param0, u32 param1);
static void ov41_02256A1C(SysTask *param0, void *param1);
static void ov41_02256A74(SysTask *param0, void *param1);
static void ov41_02256A8C(SysTask *param0, void *param1);
static void ov41_02256AE4(SysTask *param0, void *param1);
static void ov41_02256AFC(SysTask *param0, void *param1);
static void ov41_02256B60(SysTask *param0, void *param1);
static void ov41_02256B8C(SysTask *param0, void *param1);
static void ov41_02256D1C(SysTask *param0, void *param1);
BOOL ov41_022567B0(UnkStruct_ov41_022567B0 **param0, const UnkStruct_ov41_022567B0_1 *param1, BgConfig *param2)
{
UnkStruct_ov41_022567B0 *v0 = (UnkStruct_ov41_022567B0 *)Heap_Alloc(HEAP_ID_POKETCH_APP, sizeof(UnkStruct_ov41_022567B0));
if (v0 != NULL) {
PoketchTask_InitActiveTaskList(v0->unk_08, 4);
v0->unk_00 = param1;
v0->unk_04 = PoketchGraphics_GetBgConfig();
v0->unk_20 = PoketchGraphics_GetAnimationManager();
v0->unk_68 = 0;
ov41_0225680C(v0, param1);
if (v0->unk_04 != NULL) {
*param0 = v0;
return 1;
}
}
return 0;
}
void ov41_022567F8(UnkStruct_ov41_022567B0 *param0)
{
if (param0 != NULL) {
ov41_02256864(param0);
Heap_Free(param0);
}
}
static void ov41_0225680C(UnkStruct_ov41_022567B0 *param0, const UnkStruct_ov41_022567B0_1 *param1)
{
static const PoketchAnimation_AnimationData v0[] = {
{
{ (96 << FX32_SHIFT), (96 << FX32_SHIFT) },
0,
0,
2,
0,
1,
},
{
{ (187 << FX32_SHIFT), (50 << FX32_SHIFT) },
1,
0,
2,
0,
0,
},
{
{ (187 << FX32_SHIFT), (96 << FX32_SHIFT) },
4,
0,
2,
0,
0,
},
{
{ (187 << FX32_SHIFT), (142 << FX32_SHIFT) },
5,
0,
2,
0,
0,
},
};
int v1;
Graphics_LoadObjectTiles(12, 89, 1, 0, 0, 1, HEAP_ID_POKETCH_APP);
PoketchAnimation_LoadSpriteFromNARC(&param0->unk_34, 12, 87, 88, 8);
for (v1 = 0; v1 < 4; v1++) {
param0->unk_24[v1] = PoketchAnimation_SetupNewAnimatedSprite(param0->unk_20, &v0[v1], &param0->unk_34);
}
}
static void ov41_02256864(UnkStruct_ov41_022567B0 *param0)
{
int v0;
for (v0 = 0; v0 < 4; v0++) {
if (param0->unk_24[v0]) {
PoketchAnimation_RemoveAnimatedSprite(param0->unk_20, param0->unk_24[v0]);
}
}
PoketchAnimation_FreeSpriteData(&param0->unk_34);
}
static const PoketchTask Unk_ov41_02256E00[] = {
{ 0x0, ov41_022568DC, 0x0 },
{ 0x1, ov41_02256A1C, 0x0 },
{ 0x2, ov41_02256A74, 0x0 },
{ 0x3, ov41_02256A8C, 0x0 },
{ 0x4, ov41_02256AE4, 0x0 },
{ 0x5, ov41_02256AFC, 0x0 },
{ 0x6, ov41_02256B60, 0x0 },
{ 0x7, ov41_02256B8C, 0x0 },
{ 0x8, ov41_02256D1C, 0x0 },
{ 0x0, NULL, 0x0 }
};
void ov41_0225688C(UnkStruct_ov41_022567B0 *param0, u32 param1)
{
PoketchTask_Start(Unk_ov41_02256E00, param1, param0, param0->unk_00, param0->unk_08, 2, 8);
}
BOOL ov41_022568B0(UnkStruct_ov41_022567B0 *param0, u32 param1)
{
return PoketchTask_TaskIsNotActive(param0->unk_08, param1);
}
BOOL ov41_022568BC(UnkStruct_ov41_022567B0 *param0)
{
return PoketchTask_NoActiveTasks(param0->unk_08);
}
static void ov41_022568C8(PoketchTaskManager *param0)
{
UnkStruct_ov41_022567B0 *v0 = PoketchTask_GetTaskData(param0);
PoketchTask_EndTask(v0->unk_08, param0);
}
static void ov41_022568DC(SysTask *param0, void *param1)
{
static const BgTemplate v0 = {
.x = 0,
.y = 0,
.bufferSize = 0,
.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,
};
static const BgTemplate v1 = {
.x = 0,
.y = 0,
.bufferSize = 0x800,
.baseTile = 0,
.screenSize = BG_SCREEN_SIZE_256x256,
.colorMode = GX_BG_COLORMODE_16,
.screenBase = GX_BG_SCRBASE_0x7800,
.charBase = GX_BG_CHARBASE_0x00000,
.bgExtPltt = GX_BG_EXTPLTT_01,
.priority = 3,
.areaOver = 0,
.mosaic = FALSE,
};
GXSDispCnt v2;
UnkStruct_ov41_022567B0 *v3;
u32 v4;
GF_ASSERT(GF_heap_c_dummy_return_true(HEAP_ID_POKETCH_APP));
v3 = PoketchTask_GetTaskData(param1);
Bg_InitFromTemplate(v3->unk_04, BG_LAYER_SUB_2, &v0, 0);
Bg_InitFromTemplate(v3->unk_04, BG_LAYER_SUB_3, &v1, 0);
GF_ASSERT(GF_heap_c_dummy_return_true(HEAP_ID_POKETCH_APP));
v4 = Graphics_LoadTilesToBgLayer(NARC_INDEX_GRAPHIC__POKETCH, 86, v3->unk_04, 6, 0, 0, 1, HEAP_ID_POKETCH_APP);
v4 /= 0x20;
Graphics_LoadTilemapToBgLayer(NARC_INDEX_GRAPHIC__POKETCH, 85, v3->unk_04, 6, 0, 0, 1, HEAP_ID_POKETCH_APP);
PoketchGraphics_LoadActivePalette(0, 0);
GF_ASSERT(GF_heap_c_dummy_return_true(HEAP_ID_POKETCH_APP));
ov41_022569BC(v3, v4);
Bg_CopyTilemapBufferToVRAM(v3->unk_04, 7);
v2 = GXS_GetDispCnt();
GXS_SetVisiblePlane(v2.visiblePlane | GX_PLANEMASK_BG2 | GX_PLANEMASK_OBJ);
ov41_022568C8(param1);
GF_ASSERT(GF_heap_c_dummy_return_true(HEAP_ID_POKETCH_APP));
}
static void ov41_022569BC(UnkStruct_ov41_022567B0 *param0, u32 param1)
{
WindowTemplate v0 = {
7, 2, 2, 20, 19, 0, 0
};
param0->unk_58 = param1;
v0.baseTile = param1;
Window_AddFromTemplate(param0->unk_04, &param0->unk_48, &v0);
if (PoketchMemory_ReadFast(param0->unk_00->unk_08, param0->unk_48.pixels, 20 * 19 * 0x20) == FALSE) {
Window_FillTilemap(&param0->unk_48, 0x4);
}
Window_PutToTilemap(&param0->unk_48);
Window_LoadTiles(&param0->unk_48);
}
static void ov41_02256A1C(SysTask *param0, void *param1)
{
UnkStruct_ov41_022567B0 *v0 = PoketchTask_GetTaskData(param1);
switch (PoketchTask_GetState(param1)) {
case 0:
v0->unk_5C = 1;
PoketchTask_IncrementState(param1);
break;
case 1:
PoketchMemory_WriteFast(v0->unk_00->unk_08, v0->unk_48.pixels, 20 * 19 * 0x20);
Window_Remove(&v0->unk_48);
Bg_FreeTilemapBuffer(v0->unk_04, BG_LAYER_SUB_2);
Bg_FreeTilemapBuffer(v0->unk_04, BG_LAYER_SUB_3);
ov41_022568C8(param1);
}
}
static void ov41_02256A74(SysTask *param0, void *param1)
{
UnkStruct_ov41_022567B0 *v0 = PoketchTask_GetTaskData(param1);
Window_LoadTiles(&v0->unk_48);
ov41_022568C8(param1);
}
static void ov41_02256A8C(SysTask *param0, void *param1)
{
s32 v0, v1, v2, v3;
UnkStruct_ov41_022567B0 *v4 = PoketchTask_GetTaskData(param1);
v0 = v4->unk_00->unk_00 * 2;
v1 = v4->unk_00->unk_04 * 2;
v3 = ((v1 >> 3) * 20) + (v0 >> 3);
Window_FillRectWithColor(&v4->unk_48, 0x1, v0, v1, 2, 2);
GXS_LoadBG3Char((u8 *)(v4->unk_48.pixels) + (v3 * 0x20), (v4->unk_58 + v3) * 0x20, 0x20);
ov41_022568C8(param1);
}
static void ov41_02256AE4(SysTask *param0, void *param1)
{
UnkStruct_ov41_022567B0 *v0 = PoketchTask_GetTaskData(param1);
Window_LoadTiles(&v0->unk_48);
ov41_022568C8(param1);
}
static void ov41_02256AFC(SysTask *param0, void *param1)
{
UnkStruct_ov41_022567B0 *v0 = PoketchTask_GetTaskData(param1);
const UnkStruct_ov41_022567B0_1 *v1 = PoketchTask_GetConstTaskData(param1);
PoketchAnimation_UpdateAnimationIdx(v0->unk_24[1], (v1->unk_5B74) ? 2 : 1);
PoketchAnimation_UpdateAnimationIdx(v0->unk_24[2], (v1->unk_5B75) ? 4 : 3);
PoketchAnimation_UpdateAnimationIdx(v0->unk_24[3], (v1->unk_5B76) ? 6 : 5);
ov41_022568C8(param1);
}
static void ov41_02256B60(SysTask *param0, void *param1)
{
UnkStruct_ov41_022567B0 *v0 = PoketchTask_GetTaskData(param1);
const UnkStruct_ov41_022567B0_1 *v1 = PoketchTask_GetConstTaskData(param1);
Window_FillTilemap(&v0->unk_48, 0x4);
Window_LoadTiles(&v0->unk_48);
ov41_022568C8(param1);
}
static void ov41_02256B8C(SysTask *param0, void *param1)
{
UnkStruct_ov41_022567B0 *v0 = PoketchTask_GetTaskData(param1);
const UnkStruct_ov41_022567B0_1 *v1 = PoketchTask_GetConstTaskData(param1);
u32 v2 = PoketchTask_GetState(param1);
if ((v2 != 0) && v0->unk_5C) {
ov41_022568C8(param1);
return;
}
switch (v2) {
case 0:
v0->unk_68 += 336;
v0->unk_6A = 336;
PoketchAnimation_SetSpriteRotation(v0->unk_24[0], v0->unk_68);
v0->unk_64 = 0;
v0->unk_60 = 0;
v0->unk_5C = 0;
PoketchTask_IncrementState(param1);
break;
case 1:
v0->unk_68 += v0->unk_6A;
PoketchAnimation_SetSpriteRotation(v0->unk_24[0], v0->unk_68);
v0->unk_6A += 336;
if (v0->unk_6A >= 12288) {
v0->unk_6A = 12288;
v0->unk_64 = 1;
PoketchTask_IncrementState(param1);
}
break;
case 2:
v0->unk_68 += v0->unk_6A;
PoketchAnimation_SetSpriteRotation(v0->unk_24[0], v0->unk_68);
if (v0->unk_60) {
v0->unk_6C = MTRNG_Next() & 7;
if (v0->unk_6A > 6656) {
v0->unk_6A = 6656;
}
PoketchTask_IncrementState(param1);
}
break;
case 3:
v0->unk_68 += v0->unk_6A;
PoketchAnimation_SetSpriteRotation(v0->unk_24[0], v0->unk_68);
if (v0->unk_6C == 0) {
v0->unk_6C--;
} else {
PoketchTask_IncrementState(param1);
}
break;
case 4:
if (v0->unk_6A > 80) {
v0->unk_6A -= 80;
v0->unk_68 += v0->unk_6A;
PoketchAnimation_SetSpriteRotation(v0->unk_24[0], v0->unk_68);
} else {
v0->unk_6A = 0;
ov41_022568C8(param1);
}
break;
}
}
static void ov41_02256D1C(SysTask *param0, void *param1)
{
UnkStruct_ov41_022567B0 *v0 = PoketchTask_GetTaskData(param1);
const UnkStruct_ov41_022567B0_1 *v1 = PoketchTask_GetConstTaskData(param1);
switch (PoketchTask_GetState(param1)) {
case 0:
v0->unk_60 = 1;
PoketchTask_IncrementState(param1);
break;
case 1:
if (ov41_022568B0(v0, 7)) {
PoketchSystem_PlaySoundEffect(1642);
ov41_022568C8(param1);
}
break;
}
}