From ca7a4e09d6554de1b397212e66c5d7a457336fbb Mon Sep 17 00:00:00 2001 From: VicSevenT Date: Wed, 8 Oct 2025 11:09:14 -0500 Subject: [PATCH] Document Poketch Roulette (Overlay 41) (#794) --- .../applications/poketch/roulette/graphics.h | 61 +++ include/overlay041/ov41_022567B0.h | 15 - include/overlay041/struct_ov41_022567B0_1.h | 14 - .../overlay041/struct_ov41_022567B0_decl.h | 6 - platinum.us/main.lsf | 6 +- platinum.us/sbins_shared.sha1 | 2 +- src/applications/poketch/analog_watch/main.c | 4 +- src/applications/poketch/calculator/main.c | 4 +- src/applications/poketch/counter/main.c | 4 +- .../poketch/daycare_checker/main.c | 4 +- src/applications/poketch/digital_watch/main.c | 4 +- src/applications/poketch/dot_artist/main.c | 4 +- .../poketch/dowsing_machine/main.c | 4 +- .../poketch/friendship_checker/main.c | 4 +- src/applications/poketch/memo_pad/main.c | 4 +- src/applications/poketch/move_tester/main.c | 4 +- src/applications/poketch/party_status/main.c | 4 +- src/applications/poketch/pedometer/main.c | 4 +- src/applications/poketch/poketch_system.c | 4 +- src/applications/poketch/roulette/graphics.c | 391 ++++++++++++++++ src/applications/poketch/roulette/main.c | 427 ++++++++++++++++++ src/applications/poketch/stopwatch/main.c | 4 +- src/meson.build | 4 +- src/overlay041/ov41_022561C0.c | 424 ----------------- src/overlay041/ov41_022567B0.c | 406 ----------------- 25 files changed, 926 insertions(+), 886 deletions(-) create mode 100644 include/applications/poketch/roulette/graphics.h delete mode 100644 include/overlay041/ov41_022567B0.h delete mode 100644 include/overlay041/struct_ov41_022567B0_1.h delete mode 100644 include/overlay041/struct_ov41_022567B0_decl.h create mode 100644 src/applications/poketch/roulette/graphics.c create mode 100644 src/applications/poketch/roulette/main.c delete mode 100644 src/overlay041/ov41_022561C0.c delete mode 100644 src/overlay041/ov41_022567B0.c diff --git a/include/applications/poketch/roulette/graphics.h b/include/applications/poketch/roulette/graphics.h new file mode 100644 index 0000000000..01946e7cd8 --- /dev/null +++ b/include/applications/poketch/roulette/graphics.h @@ -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 diff --git a/include/overlay041/ov41_022567B0.h b/include/overlay041/ov41_022567B0.h deleted file mode 100644 index b370b6f9f1..0000000000 --- a/include/overlay041/ov41_022567B0.h +++ /dev/null @@ -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 diff --git a/include/overlay041/struct_ov41_022567B0_1.h b/include/overlay041/struct_ov41_022567B0_1.h deleted file mode 100644 index 583d920737..0000000000 --- a/include/overlay041/struct_ov41_022567B0_1.h +++ /dev/null @@ -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 diff --git a/include/overlay041/struct_ov41_022567B0_decl.h b/include/overlay041/struct_ov41_022567B0_decl.h deleted file mode 100644 index 203d9762e5..0000000000 --- a/include/overlay041/struct_ov41_022567B0_decl.h +++ /dev/null @@ -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 diff --git a/platinum.us/main.lsf b/platinum.us/main.lsf index 51d13a8668..527aa7b37d 100644 --- a/platinum.us/main.lsf +++ b/platinum.us/main.lsf @@ -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 diff --git a/platinum.us/sbins_shared.sha1 b/platinum.us/sbins_shared.sha1 index 55b227434f..08d3cf7a69 100644 --- a/platinum.us/sbins_shared.sha1 +++ b/platinum.us/sbins_shared.sha1 @@ -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 diff --git a/src/applications/poketch/analog_watch/main.c b/src/applications/poketch/analog_watch/main.c index 7345def698..a373815bfa 100644 --- a/src/applications/poketch/analog_watch/main.c +++ b/src/applications/poketch/analog_watch/main.c @@ -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 diff --git a/src/applications/poketch/calculator/main.c b/src/applications/poketch/calculator/main.c index 153d7eac2e..196f1b5dd6 100644 --- a/src/applications/poketch/calculator/main.c +++ b/src/applications/poketch/calculator/main.c @@ -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, diff --git a/src/applications/poketch/counter/main.c b/src/applications/poketch/counter/main.c index 38b7d86cfb..529d66d186 100644 --- a/src/applications/poketch/counter/main.c +++ b/src/applications/poketch/counter/main.c @@ -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 diff --git a/src/applications/poketch/daycare_checker/main.c b/src/applications/poketch/daycare_checker/main.c index 5e6b097ebf..f360c3fc0a 100644 --- a/src/applications/poketch/daycare_checker/main.c +++ b/src/applications/poketch/daycare_checker/main.c @@ -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 diff --git a/src/applications/poketch/digital_watch/main.c b/src/applications/poketch/digital_watch/main.c index c8dd79fe77..1577aa76fd 100644 --- a/src/applications/poketch/digital_watch/main.c +++ b/src/applications/poketch/digital_watch/main.c @@ -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, diff --git a/src/applications/poketch/dot_artist/main.c b/src/applications/poketch/dot_artist/main.c index a236ae856f..03edda3dc7 100644 --- a/src/applications/poketch/dot_artist/main.c +++ b/src/applications/poketch/dot_artist/main.c @@ -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 diff --git a/src/applications/poketch/dowsing_machine/main.c b/src/applications/poketch/dowsing_machine/main.c index 76936a60f3..dee48b6bf6 100644 --- a/src/applications/poketch/dowsing_machine/main.c +++ b/src/applications/poketch/dowsing_machine/main.c @@ -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 diff --git a/src/applications/poketch/friendship_checker/main.c b/src/applications/poketch/friendship_checker/main.c index 1e713914c0..1ddd827ab1 100644 --- a/src/applications/poketch/friendship_checker/main.c +++ b/src/applications/poketch/friendship_checker/main.c @@ -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, diff --git a/src/applications/poketch/memo_pad/main.c b/src/applications/poketch/memo_pad/main.c index 9444a17669..bae598406b 100644 --- a/src/applications/poketch/memo_pad/main.c +++ b/src/applications/poketch/memo_pad/main.c @@ -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 diff --git a/src/applications/poketch/move_tester/main.c b/src/applications/poketch/move_tester/main.c index e84f0f00e9..27832c865d 100644 --- a/src/applications/poketch/move_tester/main.c +++ b/src/applications/poketch/move_tester/main.c @@ -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 diff --git a/src/applications/poketch/party_status/main.c b/src/applications/poketch/party_status/main.c index 1edd578dd9..827f45b1f4 100644 --- a/src/applications/poketch/party_status/main.c +++ b/src/applications/poketch/party_status/main.c @@ -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 diff --git a/src/applications/poketch/pedometer/main.c b/src/applications/poketch/pedometer/main.c index afc56d3acb..a9b40297a3 100644 --- a/src/applications/poketch/pedometer/main.c +++ b/src/applications/poketch/pedometer/main.c @@ -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 diff --git a/src/applications/poketch/poketch_system.c b/src/applications/poketch/poketch_system.c index 2c35b04bd9..2c1d065339 100644 --- a/src/applications/poketch/poketch_system.c +++ b/src/applications/poketch/poketch_system.c @@ -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) }, diff --git a/src/applications/poketch/roulette/graphics.c b/src/applications/poketch/roulette/graphics.c new file mode 100644 index 0000000000..00732b4b0c --- /dev/null +++ b/src/applications/poketch/roulette/graphics.c @@ -0,0 +1,391 @@ +#include "applications/poketch/roulette/graphics.h" + +#include + +#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; + } +} diff --git a/src/applications/poketch/roulette/main.c b/src/applications/poketch/roulette/main.c new file mode 100644 index 0000000000..57fe179d13 --- /dev/null +++ b/src/applications/poketch/roulette/main.c @@ -0,0 +1,427 @@ +#include +#include + +#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; + } + } +} diff --git a/src/applications/poketch/stopwatch/main.c b/src/applications/poketch/stopwatch/main.c index f1fccb44a7..d3a93d4f7a 100644 --- a/src/applications/poketch/stopwatch/main.c +++ b/src/applications/poketch/stopwatch/main.c @@ -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, diff --git a/src/meson.build b/src/meson.build index 385494abf4..6cc2cf7783 100644 --- a/src/meson.build +++ b/src/meson.build @@ -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', diff --git a/src/overlay041/ov41_022561C0.c b/src/overlay041/ov41_022561C0.c deleted file mode 100644 index da82669995..0000000000 --- a/src/overlay041/ov41_022561C0.c +++ /dev/null @@ -1,424 +0,0 @@ -#include -#include -#include - -#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(¶m0->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(¶m0->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; - } - } -} diff --git a/src/overlay041/ov41_022567B0.c b/src/overlay041/ov41_022567B0.c deleted file mode 100644 index 8d7cbf8386..0000000000 --- a/src/overlay041/ov41_022567B0.c +++ /dev/null @@ -1,406 +0,0 @@ -#include "overlay041/ov41_022567B0.h" - -#include -#include - -#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(¶m0->unk_34, 12, 87, 88, 8); - - for (v1 = 0; v1 < 4; v1++) { - param0->unk_24[v1] = PoketchAnimation_SetupNewAnimatedSprite(param0->unk_20, &v0[v1], ¶m0->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(¶m0->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, ¶m0->unk_48, &v0); - - if (PoketchMemory_ReadFast(param0->unk_00->unk_08, param0->unk_48.pixels, 20 * 19 * 0x20) == FALSE) { - Window_FillTilemap(¶m0->unk_48, 0x4); - } - - Window_PutToTilemap(¶m0->unk_48); - Window_LoadTiles(¶m0->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; - } -}