From 22b5b6b0741a5e0831cc78ffaef7c1f6407044f0 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Wed, 29 Jul 2020 04:46:58 -0400 Subject: [PATCH 1/6] Start documenting roulette --- data/event_scripts.s | 1 + data/scripts/roulette.inc | 4 +- .../{poke_icons.png => grid_icons.png} | Bin .../roulette/{85B65D0.pal => unused_1.pal} | 0 .../roulette/{85B65F0.pal => unused_2.pal} | 0 .../roulette/{85B6610.pal => unused_3.pal} | 0 .../roulette/{85B6630.pal => unused_4.pal} | 0 graphics_file_rules.mk | 2 +- include/constants/coins.h | 1 + include/constants/roulette.h | 7 + include/graphics.h | 12 +- include/roulette_util.h | 4 +- src/coins.c | 2 +- src/graphics.c | 13 +- src/roulette.c | 3265 +++++++++-------- src/roulette_util.c | 4 +- 16 files changed, 1764 insertions(+), 1551 deletions(-) rename graphics/roulette/{poke_icons.png => grid_icons.png} (100%) rename graphics/roulette/{85B65D0.pal => unused_1.pal} (100%) rename graphics/roulette/{85B65F0.pal => unused_2.pal} (100%) rename graphics/roulette/{85B6610.pal => unused_3.pal} (100%) rename graphics/roulette/{85B6630.pal => unused_4.pal} (100%) create mode 100644 include/constants/roulette.h diff --git a/data/event_scripts.s b/data/event_scripts.s index 7cc5960d4..058de953b 100644 --- a/data/event_scripts.s +++ b/data/event_scripts.s @@ -40,6 +40,7 @@ #include "constants/moves.h" #include "constants/party_menu.h" #include "constants/pokemon.h" +#include "constants/roulette.h" #include "constants/script_menu.h" #include "constants/secret_bases.h" #include "constants/songs.h" diff --git a/data/scripts/roulette.inc b/data/scripts/roulette.inc index 9aea65054..f590ca358 100644 --- a/data/scripts/roulette.inc +++ b/data/scripts/roulette.inc @@ -6,7 +6,7 @@ Roulette_EventScript_Table1:: @ 82A5AB1 getpricereduction POKENEWS_GAME_CORNER compare VAR_RESULT, FALSE goto_if_eq Roulette_EventScript_Play - addvar VAR_0x8004, 128 + addvar VAR_0x8004, ROULETTE_SPECIAL_RATE goto Roulette_EventScript_Play end @@ -18,7 +18,7 @@ Roulette_EventScript_Table2:: @ 82A5ADF getpricereduction POKENEWS_GAME_CORNER compare VAR_RESULT, FALSE goto_if_eq Roulette_EventScript_Play - addvar VAR_0x8004, 128 + addvar VAR_0x8004, ROULETTE_SPECIAL_RATE goto Roulette_EventScript_Play end diff --git a/graphics/roulette/poke_icons.png b/graphics/roulette/grid_icons.png similarity index 100% rename from graphics/roulette/poke_icons.png rename to graphics/roulette/grid_icons.png diff --git a/graphics/roulette/85B65D0.pal b/graphics/roulette/unused_1.pal similarity index 100% rename from graphics/roulette/85B65D0.pal rename to graphics/roulette/unused_1.pal diff --git a/graphics/roulette/85B65F0.pal b/graphics/roulette/unused_2.pal similarity index 100% rename from graphics/roulette/85B65F0.pal rename to graphics/roulette/unused_2.pal diff --git a/graphics/roulette/85B6610.pal b/graphics/roulette/unused_3.pal similarity index 100% rename from graphics/roulette/85B6610.pal rename to graphics/roulette/unused_3.pal diff --git a/graphics/roulette/85B6630.pal b/graphics/roulette/unused_4.pal similarity index 100% rename from graphics/roulette/85B6630.pal rename to graphics/roulette/unused_4.pal diff --git a/graphics_file_rules.mk b/graphics_file_rules.mk index 42fe82155..f2d14ef3c 100644 --- a/graphics_file_rules.mk +++ b/graphics_file_rules.mk @@ -483,7 +483,7 @@ $(ROULETTEGFXDIR)/roulette_tilt.4bpp: $(ROULETTEGFXDIR)/shroomish.4bpp \ $(ROULETTEGFXDIR)/tailow.4bpp @cat $^ >$@ -$(ROULETTEGFXDIR)/poke_icons2.4bpp: $(ROULETTEGFXDIR)/wynaut.4bpp \ +$(ROULETTEGFXDIR)/board_icons.4bpp: $(ROULETTEGFXDIR)/wynaut.4bpp \ $(ROULETTEGFXDIR)/azurill.4bpp \ $(ROULETTEGFXDIR)/skitty.4bpp \ $(ROULETTEGFXDIR)/makuhita.4bpp diff --git a/include/constants/coins.h b/include/constants/coins.h index 3ae3bb23f..e65e981d6 100644 --- a/include/constants/coins.h +++ b/include/constants/coins.h @@ -2,5 +2,6 @@ #define GUARD_CONSTANTS_COINS_H #define MAX_COINS 9999 +#define MAX_COIN_DIGITS 4 #endif // GUARD_CONSTANTS_COINS_H diff --git a/include/constants/roulette.h b/include/constants/roulette.h new file mode 100644 index 000000000..2ab17e476 --- /dev/null +++ b/include/constants/roulette.h @@ -0,0 +1,7 @@ +#ifndef GUARD_CONSTANTS_ROULETTE_H +#define GUARD_CONSTANTS_ROULETTE_H + +// Flag set in gSpecialVar_0x8004 when playing Roulette on a Game Corner service day +#define ROULETTE_SPECIAL_RATE (1 << 7) + +#endif // GUARD_CONSTANTS_ROULETTE_H diff --git a/include/graphics.h b/include/graphics.h index 8514d49bd..cf2abb825 100644 --- a/include/graphics.h +++ b/include/graphics.h @@ -4919,13 +4919,13 @@ extern const u32 gPartyMenuPokeball_Pal[]; extern const u32 gStatusPal_Icons[]; // Roulette -extern const u32 gRouletteMenuTiles[]; -extern const u32 gRouletteWheelTiles[]; +extern const u32 gRouletteMenu_Gfx[]; +extern const u32 gRouletteWheel_Gfx[]; extern const u32 gRouletteCenter_Gfx[]; -extern const u32 gRouletteHeadersTiles[]; -extern const u32 gRouletteCreditTiles[]; -extern const u32 gRouletteNumbersTiles[]; -extern const u32 gRouletteMultiplierTiles[]; +extern const u32 gRouletteHeaders_Gfx[]; +extern const u32 gRouletteCredit_Gfx[]; +extern const u32 gRouletteNumbers_Gfx[]; +extern const u32 gRouletteMultiplier_Gfx[]; // Contest util extern const u32 gContestResults_Gfx[]; diff --git a/include/roulette_util.h b/include/roulette_util.h index 76752fe74..85b8de1f3 100644 --- a/include/roulette_util.h +++ b/include/roulette_util.h @@ -41,8 +41,8 @@ void MarkUsedPulseBlendPalettes(struct PulseBlend *, u16, u8); void UnloadUsedPulseBlendPalettes(struct PulseBlend *, u16, u8); void UnmarkUsedPulseBlendPalettes(struct PulseBlend *, u16, u8); void UpdatePulseBlend(struct PulseBlend *); -void sub_8152008(u16 *dest, u16 src, u8 left, u8 top, u8 width, u8 height); -void sub_8152058(u16 *dest, u16 *src, u8 left, u8 top, u8 width, u8 height); +void ClearGridSelectionRect(u16 *dest, u16 src, u8 left, u8 top, u8 width, u8 height); +void SetGridSelectionRect(u16 *dest, u16 *src, u8 left, u8 top, u8 width, u8 height); void task_tutorial_controls_fadein(struct UnkStruct0 *r0); void sub_8151678(struct UnkStruct0 *r0); u8 sub_815168C(struct UnkStruct0 *r0, u8 r1, const struct UnkStruct1 *r2); diff --git a/src/coins.c b/src/coins.c index 302817f8d..52c7dd3ec 100644 --- a/src/coins.c +++ b/src/coins.c @@ -14,7 +14,7 @@ void PrintCoinsString(u32 coinAmount) { u32 xAlign; - ConvertIntToDecimalStringN(gStringVar1, coinAmount, STR_CONV_MODE_RIGHT_ALIGN, 4); + ConvertIntToDecimalStringN(gStringVar1, coinAmount, STR_CONV_MODE_RIGHT_ALIGN, MAX_COIN_DIGITS); StringExpandPlaceholders(gStringVar4, gText_Coins); xAlign = GetStringRightAlignXOffset(1, gStringVar4, 0x40); diff --git a/src/graphics.c b/src/graphics.c index b774c5ad2..48323467d 100644 --- a/src/graphics.c +++ b/src/graphics.c @@ -1227,13 +1227,14 @@ const u32 gCableCar_Gfx[] = INCBIN_U32("graphics/misc/cable_car.4bpp.lz"); const u32 gCableCarDoor_Gfx[] = INCBIN_U32("graphics/misc/cable_car_door.4bpp.lz"); const u32 gCableCarCord_Gfx[] = INCBIN_U32("graphics/misc/cable_car_cord.4bpp.lz"); -const u32 gRouletteMenuTiles[] = INCBIN_U32("graphics/roulette/window.4bpp.lz"); -const u32 gRouletteWheelTiles[] = INCBIN_U32("graphics/roulette/wheel.8bpp.lz"); +// Roulette +const u32 gRouletteMenu_Gfx[] = INCBIN_U32("graphics/roulette/window.4bpp.lz"); +const u32 gRouletteWheel_Gfx[] = INCBIN_U32("graphics/roulette/wheel.8bpp.lz"); const u32 gRouletteCenter_Gfx[] = INCBIN_U32("graphics/roulette/center.4bpp.lz"); -const u32 gRouletteHeadersTiles[] = INCBIN_U32("graphics/roulette/headers.4bpp.lz"); -const u32 gRouletteCreditTiles[] = INCBIN_U32("graphics/roulette/credit.4bpp.lz"); -const u32 gRouletteNumbersTiles[] = INCBIN_U32("graphics/roulette/numbers.4bpp.lz"); -const u32 gRouletteMultiplierTiles[] = INCBIN_U32("graphics/roulette/multiplier.4bpp.lz"); +const u32 gRouletteHeaders_Gfx[] = INCBIN_U32("graphics/roulette/headers.4bpp.lz"); +const u32 gRouletteCredit_Gfx[] = INCBIN_U32("graphics/roulette/credit.4bpp.lz"); +const u32 gRouletteNumbers_Gfx[] = INCBIN_U32("graphics/roulette/numbers.4bpp.lz"); +const u32 gRouletteMultiplier_Gfx[] = INCBIN_U32("graphics/roulette/multiplier.4bpp.lz"); #include "data/graphics/mail.h" diff --git a/src/roulette.c b/src/roulette.c index 1015687af..983a96e3f 100644 --- a/src/roulette.c +++ b/src/roulette.c @@ -26,10 +26,170 @@ #include "trig.h" #include "tv.h" #include "window.h" +#include "constants/coins.h" #include "constants/rgb.h" +#include "constants/roulette.h" #include "constants/species.h" #include "constants/songs.h" +#define BALLS_PER_ROUND 6 + +#define NUM_BOARD_COLORS 3 // Grid rows +#define NUM_BOARD_POKES 4 // Grid columns +#define NUM_ROULETTE_SLOTS (NUM_BOARD_COLORS * NUM_BOARD_POKES) + +// IDs for grid selections when betting +#define SELECTION_NONE 0 +#define COL_WYNAUT 1 +#define COL_AZURILL 2 +#define COL_SKITTY 3 +#define COL_MAKUHITA 4 +#define ROW_ORANGE (COL_MAKUHITA + 1) +#define SQU_ORANGE_WYNAUT (ROW_ORANGE + COL_WYNAUT) +#define SQU_ORANGE_AZURILL (ROW_ORANGE + COL_AZURILL) +#define SQU_ORANGE_SKITTY (ROW_ORANGE + COL_SKITTY) +#define SQU_ORANGE_MAKUHITA (ROW_ORANGE + COL_MAKUHITA) +#define ROW_GREEN (SQU_ORANGE_MAKUHITA + 1) +#define SQU_GREEN_WYNAUT (ROW_GREEN + COL_WYNAUT) +#define SQU_GREEN_AZURILL (ROW_GREEN + COL_AZURILL) +#define SQU_GREEN_SKITTY (ROW_GREEN + COL_SKITTY) +#define SQU_GREEN_MAKUHITA (ROW_GREEN + COL_MAKUHITA) +#define ROW_PURPLE (SQU_GREEN_MAKUHITA + 1) +#define SQU_PURPLE_WYNAUT (ROW_PURPLE + COL_WYNAUT) +#define SQU_PURPLE_AZURILL (ROW_PURPLE + COL_AZURILL) +#define SQU_PURPLE_SKITTY (ROW_PURPLE + COL_SKITTY) +#define SQU_PURPLE_MAKUHITA (ROW_PURPLE + COL_MAKUHITA) +#define NUM_GRID_SELECTIONS SQU_PURPLE_MAKUHITA + +#define GET_COL(selectionId)((selectionId) % (NUM_BOARD_POKES + 1)) +#define GET_ROW(selectionId)((selectionId) / (NUM_BOARD_POKES + 1) * (NUM_BOARD_POKES + 1)) + +// Flags for the above selections, used to set which spaces have been hit or bet on +#define F_WYNAUT_COL (1 << COL_WYNAUT) +#define F_AZURILL_COL (1 << COL_AZURILL) +#define F_SKITTY_COL (1 << COL_SKITTY) +#define F_MAKUHITA_COL (1 << COL_MAKUHITA) +#define F_ORANGE_ROW (1 << ROW_ORANGE) +#define F_ORANGE_WYNAUT (1 << SQU_ORANGE_WYNAUT) +#define F_ORANGE_AZURILL (1 << SQU_ORANGE_AZURILL) +#define F_ORANGE_SKITTY (1 << SQU_ORANGE_SKITTY) +#define F_ORANGE_MAKUHITA (1 << SQU_ORANGE_MAKUHITA) +#define F_GREEN_ROW (1 << ROW_GREEN) +#define F_GREEN_WYNAUT (1 << SQU_GREEN_WYNAUT) +#define F_GREEN_AZURILL (1 << SQU_GREEN_AZURILL) +#define F_GREEN_SKITTY (1 << SQU_GREEN_SKITTY) +#define F_GREEN_MAKUHITA (1 << SQU_GREEN_MAKUHITA) +#define F_PURPLE_ROW (1 << ROW_PURPLE) +#define F_PURPLE_WYNAUT (1 << SQU_PURPLE_WYNAUT) +#define F_PURPLE_AZURILL (1 << SQU_PURPLE_AZURILL) +#define F_PURPLE_SKITTY (1 << SQU_PURPLE_SKITTY) +#define F_PURPLE_MAKUHITA (1 << SQU_PURPLE_MAKUHITA) + +#define MAX_MULTIPLIER 12 + +#define PALTAG_SHADOW 1 +#define PALTAG_BALL 2 +#define PALTAG_BALL_COUNTER 3 +#define PALTAG_INTERFACE 5 +#define PALTAG_SHROOMISH 6 +#define PALTAG_TAILLOW 7 +#define PALTAG_GRID_ICONS 8 +#define PALTAG_WYNAUT 9 +#define PALTAG_AZURILL 10 +#define PALTAG_SKITTY 11 +#define PALTAG_MAKUHITA 12 + +#define GFXTAG_BOARD_ICONS 0 +#define GFXTAG_HEADERS 4 +#define GFXTAG_GRID_ICONS 5 +#define GFXTAG_BOARD_CENTER 6 +#define GFXTAG_CREDIT 7 +#define GFXTAG_CREDIT_DIGIT 8 +#define GFXTAG_MULTIPLIER 9 +#define GFXTAG_BALL_COUNTER 10 +#define GFXTAG_CURSOR 11 +#define GFXTAG_BALL 12 +#define GFXTAG_SHROOMISH_TAILLOW 13 +#define GFXTAG_SHADOW 14 + +// 2 different Roulette tables with 2 different rates (normal vs service day special) +// & 1 gets which table, >> 7 gets if ROULETTE_SPECIAL_RATE is set +#define GET_TABLE_ID(var)(((var) & 1) + (((var) >> 7) * 2)) + +#define HAS_SHROOMISH (1 << 0) +#define HAS_TAILLOW (1 << 1) + +enum { + SPR_BALL_1, + SPR_BALL_2, + SPR_BALL_3, + SPR_BALL_4, + SPR_BALL_5, + SPR_BALL_6, + SPR_6, + SPR_BOARD_ICON_ORANGE_WYNAUT, + SPR_BOARD_ICON_GREEN_AZURILL, + SPR_BOARD_ICON_PURPLE_SKITTY, + SPR_BOARD_ICON_ORANGE_MAKUHITA, + SPR_BOARD_ICON_GREEN_WYNAUT, + SPR_BOARD_ICON_PURPLE_AZURILL, + SPR_BOARD_ICON_ORANGE_SKITTY, + SPR_BOARD_ICON_GREEN_MAKUHITA, + SPR_BOARD_ICON_PURPLE_WYNAUT, + SPR_BOARD_ICON_ORANGE_AZURILL, + SPR_BOARD_ICON_GREEN_SKITTY, + SPR_BOARD_ICON_PURPLE_MAKUHITA, + SPR_19, + SPR_CREDIT, + SPR_CREDIT_DIG_1, + SPR_CREDIT_DIG_10, + SPR_CREDIT_DIG_100, + SPR_CREDIT_DIG_1000, + SPR_MULTIPLIER, + SPR_BALL_COUNTER_1, + SPR_BALL_COUNTER_2, + SPR_BALL_COUNTER_3, + SPR_GRID_ICON_ORANGE_WYNAUT, + SPR_GRID_ICON_2, + SPR_GRID_ICON_3, + SPR_GRID_ICON_4, + SPR_GRID_ICON_5, + SPR_GRID_ICON_6, + SPR_GRID_ICON_7, + SPR_GRID_ICON_8, + SPR_GRID_ICON_9, + SPR_GRID_ICON_10, + SPR_GRID_ICON_11, + SPR_GRID_ICON_12, + SPR_POKE_HEADER_1, + SPR_POKE_HEADER_2, + SPR_POKE_HEADER_3, + SPR_POKE_HEADER_4, + SPR_COLOR_HEADER_1, + SPR_COLOR_HEADER_2, + SPR_COLOR_HEADER_3, + SPR_WIN_SLOT_CURSOR, + SPR_GRID_BALL_1, + SPR_GRID_BALL_2, + SPR_GRID_BALL_3, + SPR_GRID_BALL_4, + SPR_GRID_BALL_5, + SPR_GRID_BALL_6, + SPR_CLEAR_MON, // Shroomish/Taillow + SPR_CLEAR_MON_SHADOW_1, + SPR_CLEAR_MON_SHADOW_2, + SPR_58, + SPR_59, + SPR_60, + SPR_61, + SPR_62, + SPR_63, +}; + +// Start points for sprite IDs that are looped over +#define SPR_BOARD_ICONS SPR_BOARD_ICON_ORANGE_WYNAUT +#define SPR_GRID_ICONS SPR_GRID_ICON_ORANGE_WYNAUT + struct StructgUnknown_083F8DF4 { u8 var00; @@ -51,49 +211,49 @@ struct StructgUnknown_083F8DF4 float var1C; }; -struct StructgUnknown_085B6154 +struct GridSelection { u8 var00; - u8 var01_0:4; - u8 var01_4:4; - u8 var02; - u8 var03; - u8 var04; - u8 var05; + u8 baseMultiplier:4; + u8 column:4; // Never read + u8 row; // Never read + u8 x; + u8 y; + u8 var05; // Never read u8 var06; - u32 var08; - u32 var0C; + u32 flag; + u32 inSelectionFlags; u16 var10; }; -struct StructgUnknown_083F8D90 +struct RouletteSlot { - u8 var00; - u8 var01; - u8 var02; - u32 var04; + u8 id1; // Never read + u8 id2; // Never read + u8 gridSquare; + u32 flag; }; -EWRAM_DATA struct Roulette +static EWRAM_DATA struct Roulette { u8 var00; u8 var01; - u8 var02; - u8 var03_0:5; - u8 var03_5:1; - u8 var03_6:1; - u8 var03_7:1; - u8 var04_0:2; + u8 partySpeciesFlags; + bool8 useTaillow:5; + bool8 var03_5:1; + bool8 var03_6:1; + bool8 var03_7:1; + u8 tableId:2; u8 var04_2:5; - u8 var04_7:1; - u32 var08; - u8 var0C[6]; - u8 var12[4]; - u8 var16[3]; - u8 var19; - u8 var1A_0:4; - u8 var1A_4:4; - u8 var1B[6]; + bool8 isSpecialRate:1; + u32 hitFlags; + u8 hitSquares[BALLS_PER_ROUND]; + u8 pokeHits[NUM_BOARD_POKES]; + u8 colorHits[NUM_BOARD_COLORS]; + u8 minBet; + u8 curBallNum:4; // Never actually gets incremented + u8 unk:4; // Never read + u8 betSelection[BALLS_PER_ROUND]; // Because curBallNum is used as the only index, only the first element is ever used (prev bet selections are never needed) u8 var21; u8 var22; u8 var23; @@ -104,7 +264,7 @@ EWRAM_DATA struct Roulette struct OamMatrix var2C; u16 var34; struct Sprite *var38; - u8 var3C[MAX_SPRITES]; // Sprite IDs + u8 spriteIds[MAX_SPRITES]; // Sprite IDs u8 var7C; u8 var7D; u8 var7E; @@ -123,70 +283,71 @@ EWRAM_DATA struct Roulette u8 varA4; u8 varA5; u8 v51[2]; - u16 varA8; - u16 varAA; - TaskFunc varAC; + u16 taskWaitDelay; + u16 taskWaitKey; + TaskFunc nextTask; u8 v46[4]; TaskFunc varB4; struct UnkStruct0 varB8; u16 tilemapBuffers[7][0x400]; u16 *unk_397C; -} *gUnknown_0203AB88 = NULL; -EWRAM_DATA u8 gUnknown_0203AB8C = 0; +} *sRoulette = NULL; -static void sub_8140814(u8); -static void sub_81408A8(u8); -static void sub_8140968(u8); -static void sub_8140994(u8); -static void sub_8140BD0(u8); -static void sub_8141040(u8); -static void sub_81410FC(u8); -static void sub_8141344(u8); -static void sub_814155C(u8); -static void sub_81415D4(u8); -static void sub_81416D4(u8); +static EWRAM_DATA u8 sTextWindowId = 0; + +static void Task_SpinBoard(u8); +static void Task_StartPlaying(u8); +static void Task_ContinuePlaying(u8); +static void Task_StopPlaying(u8); +static void Task_SelectFirstEmptySquare(u8); +static void Task_HandleBetGridInput(u8); +static void Task_SlideGridOffscreen(u8); +static void Task_RollBall(u8); +static void Task_EndBallRoll(u8); +static void Task_RecordBallHit(u8); +static void Task_SlideGridOnscreen(u8); static void sub_8141778(u8); -static void sub_814189C(u8); -static void sub_8141A18(u8); -static void sub_8141AC0(u8); -static void sub_8141B58(u8); -static void dp01t_12_3_battle_menu(u8); -static void sub_8141DE4(u8); -static void sub_8141E7C(u8); -static void sub_8141F7C(u8 taskId, TaskFunc r1, u16 r2, u16 r3); +static void Task_PrintSpinResult(u8); +static void Task_PrintPayout(u8); +static void Task_EndTurn(u8); +static void Task_TryPrintEndTurnMsg(u8); +static void Task_ClearBoard(u8); +static void ExitRoulette(u8); +static void Task_ExitRoulette(u8); +static void StartTaskAfterDelayOrInput(u8, TaskFunc, u16, u16); static void sub_8141FF4(u8); -static void sub_8142070(void); -static void sub_8142918(u8); -static void sub_814297C(u8); -static u8 sub_81420D0(u8, u8); -static bool8 sub_81421E8(u8, u8); -static void sub_8142284(u8); -static void sub_81424FC(u8); -static u8 sub_8142758(u8); +static void ResetHits(void); +static void Task_AcceptMinBet(u8); +static void Task_DeclineMinBet(u8); +static u8 RecordHit(u8, u8); +static bool8 IsHitInBetSelection(u8, u8); +static void FlashSelectionOnWheel(u8); +static void DrawGridBackground(u8); +static u8 GetMultiplier(u8); static void sub_8142814(void); -static void sub_8142C0C(u8); -static void sub_8142CD0(void); -static void sub_8142E70(u8, u8); -static void sub_8142F7C(void); -static void sub_8143038(u8, u8); -static void sub_8143150(u8); -static void sub_81431E4(void); -static void sub_8143280(struct Sprite *); -static void sub_8143314(void); -static void sub_8143514(u16); -static void sub_81436D0(u8); -static void sub_814372C(u8); -static void sub_814390C(struct Sprite *); -static void sub_814391C(void); -static void sub_814399C(struct Sprite *); -static void sub_81439C8(void); -static void sub_8143A40(void); +static void LoadOrFreeMiscSpritePalettesAndSheets(u8); +static void CreateGridSprites(void); +static void ShowHideGridIcons(bool8, u8); +static void CreateGridBallSprites(void); +static void ShowHideGridBalls(bool8, u8); +static void ShowHideWinSlotCursor(u8); +static void CreateBoardIconSprites(void); +static void SpriteCB_BoardIcon(struct Sprite *); +static void CreateInterfaceSprites(void); +static void SetCreditDigits(u16); +static void SetMultiplierSprite(u8); +static void SetBallCounterNumLeft(u8); +static void SpriteCB_GridSquare(struct Sprite *); +static void CreateBoardCenterSprite(void); +static void SpriteCB_BoardCenter(struct Sprite *); +static void CreateBoardBallSprites(void); +static void HideBoardBalls(void); static void sub_81446AC(struct Sprite *); -static void sub_81446DC(struct Sprite *); -static void sub_81448B8(struct Sprite *); +static void CreateShroomishSprite(struct Sprite *); +static void CreateTaillowSprite(struct Sprite *); static void sub_8144A24(struct Sprite *); static void sub_8144E60(struct Sprite *); -static void sub_8145294(struct Sprite *); +static void SpriteCB_Taillow(struct Sprite *); extern const u8 Roulette_Text_ControlsInstruction[]; extern const u8 Roulette_Text_KeepPlaying[]; @@ -203,8 +364,8 @@ extern const u8 Roulette_Text_NotEnoughCoins[]; static const u16 gUnknown_085B5BFC[] = INCBIN_U16("graphics/roulette/85B5BFC.gbapal"); static const u32 gUnknown_085B5DFC[] = INCBIN_U32("graphics/roulette/85B5DFC.bin.lz"); -static const u32 gUnknown_085B5FA0[] = INCBIN_U32("graphics/roulette/wheel_map.bin.lz"); -static const struct BgTemplate gUnknown_085B6140[] = +static const u32 sWheel_Tilemap[] = INCBIN_U32("graphics/roulette/wheel_map.bin.lz"); +static const struct BgTemplate sBgTemplates[] = { { .bg = 0, @@ -234,7 +395,7 @@ static const struct BgTemplate gUnknown_085B6140[] = .baseTile = 0 } }; -static const struct WindowTemplate gUnknown_085B614C[] = +static const struct WindowTemplate sWindowTemplates[] = { { .bg = 0, @@ -248,346 +409,349 @@ static const struct WindowTemplate gUnknown_085B614C[] = // BUG: Array not terminated properly //DUMMY_WIN_TEMPLATE }; -static const struct StructgUnknown_085B6154 gUnknown_085B6154[] = + +// var00, sprite id offset (from 7)? +static const struct GridSelection sGridSelections[NUM_GRID_SELECTIONS + 1] = { - { + [SELECTION_NONE] = { .var00 = 0xFF, - .var01_0 = 0, - .var01_4 = 0, - .var02 = 0, - .var03 = 7, - .var04 = 7, + .baseMultiplier = 0, + .column = 0, + .row = 0, + .x = 7, + .y = 7, .var05 = 0, .var06 = 0, - .var08 = 0x0, - .var0C = 0x0, + .flag = 0, + .inSelectionFlags = 0, .var10 = 0x0, }, - { + [COL_WYNAUT] = { .var00 = 12, - .var01_0 = 4, - .var01_4 = 1, - .var02 = 0, - .var03 = 17, - .var04 = 7, + .baseMultiplier = NUM_BOARD_POKES, + .column = 1, + .row = 0, + .x = 17, + .y = 7, .var05 = 0, .var06 = 0, - .var08 = 0x2, - .var0C = 0x10842, + .flag = F_WYNAUT_COL, + .inSelectionFlags = F_WYNAUT_COL | F_ORANGE_WYNAUT | F_GREEN_WYNAUT | F_PURPLE_WYNAUT, .var10 = 0xE000, }, - { + [COL_AZURILL] = { .var00 = 13, - .var01_0 = 4, - .var01_4 = 2, - .var02 = 0, - .var03 = 20, - .var04 = 7, + .baseMultiplier = NUM_BOARD_POKES, + .column = 2, + .row = 0, + .x = 20, + .y = 7, .var05 = 0, .var06 = 0, - .var08 = 0x4, - .var0C = 0x21084, + .flag = F_AZURILL_COL, + .inSelectionFlags = F_AZURILL_COL | F_ORANGE_AZURILL | F_GREEN_AZURILL | F_PURPLE_AZURILL, .var10 = 0xE000, }, - { + [COL_SKITTY] = { .var00 = 14, - .var01_0 = 4, - .var01_4 = 3, - .var02 = 0, - .var03 = 23, - .var04 = 7, + .baseMultiplier = NUM_BOARD_POKES, + .column = 3, + .row = 0, + .x = 23, + .y = 7, .var05 = 0, .var06 = 0, - .var08 = 0x8, - .var0C = 0x42108, + .flag = F_SKITTY_COL, + .inSelectionFlags = F_SKITTY_COL | F_ORANGE_SKITTY | F_GREEN_SKITTY | F_PURPLE_SKITTY, .var10 = 0xE000, }, - { + [COL_MAKUHITA] = { .var00 = 15, - .var01_0 = 4, - .var01_4 = 4, - .var02 = 0, - .var03 = 26, - .var04 = 7, + .baseMultiplier = NUM_BOARD_POKES, + .column = 4, + .row = 0, + .x = 26, + .y = 7, .var05 = 0, .var06 = 0, - .var08 = 0x10, - .var0C = 0x84210, + .flag = F_MAKUHITA_COL, + .inSelectionFlags = F_MAKUHITA_COL | F_ORANGE_MAKUHITA | F_GREEN_MAKUHITA | F_PURPLE_MAKUHITA, .var10 = 0xE000, }, - { + [ROW_ORANGE] = { .var00 = 16, - .var01_0 = 3, - .var01_4 = 0, - .var02 = 1, - .var03 = 14, - .var04 = 10, + .baseMultiplier = NUM_BOARD_COLORS, + .column = 0, + .row = 1, + .x = 14, + .y = 10, .var05 = 0, .var06 = 12, - .var08 = 0x20, - .var0C = 0x3E0, + .flag = F_ORANGE_ROW, + .inSelectionFlags = F_ORANGE_ROW | F_ORANGE_WYNAUT | F_ORANGE_AZURILL | F_ORANGE_SKITTY | F_ORANGE_MAKUHITA, .var10 = 0x249, }, - { + [SQU_ORANGE_WYNAUT] = { .var00 = 0, - .var01_0 = 12, - .var01_4 = 1, - .var02 = 1, - .var03 = 17, - .var04 = 10, + .baseMultiplier = NUM_ROULETTE_SLOTS, + .column = 1, + .row = 1, + .x = 17, + .y = 10, .var05 = 3, .var06 = 3, - .var08 = 0x40, - .var0C = 0x40, + .flag = F_ORANGE_WYNAUT, + .inSelectionFlags = F_ORANGE_WYNAUT, .var10 = 0x2001, }, - { + [SQU_ORANGE_AZURILL] = { .var00 = 9, - .var01_0 = 12, - .var01_4 = 2, - .var02 = 1, - .var03 = 20, - .var04 = 10, + .baseMultiplier = NUM_ROULETTE_SLOTS, + .column = 2, + .row = 1, + .x = 20, + .y = 10, .var05 = 3, .var06 = 3, - .var08 = 0x80, - .var0C = 0x80, + .flag = F_ORANGE_AZURILL, + .inSelectionFlags = F_ORANGE_AZURILL, .var10 = 0x2200, }, - { + [SQU_ORANGE_SKITTY] = { .var00 = 6, - .var01_0 = 12, - .var01_4 = 3, - .var02 = 1, - .var03 = 23, - .var04 = 10, + .baseMultiplier = NUM_ROULETTE_SLOTS, + .column = 3, + .row = 1, + .x = 23, + .y = 10, .var05 = 3, .var06 = 3, - .var08 = 0x100, - .var0C = 0x100, + .flag = F_ORANGE_SKITTY, + .inSelectionFlags = F_ORANGE_SKITTY, .var10 = 0x2040, }, - { + [SQU_ORANGE_MAKUHITA] = { .var00 = 3, - .var01_0 = 12, - .var01_4 = 4, - .var02 = 1, - .var03 = 26, - .var04 = 10, + .baseMultiplier = NUM_ROULETTE_SLOTS, + .column = 4, + .row = 1, + .x = 26, + .y = 10, .var05 = 3, .var06 = 3, - .var08 = 0x200, - .var0C = 0x200, + .flag = F_ORANGE_MAKUHITA, + .inSelectionFlags = F_ORANGE_MAKUHITA, .var10 = 0x2008, }, - { + [ROW_GREEN] = { .var00 = 17, - .var01_0 = 3, - .var01_4 = 0, - .var02 = 2, - .var03 = 14, - .var04 = 13, + .baseMultiplier = NUM_BOARD_COLORS, + .column = 0, + .row = 2, + .x = 14, + .y = 13, .var05 = 3, .var06 = 15, - .var08 = 0x400, - .var0C = 0x7C00, + .flag = F_GREEN_ROW, + .inSelectionFlags = F_GREEN_ROW | F_GREEN_WYNAUT | F_GREEN_AZURILL | F_GREEN_SKITTY | F_GREEN_MAKUHITA, .var10 = 0x492, }, - { + [SQU_GREEN_WYNAUT] = { .var00 = 4, - .var01_0 = 12, - .var01_4 = 1, - .var02 = 2, - .var03 = 17, - .var04 = 13, + .baseMultiplier = NUM_ROULETTE_SLOTS, + .column = 1, + .row = 2, + .x = 17, + .y = 13, .var05 = 6, .var06 = 6, - .var08 = 0x800, - .var0C = 0x800, + .flag = F_GREEN_WYNAUT, + .inSelectionFlags = F_GREEN_WYNAUT, .var10 = 0x2010, }, - { + [SQU_GREEN_AZURILL] = { .var00 = 1, - .var01_0 = 12, - .var01_4 = 2, - .var02 = 2, - .var03 = 20, - .var04 = 13, + .baseMultiplier = NUM_ROULETTE_SLOTS, + .column = 2, + .row = 2, + .x = 20, + .y = 13, .var05 = 6, .var06 = 6, - .var08 = 0x1000, - .var0C = 0x1000, + .flag = F_GREEN_AZURILL, + .inSelectionFlags = F_GREEN_AZURILL, .var10 = 0x2002, }, - { + [SQU_GREEN_SKITTY] = { .var00 = 10, - .var01_0 = 12, - .var01_4 = 3, - .var02 = 2, - .var03 = 23, - .var04 = 13, + .baseMultiplier = NUM_ROULETTE_SLOTS, + .column = 3, + .row = 2, + .x = 23, + .y = 13, .var05 = 6, .var06 = 6, - .var08 = 0x2000, - .var0C = 0x2000, + .flag = F_GREEN_SKITTY, + .inSelectionFlags = F_GREEN_SKITTY, .var10 = 0x2400, }, - { + [SQU_GREEN_MAKUHITA] = { .var00 = 7, - .var01_0 = 12, - .var01_4 = 4, - .var02 = 2, - .var03 = 26, - .var04 = 13, + .baseMultiplier = NUM_ROULETTE_SLOTS, + .column = 4, + .row = 2, + .x = 26, + .y = 13, .var05 = 6, .var06 = 6, - .var08 = 0x4000, - .var0C = 0x4000, + .flag = F_GREEN_MAKUHITA, + .inSelectionFlags = F_GREEN_MAKUHITA, .var10 = 0x2080, }, - { + [ROW_PURPLE] = { .var00 = 18, - .var01_0 = 3, - .var01_4 = 0, - .var02 = 3, - .var03 = 14, - .var04 = 16, + .baseMultiplier = NUM_BOARD_COLORS, + .column = 0, + .row = 3, + .x = 14, + .y = 16, .var05 = 6, .var06 = 18, - .var08 = 0x8000, - .var0C = 0xF8000, + .flag = F_PURPLE_ROW, + .inSelectionFlags = F_PURPLE_ROW | F_PURPLE_WYNAUT | F_PURPLE_AZURILL | F_PURPLE_SKITTY | F_PURPLE_MAKUHITA, .var10 = 0x924, }, - { + [SQU_PURPLE_WYNAUT] = { .var00 = 8, - .var01_0 = 12, - .var01_4 = 1, - .var02 = 3, - .var03 = 17, - .var04 = 16, + .baseMultiplier = NUM_ROULETTE_SLOTS, + .column = 1, + .row = 3, + .x = 17, + .y = 16, .var05 = 9, .var06 = 9, - .var08 = 0x10000, - .var0C = 0x10000, + .flag = F_PURPLE_WYNAUT, + .inSelectionFlags = F_PURPLE_WYNAUT, .var10 = 0x2100, }, - { + [SQU_PURPLE_AZURILL] = { .var00 = 5, - .var01_0 = 12, - .var01_4 = 2, - .var02 = 3, - .var03 = 20, - .var04 = 16, + .baseMultiplier = NUM_ROULETTE_SLOTS, + .column = 2, + .row = 3, + .x = 20, + .y = 16, .var05 = 9, .var06 = 9, - .var08 = 0x20000, - .var0C = 0x20000, + .flag = F_PURPLE_AZURILL, + .inSelectionFlags = F_PURPLE_AZURILL, .var10 = 0x2020, }, - { + [SQU_PURPLE_SKITTY] = { .var00 = 2, - .var01_0 = 12, - .var01_4 = 3, - .var02 = 3, - .var03 = 23, - .var04 = 16, + .baseMultiplier = NUM_ROULETTE_SLOTS, + .column = 3, + .row = 3, + .x = 23, + .y = 16, .var05 = 9, .var06 = 9, - .var08 = 0x40000, - .var0C = 0x40000, + .flag = F_PURPLE_SKITTY, + .inSelectionFlags = F_PURPLE_SKITTY, .var10 = 0x2004, }, - { + [SQU_PURPLE_MAKUHITA] = { .var00 = 11, - .var01_0 = 12, - .var01_4 = 4, - .var02 = 3, - .var03 = 26, - .var04 = 16, + .baseMultiplier = NUM_ROULETTE_SLOTS, + .column = 4, + .row = 3, + .x = 26, + .y = 16, .var05 = 9, .var06 = 9, - .var08 = 0x80000, - .var0C = 0x80000, + .flag = F_PURPLE_MAKUHITA, + .inSelectionFlags = F_PURPLE_MAKUHITA, .var10 = 0x2800, }, }; -static const struct StructgUnknown_083F8D90 gUnknown_085B62E4[] = +static const struct RouletteSlot sRouletteSlots[] = { { - .var00 = 0, - .var01 = 1, - .var02 = 6, - .var04 = 0x40, + .id1 = 0, + .id2 = 1, + .gridSquare = SQU_ORANGE_WYNAUT, + .flag = F_ORANGE_WYNAUT, }, { - .var00 = 1, - .var01 = 3, - .var02 = 12, - .var04 = 0x1000, + .id1 = 1, + .id2 = 3, + .gridSquare = SQU_GREEN_AZURILL, + .flag = F_GREEN_AZURILL, }, { - .var00 = 2, - .var01 = 5, - .var02 = 18, - .var04 = 0x40000, + .id1 = 2, + .id2 = 5, + .gridSquare = SQU_PURPLE_SKITTY, + .flag = F_PURPLE_SKITTY, }, { - .var00 = 3, - .var01 = 7, - .var02 = 9, - .var04 = 0x200, + .id1 = 3, + .id2 = 7, + .gridSquare = SQU_ORANGE_MAKUHITA, + .flag = F_ORANGE_MAKUHITA, }, { - .var00 = 4, - .var01 = 9, - .var02 = 11, - .var04 = 0x800, + .id1 = 4, + .id2 = 9, + .gridSquare = SQU_GREEN_WYNAUT, + .flag = F_GREEN_WYNAUT, }, { - .var00 = 5, - .var01 = 11, - .var02 = 17, - .var04 = 0x20000, + .id1 = 5, + .id2 = 11, + .gridSquare = SQU_PURPLE_AZURILL, + .flag = F_PURPLE_AZURILL, }, { - .var00 = 6, - .var01 = 13, - .var02 = 8, - .var04 = 0x100, + .id1 = 6, + .id2 = 13, + .gridSquare = SQU_ORANGE_SKITTY, + .flag = F_ORANGE_SKITTY, }, { - .var00 = 7, - .var01 = 15, - .var02 = 14, - .var04 = 0x4000, + .id1 = 7, + .id2 = 15, + .gridSquare = SQU_GREEN_MAKUHITA, + .flag = F_GREEN_MAKUHITA, }, { - .var00 = 8, - .var01 = 17, - .var02 = 16, - .var04 = 0x10000, + .id1 = 8, + .id2 = 17, + .gridSquare = SQU_PURPLE_WYNAUT, + .flag = F_PURPLE_WYNAUT, }, { - .var00 = 9, - .var01 = 19, - .var02 = 7, - .var04 = 0x80, + .id1 = 9, + .id2 = 19, + .gridSquare = SQU_ORANGE_AZURILL, + .flag = F_ORANGE_AZURILL, }, { - .var00 = 10, - .var01 = 21, - .var02 = 13, - .var04 = 0x2000, + .id1 = 10, + .id2 = 21, + .gridSquare = SQU_GREEN_SKITTY, + .flag = F_GREEN_SKITTY, }, { - .var00 = 11, - .var01 = 23, - .var02 = 19, - .var04 = 0x80000, + .id1 = 11, + .id2 = 23, + .gridSquare = SQU_PURPLE_MAKUHITA, + .flag = F_PURPLE_MAKUHITA, }, }; -static const u8 gUnknown_085B6344[] = {1, 3, 1, 6}; +static const u8 sTableMinBets[] = {1, 3, 1, 6}; + static const struct StructgUnknown_083F8DF4 gUnknown_085B6348[] = { { @@ -792,88 +956,88 @@ static const struct UnkStruct1 gUnknown_085B63F0[] = } }; -static const struct YesNoFuncTable gUnknown_085B6408 = +static const struct YesNoFuncTable sYesNoTable_AcceptMinBet = { - sub_8142918, - sub_814297C + Task_AcceptMinBet, + Task_DeclineMinBet }; -static const struct YesNoFuncTable gUnknown_085B6410 = +static const struct YesNoFuncTable sYesNoTable_KeepPlaying = { - sub_8140968, - sub_8140994 + Task_ContinuePlaying, + Task_StopPlaying }; -static void sub_8140238(void) +static void CB2_Roulette(void) { RunTasks(); AnimateSprites(); BuildOamBuffer(); - if (gUnknown_0203AB88->varB8.var00) - task_tutorial_controls_fadein(&gUnknown_0203AB88->varB8); + if (sRoulette->varB8.var00) + task_tutorial_controls_fadein(&sRoulette->varB8); } -static void sub_8140264(void) +static void VBlankCB_Roulette(void) { LoadOam(); ProcessSpriteCopyRequests(); TransferPlttBuffer(); sub_8142814(); - SetGpuReg(REG_OFFSET_BG1HOFS, 0x200 - gUnknown_0203AB88->var26); - if (gUnknown_0203AB88->var01) - SetGpuReg(REG_OFFSET_BLDALPHA, gUnknown_0203AB88->var34); - if (gUnknown_0203AB88->var2A != 0) + SetGpuReg(REG_OFFSET_BG1HOFS, 0x200 - sRoulette->var26); + if (sRoulette->var01) + SetGpuReg(REG_OFFSET_BLDALPHA, sRoulette->var34); + if (sRoulette->var2A != 0) { - DmaCopy16(3, &gUnknown_0203AB88->tilemapBuffers[2][0xE0], (void *)BG_SCREEN_ADDR(4) + 0x1C0, 0x340); - gUnknown_0203AB88->var2A = 0; + DmaCopy16(3, &sRoulette->tilemapBuffers[2][0xE0], (void *)BG_SCREEN_ADDR(4) + 0x1C0, 0x340); + sRoulette->var2A = 0; } - switch (gUnknown_0203AB88->var28) + switch (sRoulette->var28) { case 1: SetBgAttribute(0, BG_ATTR_CHARBASEINDEX, 0); ShowBg(0); - DmaCopy16(3, &gUnknown_0203AB88->tilemapBuffers[0][0xE0], (void *)BG_SCREEN_ADDR(31) + 0x1C0, 0x340); - gUnknown_0203AB88->var28 = 2; + DmaCopy16(3, &sRoulette->tilemapBuffers[0][0xE0], (void *)BG_SCREEN_ADDR(31) + 0x1C0, 0x340); + sRoulette->var28 = 2; break; case 2: - DmaCopy16(3, &gUnknown_0203AB88->tilemapBuffers[0][0xE0], (void *)BG_SCREEN_ADDR(31) + 0x1C0, 0x340); + DmaCopy16(3, &sRoulette->tilemapBuffers[0][0xE0], (void *)BG_SCREEN_ADDR(31) + 0x1C0, 0x340); break; case 0xFF: SetBgAttribute(0, BG_ATTR_CHARBASEINDEX, 2); ShowBg(0); DmaFill16(3, 0, (void *)BG_SCREEN_ADDR(31) + 0x1C0, 0x340); - gUnknown_0203AB88->var28 = 0; + sRoulette->var28 = 0; case 0: break; } } -static void sub_8140388(void) +static void InitRouletteBgAndWindows(void) { u32 size = 0; - gUnknown_0203AB88 = AllocZeroed(sizeof(*gUnknown_0203AB88)); + sRoulette = AllocZeroed(sizeof(*sRoulette)); ResetBgsAndClearDma3BusyFlags(0); - InitBgsFromTemplates(1, gUnknown_085B6140, ARRAY_COUNT(gUnknown_085B6140)); - SetBgTilemapBuffer(0, gUnknown_0203AB88->tilemapBuffers[0]); - SetBgTilemapBuffer(1, gUnknown_0203AB88->tilemapBuffers[2]); - SetBgTilemapBuffer(2, gUnknown_0203AB88->tilemapBuffers[6]); - InitWindows(gUnknown_085B614C); + InitBgsFromTemplates(1, sBgTemplates, ARRAY_COUNT(sBgTemplates)); + SetBgTilemapBuffer(0, sRoulette->tilemapBuffers[0]); + SetBgTilemapBuffer(1, sRoulette->tilemapBuffers[2]); + SetBgTilemapBuffer(2, sRoulette->tilemapBuffers[6]); + InitWindows(sWindowTemplates); InitTextBoxGfxAndPrinters(); - gUnknown_0203AB8C = 0; - gUnknown_0203AB88->unk_397C = malloc_and_decompress(gUnknown_085B5DFC, &size); + sTextWindowId = 0; + sRoulette->unk_397C = malloc_and_decompress(gUnknown_085B5DFC, &size); } -static void sub_8140418(void) +static void FreeRoulette(void) { - FREE_AND_SET_NULL(gUnknown_0203AB88->unk_397C); + FREE_AND_SET_NULL(sRoulette->unk_397C); FreeAllWindowBuffers(); UnsetBgTilemapBuffer(0); UnsetBgTilemapBuffer(1); UnsetBgTilemapBuffer(2); ResetBgsAndClearDma3BusyFlags(0); - memset(gUnknown_0203AB88, 0, sizeof(*gUnknown_0203AB88)); - FREE_AND_SET_NULL(gUnknown_0203AB88); + memset(sRoulette, 0, sizeof(*sRoulette)); + FREE_AND_SET_NULL(sRoulette); } static void sub_8140470(void) @@ -881,26 +1045,26 @@ static void sub_8140470(void) u8 i; u16 arr[3] = {RGB(24, 4, 10), RGB(10, 19, 6), RGB(24, 4, 10)}; // the third is never used ? - gUnknown_0203AB88->var04_0 = (gSpecialVar_0x8004 & 1); + sRoulette->tableId = (gSpecialVar_0x8004 & 1); - if (gSpecialVar_0x8004 & 0x80) - gUnknown_0203AB88->var04_7 = 1; + if (gSpecialVar_0x8004 & ROULETTE_SPECIAL_RATE) + sRoulette->isSpecialRate = TRUE; - gUnknown_0203AB88->var22 = gUnknown_085B6348[gUnknown_0203AB88->var04_0].var03; - gUnknown_0203AB88->var23 = gUnknown_085B6348[gUnknown_0203AB88->var04_0].var04; - gUnknown_0203AB88->var19 = gUnknown_085B6344[gUnknown_0203AB88->var04_0 + gUnknown_0203AB88->var04_7 * 2]; - gUnknown_0203AB88->var1A_4 = 1; + sRoulette->var22 = gUnknown_085B6348[sRoulette->tableId].var03; + sRoulette->var23 = gUnknown_085B6348[sRoulette->tableId].var04; + sRoulette->minBet = sTableMinBets[sRoulette->tableId + sRoulette->isSpecialRate * 2]; + sRoulette->unk = 1; - if (gUnknown_0203AB88->var19 == 1) + if (sRoulette->minBet == 1) gPlttBufferUnfaded[0] = gPlttBufferUnfaded[0x51] = gPlttBufferFaded[0] = gPlttBufferFaded[0x51] = arr[0]; else gPlttBufferUnfaded[0] = gPlttBufferUnfaded[0x51] = gPlttBufferFaded[0] = gPlttBufferFaded[0x51] = arr[1]; - sub_8151678(&gUnknown_0203AB88->varB8); + sub_8151678(&sRoulette->varB8); for (i = 0; i < 13; i++) { - sub_815168C(&gUnknown_0203AB88->varB8, i, &gUnknown_085B6388[i]); + sub_815168C(&sRoulette->varB8, i, &gUnknown_085B6388[i]); } for (i = 0; i < PARTY_SIZE; i++) @@ -908,17 +1072,26 @@ static void sub_8140470(void) switch (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2)) { case SPECIES_SHROOMISH: - gUnknown_0203AB88->var02 |= 0x1; + sRoulette->partySpeciesFlags |= HAS_SHROOMISH; break; case SPECIES_TAILLOW: - gUnknown_0203AB88->var02 |= 0x2; + sRoulette->partySpeciesFlags |= HAS_TAILLOW; break; } } RtcCalcLocalTime(); } -static void sub_81405CC(void) +// Task data for the roulette game tasks, starting with Task_StartPlaying +#define tMultiplier data[2] +#define tSelectionId data[4] +#define tWonBet data[5] +#define tBallNum data[6] +#define tConsecutiveWins data[11] +#define tWinningSquare data[12] +#define tCoins data[13] + +static void CB2_LoadRoulette(void) { u8 taskId; @@ -932,7 +1105,7 @@ static void sub_81405CC(void) ResetAllBgsCoordinates(); break; case 1: - sub_8140388(); + InitRouletteBgAndWindows(); DeactivateAllTextPrinters(); SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_EFFECT_NONE | BLDCNT_TGT2_BG2 | @@ -947,35 +1120,35 @@ static void sub_81405CC(void) break; case 3: LoadPalette(&gUnknown_085B5BFC, 0, 0x1C0); - DecompressAndCopyTileDataToVram(1, gRouletteMenuTiles, 0, 0, 0); - DecompressAndCopyTileDataToVram(2, gRouletteWheelTiles, 0, 0, 0); + DecompressAndCopyTileDataToVram(1, gRouletteMenu_Gfx, 0, 0, 0); + DecompressAndCopyTileDataToVram(2, gRouletteWheel_Gfx, 0, 0, 0); break; case 4: if (FreeTempTileDataBuffersIfPossible()) return; sub_8140470(); - CopyToBgTilemapBuffer(2, gUnknown_085B5FA0, 0, 0); + CopyToBgTilemapBuffer(2, sWheel_Tilemap, 0, 0); break; case 5: - sub_8142C0C(0); - sub_81439C8(); - sub_814391C(); - sub_8143314(); - sub_8142CD0(); - sub_8142F7C(); - sub_81431E4(); + LoadOrFreeMiscSpritePalettesAndSheets(FALSE); + CreateBoardBallSprites(); + CreateBoardCenterSprite(); + CreateInterfaceSprites(); + CreateGridSprites(); + CreateGridBallSprites(); + CreateBoardIconSprites(); break; case 6: AnimateSprites(); BuildOamBuffer(); - sub_8143514(GetCoins()); - sub_814372C(6); - sub_81436D0(0); - sub_81424FC(0); - DrawStdWindowFrame(gUnknown_0203AB8C, FALSE); - AddTextPrinterParameterized(gUnknown_0203AB8C, 1, Roulette_Text_ControlsInstruction, 0, 1, TEXT_SPEED_FF, NULL); - CopyWindowToVram(gUnknown_0203AB8C, 3); + SetCreditDigits(GetCoins()); + SetBallCounterNumLeft(BALLS_PER_ROUND); + SetMultiplierSprite(SELECTION_NONE); + DrawGridBackground(SELECTION_NONE); + DrawStdWindowFrame(sTextWindowId, FALSE); + AddTextPrinterParameterized(sTextWindowId, 1, Roulette_Text_ControlsInstruction, 0, 1, TEXT_SPEED_FF, NULL); + CopyWindowToVram(sTextWindowId, 3); gSpriteCoordOffsetX = -60; gSpriteCoordOffsetY = 0; break; @@ -991,39 +1164,39 @@ static void sub_81405CC(void) break; case 8: EnableInterrupts(INTR_FLAG_VBLANK); - SetVBlankCallback(sub_8140264); + SetVBlankCallback(VBlankCB_Roulette); BeginHardwarePaletteFade(0xFF, 0, 16, 0, 1); - taskId = gUnknown_0203AB88->varA4 = CreateTask(sub_81408A8, 0); - gTasks[taskId].data[6] = 6; - gTasks[taskId].data[13] = GetCoins(); + taskId = sRoulette->varA4 = CreateTask(Task_StartPlaying, 0); + gTasks[taskId].tBallNum = BALLS_PER_ROUND; + gTasks[taskId].tCoins = GetCoins(); AlertTVThatPlayerPlayedRoulette(GetCoins()); - gUnknown_0203AB88->varA5 = CreateTask(sub_8140814, 1); - SetMainCallback2(sub_8140238); + sRoulette->varA5 = CreateTask(Task_SpinBoard, 1); + SetMainCallback2(CB2_Roulette); return; } gMain.state++; } -static void sub_8140814(u8 unused) +static void Task_SpinBoard(u8 taskId) { s16 sin; s16 cos; - if (gUnknown_0203AB88->var21++ == gUnknown_0203AB88->var23) + if (sRoulette->var21++ == sRoulette->var23) { - gUnknown_0203AB88->var21 = 0; - if ((gUnknown_0203AB88->var24 -= gUnknown_0203AB88->var22) < 0) - gUnknown_0203AB88->var24 = 360 - gUnknown_0203AB88->var22; + sRoulette->var21 = 0; + if ((sRoulette->var24 -= sRoulette->var22) < 0) + sRoulette->var24 = 360 - sRoulette->var22; } - sin = Sin2(gUnknown_0203AB88->var24); - cos = Cos2(gUnknown_0203AB88->var24); + sin = Sin2(sRoulette->var24); + cos = Cos2(sRoulette->var24); sin = sin / 16; - gUnknown_0203AB88->var2C.a = gUnknown_0203AB88->var2C.d = cos / 16; - gUnknown_0203AB88->var2C.b = sin; - gUnknown_0203AB88->var2C.c = -sin; + sRoulette->var2C.a = sRoulette->var2C.d = cos / 16; + sRoulette->var2C.b = sin; + sRoulette->var2C.c = -sin; } -static void sub_81408A8(u8 taskId) +static void Task_StartPlaying(u8 taskId) { if (UpdatePaletteFade() == 0) { @@ -1031,222 +1204,227 @@ static void sub_81408A8(u8 taskId) BLDCNT_TGT2_BG2 | BLDCNT_TGT2_BD); SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(8, 8)); - gTasks[taskId].data[6] = 0; + gTasks[taskId].tBallNum = 0; sub_8141FF4(taskId); - sub_8142070(); - sub_8143A40(); - sub_81424FC(0); - sub_814372C(6); - sub_8141F7C(taskId, sub_8140968, 0xFFFF, 0x3); + ResetHits(); + HideBoardBalls(); + DrawGridBackground(SELECTION_NONE); + SetBallCounterNumLeft(BALLS_PER_ROUND); + StartTaskAfterDelayOrInput(taskId, Task_ContinuePlaying, 0xFFFF, A_BUTTON | B_BUTTON); } } -static void sub_8140914(u8 taskId) +static void Task_AskKeepPlaying(u8 taskId) { DisplayYesNoMenuDefaultYes(); - DrawStdWindowFrame(gUnknown_0203AB8C, 0); - AddTextPrinterParameterized(gUnknown_0203AB8C, 1, Roulette_Text_KeepPlaying, 0, 1, TEXT_SPEED_FF, 0); - CopyWindowToVram(gUnknown_0203AB8C, 3); - DoYesNoFuncWithChoice(taskId, &gUnknown_085B6410); + DrawStdWindowFrame(sTextWindowId, 0); + AddTextPrinterParameterized(sTextWindowId, 1, Roulette_Text_KeepPlaying, 0, 1, TEXT_SPEED_FF, 0); + CopyWindowToVram(sTextWindowId, 3); + DoYesNoFuncWithChoice(taskId, &sYesNoTable_KeepPlaying); } -static void sub_8140968(u8 taskId) +static void Task_ContinuePlaying(u8 taskId) { ClearStdWindowAndFrame(0, TRUE); - gTasks[taskId].func = sub_8140BD0; + gTasks[taskId].func = Task_SelectFirstEmptySquare; } -static void sub_8140994(u8 taskId) +static void Task_StopPlaying(u8 taskId) { - DestroyTask(gUnknown_0203AB88->varA5); - sub_8141DE4(taskId); + DestroyTask(sRoulette->varA5); + ExitRoulette(taskId); } -static void sub_81409B8(u8 r0) +static void UpdateGridSelectionRect(u8 selectionId) { u8 temp0, temp1; - switch (r0) + switch (selectionId) { - case 0: - sub_8152008(&gUnknown_0203AB88->tilemapBuffers[0][0], 0, 14, 7, 16, 13); + case SELECTION_NONE: + ClearGridSelectionRect(&sRoulette->tilemapBuffers[0][0], 0, 14, 7, 16, 13); break; - case 1: - case 2: - case 3: - case 4: - temp0 = (r0 * 3 + 14); - sub_8152008(&gUnknown_0203AB88->tilemapBuffers[0][0], 0, 14, 7, 16, 13); - sub_8152058(&gUnknown_0203AB88->tilemapBuffers[0][0], &gUnknown_0203AB88->unk_397C[281], temp0, 7, 3, 13); + case COL_WYNAUT: + case COL_AZURILL: + case COL_SKITTY: + case COL_MAKUHITA: + temp0 = (selectionId * 3 + 14); + ClearGridSelectionRect(&sRoulette->tilemapBuffers[0][0], 0, 14, 7, 16, 13); + SetGridSelectionRect(&sRoulette->tilemapBuffers[0][0], &sRoulette->unk_397C[281], temp0, 7, 3, 13); break; - case 0x5: - case 0xA: - case 0xF: - temp1 = ((r0 - 1) / 5 * 3 + 10); - sub_8152008(&gUnknown_0203AB88->tilemapBuffers[0][0], 0, 14, 7, 16, 13); - sub_8152058(&gUnknown_0203AB88->tilemapBuffers[0][0], &gUnknown_0203AB88->unk_397C[320], 14, temp1, 16, 3); + case ROW_ORANGE: + case ROW_GREEN: + case ROW_PURPLE: + temp1 = ((selectionId - 1) / 5 * 3 + 10); + ClearGridSelectionRect(&sRoulette->tilemapBuffers[0][0], 0, 14, 7, 16, 13); + SetGridSelectionRect(&sRoulette->tilemapBuffers[0][0], &sRoulette->unk_397C[320], 14, temp1, 16, 3); break; + // Individual square default: - temp0 = ((r0 % 5) * 3 + 14); - temp1 = ((r0 - 1) / 5 * 3 + 7); - sub_8152008(&gUnknown_0203AB88->tilemapBuffers[0][0], 0, 14, 7, 16, 13); - sub_8152058(&gUnknown_0203AB88->tilemapBuffers[0][0], &gUnknown_0203AB88->unk_397C[272], temp0, temp1, 3, 3); + temp0 = GET_COL(selectionId) * 3 + 14; + temp1 = ((selectionId - 1) / 5 * 3 + 7); + ClearGridSelectionRect(&sRoulette->tilemapBuffers[0][0], 0, 14, 7, 16, 13); + SetGridSelectionRect(&sRoulette->tilemapBuffers[0][0], &sRoulette->unk_397C[272], temp0, temp1, 3, 3); break; } } -static void sub_8140B64(u8 taskId) +static void UpdateGridSelection(u8 taskId) { - sub_81436D0(gTasks[taskId].data[4]); - sub_81409B8(gTasks[taskId].data[4]); + SetMultiplierSprite(gTasks[taskId].tSelectionId); + UpdateGridSelectionRect(gTasks[taskId].tSelectionId); } -static void sub_8140B8C(u8 taskId) +static void Task_StartHandleBetGridInput(u8 taskId) { - gUnknown_0203AB88->var28 = 1; - sub_81409B8(gTasks[taskId].data[4]); - gUnknown_0203AB88->var23 = 2; - gUnknown_0203AB88->var21 = 0; - gTasks[taskId].func = sub_8141040; + sRoulette->var28 = 1; + UpdateGridSelectionRect(gTasks[taskId].tSelectionId); + sRoulette->var23 = 2; + sRoulette->var21 = 0; + gTasks[taskId].func = Task_HandleBetGridInput; } -static void sub_8140BD0(u8 taskId) +static void Task_SelectFirstEmptySquare(u8 taskId) { s16 i; - if (gUnknown_0203AB88->var08 & 0x20) + if (sRoulette->hitFlags & F_ORANGE_ROW) { - for (i = 11; i < 14; i++) + // If the whole orange row is filled, get first in green row + for (i = SQU_GREEN_WYNAUT; i < SQU_GREEN_MAKUHITA; i++) { - if ((gUnknown_0203AB88->var08 & gUnknown_085B6154[i].var08) == 0) + if (!(sRoulette->hitFlags & sGridSelections[i].flag)) break; } } else { - for (i = 6; i < 10; i++) + // Otherwise get first in orange row + // With only 6 balls both rows can't be filled, no need to check purple row + for (i = SQU_ORANGE_WYNAUT; i <= SQU_ORANGE_MAKUHITA; i++) // <= is accidental, but it will never get that far { - if ((gUnknown_0203AB88->var08 & gUnknown_085B6154[i].var08) == 0) + if (!(sRoulette->hitFlags & sGridSelections[i].flag)) break; } } - gTasks[taskId].data[4] = i; + gTasks[taskId].tSelectionId = i; sub_8141FF4(taskId); - sub_81424FC(gTasks[taskId].data[4]); - sub_81436D0(gTasks[taskId].data[4]); - sub_8142284(gTasks[taskId].data[4]); + DrawGridBackground(gTasks[taskId].tSelectionId); + SetMultiplierSprite(gTasks[taskId].tSelectionId); + FlashSelectionOnWheel(gTasks[taskId].tSelectionId); gTasks[taskId].data[1] = 0; - gTasks[taskId].func = sub_8140B8C; + gTasks[taskId].func = Task_StartHandleBetGridInput; } -static u8 sub_8140CA8(s16 *r0, u8 r1) +static bool8 CanMoveSelectionInDir(s16 *selectionId, u8 dir) { s8 temp1 = 0; s8 temp = 0; - s8 arr[4] = {-5, 5, -1, 1}; - s8 t = *r0; + s8 moveOffsets[4] = {-5, 5, -1, 1}; + s8 originalSelection = *selectionId; - switch (r1) + switch (dir) { - case 0: - case 1: - temp1 = (*r0 % 5); - temp = temp1 + 15; - if (temp1 == 0) + case 0: // UP + case 1: // DOWN + temp1 = GET_COL(*selectionId); + temp = temp1 + ROW_PURPLE; + if (temp1 == SELECTION_NONE) temp1 = 5; break; - case 2: - case 3: - temp1 = (*r0 / 5) * 5; - temp = temp1 + 4; - if (temp1 == 0) + case 2: // LEFT + case 3: // RIGHT + temp1 = GET_ROW(*selectionId); + temp = temp1 + COL_MAKUHITA; + if (temp1 == SELECTION_NONE) temp1 = 1; break; } - *r0 += arr[r1]; + *selectionId += moveOffsets[dir]; - if (*r0 < temp1) - *r0 = temp; + if (*selectionId < temp1) + *selectionId = temp; - if (*r0 > temp) - *r0 = temp1; + if (*selectionId > temp) + *selectionId = temp1; - if (*r0 != t) + if (*selectionId != originalSelection) return TRUE; return FALSE; } -static void sub_8140D6C(u8 r0) +static void ProcessBetGridInput(u8 taskId) { u8 z = 0; - bool8 var0 = FALSE; - if (!(gMain.newKeys & DPAD_UP) || ((var0 = TRUE), sub_8140CA8(&gTasks[r0].data[4], 0))) - if (!(gMain.newKeys & DPAD_DOWN) || ((var0 = TRUE), sub_8140CA8(&gTasks[r0].data[4], 1))) - if (!(gMain.newKeys & DPAD_LEFT) || ((var0 = TRUE), sub_8140CA8(&gTasks[r0].data[4], 2))) - if (!(gMain.newKeys & DPAD_RIGHT) || ((var0 = TRUE), sub_8140CA8(&gTasks[r0].data[4], 3))) - if (var0) - { - u8 i; - sub_81424FC(gTasks[r0].data[4]); - sub_8140B64(r0); - gTasks[r0].data[1] = z; - PlaySE(SE_SELECT); - sub_8151A9C(&gUnknown_0203AB88->varB8, 0xFFFF); - gUnknown_0203AB88->varB8.var04[13].var00_7 = gUnknown_0203AB88->varB8.var04[14].var00_7 = gUnknown_0203AB88->varB8.var04[15].var00_7 = 0; - sub_8142284(gTasks[r0].data[4]); - for (i = 0; i < 4; i++) - { - gSprites[gUnknown_0203AB88->var3C[i + 41]].oam.tileNum = - gSprites[gUnknown_0203AB88->var3C[i + 41]].sheetTileStart - + (*gSprites[gUnknown_0203AB88->var3C[i + 41]].anims)->type; - } - if ((u16)(gTasks[r0].data[4] - 1) < 4 && !(gUnknown_0203AB88->var08 & gUnknown_085B6154[gTasks[r0].data[4]].var08) ) - { - z = gTasks[r0].data[4] - 1; - gSprites[gUnknown_0203AB88->var3C[z + 41]].oam.tileNum = - gSprites[gUnknown_0203AB88->var3C[z + 41]].sheetTileStart - + (*gSprites[gUnknown_0203AB88->var3C[z + 41]].anims + 1)->type; - } - } + bool8 dirPressed = FALSE; + if ((!(JOY_NEW(DPAD_UP)) || ((dirPressed = TRUE), CanMoveSelectionInDir(&gTasks[taskId].tSelectionId, 0))) + && (!(JOY_NEW(DPAD_DOWN)) || ((dirPressed = TRUE), CanMoveSelectionInDir(&gTasks[taskId].tSelectionId, 1))) + && (!(JOY_NEW(DPAD_LEFT)) || ((dirPressed = TRUE), CanMoveSelectionInDir(&gTasks[taskId].tSelectionId, 2))) + && (!(JOY_NEW(DPAD_RIGHT)) || ((dirPressed = TRUE), CanMoveSelectionInDir(&gTasks[taskId].tSelectionId, 3))) + && (dirPressed)) + { + u8 i; + DrawGridBackground(gTasks[taskId].tSelectionId); + UpdateGridSelection(taskId); + gTasks[taskId].data[1] = z; + PlaySE(SE_SELECT); + sub_8151A9C(&sRoulette->varB8, 0xFFFF); + sRoulette->varB8.var04[13].var00_7 = sRoulette->varB8.var04[14].var00_7 = sRoulette->varB8.var04[15].var00_7 = 0; + FlashSelectionOnWheel(gTasks[taskId].tSelectionId); + for (i = 0; i < NUM_BOARD_POKES; i++) + { + gSprites[sRoulette->spriteIds[i + SPR_POKE_HEADER_1]].oam.tileNum = + gSprites[sRoulette->spriteIds[i + SPR_POKE_HEADER_1]].sheetTileStart + + (*gSprites[sRoulette->spriteIds[i + SPR_POKE_HEADER_1]].anims)->type; + } + if ((u16)(gTasks[taskId].tSelectionId - 1) < 4 && !(sRoulette->hitFlags & sGridSelections[gTasks[taskId].tSelectionId].flag) ) + { + z = gTasks[taskId].tSelectionId - 1; + gSprites[sRoulette->spriteIds[z + SPR_POKE_HEADER_1]].oam.tileNum = + gSprites[sRoulette->spriteIds[z + SPR_POKE_HEADER_1]].sheetTileStart + + (*gSprites[sRoulette->spriteIds[z + SPR_POKE_HEADER_1]].anims + 1)->type; + } + } } static void sub_8140F6C(u8 r0) { IncrementDailyRouletteUses(); - gUnknown_0203AB88->var28 = 0xFF; - if (gUnknown_0203AB88->var19 == 1) - gUnknown_0203AB88->var23 = 1; + sRoulette->var28 = 0xFF; + if (sRoulette->minBet == 1) + sRoulette->var23 = 1; else - gUnknown_0203AB88->var23 = 0; - gUnknown_0203AB88->var21 = 0; + sRoulette->var23 = 0; + sRoulette->var21 = 0; gTasks[r0].data[1] = 32; - gTasks[r0].func = sub_81410FC; + gTasks[r0].func = Task_SlideGridOffscreen; } -static void sub_8140FC4(u8 taskId) +static void Task_PlaceBet(u8 taskId) { - gUnknown_0203AB88->var1B[gUnknown_0203AB88->var1A_0] = gTasks[taskId].data[4]; - gTasks[taskId].data[2] = sub_8142758(gUnknown_0203AB88->var1B[gUnknown_0203AB88->var1A_0]); - sub_81436D0(gUnknown_0203AB88->var1B[gUnknown_0203AB88->var1A_0]); - if ((gTasks[taskId].data[13] -= gUnknown_0203AB88->var19) < 0) - gTasks[taskId].data[13] = 0; - sub_8143514(gTasks[taskId].data[13]); + sRoulette->betSelection[sRoulette->curBallNum] = gTasks[taskId].tSelectionId; + gTasks[taskId].tMultiplier = GetMultiplier(sRoulette->betSelection[sRoulette->curBallNum]); + SetMultiplierSprite(sRoulette->betSelection[sRoulette->curBallNum]); + if ((gTasks[taskId].tCoins -= sRoulette->minBet) < 0) + gTasks[taskId].tCoins = 0; + SetCreditDigits(gTasks[taskId].tCoins); gTasks[taskId].func = sub_8140F6C; } -static void sub_8141040(u8 taskId) +static void Task_HandleBetGridInput(u8 taskId) { - sub_8140D6C(taskId); + ProcessBetGridInput(taskId); + // Flash selection rect switch (gTasks[taskId].data[1]) { case 0: - sub_81409B8(gTasks[taskId].data[4]); + UpdateGridSelectionRect(gTasks[taskId].tSelectionId); gTasks[taskId].data[1]++; break; case 30: - sub_81409B8(0); + UpdateGridSelectionRect(SELECTION_NONE); gTasks[taskId].data[1]++; break; case 59: @@ -1256,83 +1434,78 @@ static void sub_8141040(u8 taskId) gTasks[taskId].data[1]++; } - if (gMain.newKeys & A_BUTTON) + if (JOY_NEW(A_BUTTON)) { - if ((gUnknown_0203AB88->var08 & gUnknown_085B6154[gTasks[taskId].data[4]].var08)) + if ((sRoulette->hitFlags & sGridSelections[gTasks[taskId].tSelectionId].flag)) + { + // Ball has already landed on this space PlaySE(SE_BOO); + } else { m4aSongNumStart(SE_REGI); - gTasks[taskId].func = sub_8140FC4; + gTasks[taskId].func = Task_PlaceBet; } } } -static void sub_81410FC(u8 taskId) +static void Task_SlideGridOffscreen(u8 taskId) { if (gTasks[taskId].data[1]-- > 0) { if (gTasks[taskId].data[1] > 2) gSpriteCoordOffsetX += 2; - if ((gUnknown_0203AB88->var26 += 4) == 104) - gSprites[gUnknown_0203AB88->var3C[25]].callback = &SpriteCallbackDummy; + if ((sRoulette->var26 += 4) == 104) + gSprites[sRoulette->spriteIds[SPR_MULTIPLIER]].callback = &SpriteCallbackDummy; } else { - sub_8142E70(1, -1); - sub_8143038(1, -1); - gTasks[taskId].func = sub_8141344; + ShowHideGridIcons(TRUE, -1); + ShowHideGridBalls(TRUE, -1); + gTasks[taskId].func = Task_RollBall; gTasks[taskId].data[1] = 0; } } static u8 sub_814118C(u16 r0, u16 r1) { - switch (gUnknown_0203AB88->var02) + switch (sRoulette->partySpeciesFlags) { - case 1: // SHROOMISH - case 2: // TAILLOW + case HAS_SHROOMISH: + case HAS_TAILLOW: // one of the two is in party if (gLocalTime.hours > 3 && gLocalTime.hours < 10) { if (r0 < 12 || (r1 & 1)) - { - return gUnknown_085B6348[gUnknown_0203AB88->var04_0].var02 / 2; - } + return gUnknown_085B6348[sRoulette->tableId].var02 / 2; else - { return 1; - } } - else if (!(r1 & 0x3)) + else if (!(r1 & 0x3)) { - return gUnknown_085B6348[gUnknown_0203AB88->var04_0].var02 / 2; + return gUnknown_085B6348[sRoulette->tableId].var02 / 2; } - else + else { - return gUnknown_085B6348[gUnknown_0203AB88->var04_0].var02; + return gUnknown_085B6348[sRoulette->tableId].var02; } break; - case 3: + case HAS_SHROOMISH | HAS_TAILLOW: // both are in party if (gLocalTime.hours > 3 && gLocalTime.hours < 11) { if (r0 < 6 || (r1 & 1)) - { - return gUnknown_085B6348[gUnknown_0203AB88->var04_0].var02 / 2; - } + return gUnknown_085B6348[sRoulette->tableId].var02 / 2; else - { return 1; - } } - else if ((r1 & 1) && r0 > 6) + else if ((r1 & 1) && r0 > 6) { - return gUnknown_085B6348[gUnknown_0203AB88->var04_0].var02 / 4; + return gUnknown_085B6348[sRoulette->tableId].var02 / 4; } - else + else { - return gUnknown_085B6348[gUnknown_0203AB88->var04_0].var02 / 2; + return gUnknown_085B6348[sRoulette->tableId].var02 / 2; } break; case 0: @@ -1341,45 +1514,33 @@ static u8 sub_814118C(u16 r0, u16 r1) if (gLocalTime.hours > 3 && gLocalTime.hours < 10) { if (!(r1 & 3)) - { return 1; - } else - { - return gUnknown_085B6348[gUnknown_0203AB88->var04_0].var02 / 2; - } + return gUnknown_085B6348[sRoulette->tableId].var02 / 2; } else if (!(r1 & 3)) { if (r0 > 12) - { - return gUnknown_085B6348[gUnknown_0203AB88->var04_0].var02 / 2; - } + return gUnknown_085B6348[sRoulette->tableId].var02 / 2; else - { - return gUnknown_085B6348[gUnknown_0203AB88->var04_0].var02; - } + return gUnknown_085B6348[sRoulette->tableId].var02; } else if (r1 & 0x8000) { if (r0 > 12) - { - return gUnknown_085B6348[gUnknown_0203AB88->var04_0].var02; - } + return gUnknown_085B6348[sRoulette->tableId].var02; else - { - return gUnknown_085B6348[gUnknown_0203AB88->var04_0].var01; - } + return gUnknown_085B6348[sRoulette->tableId].var01; } else { - return gUnknown_085B6348[gUnknown_0203AB88->var04_0].var01 * 2; + return gUnknown_085B6348[sRoulette->tableId].var01 * 2; } break; } } -static void sub_8141344(u8 taskId) +static void Task_RollBall(u8 taskId) { u8 randf; s8 randfinal; @@ -1391,8 +1552,8 @@ static void sub_8141344(u8 taskId) rand = Random(); randmod = rand % 100; - gUnknown_0203AB88->var7C = gTasks[taskId].data[6]; - gUnknown_0203AB88->var7D = gUnknown_0203AB88->var7E = gUnknown_0203AB88->var7F = g; + sRoulette->var7C = gTasks[taskId].tBallNum; + sRoulette->var7D = sRoulette->var7E = sRoulette->var7F = g; randf = sub_814118C(gTasks[taskId].data[8], rand); randfinal = (rand % randf) - (randf / 2); @@ -1406,88 +1567,88 @@ static void sub_8141344(u8 taskId) else r5 = (1 - r5) * 2; - gUnknown_0203AB88->var80 = g = gUnknown_085B6348[gUnknown_0203AB88->var04_0].var1A + randfinal; + sRoulette->var80 = g = gUnknown_085B6348[sRoulette->tableId].var1A + randfinal; g = S16TOPOSFLOAT(g) / 5.0f; - gUnknown_0203AB88->var82 = g * 3; - gUnknown_0203AB88->var86 = gUnknown_0203AB88->var84 = g; + sRoulette->var82 = g * 3; + sRoulette->var86 = sRoulette->var84 = g; - gUnknown_0203AB88->var88 = S16TOPOSFLOAT(angles[(rand & 1) + r5]); - gUnknown_0203AB88->var8C = S16TOPOSFLOAT(gUnknown_085B6348[gUnknown_0203AB88->var04_0].var18); - gUnknown_0203AB88->var90 = ((gUnknown_0203AB88->var8C * 0.5f) - gUnknown_0203AB88->var8C) / S16TOPOSFLOAT(gUnknown_0203AB88->var82); - gUnknown_0203AB88->var94 = 68.0f; - gUnknown_0203AB88->var9C = 0.0f; - gUnknown_0203AB88->var98 = -(8.0f / S16TOPOSFLOAT(gUnknown_0203AB88->var82)); - gUnknown_0203AB88->varA0 = 36.0f; - gTasks[taskId].func = sub_814155C; + sRoulette->var88 = S16TOPOSFLOAT(angles[(rand & 1) + r5]); + sRoulette->var8C = S16TOPOSFLOAT(gUnknown_085B6348[sRoulette->tableId].var18); + sRoulette->var90 = ((sRoulette->var8C * 0.5f) - sRoulette->var8C) / S16TOPOSFLOAT(sRoulette->var82); + sRoulette->var94 = 68.0f; + sRoulette->var9C = 0.0f; + sRoulette->var98 = -(8.0f / S16TOPOSFLOAT(sRoulette->var82)); + sRoulette->varA0 = 36.0f; + gTasks[taskId].func = Task_EndBallRoll; } -static void sub_814155C(u8 taskId) +static void Task_EndBallRoll(u8 taskId) { u8 index; - gUnknown_0203AB88->var03_7 = 1; - index = gUnknown_0203AB88->var3C[gUnknown_0203AB88->var7C]; - gUnknown_0203AB88->var38 = &gSprites[index]; - gUnknown_0203AB88->var38->callback = sub_81446AC; - gTasks[taskId].data[6]++; - gTasks[taskId].data[0x8]++; - sub_814372C(6 - gTasks[taskId].data[6]); + sRoulette->var03_7 = TRUE; + index = sRoulette->spriteIds[sRoulette->var7C]; + sRoulette->var38 = &gSprites[index]; + sRoulette->var38->callback = sub_81446AC; + gTasks[taskId].tBallNum++; + gTasks[taskId].data[8]++; + SetBallCounterNumLeft(BALLS_PER_ROUND - gTasks[taskId].tBallNum); m4aSongNumStart(SE_TAMAKORO); - gTasks[taskId].func = sub_81415D4; + gTasks[taskId].func = Task_RecordBallHit; } -static void sub_81415D4(u8 taskId) +static void Task_RecordBallHit(u8 taskId) { - if (gUnknown_0203AB88->var7D) + if (sRoulette->var7D) { - if (gUnknown_0203AB88->var03_5) + if (sRoulette->var03_5) { - if (gUnknown_0203AB88->var03_6) + if (sRoulette->var03_6) { - gUnknown_0203AB88->var03_6 = FALSE; - gUnknown_0203AB88->var03_5 = FALSE; + sRoulette->var03_6 = FALSE; + sRoulette->var03_5 = FALSE; } } else { if (!gTasks[taskId].data[1]) { - bool8 temp = sub_81421E8(sub_81420D0(taskId, gUnknown_0203AB88->var7E), gUnknown_0203AB88->var1B[gUnknown_0203AB88->var1A_0]); - gTasks[taskId].data[5] = temp; + bool8 temp = IsHitInBetSelection(RecordHit(taskId, sRoulette->var7E), sRoulette->betSelection[sRoulette->curBallNum]); + gTasks[taskId].tWonBet = temp; if (temp == TRUE) - sub_8151A48(&gUnknown_0203AB88->varB8, 0x1000); + sub_8151A48(&sRoulette->varB8, 0x1000); } if (gTasks[taskId].data[1] <= 60) { - if (gMain.newKeys & A_BUTTON) + if (JOY_NEW(A_BUTTON)) gTasks[taskId].data[1] = 60; gTasks[taskId].data[1]++; } else { - sub_81424FC(gUnknown_0203AB88->var1B[gUnknown_0203AB88->var1A_0]); - sub_8142E70(0, gTasks[taskId].data[12]); - sub_8143038(0, gTasks[taskId].data[6] - 1); + DrawGridBackground(sRoulette->betSelection[sRoulette->curBallNum]); + ShowHideGridIcons(FALSE, gTasks[taskId].tWinningSquare); + ShowHideGridBalls(FALSE, gTasks[taskId].tBallNum - 1); gTasks[taskId].data[1] = 32; - gTasks[taskId].func = sub_81416D4; + gTasks[taskId].func = Task_SlideGridOnscreen; } } } } -static void sub_81416D4(u8 taskId) +static void Task_SlideGridOnscreen(u8 taskId) { if (gTasks[taskId].data[1]-- > 0) { if (gTasks[taskId].data[1] > 2) gSpriteCoordOffsetX -= 2; - if ((gUnknown_0203AB88->var26 -= 4) == 104) - gSprites[gUnknown_0203AB88->var3C[25]].callback = sub_814390C; + if ((sRoulette->var26 -= 4) == 104) + gSprites[sRoulette->spriteIds[SPR_MULTIPLIER]].callback = SpriteCB_GridSquare; } else { - sub_8143150(gTasks[taskId].data[12]); - if (gTasks[taskId].data[5] == 1) + ShowHideWinSlotCursor(gTasks[taskId].tWinningSquare); + if (gTasks[taskId].tWonBet == TRUE) gTasks[taskId].data[1] = 121; else gTasks[taskId].data[1] = 61; @@ -1502,95 +1663,96 @@ static void sub_8141778(u8 taskId) switch (gTasks[taskId].data[1] % 16) { case 8: - sub_8142E70(0, -1); - sub_8143038(0, -1); + ShowHideGridIcons(FALSE, -1); + ShowHideGridBalls(FALSE, -1); break; case 0: - sub_8142E70(0, gTasks[taskId].data[12]); - sub_8143038(0, gTasks[taskId].data[6] - 1); + ShowHideGridIcons(FALSE, gTasks[taskId].tWinningSquare); + ShowHideGridBalls(FALSE, gTasks[taskId].tBallNum - 1); break; } } else { - sub_8141F7C(taskId, sub_814189C, 30, 0); + StartTaskAfterDelayOrInput(taskId, Task_PrintSpinResult, 30, 0); } } -static void sub_8141800(u8 taskId) +static void Task_TryIncrementWins(u8 taskId) { - switch (gTasks[taskId].data[0x5]) + switch (gTasks[taskId].tWonBet) { - case 1: - case 2: + case TRUE: + case 2: // never happens if (IsFanfareTaskInactive()) { u32 wins = GetGameStat(GAME_STAT_CONSECUTIVE_ROULETTE_WINS); - if (wins < ++gTasks[taskId].data[11]) - SetGameStat(GAME_STAT_CONSECUTIVE_ROULETTE_WINS, gTasks[taskId].data[11]); - sub_8141F7C(taskId, sub_8141A18, 0xFFFF, 3); + if (wins < ++gTasks[taskId].tConsecutiveWins) + SetGameStat(GAME_STAT_CONSECUTIVE_ROULETTE_WINS, gTasks[taskId].tConsecutiveWins); + StartTaskAfterDelayOrInput(taskId, Task_PrintPayout, 0xFFFF, A_BUTTON | B_BUTTON); } break; - case 0: + case FALSE: default: if (!IsSEPlaying()) { - gTasks[taskId].data[11] = FALSE; - sub_8141F7C(taskId, sub_8141AC0, 0xFFFF, 3); + gTasks[taskId].tConsecutiveWins = 0; + StartTaskAfterDelayOrInput(taskId, Task_EndTurn, 0xFFFF, A_BUTTON | B_BUTTON); } break; } } -static void sub_814189C(u8 taskId) +static void Task_PrintSpinResult(u8 taskId) { - switch (gTasks[taskId].data[5]) + switch (gTasks[taskId].tWonBet) { - case 1: - case 2: - if (gTasks[taskId].data[2] == 12) + case TRUE: + case 2: // never happens + if (gTasks[taskId].tMultiplier == MAX_MULTIPLIER) { PlayFanfare(MUS_ME_B_BIG); - DrawStdWindowFrame(gUnknown_0203AB8C, FALSE); - AddTextPrinterParameterized(gUnknown_0203AB8C, 1, Roulette_Text_Jackpot, 0, 1, TEXT_SPEED_FF, NULL); - CopyWindowToVram(gUnknown_0203AB8C, 3); + DrawStdWindowFrame(sTextWindowId, FALSE); + AddTextPrinterParameterized(sTextWindowId, 1, Roulette_Text_Jackpot, 0, 1, TEXT_SPEED_FF, NULL); + CopyWindowToVram(sTextWindowId, 3); } else { PlayFanfare(MUS_ME_B_SMALL); - DrawStdWindowFrame(gUnknown_0203AB8C, FALSE); - AddTextPrinterParameterized(gUnknown_0203AB8C, 1, Roulette_Text_ItsAHit, 0, 1, TEXT_SPEED_FF, NULL); - CopyWindowToVram(gUnknown_0203AB8C, 3); + DrawStdWindowFrame(sTextWindowId, FALSE); + AddTextPrinterParameterized(sTextWindowId, 1, Roulette_Text_ItsAHit, 0, 1, TEXT_SPEED_FF, NULL); + CopyWindowToVram(sTextWindowId, 3); } break; - case 0: + case FALSE: default: m4aSongNumStart(SE_HAZURE); - DrawStdWindowFrame(gUnknown_0203AB8C, FALSE); - AddTextPrinterParameterized(gUnknown_0203AB8C, 1, Roulette_Text_NothingDoing, 0, 1, TEXT_SPEED_FF, NULL); - CopyWindowToVram(gUnknown_0203AB8C, 3); + DrawStdWindowFrame(sTextWindowId, FALSE); + AddTextPrinterParameterized(sTextWindowId, 1, Roulette_Text_NothingDoing, 0, 1, TEXT_SPEED_FF, NULL); + CopyWindowToVram(sTextWindowId, 3); break; } gTasks[taskId].data[1] = 0; - gTasks[taskId].func = sub_8141800; + gTasks[taskId].func = Task_TryIncrementWins; } -static void sub_8141984(u8 taskId) +#define tPayout data[1] + +static void Task_GivePayout(u8 taskId) { - s32 r0 = gTasks[taskId].data[7]; - switch (r0) + switch (gTasks[taskId].data[7]) { case 0: - gTasks[taskId].data[13]++; + gTasks[taskId].tCoins++; m4aSongNumStart(SE_PIN); - sub_8143514(gTasks[taskId].data[13]); - if (gTasks[taskId].data[13] >= 9999) + SetCreditDigits(gTasks[taskId].tCoins); + if (gTasks[taskId].tCoins >= MAX_COINS) { - gTasks[taskId].data[1] = r0; + gTasks[taskId].tPayout = 0; } else { - gTasks[taskId].data[1]--; + gTasks[taskId].tPayout--; gTasks[taskId].data[7]++; } break; @@ -1602,117 +1764,123 @@ static void sub_8141984(u8 taskId) gTasks[taskId].data[7]++; break; } - if (gTasks[taskId].data[1] == 0) - sub_8141F7C(taskId, sub_8141AC0, 0xFFFF, 3); + if (gTasks[taskId].tPayout == 0) + StartTaskAfterDelayOrInput(taskId, Task_EndTurn, 0xFFFF, A_BUTTON | B_BUTTON); } -static void sub_8141A18(u8 taskId) +static void Task_PrintPayout(u8 taskId) { - ConvertIntToDecimalStringN(gStringVar1, (gUnknown_0203AB88->var19 * gTasks[taskId].data[2]), STR_CONV_MODE_LEFT_ALIGN, 2); + ConvertIntToDecimalStringN(gStringVar1, (sRoulette->minBet * gTasks[taskId].tMultiplier), STR_CONV_MODE_LEFT_ALIGN, 2); StringExpandPlaceholders(gStringVar4, Roulette_Text_YouveWonXCoins); - DrawStdWindowFrame(gUnknown_0203AB8C, FALSE); - AddTextPrinterParameterized(gUnknown_0203AB8C, 1, gStringVar4, 0, 1, TEXT_SPEED_FF, NULL); - CopyWindowToVram(gUnknown_0203AB8C, 3); - gTasks[taskId].data[1] = (gUnknown_0203AB88->var19 * gTasks[taskId].data[2]); + DrawStdWindowFrame(sTextWindowId, FALSE); + AddTextPrinterParameterized(sTextWindowId, 1, gStringVar4, 0, 1, TEXT_SPEED_FF, NULL); + CopyWindowToVram(sTextWindowId, 3); + gTasks[taskId].tPayout = (sRoulette->minBet * gTasks[taskId].tMultiplier); gTasks[taskId].data[7] = 0; - gTasks[taskId].func = sub_8141984; + gTasks[taskId].func = Task_GivePayout; } -static void sub_8141AC0(u8 taskId) +#undef tPayout + +static void Task_EndTurn(u8 taskId) { - sub_8151A9C(&gUnknown_0203AB88->varB8, 0xFFFF); - gUnknown_0203AB88->varB8.var04[13].var00_7 = gUnknown_0203AB88->varB8.var04[14].var00_7 = gUnknown_0203AB88->varB8.var04[15].var00_7 = 0; - gSprites[gUnknown_0203AB88->var3C[7 + gUnknown_085B6154[gTasks[taskId].data[12]].var00]].invisible = TRUE; - gTasks[taskId].func = sub_8141B58; + sub_8151A9C(&sRoulette->varB8, 0xFFFF); + sRoulette->varB8.var04[13].var00_7 = sRoulette->varB8.var04[14].var00_7 = sRoulette->varB8.var04[15].var00_7 = 0; + gSprites[sRoulette->spriteIds[SPR_BOARD_ICONS + sGridSelections[gTasks[taskId].tWinningSquare].var00]].invisible = TRUE; + gTasks[taskId].func = Task_TryPrintEndTurnMsg; } -static void sub_8141B58(u8 taskId) +static void Task_TryPrintEndTurnMsg(u8 taskId) { u8 i = 0; - gTasks[taskId].data[4] = i; - gUnknown_0203AB88->var1B[gUnknown_0203AB88->var1A_0] = 0; - sub_81424FC(0); - gSprites[gUnknown_0203AB88->var3C[48]].invisible = TRUE; - for (i = 0; i < 4; i++) + gTasks[taskId].tSelectionId = i; + sRoulette->betSelection[sRoulette->curBallNum] = SELECTION_NONE; + DrawGridBackground(SELECTION_NONE); + gSprites[sRoulette->spriteIds[SPR_WIN_SLOT_CURSOR]].invisible = TRUE; + for (i = 0; i < NUM_BOARD_POKES; i++) { - gSprites[gUnknown_0203AB88->var3C[i + 41]].oam.tileNum = - gSprites[gUnknown_0203AB88->var3C[i + 41]].sheetTileStart - + (*gSprites[gUnknown_0203AB88->var3C[i + 41]].anims)->type; + gSprites[sRoulette->spriteIds[i + SPR_POKE_HEADER_1]].oam.tileNum = + gSprites[sRoulette->spriteIds[i + SPR_POKE_HEADER_1]].sheetTileStart + + (*gSprites[sRoulette->spriteIds[i + SPR_POKE_HEADER_1]].anims)->type; } - if (gTasks[taskId].data[13] >= gUnknown_0203AB88->var19) + if (gTasks[taskId].tCoins >= sRoulette->minBet) { - if (gTasks[taskId].data[6] == 6) + if (gTasks[taskId].tBallNum == BALLS_PER_ROUND) { - DrawStdWindowFrame(gUnknown_0203AB8C, FALSE); - AddTextPrinterParameterized(gUnknown_0203AB8C, 1, Roulette_Text_BoardWillBeCleared, 0, 1, TEXT_SPEED_FF, NULL); - CopyWindowToVram(gUnknown_0203AB8C, 3); - sub_8141F7C(taskId, dp01t_12_3_battle_menu, 0xFFFF, 3); + // Reached Ball 6, clear board + DrawStdWindowFrame(sTextWindowId, FALSE); + AddTextPrinterParameterized(sTextWindowId, 1, Roulette_Text_BoardWillBeCleared, 0, 1, TEXT_SPEED_FF, NULL); + CopyWindowToVram(sTextWindowId, 3); + StartTaskAfterDelayOrInput(taskId, Task_ClearBoard, 0xFFFF, A_BUTTON | B_BUTTON); } - else if (gTasks[taskId].data[13] == 9999) + else if (gTasks[taskId].tCoins == MAX_COINS) { - DrawStdWindowFrame(gUnknown_0203AB8C, FALSE); - AddTextPrinterParameterized(gUnknown_0203AB8C, 1, Roulette_Text_CoinCaseIsFull, 0, 1, TEXT_SPEED_FF, NULL); - CopyWindowToVram(gUnknown_0203AB8C, 3); - sub_8141F7C(taskId, sub_8140914, 0xFFFF, 0x3); + // Player maxed out coins + DrawStdWindowFrame(sTextWindowId, FALSE); + AddTextPrinterParameterized(sTextWindowId, 1, Roulette_Text_CoinCaseIsFull, 0, 1, TEXT_SPEED_FF, NULL); + CopyWindowToVram(sTextWindowId, 3); + StartTaskAfterDelayOrInput(taskId, Task_AskKeepPlaying, 0xFFFF, A_BUTTON | B_BUTTON); } else { - gTasks[taskId].func = sub_8140914; + // No special msg, ask to continue + gTasks[taskId].func = Task_AskKeepPlaying; } } else { - DrawStdWindowFrame(gUnknown_0203AB8C, FALSE); - AddTextPrinterParameterized(gUnknown_0203AB8C, 1, Roulette_Text_NoCoinsLeft, 0, 1, TEXT_SPEED_FF, NULL); - CopyWindowToVram(gUnknown_0203AB8C, 3); - sub_8141F7C(taskId, sub_8140994, 0x3C, 0x3); + // Player out of coins + DrawStdWindowFrame(sTextWindowId, FALSE); + AddTextPrinterParameterized(sTextWindowId, 1, Roulette_Text_NoCoinsLeft, 0, 1, TEXT_SPEED_FF, NULL); + CopyWindowToVram(sTextWindowId, 3); + StartTaskAfterDelayOrInput(taskId, Task_StopPlaying, 60, A_BUTTON | B_BUTTON); } } -static void dp01t_12_3_battle_menu(u8 taskId) +static void Task_ClearBoard(u8 taskId) { u8 i = 0; - gTasks[taskId].data[6] = 0; + gTasks[taskId].tBallNum = 0; sub_8141FF4(taskId); - sub_8142070(); - sub_8143A40(); - sub_81424FC(0); - sub_814372C(6); + ResetHits(); + HideBoardBalls(); + DrawGridBackground(SELECTION_NONE); + SetBallCounterNumLeft(BALLS_PER_ROUND); - for (i = 0; i < 12; i++) + for (i = 0; i < NUM_ROULETTE_SLOTS; i++) { - gSprites[gUnknown_0203AB88->var3C[i + 7]].invisible = FALSE; + gSprites[sRoulette->spriteIds[i + SPR_BOARD_ICONS]].invisible = FALSE; } - if (gTasks[taskId].data[13] == 9999) + if (gTasks[taskId].tCoins == MAX_COINS) { - DrawStdWindowFrame(gUnknown_0203AB8C, FALSE); - AddTextPrinterParameterized(gUnknown_0203AB8C, 1, Roulette_Text_CoinCaseIsFull, 0, 1, TEXT_SPEED_FF, NULL); - CopyWindowToVram(gUnknown_0203AB8C, 3); - sub_8141F7C(taskId, sub_8140914, 0xFFFF, 3); + DrawStdWindowFrame(sTextWindowId, FALSE); + AddTextPrinterParameterized(sTextWindowId, 1, Roulette_Text_CoinCaseIsFull, 0, 1, TEXT_SPEED_FF, NULL); + CopyWindowToVram(sTextWindowId, 3); + StartTaskAfterDelayOrInput(taskId, Task_AskKeepPlaying, 0xFFFF, A_BUTTON | B_BUTTON); } else { - gTasks[taskId].func = sub_8140914; + gTasks[taskId].func = Task_AskKeepPlaying; } } -static void sub_8141DE4(u8 taskId) +static void ExitRoulette(u8 taskId) { - sub_8151A9C(&gUnknown_0203AB88->varB8, 0xFFFF); - sub_8151678(&gUnknown_0203AB88->varB8); - SetCoins(gTasks[taskId].data[13]); - if (GetCoins() < gUnknown_0203AB88->var19) + sub_8151A9C(&sRoulette->varB8, 0xFFFF); + sub_8151678(&sRoulette->varB8); + SetCoins(gTasks[taskId].tCoins); + if (GetCoins() < sRoulette->minBet) gSpecialVar_0x8004 = TRUE; else gSpecialVar_0x8004 = FALSE; AlertTVOfNewCoinTotal(GetCoins()); BeginHardwarePaletteFade(0xFF, 0, 0, 16, 0); - gTasks[taskId].func = sub_8141E7C; + gTasks[taskId].func = Task_ExitRoulette; } -static void sub_8141E7C(u8 taskId) // end roulette ? +static void Task_ExitRoulette(u8 taskId) { if (UpdatePaletteFade() == 0) { @@ -1726,184 +1894,201 @@ static void sub_8141E7C(u8 taskId) // end roulette ? FreeAllSpritePalettes(); ResetPaletteFade(); ResetSpriteData(); - sub_8140418(); + FreeRoulette(); gFieldCallback = FieldCB_ContinueScriptHandleMusic; SetMainCallback2(CB2_ReturnToField); DestroyTask(taskId); } } -static void sub_8141EF8(u8 taskId) +static void Task_WaitForNextTask(u8 taskId) { - if (gUnknown_0203AB88->varA8 == 0 || gMain.newKeys & gUnknown_0203AB88->varAA) + if (sRoulette->taskWaitDelay == 0 || JOY_NEW(sRoulette->taskWaitKey)) { - gTasks[taskId].func = gUnknown_0203AB88->varAC; - if (gUnknown_0203AB88->varAA > 0) + gTasks[taskId].func = sRoulette->nextTask; + if (sRoulette->taskWaitKey > 0) PlaySE(SE_SELECT); - gUnknown_0203AB88->varAC = NULL; - gUnknown_0203AB88->varAA = 0; - gUnknown_0203AB88->varA8 = 0; + sRoulette->nextTask = NULL; + sRoulette->taskWaitKey = 0; + sRoulette->taskWaitDelay = 0; } - if (gUnknown_0203AB88->varA8 != 0xFFFF) - gUnknown_0203AB88->varA8--; + if (sRoulette->taskWaitDelay != 0xFFFF) + sRoulette->taskWaitDelay--; } -static void sub_8141F7C(u8 taskId, TaskFunc r1, u16 r2, u16 r3) +static void StartTaskAfterDelayOrInput(u8 taskId, TaskFunc task, u16 delay, u16 key) { - gUnknown_0203AB88->varB4 = gTasks[taskId].func; - if (r1 == NULL) - r1 = gUnknown_0203AB88->varB4; - gUnknown_0203AB88->varAC = r1; - gUnknown_0203AB88->varA8 = r2; - if (r2 == 0xFFFF && r3 == 0) - gUnknown_0203AB88->varAA = 0xFFFF; + sRoulette->varB4 = gTasks[taskId].func; + if (task == NULL) + task = sRoulette->varB4; + sRoulette->nextTask = task; + sRoulette->taskWaitDelay = delay; + if (delay == 0xFFFF && key == 0) + sRoulette->taskWaitKey = 0xFFFF; else - gUnknown_0203AB88->varAA = r3; - gTasks[taskId].func = sub_8141EF8; + sRoulette->taskWaitKey = key; + gTasks[taskId].func = Task_WaitForNextTask; } static void sub_8141FF4(u8 taskId) { u8 i = 0; - gUnknown_0203AB88->var00 = i; - gUnknown_0203AB88->var03_7 = 0; - gUnknown_0203AB88->var03_5 = 0; - gUnknown_0203AB88->var03_6 = 0; - gUnknown_0203AB88->var03_0 = 0; - for (i = 0; i < 6; i++) - { - gUnknown_0203AB88->var1B[i] = 0; - } - gUnknown_0203AB88->var1A_0 = 0; + sRoulette->var00 = i; + sRoulette->var03_7 = FALSE; + sRoulette->var03_5 = FALSE; + sRoulette->var03_6 = FALSE; + sRoulette->useTaillow = FALSE; + + for (i = 0; i < BALLS_PER_ROUND; i++) + sRoulette->betSelection[i] = SELECTION_NONE; + + sRoulette->curBallNum = 0; gTasks[taskId].data[1] = 0; } -static void sub_8142070(void) +static void ResetHits(void) { u8 i; - gUnknown_0203AB88->var08 = 0; - for (i = 0; i < 6; i++) - { - gUnknown_0203AB88->var0C[i] = 0; - } - for (i = 0; i < 4; i++) - { - gUnknown_0203AB88->var12[i] = 0; - } - for (i = 0; i < 3; i++) - { - gUnknown_0203AB88->var16[i] = 0; - } - sub_8143038(1, -1); + sRoulette->hitFlags = 0; + + for (i = 0; i < BALLS_PER_ROUND; i++) + sRoulette->hitSquares[i] = 0; + + for (i = 0; i < NUM_BOARD_POKES; i++) + sRoulette->pokeHits[i] = 0; + + for (i = 0; i < NUM_BOARD_COLORS; i++) + sRoulette->colorHits[i] = 0; + + ShowHideGridBalls(TRUE, -1); } -static u8 sub_81420D0(u8 taskId, u8 r1) +static u8 RecordHit(u8 taskId, u8 slotId) { - u8 i; - u8 z; - u32 t0[4] = {0x10842, 0x21084, 0x42108, 0x84210}; - u32 t1[3] = {0x3E0, 0x7C00, 0xF8000}; + u8 i, j; + u32 columnFlags[NUM_BOARD_POKES] = { + F_WYNAUT_COL | F_ORANGE_WYNAUT | F_GREEN_WYNAUT | F_PURPLE_WYNAUT, + F_AZURILL_COL | F_ORANGE_AZURILL | F_GREEN_AZURILL | F_PURPLE_AZURILL, + F_SKITTY_COL | F_ORANGE_SKITTY | F_GREEN_SKITTY | F_PURPLE_SKITTY, + F_MAKUHITA_COL | F_ORANGE_MAKUHITA | F_GREEN_MAKUHITA | F_PURPLE_MAKUHITA + }; + u32 rowFlags[NUM_BOARD_COLORS] = { + F_ORANGE_ROW | F_ORANGE_WYNAUT | F_ORANGE_AZURILL | F_ORANGE_SKITTY | F_ORANGE_MAKUHITA, + F_GREEN_ROW | F_GREEN_WYNAUT | F_GREEN_AZURILL | F_GREEN_SKITTY | F_GREEN_MAKUHITA, + F_PURPLE_ROW | F_PURPLE_WYNAUT | F_PURPLE_AZURILL | F_PURPLE_SKITTY | F_PURPLE_MAKUHITA + }; - if (r1 > 11) + if (slotId >= NUM_ROULETTE_SLOTS) return 0; - gUnknown_0203AB88->var0C[gTasks[taskId].data[6] - 1] = gUnknown_085B62E4[r1].var02; - gTasks[taskId].data[12] = gUnknown_085B62E4[r1].var02; - gUnknown_0203AB88->var08 |= gUnknown_085B62E4[r1].var04; - for (i = 0; i < 4; i++) + sRoulette->hitSquares[gTasks[taskId].tBallNum - 1] = sRouletteSlots[slotId].gridSquare; + gTasks[taskId].tWinningSquare = sRouletteSlots[slotId].gridSquare; + sRoulette->hitFlags |= sRouletteSlots[slotId].flag; + for (i = 0; i < NUM_BOARD_POKES; i++) { - if (gUnknown_085B62E4[r1].var04 & t0[i]) - gUnknown_0203AB88->var12[i]++; - if (gUnknown_0203AB88->var12[i] > 2) - gUnknown_0203AB88->var08 |= t0[i]; + if (sRouletteSlots[slotId].flag & columnFlags[i]) + sRoulette->pokeHits[i]++; + // If hit every color of a poke, set column completed + if (sRoulette->pokeHits[i] >= NUM_BOARD_COLORS) + sRoulette->hitFlags |= columnFlags[i]; } - for (z = 0; z < 3; z++) + for (j = 0; j < NUM_BOARD_COLORS; j++) { - if (gUnknown_085B62E4[r1].var04 & t1[z]) - gUnknown_0203AB88->var16[z]++; - if (gUnknown_0203AB88->var16[z] > 3) - gUnknown_0203AB88->var08 |= t1[z]; + if (sRouletteSlots[slotId].flag & rowFlags[j]) + sRoulette->colorHits[j]++; + // If hit every poke of a color, set row completed + if (sRoulette->colorHits[j] >= NUM_BOARD_POKES) + sRoulette->hitFlags |= rowFlags[j]; } - return gUnknown_085B62E4[r1].var02; + return sRouletteSlots[slotId].gridSquare; } -static bool8 sub_81421E8(u8 r0, u8 r1) +static bool8 IsHitInBetSelection(u8 gridSquare, u8 betSelection) { - u8 t = r0; - if (--r0 < 19) + u8 hit = gridSquare; + if (--gridSquare < NUM_GRID_SELECTIONS) { - switch (r1) + switch (betSelection) { - case 0: - return 3; - case 1 ... 4: - if (t == r1 + 5 || t == r1 + 10 || t == r1 + 15) + case SELECTION_NONE: + return 3; // should never happen, player must place bet + case COL_WYNAUT: + case COL_AZURILL: + case COL_SKITTY: + case COL_MAKUHITA: + if (hit == betSelection + ROW_ORANGE + || hit == betSelection + ROW_GREEN + || hit == betSelection + ROW_PURPLE) return TRUE; break; - case 5: - case 10: - case 15: - if (t >= (r1 + 1) && t <= (r1 + 4)) + case ROW_ORANGE: + case ROW_GREEN: + case ROW_PURPLE: + if (hit >= (betSelection + COL_WYNAUT) + && hit <= (betSelection + COL_MAKUHITA)) return TRUE; break; + // Individual square default: - if (t == r1) + if (hit == betSelection) return TRUE; } } return FALSE; } -static void sub_8142284(u8 r0) +static void FlashSelectionOnWheel(u8 selectionId) { - u16 var0 = 0; u8 var2; u16 var3; u8 i; - switch (r0) + switch (selectionId) { - case 5: - case 10: - case 15: - for (i = (r0 + 1); i < (r0 + 5); i++) + case ROW_ORANGE: + case ROW_GREEN: + case ROW_PURPLE: + for (i = (selectionId + 1); i < (selectionId + 5); i++) { - if (!(gUnknown_0203AB88->var08 & gUnknown_085B6154[i].var08)) - var0 |= gUnknown_085B6154[i].var10; + if (!(sRoulette->hitFlags & sGridSelections[i].flag)) + var0 |= sGridSelections[i].var10; } - sub_8151A48(&gUnknown_0203AB88->varB8, var0 &= 0xDFFF); + sub_8151A48(&sRoulette->varB8, var0 &= 0xDFFF); break; default: { struct UnkStruct1 var1[3]; memcpy(var1, gUnknown_085B63F0, sizeof(var1)); - if (r0 > 0 && r0 < 5) + if (selectionId >= COL_WYNAUT && selectionId <= COL_MAKUHITA) var2 = 3; else var2 = 1; - var3 = r0 / 5 - 1; - switch (r0 % 5) + + var3 = selectionId / 5 - 1; + switch (GET_COL(selectionId)) { - case 1: - var3 = gSprites[gUnknown_0203AB88->var3C[7]].oam.paletteNum * 16; - break; - case 2: - var3 = gSprites[gUnknown_0203AB88->var3C[8]].oam.paletteNum * 16; - break; - case 3: - var3 = gSprites[gUnknown_0203AB88->var3C[9]].oam.paletteNum * 16; - break; - case 4: - var3 = gSprites[gUnknown_0203AB88->var3C[10]].oam.paletteNum * 16; - break; + // The specific color of the poke it references doesn't matter, because the icons themelves all share a palette + // So it just uses the first sprite ID of each + case COL_WYNAUT: + var3 = gSprites[sRoulette->spriteIds[SPR_BOARD_ICON_ORANGE_WYNAUT]].oam.paletteNum * 16; + break; + case COL_AZURILL: + var3 = gSprites[sRoulette->spriteIds[SPR_BOARD_ICON_GREEN_AZURILL]].oam.paletteNum * 16; + break; + case COL_SKITTY: + var3 = gSprites[sRoulette->spriteIds[SPR_BOARD_ICON_PURPLE_SKITTY]].oam.paletteNum * 16; + break; + case COL_MAKUHITA: + var3 = gSprites[sRoulette->spriteIds[SPR_BOARD_ICON_ORANGE_MAKUHITA]].oam.paletteNum * 16; + break; } if (var2 == 1) { - if (!(gUnknown_0203AB88->var08 & gUnknown_085B6154[r0].var08)) + if (!(sRoulette->hitFlags & sGridSelections[selectionId].flag)) { - var1[r0 / 5 - 1].var02 += var3; - sub_815168C(&gUnknown_0203AB88->varB8, 13, &var1[r0 / 5 - 1]); + var1[selectionId / 5 - 1].var02 += var3; + sub_815168C(&sRoulette->varB8, 13, &var1[selectionId / 5 - 1]); } else { @@ -1914,26 +2099,26 @@ static void sub_8142284(u8 r0) { for (i = 0; i < 3; i++) { - u8 var4 = i * 5 + r0 + 5; - if (!(gUnknown_0203AB88->var08 & gUnknown_085B6154[var4].var08)) + u8 var4 = i * 5 + selectionId + 5; + if (!(sRoulette->hitFlags & sGridSelections[var4].flag)) { var1[var4 / 5 - 1].var02 += var3; - sub_815168C(&gUnknown_0203AB88->varB8, i + 13, &var1[var4 / 5 - 1]); + sub_815168C(&sRoulette->varB8, i + 13, &var1[var4 / 5 - 1]); if (var2 == 3) - var0 = gUnknown_085B6154[var4].var10; + var0 = sGridSelections[var4].var10; var2--; } } if (var2 != 2) var0 = 0; } - sub_8151A48(&gUnknown_0203AB88->varB8, var0 |= gUnknown_085B6154[r0].var10); + sub_8151A48(&sRoulette->varB8, var0 |= sGridSelections[selectionId].var10); break; } } } -static void sub_81424FC(u8 r0) +static void DrawGridBackground(u8 selectionId) { vu8 i; vu8 z; @@ -1942,69 +2127,77 @@ static void sub_81424FC(u8 r0) vu8 var0; u8 v[5]; u8 l; - gUnknown_0203AB88->var2A = 1; - sub_8142E70(0, 0); - sub_8152058(gUnknown_0203AB88->tilemapBuffers[2], gUnknown_0203AB88->unk_397C, 14, 7, 16, 13); - switch (r0) + sRoulette->var2A = 1; + ShowHideGridIcons(FALSE, 0); + SetGridSelectionRect(sRoulette->tilemapBuffers[2], sRoulette->unk_397C, 14, 7, 16, 13); + switch (selectionId) { - case 0: + case SELECTION_NONE: return; - case 1 ... 4: + case COL_WYNAUT: + case COL_AZURILL: + case COL_SKITTY: + case COL_MAKUHITA: l = 4; for (i = 0; i < l; i++) { - v[i] = i * 5 + r0; + v[i] = i * 5 + selectionId; } break; - case 5: - case 10: - case 15: + case ROW_ORANGE: + case ROW_GREEN: + case ROW_PURPLE: l = 5; for (i = 0; i < l; i++) { - v[i] = i + r0; + v[i] = i + selectionId; } break; + // Individual square default: l = 1; - v[0] = r0; + v[0] = selectionId; } for (i = 0; i < l; i++) { - var0 = gUnknown_085B6154[v[i]].var06; - var1 = gUnknown_085B6154[v[i]].var03; + var0 = sGridSelections[v[i]].var06; + var1 = sGridSelections[v[i]].x; for (z = 0; z < 3; z++) { - var2 = (gUnknown_085B6154[v[i]].var04 + z) * 32; - gUnknown_0203AB88->tilemapBuffers[2][var1 + var2 + 0] = gUnknown_0203AB88->unk_397C[(var0 + z) * 3 + 208]; - gUnknown_0203AB88->tilemapBuffers[2][var1 + var2 + 1] = gUnknown_0203AB88->unk_397C[(var0 + z) * 3 + 209]; - gUnknown_0203AB88->tilemapBuffers[2][var1 + var2 + 2] = gUnknown_0203AB88->unk_397C[(var0 + z) * 3 + 210]; + var2 = (sGridSelections[v[i]].y + z) * 32; + sRoulette->tilemapBuffers[2][var1 + var2 + 0] = sRoulette->unk_397C[(var0 + z) * 3 + 208]; + sRoulette->tilemapBuffers[2][var1 + var2 + 1] = sRoulette->unk_397C[(var0 + z) * 3 + 209]; + sRoulette->tilemapBuffers[2][var1 + var2 + 2] = sRoulette->unk_397C[(var0 + z) * 3 + 210]; } } } -static u8 sub_8142758(u8 r0) +static u8 GetMultiplier(u8 selectionId) { - u8 var0[5] = {0, 3, 4, 6, 12}; + u8 multipliers[5] = {0, 3, 4, 6, 12}; - if (r0 > 19) - r0 = 0; - switch (gUnknown_085B6154[r0].var01_0) + if (selectionId > NUM_GRID_SELECTIONS) + selectionId = 0; + + switch (sGridSelections[selectionId].baseMultiplier) { - case 3: - r0 = r0 / 5 - 1; - if (gUnknown_0203AB88->var16[r0] > 3) + case NUM_BOARD_COLORS: + selectionId = selectionId / 5 - 1; + // If already hit all pokes of this color, multiplier is 0 + if (sRoulette->colorHits[selectionId] >= NUM_BOARD_POKES) return 0; - return var0[gUnknown_0203AB88->var16[r0] + 1]; - case 4: - r0--; - if (gUnknown_0203AB88->var12[r0] > 2) + return multipliers[sRoulette->colorHits[selectionId] + 1]; + case NUM_BOARD_POKES: + selectionId--; + // If already hit all colors of this poke, multiplier is 0 + if (sRoulette->pokeHits[selectionId] >= NUM_BOARD_COLORS) return 0; - return var0[gUnknown_0203AB88->var12[r0] + 2]; - case 12: - if (gUnknown_0203AB88->var08 & gUnknown_085B6154[r0].var08) + return multipliers[sRoulette->pokeHits[selectionId] + 2]; + case NUM_ROULETTE_SLOTS: + // If square has been hit already, multiplier is 0 + if (sRoulette->hitFlags & sGridSelections[selectionId].flag) return 0; - return var0[4]; + return multipliers[4]; } return 0; } @@ -2013,59 +2206,59 @@ static void sub_8142814(void) { s32 x1; s32 x2; - SetGpuReg(REG_OFFSET_BG2PA, gUnknown_0203AB88->var2C.a); - SetGpuReg(REG_OFFSET_BG2PB, gUnknown_0203AB88->var2C.b); - SetGpuReg(REG_OFFSET_BG2PC, gUnknown_0203AB88->var2C.c); - SetGpuReg(REG_OFFSET_BG2PD, gUnknown_0203AB88->var2C.d); - x1 = 0x7400 - gUnknown_0203AB88->var2C.a * (gSpriteCoordOffsetX + 116) - - gUnknown_0203AB88->var2C.b * (gSpriteCoordOffsetY + 80); - x2 = 0x5400 - gUnknown_0203AB88->var2C.c * (gSpriteCoordOffsetX + 116) - - gUnknown_0203AB88->var2C.d * (gSpriteCoordOffsetY + 80); + SetGpuReg(REG_OFFSET_BG2PA, sRoulette->var2C.a); + SetGpuReg(REG_OFFSET_BG2PB, sRoulette->var2C.b); + SetGpuReg(REG_OFFSET_BG2PC, sRoulette->var2C.c); + SetGpuReg(REG_OFFSET_BG2PD, sRoulette->var2C.d); + x1 = 0x7400 - sRoulette->var2C.a * (gSpriteCoordOffsetX + 116) + - sRoulette->var2C.b * (gSpriteCoordOffsetY + 80); + x2 = 0x5400 - sRoulette->var2C.c * (gSpriteCoordOffsetX + 116) + - sRoulette->var2C.d * (gSpriteCoordOffsetY + 80); SetGpuReg(REG_OFFSET_BG2X_L, x1); SetGpuReg(REG_OFFSET_BG2X_H, (x1 & 0x0fff0000) >> 16); SetGpuReg(REG_OFFSET_BG2Y_L, x2); SetGpuReg(REG_OFFSET_BG2Y_H, (x2 & 0x0fff0000) >> 16); } -static const u8 sFiller_085B644D[3] = {}; -static const u16 RouletteSpritePalette_01[] = INCBIN_U16("graphics/roulette/shadow.gbapal"); -static const u16 RouletteSpritePalette_02[] = INCBIN_U16("graphics/roulette/ball.gbapal"); -static const u16 RouletteSpritePalette_03[] = INCBIN_U16("graphics/roulette/ball_counter.gbapal"); -static const u16 RouletteSpritePalette_04[] = INCBIN_U16("graphics/roulette/cursor.gbapal"); -static const u16 RouletteSpritePalette_05[] = INCBIN_U16("graphics/roulette/credit.gbapal"); -static const u16 RouletteSpritePalette_06[] = INCBIN_U16("graphics/roulette/shroomish.gbapal"); -static const u16 RouletteSpritePalette_07[] = INCBIN_U16("graphics/roulette/tailow.gbapal"); -static const u16 RouletteSpritePalette_08[] = INCBIN_U16("graphics/roulette/poke_icons.gbapal"); -static const u16 RouletteSpritePalette_09[] = INCBIN_U16("graphics/roulette/wynaut.gbapal"); -static const u16 RouletteSpritePalette_10[] = INCBIN_U16("graphics/roulette/azurill.gbapal"); -static const u16 RouletteSpritePalette_11[] = INCBIN_U16("graphics/roulette/skitty.gbapal"); -static const u16 RouletteSpritePalette_12[] = INCBIN_U16("graphics/roulette/makuhita.gbapal"); -static const u16 RouletteSpritePalette_13[] = INCBIN_U16("graphics/roulette/85B65D0.gbapal"); -static const u16 RouletteSpritePalette_14[] = INCBIN_U16("graphics/roulette/85B65F0.gbapal"); -static const u16 RouletteSpritePalette_15[] = INCBIN_U16("graphics/roulette/85B6610.gbapal"); -static const u16 RouletteSpritePalette_16[] = INCBIN_U16("graphics/roulette/85B6630.gbapal"); -static const u32 gUnknown_085B6650[] = INCBIN_U32("graphics/roulette/ball.4bpp.lz"); -static const u32 RouletteBallCounterTiles[] = INCBIN_U32("graphics/roulette/ball_counter.4bpp.lz"); -static const u32 gUnknown_085B67FC[] = INCBIN_U32("graphics/roulette/roulette_tilt.4bpp.lz"); -static const u32 RoulettePokeIconsTiles[] = INCBIN_U32("graphics/roulette/poke_icons.4bpp.lz"); -static const u32 RoulettePokeIcons2Tiles[] = INCBIN_U32("graphics/roulette/poke_icons2.4bpp.lz"); -static const u32 gUnknown_085B7290[] = INCBIN_U32("graphics/roulette/shadow.4bpp.lz"); -static const u32 RouletteCursorTiles[] = INCBIN_U32("graphics/roulette/cursor.4bpp.lz"); +static const u8 sFiller[3] = {}; +static const u16 sShadow_Pal[] = INCBIN_U16("graphics/roulette/shadow.gbapal"); +static const u16 sBall_Pal[] = INCBIN_U16("graphics/roulette/ball.gbapal"); +static const u16 sBallCounter_Pal[] = INCBIN_U16("graphics/roulette/ball_counter.gbapal"); +static const u16 sCursor_Pal[] = INCBIN_U16("graphics/roulette/cursor.gbapal"); +static const u16 sCredit_Pal[] = INCBIN_U16("graphics/roulette/credit.gbapal"); +static const u16 sShroomish_Pal[] = INCBIN_U16("graphics/roulette/shroomish.gbapal"); +static const u16 sTaillow_Pal[] = INCBIN_U16("graphics/roulette/tailow.gbapal"); +static const u16 sGridIcons_Pal[] = INCBIN_U16("graphics/roulette/grid_icons.gbapal"); +static const u16 sWynaut_Pal[] = INCBIN_U16("graphics/roulette/wynaut.gbapal"); +static const u16 sAzurill_Pal[] = INCBIN_U16("graphics/roulette/azurill.gbapal"); +static const u16 sSkitty_Pal[] = INCBIN_U16("graphics/roulette/skitty.gbapal"); +static const u16 sMakuhita_Pal[] = INCBIN_U16("graphics/roulette/makuhita.gbapal"); +static const u16 sUnused1_Pal[] = INCBIN_U16("graphics/roulette/unused_1.gbapal"); +static const u16 sUnused2_Pal[] = INCBIN_U16("graphics/roulette/unused_2.gbapal"); +static const u16 sUnused3_Pal[] = INCBIN_U16("graphics/roulette/unused_3.gbapal"); +static const u16 sUnused4_Pal[] = INCBIN_U16("graphics/roulette/unused_4.gbapal"); +static const u32 sBall_Gfx[] = INCBIN_U32("graphics/roulette/ball.4bpp.lz"); +static const u32 sBallCounter_Gfx[] = INCBIN_U32("graphics/roulette/ball_counter.4bpp.lz"); +static const u32 sShroomishTaillow_Gfx[] = INCBIN_U32("graphics/roulette/roulette_tilt.4bpp.lz"); +static const u32 sGridIcons_Gfx[] = INCBIN_U32("graphics/roulette/grid_icons.4bpp.lz"); +static const u32 sBoardIcons_Gfx[] = INCBIN_U32("graphics/roulette/board_icons.4bpp.lz"); +static const u32 sShadow_Gfx[] = INCBIN_U32("graphics/roulette/shadow.4bpp.lz"); +static const u32 sCursor_Gfx[] = INCBIN_U32("graphics/roulette/cursor.4bpp.lz"); -static const struct SpritePalette gUnknown_085B7384[] = +static const struct SpritePalette sSpritePalettes[] = { - { .data = RouletteSpritePalette_01, .tag = 1 }, - { .data = RouletteSpritePalette_02, .tag = 2 }, - { .data = RouletteSpritePalette_03, .tag = 3 }, - { .data = RouletteSpritePalette_04, .tag = 4 }, - { .data = RouletteSpritePalette_05, .tag = 5 }, - { .data = RouletteSpritePalette_06, .tag = 6 }, - { .data = RouletteSpritePalette_07, .tag = 7 }, - { .data = RouletteSpritePalette_08, .tag = 8 }, - { .data = RouletteSpritePalette_09, .tag = 9 }, - { .data = RouletteSpritePalette_10, .tag = 10 }, - { .data = RouletteSpritePalette_11, .tag = 11 }, - { .data = RouletteSpritePalette_12, .tag = 12 }, + { .data = sShadow_Pal, .tag = PALTAG_SHADOW }, + { .data = sBall_Pal, .tag = PALTAG_BALL }, + { .data = sBallCounter_Pal, .tag = PALTAG_BALL_COUNTER }, + { .data = sCursor_Pal, .tag = 4 }, + { .data = sCredit_Pal, .tag = PALTAG_INTERFACE }, + { .data = sShroomish_Pal, .tag = PALTAG_SHROOMISH }, + { .data = sTaillow_Pal, .tag = PALTAG_TAILLOW }, + { .data = sGridIcons_Pal, .tag = PALTAG_GRID_ICONS }, + { .data = sWynaut_Pal, .tag = PALTAG_WYNAUT }, + { .data = sAzurill_Pal, .tag = PALTAG_AZURILL }, + { .data = sSkitty_Pal, .tag = PALTAG_SKITTY }, + { .data = sMakuhita_Pal, .tag = PALTAG_MAKUHITA }, {} }; @@ -2078,7 +2271,7 @@ static const struct OamData gOamData_85B73EC = .priority = 1, }; -static const struct OamData gOamData_85B73F4 = +static const struct OamData sOam_GridIcon = { .affineMode = ST_OAM_AFFINE_OFF, .objMode = ST_OAM_OBJ_NORMAL, @@ -2087,7 +2280,7 @@ static const struct OamData gOamData_85B73F4 = .priority = 1, }; -static const struct OamData gOamData_85B73FC = +static const struct OamData sOam_BoardIcon = { .y = 60, .affineMode = ST_OAM_AFFINE_DOUBLE, @@ -2097,35 +2290,35 @@ static const struct OamData gOamData_85B73FC = .priority = 2, }; -static const union AnimCmd gSpriteAnim_85B7404[] = +static const union AnimCmd sAffineAnim_Unused1[] = { ANIMCMD_FRAME(0, 0), ANIMCMD_END }; -static const union AnimCmd *const gSpriteAnimTable_85B740C[] = +static const union AnimCmd *const sAffineAnims_Unused1[] = { - gSpriteAnim_85B7404 + sAffineAnim_Unused1 }; -static const union AffineAnimCmd gSpriteAffineAnim_85B7410[] = +static const union AffineAnimCmd sAffineAnim_Unused2[] = { AFFINEANIMCMD_END }; -static const union AffineAnimCmd *const gSpriteAffineAnimTable_85B7418[] = +static const union AffineAnimCmd *const sAffineAnims_Unused2[] = { - gSpriteAffineAnim_85B7410 + sAffineAnim_Unused2 }; -static const struct CompressedSpriteSheet gUnknown_085B741C = +static const struct CompressedSpriteSheet sSpriteSheet_BoardIcons = { - .data = RoulettePokeIcons2Tiles, + .data = sBoardIcons_Gfx, .size = 0xC00, - .tag = 0 + .tag = GFXTAG_BOARD_ICONS }; -static const union AnimCmd gSpriteAnim_85B7420[] = +static const union AnimCmd sAnim_BoardIcons[] = { ANIMCMD_FRAME(0, 0), ANIMCMD_FRAME(32, 0), @@ -2142,81 +2335,81 @@ static const union AnimCmd gSpriteAnim_85B7420[] = ANIMCMD_END }; -static const union AnimCmd *const gSpriteAnimTable_85B7458[] = +static const union AnimCmd *const sAnim_BoardIcon_OrangeWynaut[] = { - &gSpriteAnim_85B7420[0] + &sAnim_BoardIcons[0] }; -static const union AnimCmd *const gSpriteAnimTable_85B745C[] = +static const union AnimCmd *const sAnim_BoardIcon_GreenAzurill[] = { - &gSpriteAnim_85B7420[1] + &sAnim_BoardIcons[1] }; -static const union AnimCmd *const gSpriteAnimTable_85B7460[] = +static const union AnimCmd *const sAnim_BoardIcon_PurpleSkitty[] = { - &gSpriteAnim_85B7420[2] + &sAnim_BoardIcons[2] }; -static const union AnimCmd *const gSpriteAnimTable_85B7464[] = +static const union AnimCmd *const sAnim_BoardIcon_OrangeMakuhita[] = { - &gSpriteAnim_85B7420[3] + &sAnim_BoardIcons[3] }; -static const union AnimCmd *const gSpriteAnimTable_85B7468[] = +static const union AnimCmd *const sAnim_BoardIcon_GreenWynaut[] = { - &gSpriteAnim_85B7420[4] + &sAnim_BoardIcons[4] }; -static const union AnimCmd *const gSpriteAnimTable_85B746C[] = +static const union AnimCmd *const sAnim_BoardIcon_PurpleAzurill[] = { - &gSpriteAnim_85B7420[5] + &sAnim_BoardIcons[5] }; -static const union AnimCmd *const gSpriteAnimTable_85B7470[] = +static const union AnimCmd *const sAnim_BoardIcon_OrangeSkitty[] = { - &gSpriteAnim_85B7420[6] + &sAnim_BoardIcons[6] }; -static const union AnimCmd *const gSpriteAnimTable_85B7474[] = +static const union AnimCmd *const sAnim_BoardIcon_GreenMakuhita[] = { - &gSpriteAnim_85B7420[7] + &sAnim_BoardIcons[7] }; -static const union AnimCmd *const gSpriteAnimTable_85B7478[] = +static const union AnimCmd *const sAnim_BoardIcon_PurpleWynaut[] = { - &gSpriteAnim_85B7420[8] + &sAnim_BoardIcons[8] }; -static const union AnimCmd *const gSpriteAnimTable_85B747C[] = +static const union AnimCmd *const sAnim_BoardIcon_OrangeAzurill[] = { - &gSpriteAnim_85B7420[9] + &sAnim_BoardIcons[9] }; -static const union AnimCmd *const gSpriteAnimTable_85B7480[] = +static const union AnimCmd *const sAnim_BoardIcon_GreenSkitty[] = { - &gSpriteAnim_85B7420[10] + &sAnim_BoardIcons[10] }; -static const union AnimCmd *const gSpriteAnimTable_85B7484[] = +static const union AnimCmd *const sAnim_BoardIcon_PurpleMakuhita[] = { - &gSpriteAnim_85B7420[11] + &sAnim_BoardIcons[11] }; -static const struct CompressedSpriteSheet gUnknown_085B7488 = +static const struct CompressedSpriteSheet sSpriteSheet_Headers = { - .data = gRouletteHeadersTiles, + .data = gRouletteHeaders_Gfx, .size = 0x1600, - .tag = 4 + .tag = GFXTAG_HEADERS }; -static const struct CompressedSpriteSheet gUnknown_085B7490 = +static const struct CompressedSpriteSheet sSpriteSheet_PokeIcons = { - .data = RoulettePokeIconsTiles, + .data = sGridIcons_Gfx, .size = 0x400, - .tag = 5 + .tag = GFXTAG_GRID_ICONS }; -static const union AnimCmd gSpriteAnim_85B7498[] = +static const union AnimCmd sAnim_Headers[] = { ANIMCMD_FRAME(0, 0), ANIMCMD_FRAME(16, 0), @@ -2232,7 +2425,7 @@ static const union AnimCmd gSpriteAnim_85B7498[] = ANIMCMD_END }; -static const union AnimCmd gSpriteAnim_85B74C8[] = +static const union AnimCmd sAnim_GridIcons[] = { ANIMCMD_FRAME(0, 0), ANIMCMD_FRAME(4, 0), @@ -2241,285 +2434,287 @@ static const union AnimCmd gSpriteAnim_85B74C8[] = ANIMCMD_END }; -static const union AnimCmd *const gSpriteAnimTable_85B74DC[] = +static const union AnimCmd *const sAnim_WynautHeader[] = { - &gSpriteAnim_85B7498[0] + &sAnim_Headers[0] }; -static const union AnimCmd *const gSpriteAnimTable_85B74E0[] = +static const union AnimCmd *const sAnim_AzurillHeader[] = { - &gSpriteAnim_85B7498[2] + &sAnim_Headers[2] }; -static const union AnimCmd *const gSpriteAnimTable_85B74E4[] = +static const union AnimCmd *const sAnim_SkittyHeader[] = { - &gSpriteAnim_85B7498[4] + &sAnim_Headers[4] }; -static const union AnimCmd *const gSpriteAnimTable_85B74E8[] = +static const union AnimCmd *const sAnim_MakuhitaHeader[] = { - &gSpriteAnim_85B7498[6] + &sAnim_Headers[6] }; -static const union AnimCmd *const gSpriteAnimTable_85B74EC[] = +static const union AnimCmd *const sAnim_OrangeHeader[] = { - &gSpriteAnim_85B7498[8] + &sAnim_Headers[8] }; -static const union AnimCmd *const gSpriteAnimTable_85B74F0[] = +static const union AnimCmd *const sAnim_GreenHeader[] = { - &gSpriteAnim_85B7498[9] + &sAnim_Headers[9] }; -static const union AnimCmd *const gSpriteAnimTable_85B74F4[] = +static const union AnimCmd *const sAnim_PurpleHeader[] = { - &gSpriteAnim_85B7498[10] + &sAnim_Headers[10] }; -static const union AnimCmd *const gSpriteAnimTable_85B74F8[] = +static const union AnimCmd *const sAnim_GridIcon_Wynaut[] = { - &gSpriteAnim_85B74C8[0] + &sAnim_GridIcons[0] }; -static const union AnimCmd *const gSpriteAnimTable_85B74FC[] = +static const union AnimCmd *const sAnim_GridIcon_Azurill[] = { - &gSpriteAnim_85B74C8[1] + &sAnim_GridIcons[1] }; -static const union AnimCmd *const gSpriteAnimTable_85B7500[] = +static const union AnimCmd *const sAnim_GridIcon_Skitty[] = { - &gSpriteAnim_85B74C8[2] + &sAnim_GridIcons[2] }; -static const union AnimCmd *const gSpriteAnimTable_85B7504[] = +static const union AnimCmd *const sAnim_GridIcon_Makuhita[] = { - &gSpriteAnim_85B74C8[3] + &sAnim_GridIcons[3] }; -static const struct SpriteTemplate gSpriteTemplate_85B7508[] = +static const struct SpriteTemplate sSpriteTemplates_PokeHeaders[NUM_BOARD_POKES] = { { - .tileTag = 4, - .paletteTag = 8, + .tileTag = GFXTAG_HEADERS, + .paletteTag = PALTAG_GRID_ICONS, .oam = &gOamData_85B73EC, - .anims = gSpriteAnimTable_85B74DC, + .anims = sAnim_WynautHeader, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_814390C + .callback = SpriteCB_GridSquare }, { - .tileTag = 4, - .paletteTag = 8, + .tileTag = GFXTAG_HEADERS, + .paletteTag = PALTAG_GRID_ICONS, .oam = &gOamData_85B73EC, - .anims = gSpriteAnimTable_85B74E0, + .anims = sAnim_AzurillHeader, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_814390C + .callback = SpriteCB_GridSquare }, { - .tileTag = 4, - .paletteTag = 8, + .tileTag = GFXTAG_HEADERS, + .paletteTag = PALTAG_GRID_ICONS, .oam = &gOamData_85B73EC, - .anims = gSpriteAnimTable_85B74E4, + .anims = sAnim_SkittyHeader, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_814390C + .callback = SpriteCB_GridSquare }, { - .tileTag = 4, - .paletteTag = 8, + .tileTag = GFXTAG_HEADERS, + .paletteTag = PALTAG_GRID_ICONS, .oam = &gOamData_85B73EC, - .anims = gSpriteAnimTable_85B74E8, + .anims = sAnim_MakuhitaHeader, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_814390C + .callback = SpriteCB_GridSquare } }; -static const struct SpriteTemplate gSpriteTemplate_85B7568[] = +static const struct SpriteTemplate sSpriteTemplates_ColorHeaders[NUM_BOARD_COLORS] = { { - .tileTag = 4, - .paletteTag = 8, + .tileTag = GFXTAG_HEADERS, + .paletteTag = PALTAG_GRID_ICONS, .oam = &gOamData_85B73EC, - .anims = gSpriteAnimTable_85B74EC, + .anims = sAnim_OrangeHeader, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_814390C + .callback = SpriteCB_GridSquare }, { - .tileTag = 4, - .paletteTag = 8, + .tileTag = GFXTAG_HEADERS, + .paletteTag = PALTAG_GRID_ICONS, .oam = &gOamData_85B73EC, - .anims = gSpriteAnimTable_85B74F0, + .anims = sAnim_GreenHeader, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_814390C + .callback = SpriteCB_GridSquare }, { - .tileTag = 4, - .paletteTag = 8, + .tileTag = GFXTAG_HEADERS, + .paletteTag = PALTAG_GRID_ICONS, .oam = &gOamData_85B73EC, - .anims = gSpriteAnimTable_85B74F4, + .anims = sAnim_PurpleHeader, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_814390C + .callback = SpriteCB_GridSquare } }; -static const struct SpriteTemplate gSpriteTemplate_85B75B0[] = +static const struct SpriteTemplate sSpriteTemplate_GridIcons[NUM_BOARD_POKES] = { { - .tileTag = 5, - .paletteTag = 8, - .oam = &gOamData_85B73F4, - .anims = gSpriteAnimTable_85B74F8, + .tileTag = GFXTAG_GRID_ICONS, + .paletteTag = PALTAG_GRID_ICONS, + .oam = &sOam_GridIcon, + .anims = sAnim_GridIcon_Wynaut, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_814390C + .callback = SpriteCB_GridSquare }, { - .tileTag = 5, - .paletteTag = 8, - .oam = &gOamData_85B73F4, - .anims = gSpriteAnimTable_85B74FC, + .tileTag = GFXTAG_GRID_ICONS, + .paletteTag = PALTAG_GRID_ICONS, + .oam = &sOam_GridIcon, + .anims = sAnim_GridIcon_Azurill, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_814390C + .callback = SpriteCB_GridSquare }, { - .tileTag = 5, - .paletteTag = 8, - .oam = &gOamData_85B73F4, - .anims = gSpriteAnimTable_85B7500, + .tileTag = GFXTAG_GRID_ICONS, + .paletteTag = PALTAG_GRID_ICONS, + .oam = &sOam_GridIcon, + .anims = sAnim_GridIcon_Skitty, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_814390C + .callback = SpriteCB_GridSquare }, { - .tileTag = 5, - .paletteTag = 8, - .oam = &gOamData_85B73F4, - .anims = gSpriteAnimTable_85B7504, + .tileTag = GFXTAG_GRID_ICONS, + .paletteTag = PALTAG_GRID_ICONS, + .oam = &sOam_GridIcon, + .anims = sAnim_GridIcon_Makuhita, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_814390C + .callback = SpriteCB_GridSquare } }; -static const struct SpriteTemplate gSpriteTemplate_85B7610[] = +// Board icons are listed clockwise starting from 1 oclock on the roulette board (with pokeball upside right) +// They go Wynaut -> Azurill -> Skitty -> Makuhita, and Orange -> Green -> Purple +static const struct SpriteTemplate sSpriteTemplates_BoardIcons[NUM_ROULETTE_SLOTS] = { { - .tileTag = 0, - .paletteTag = 9, - .oam = &gOamData_85B73FC, - .anims = gSpriteAnimTable_85B7458, + .tileTag = GFXTAG_BOARD_ICONS, + .paletteTag = PALTAG_WYNAUT, + .oam = &sOam_BoardIcon, + .anims = sAnim_BoardIcon_OrangeWynaut, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_8143280 + .callback = SpriteCB_BoardIcon }, { - .tileTag = 0, - .paletteTag = 10, - .oam = &gOamData_85B73FC, - .anims = gSpriteAnimTable_85B745C, + .tileTag = GFXTAG_BOARD_ICONS, + .paletteTag = PALTAG_AZURILL, + .oam = &sOam_BoardIcon, + .anims = sAnim_BoardIcon_GreenAzurill, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_8143280 + .callback = SpriteCB_BoardIcon }, { - .tileTag = 0, - .paletteTag = 11, - .oam = &gOamData_85B73FC, - .anims = gSpriteAnimTable_85B7460, + .tileTag = GFXTAG_BOARD_ICONS, + .paletteTag = PALTAG_SKITTY, + .oam = &sOam_BoardIcon, + .anims = sAnim_BoardIcon_PurpleSkitty, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_8143280 + .callback = SpriteCB_BoardIcon }, { - .tileTag = 0, - .paletteTag = 12, - .oam = &gOamData_85B73FC, - .anims = gSpriteAnimTable_85B7464, + .tileTag = GFXTAG_BOARD_ICONS, + .paletteTag = PALTAG_MAKUHITA, + .oam = &sOam_BoardIcon, + .anims = sAnim_BoardIcon_OrangeMakuhita, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_8143280 + .callback = SpriteCB_BoardIcon }, { - .tileTag = 0, - .paletteTag = 9, - .oam = &gOamData_85B73FC, - .anims = gSpriteAnimTable_85B7468, + .tileTag = GFXTAG_BOARD_ICONS, + .paletteTag = PALTAG_WYNAUT, + .oam = &sOam_BoardIcon, + .anims = sAnim_BoardIcon_GreenWynaut, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_8143280 + .callback = SpriteCB_BoardIcon }, { - .tileTag = 0, - .paletteTag = 10, - .oam = &gOamData_85B73FC, - .anims = gSpriteAnimTable_85B746C, + .tileTag = GFXTAG_BOARD_ICONS, + .paletteTag = PALTAG_AZURILL, + .oam = &sOam_BoardIcon, + .anims = sAnim_BoardIcon_PurpleAzurill, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_8143280 + .callback = SpriteCB_BoardIcon }, { - .tileTag = 0, - .paletteTag = 11, - .oam = &gOamData_85B73FC, - .anims = gSpriteAnimTable_85B7470, + .tileTag = GFXTAG_BOARD_ICONS, + .paletteTag = PALTAG_SKITTY, + .oam = &sOam_BoardIcon, + .anims = sAnim_BoardIcon_OrangeSkitty, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_8143280 + .callback = SpriteCB_BoardIcon }, { - .tileTag = 0, - .paletteTag = 12, - .oam = &gOamData_85B73FC, - .anims = gSpriteAnimTable_85B7474, + .tileTag = GFXTAG_BOARD_ICONS, + .paletteTag = PALTAG_MAKUHITA, + .oam = &sOam_BoardIcon, + .anims = sAnim_BoardIcon_GreenMakuhita, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_8143280 + .callback = SpriteCB_BoardIcon }, { - .tileTag = 0, - .paletteTag = 9, - .oam = &gOamData_85B73FC, - .anims = gSpriteAnimTable_85B7478, + .tileTag = GFXTAG_BOARD_ICONS, + .paletteTag = PALTAG_WYNAUT, + .oam = &sOam_BoardIcon, + .anims = sAnim_BoardIcon_PurpleWynaut, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_8143280 + .callback = SpriteCB_BoardIcon }, { - .tileTag = 0, - .paletteTag = 10, - .oam = &gOamData_85B73FC, - .anims = gSpriteAnimTable_85B747C, + .tileTag = GFXTAG_BOARD_ICONS, + .paletteTag = PALTAG_AZURILL, + .oam = &sOam_BoardIcon, + .anims = sAnim_BoardIcon_OrangeAzurill, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_8143280 + .callback = SpriteCB_BoardIcon }, { - .tileTag = 0, - .paletteTag = 11, - .oam = &gOamData_85B73FC, - .anims = gSpriteAnimTable_85B7480, + .tileTag = GFXTAG_BOARD_ICONS, + .paletteTag = PALTAG_SKITTY, + .oam = &sOam_BoardIcon, + .anims = sAnim_BoardIcon_GreenSkitty, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_8143280 + .callback = SpriteCB_BoardIcon }, { - .tileTag = 0, - .paletteTag = 12, - .oam = &gOamData_85B73FC, - .anims = gSpriteAnimTable_85B7484, + .tileTag = GFXTAG_BOARD_ICONS, + .paletteTag = PALTAG_MAKUHITA, + .oam = &sOam_BoardIcon, + .anims = sAnim_BoardIcon_PurpleMakuhita, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_8143280 + .callback = SpriteCB_BoardIcon } }; -static const struct OamData gOamData_85B7730 = +static const struct OamData sOam_Credit = { .affineMode = ST_OAM_AFFINE_OFF, .objMode = ST_OAM_OBJ_NORMAL, @@ -2528,7 +2723,7 @@ static const struct OamData gOamData_85B7730 = .priority = 1, }; -static const struct OamData gOamData_85B7738 = +static const struct OamData sOam_CreditDigit = { .affineMode = ST_OAM_AFFINE_OFF, .objMode = ST_OAM_OBJ_NORMAL, @@ -2537,7 +2732,7 @@ static const struct OamData gOamData_85B7738 = .priority = 1, }; -static const struct OamData gOamData_85B7740 = +static const struct OamData sOam_Multiplier = { .affineMode = ST_OAM_AFFINE_OFF, .objMode = ST_OAM_OBJ_NORMAL, @@ -2546,7 +2741,7 @@ static const struct OamData gOamData_85B7740 = .priority = 1, }; -static const struct OamData gOamData_85B7748 = +static const struct OamData sOam_BallCounter = { .affineMode = ST_OAM_AFFINE_OFF, .objMode = ST_OAM_OBJ_NORMAL, @@ -2555,32 +2750,32 @@ static const struct OamData gOamData_85B7748 = .priority = 1, }; -static const struct CompressedSpriteSheet gUnknown_085B7750[] = +static const struct CompressedSpriteSheet sSpriteSheets_Interface[] = { { - .data = gRouletteCreditTiles, + .data = gRouletteCredit_Gfx, .size = 0x400, - .tag = 7 + .tag = GFXTAG_CREDIT }, { - .data = gRouletteNumbersTiles, + .data = gRouletteNumbers_Gfx, .size = 0x280, - .tag = 8 + .tag = GFXTAG_CREDIT_DIGIT }, { - .data = gRouletteMultiplierTiles, + .data = gRouletteMultiplier_Gfx, .size = 0x500, - .tag = 9 + .tag = GFXTAG_MULTIPLIER }, { - .data = RouletteBallCounterTiles, + .data = sBallCounter_Gfx, .size = 0x140, - .tag = 10 + .tag = GFXTAG_BALL_COUNTER }, { - .data = RouletteCursorTiles, + .data = sCursor_Gfx, .size = 0x200, - .tag = 11 + .tag = GFXTAG_CURSOR }, {} }; @@ -2606,7 +2801,7 @@ static const union AnimCmd *const gSpriteAnimTable_85B77A8[] = gSpriteAnim_85B7780 }; -static const union AnimCmd gSpriteAnim_85B77AC[] = +static const union AnimCmd sAnim_Multiplier[] = { ANIMCMD_FRAME(0, 0), ANIMCMD_FRAME(8, 0), @@ -2616,12 +2811,12 @@ static const union AnimCmd gSpriteAnim_85B77AC[] = ANIMCMD_END }; -static const union AnimCmd *const gSpriteAnimTable_85B77C4[] = +static const union AnimCmd *const sAnims_Multiplier[] = { - gSpriteAnim_85B77AC + sAnim_Multiplier }; -static const union AnimCmd gSpriteAnim_85B77C8[] = +static const union AnimCmd sAnim_BallCounter[] = { ANIMCMD_FRAME(0, 0), ANIMCMD_FRAME(2, 0), @@ -2631,59 +2826,60 @@ static const union AnimCmd gSpriteAnim_85B77C8[] = ANIMCMD_END }; -static const union AnimCmd *const gSpriteAnimTable_85B77E0[] = +static const union AnimCmd *const sAnims_BallCounter[] = { - gSpriteAnim_85B77C8 + sAnim_BallCounter }; -static const struct SpriteTemplate gSpriteTemplate_85B77E4 = +static const struct SpriteTemplate sSpriteTemplate_Credit = { - .tileTag = 7, - .paletteTag = 5, - .oam = &gOamData_85B7730, + .tileTag = GFXTAG_CREDIT, + .paletteTag = PALTAG_INTERFACE, + .oam = &sOam_Credit, .anims = gDummySpriteAnimTable, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = SpriteCallbackDummy }; -static const struct SpriteTemplate gUnknown_085B77FC = +static const struct SpriteTemplate sSpriteTemplate_CreditDigit = { - .tileTag = 8, - .paletteTag = 5, - .oam = &gOamData_85B7738, + .tileTag = GFXTAG_CREDIT_DIGIT, + .paletteTag = PALTAG_INTERFACE, + .oam = &sOam_CreditDigit, .anims = gSpriteAnimTable_85B77A8, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = SpriteCallbackDummy }; -static const struct SpriteTemplate gUnknown_085B7814 = +static const struct SpriteTemplate sSpriteTemplate_Multiplier = { - .tileTag = 9, - .paletteTag = 5, - .oam = &gOamData_85B7740, - .anims = gSpriteAnimTable_85B77C4, + .tileTag = GFXTAG_MULTIPLIER, + .paletteTag = PALTAG_INTERFACE, + .oam = &sOam_Multiplier, + .anims = sAnims_Multiplier, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_814390C + .callback = SpriteCB_GridSquare }; -static const struct SpriteTemplate gUnknown_085B782C = +static const struct SpriteTemplate sSpriteTemplate_BallCounter = { - .tileTag = 10, - .paletteTag = 3, - .oam = &gOamData_85B7748, - .anims = gSpriteAnimTable_85B77E0, + .tileTag = GFXTAG_BALL_COUNTER, + .paletteTag = PALTAG_BALL_COUNTER, + .oam = &sOam_BallCounter, + .anims = sAnims_BallCounter, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = SpriteCallbackDummy }; -static const struct SpriteTemplate gUnknown_085B7844 = +// NOTE: This cursor is only used to identify the winning square on the grid +static const struct SpriteTemplate sSpriteTemplate_Cursor = { - .tileTag = 11, - .paletteTag = 5, + .tileTag = GFXTAG_CURSOR, + .paletteTag = PALTAG_INTERFACE, .oam = &gOamData_85B73EC, .anims = gDummySpriteAnimTable, .images = NULL, @@ -2691,7 +2887,7 @@ static const struct SpriteTemplate gUnknown_085B7844 = .callback = SpriteCallbackDummy }; -static const struct OamData gOamData_85B785C = +static const struct OamData sOam_Ball = { .affineMode = ST_OAM_AFFINE_OFF, .objMode = ST_OAM_OBJ_NORMAL, @@ -2700,10 +2896,10 @@ static const struct OamData gOamData_85B785C = .priority = 2, }; -static const struct CompressedSpriteSheet gUnknown_085B7864 = { - .data = gUnknown_085B6650, +static const struct CompressedSpriteSheet sSpriteSheet_Ball = { + .data = sBall_Gfx, .size = 0x200, - .tag = 12 + .tag = GFXTAG_BALL }; static const union AnimCmd gSpriteAnim_85B786C[] = @@ -2776,7 +2972,7 @@ static const union AnimCmd gSpriteAnim_85B78F0[] = ANIMCMD_END }; -static const union AnimCmd *const gSpriteAnimTable_85B7904[] = +static const union AnimCmd *const sAnims_Ball[] = { gSpriteAnim_85B786C, gSpriteAnim_85B7880, @@ -2789,18 +2985,18 @@ static const union AnimCmd *const gSpriteAnimTable_85B7904[] = gSpriteAnim_85B78E8 }; -static const struct SpriteTemplate gSpriteTemplate_85B7928 = +static const struct SpriteTemplate sSpriteTemplate_Ball = { - .tileTag = 12, - .paletteTag = 2, - .oam = &gOamData_85B785C, - .anims = gSpriteAnimTable_85B7904, + .tileTag = GFXTAG_BALL, + .paletteTag = PALTAG_BALL, + .oam = &sOam_Ball, + .anims = sAnims_Ball, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = SpriteCallbackDummy }; -static const struct OamData gOamData_85B7940 = +static const struct OamData sOam_BoardCenter = { .y = 81, .affineMode = ST_OAM_AFFINE_DOUBLE, @@ -2810,25 +3006,25 @@ static const struct OamData gOamData_85B7940 = .priority = 2, }; -static const struct CompressedSpriteSheet gUnknown_085B7948 = +static const struct CompressedSpriteSheet sSpriteSheet_BoardCenter = { .data = gRouletteCenter_Gfx, .size = 0x800, - .tag = 6 + .tag = GFXTAG_BOARD_CENTER }; -static const struct SpriteTemplate gSpriteTemplate_85B7950 = +static const struct SpriteTemplate sSpriteTemplate_BoardCenter = { - .tileTag = 6, - .paletteTag = 2, - .oam = &gOamData_85B7940, + .tileTag = GFXTAG_BOARD_CENTER, + .paletteTag = PALTAG_BALL, + .oam = &sOam_BoardCenter, .anims = gDummySpriteAnimTable, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_814399C + .callback = SpriteCB_BoardCenter }; -static const struct OamData gOamData_85B7968 = +static const struct OamData sOam_Shroomish = { .affineMode = ST_OAM_AFFINE_OFF, .objMode = ST_OAM_OBJ_NORMAL, @@ -2837,7 +3033,7 @@ static const struct OamData gOamData_85B7968 = .priority = 2, }; -static const struct OamData gOamData_85B7970 = +static const struct OamData sOam_Taillow = { .affineMode = ST_OAM_AFFINE_OFF, .objMode = ST_OAM_OBJ_NORMAL, @@ -2846,14 +3042,14 @@ static const struct OamData gOamData_85B7970 = .priority = 2, }; -static const struct CompressedSpriteSheet gUnknown_085B7978 = +static const struct CompressedSpriteSheet sSpriteSheet_ShroomishTaillow = { - .data = gUnknown_085B67FC, + .data = sShroomishTaillow_Gfx, .size = 0xE00, - .tag = 13 + .tag = GFXTAG_SHROOMISH_TAILLOW }; -static const union AnimCmd gSpriteAnim_85B7980[] = +static const union AnimCmd sAnim_Shroomish[] = { ANIMCMD_FRAME(0, 6), ANIMCMD_FRAME(16, 6), @@ -2904,12 +3100,12 @@ static const union AnimCmd gSpriteAnim_85B79D0[] = ANIMCMD_JUMP(0) }; -static const union AnimCmd *const gSpriteAnimTable_85B79DC[] = +static const union AnimCmd *const sAnims_Shroomish[] = { - gSpriteAnim_85B7980 + sAnim_Shroomish }; -static const union AnimCmd *const gSpriteAnimTable_85B79E0[] = +static const union AnimCmd *const sAnims_Taillow[] = { gSpriteAnim_85B799C, gSpriteAnim_85B79A4, @@ -2919,26 +3115,26 @@ static const union AnimCmd *const gSpriteAnimTable_85B79E0[] = gSpriteAnim_85B79D0 }; -static const struct SpriteTemplate gSpriteTemplate_85B79F8 = +static const struct SpriteTemplate sSpriteTemplate_Shroomish = { - .tileTag = 13, - .paletteTag = 6, - .oam = &gOamData_85B7968, - .anims = gSpriteAnimTable_85B79DC, + .tileTag = GFXTAG_SHROOMISH_TAILLOW, + .paletteTag = PALTAG_SHROOMISH, + .oam = &sOam_Shroomish, + .anims = sAnims_Shroomish, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = SpriteCallbackDummy }; -static const struct SpriteTemplate gSpriteTemplate_85B7A10 = +static const struct SpriteTemplate sSpriteTemplate_Taillow = { - .tileTag = 13, - .paletteTag = 7, - .oam = &gOamData_85B7970, - .anims = gSpriteAnimTable_85B79E0, + .tileTag = GFXTAG_SHROOMISH_TAILLOW, + .paletteTag = PALTAG_TAILLOW, + .oam = &sOam_Taillow, + .anims = sAnims_Taillow, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_8145294 + .callback = SpriteCB_Taillow }; static const struct OamData gOamData_85B7A28 = @@ -2959,7 +3155,7 @@ static const struct OamData gOamData_85B7A30 = .priority = 2, }; -static const struct OamData gOamData_85B7A38 = +static const struct OamData sOam_TaillowShadow = { .affineMode = ST_OAM_AFFINE_NORMAL, .objMode = ST_OAM_OBJ_NORMAL, @@ -2968,11 +3164,11 @@ static const struct OamData gOamData_85B7A38 = .priority = 2, }; -static const struct CompressedSpriteSheet gUnknown_085B7A40 = +static const struct CompressedSpriteSheet sSpriteSheet_Shadow = { - .data = gUnknown_085B7290, + .data = sShadow_Gfx, .size = 0x180, - .tag = 14 + .tag = GFXTAG_SHADOW }; static const union AffineAnimCmd gSpriteAffineAnim_85B7A48[] = @@ -2982,7 +3178,7 @@ static const union AffineAnimCmd gSpriteAffineAnim_85B7A48[] = AFFINEANIMCMD_END }; -static const union AffineAnimCmd gSpriteAffineAnim_85B7A60[] = +static const union AffineAnimCmd sAffineAnim_TaillowShadow[] = { AFFINEANIMCMD_FRAME(0x100, 0x100, 0, 0), AFFINEANIMCMD_FRAME(-2, 0x0, 0, 15), @@ -2996,9 +3192,9 @@ static const union AffineAnimCmd *const gSpriteAffineAnimTable_85B7A88[] = gSpriteAffineAnim_85B7A48 }; -static const union AffineAnimCmd *const gSpriteAffineAnimTable_85B7A8C[] = +static const union AffineAnimCmd *const sAffineAnims_TaillowShadow[] = { - gSpriteAffineAnim_85B7A60 + sAffineAnim_TaillowShadow }; static const union AffineAnimCmd gSpriteAffineAnim_85B7A90[] = @@ -3034,11 +3230,11 @@ static const union AnimCmd *const gSpriteAnimTable_85B7AB8[] = gSpriteAnim_85B7AAC }; -static const struct SpriteTemplate gSpriteTemplate_85B7ABC[] = +static const struct SpriteTemplate sSpriteTemplate_ShroomishShadow[] = { { - .tileTag = 14, - .paletteTag = 1, + .tileTag = GFXTAG_SHADOW, + .paletteTag = PALTAG_SHADOW, .oam = &gOamData_85B7A28, .anims = gSpriteAnimTable_85B7AB4, .images = NULL, @@ -3046,8 +3242,8 @@ static const struct SpriteTemplate gSpriteTemplate_85B7ABC[] = .callback = SpriteCallbackDummy }, { - .tileTag = 14, - .paletteTag = 1, + .tileTag = GFXTAG_SHADOW, + .paletteTag = PALTAG_SHADOW, .oam = &gOamData_85B7A30, .anims = gSpriteAnimTable_85B7AB8, .images = NULL, @@ -3056,34 +3252,34 @@ static const struct SpriteTemplate gSpriteTemplate_85B7ABC[] = } }; -static const struct SpriteTemplate gUnknown_085B7AEC = +static const struct SpriteTemplate sSpriteTemplate_TaillowShadow = { - .tileTag = 14, - .paletteTag = 1, - .oam = &gOamData_85B7A38, + .tileTag = GFXTAG_SHADOW, + .paletteTag = PALTAG_SHADOW, + .oam = &sOam_TaillowShadow, .anims = gSpriteAnimTable_85B7AB8, .images = NULL, - .affineAnims = gSpriteAffineAnimTable_85B7A8C, - .callback = sub_8145294 + .affineAnims = sAffineAnims_TaillowShadow, + .callback = SpriteCB_Taillow }; -static void sub_81428C4(u8 r0) +static void Task_ShowMinBetYesNo(u8 taskId) { DisplayYesNoMenuDefaultYes(); - DoYesNoFuncWithChoice(r0, &gUnknown_085B6408); + DoYesNoFuncWithChoice(taskId, &sYesNoTable_AcceptMinBet); } -static void sub_81428E4(u8 taskId) +static void Task_FadeToRouletteGame(u8 taskId) { if (!gPaletteFade.active) { SetVBlankCallback(NULL); - SetMainCallback2(sub_81405CC); + SetMainCallback2(CB2_LoadRoulette); DestroyTask(taskId); } } -static void sub_8142918(u8 taskId) +static void Task_AcceptMinBet(u8 taskId) { ClearStdWindowAndFrame(0, TRUE); HideCoinsWindow(); @@ -3091,10 +3287,10 @@ static void sub_8142918(u8 taskId) BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB_BLACK); gPaletteFade.delayCounter = gPaletteFade.multipurpose2; UpdatePaletteFade(); - gTasks[taskId].func = sub_81428E4; + gTasks[taskId].func = Task_FadeToRouletteGame; } -static void sub_814297C(u8 taskId) +static void Task_DeclineMinBet(u8 taskId) { ClearStdWindowAndFrame(0, FALSE); HideCoinsWindow(); @@ -3102,10 +3298,10 @@ static void sub_814297C(u8 taskId) DestroyTask(taskId); } -static void sub_81429A0(u8 taskId) +static void Task_NotEnoughForMinBet(u8 taskId) { gTasks[taskId].data[0]++; - if (gMain.newKeys & (A_BUTTON | B_BUTTON)) + if (JOY_NEW(A_BUTTON | B_BUTTON)) { gSpecialVar_0x8004 = 1; HideCoinsWindow(); @@ -3115,52 +3311,56 @@ static void sub_81429A0(u8 taskId) } } -static void sub_81429F0(u8 taskId) +static void Task_PrintMinBet(u8 taskId) { - if (gMain.newKeys & (A_BUTTON | B_BUTTON)) + if (JOY_NEW(A_BUTTON | B_BUTTON)) { - u32 temp = gUnknown_085B6344[(gSpecialVar_0x8004 & 1) + (gSpecialVar_0x8004 >> 7 << 1)]; - ConvertIntToDecimalStringN(gStringVar1, temp, STR_CONV_MODE_LEADING_ZEROS, 1); + u32 minBet = sTableMinBets[GET_TABLE_ID(gSpecialVar_0x8004)]; + ConvertIntToDecimalStringN(gStringVar1, minBet, STR_CONV_MODE_LEADING_ZEROS, 1); StringExpandPlaceholders(gStringVar4, Roulette_Text_PlayMinimumWagerIsX); DrawStdWindowFrame(0, FALSE); AddTextPrinterParameterized(0, 1, gStringVar4, 0, 1, TEXT_SPEED_FF, NULL); CopyWindowToVram(0, 3); - gTasks[taskId].func = sub_81428C4; + gTasks[taskId].func = Task_ShowMinBetYesNo; } } -static void Task_Roulette_0(u8 taskId) +static void Task_PrintRouletteEntryMsg(u8 taskId) { - s32 temp; - PrintCoinsString(gTasks[taskId].data[13]); - temp = gUnknown_085B6344[(gSpecialVar_0x8004 & 1) + (gSpecialVar_0x8004 >> 7 << 1)]; - ConvertIntToDecimalStringN(gStringVar1, temp, STR_CONV_MODE_LEADING_ZEROS, 1); - if (gTasks[taskId].data[13] >= temp) + s32 minBet; + PrintCoinsString(gTasks[taskId].tCoins); + minBet = sTableMinBets[GET_TABLE_ID(gSpecialVar_0x8004)]; + ConvertIntToDecimalStringN(gStringVar1, minBet, STR_CONV_MODE_LEADING_ZEROS, 1); + + if (gTasks[taskId].tCoins >= minBet) { - if ((gSpecialVar_0x8004 & 0x80) && (gSpecialVar_0x8004 & 1)) + if ((gSpecialVar_0x8004 & ROULETTE_SPECIAL_RATE) && (gSpecialVar_0x8004 & 1)) { + // Special rate for Game Corner service day (only at second table) DrawStdWindowFrame(0, FALSE); AddTextPrinterParameterized(0, 1, Roulette_Text_SpecialRateTable, 0, 1, TEXT_SPEED_FF, NULL); CopyWindowToVram(0, 3); - gTasks[taskId].func = sub_81429F0; + gTasks[taskId].func = Task_PrintMinBet; } else { + // Print minimum bet StringExpandPlaceholders(gStringVar4, Roulette_Text_PlayMinimumWagerIsX); DrawStdWindowFrame(0, FALSE); AddTextPrinterParameterized(0, 1, gStringVar4, 0, 1, TEXT_SPEED_FF, NULL); CopyWindowToVram(0, 3); - gTasks[taskId].func = sub_81428C4; + gTasks[taskId].func = Task_ShowMinBetYesNo; } } else { + // Not enough for minimum bet StringExpandPlaceholders(gStringVar4, Roulette_Text_NotEnoughCoins); DrawStdWindowFrame(0, FALSE); AddTextPrinterParameterized(0, 1, gStringVar4, 0, 1, TEXT_SPEED_FF, NULL); CopyWindowToVram(0, 3); - gTasks[taskId].func = sub_81429A0; - gTasks[taskId].data[13] = 0; + gTasks[taskId].func = Task_NotEnoughForMinBet; + gTasks[taskId].tCoins = 0; gTasks[taskId].data[0] = 0; } } @@ -3171,38 +3371,39 @@ void PlayRoulette(void) ScriptContext2_Enable(); ShowCoinsWindow(GetCoins(), 1, 1); - taskId = CreateTask(Task_Roulette_0, 0); - gTasks[taskId].data[13] = GetCoins(); + taskId = CreateTask(Task_PrintRouletteEntryMsg, 0); + gTasks[taskId].tCoins = GetCoins(); } -static void sub_8142C0C(u8 r0) +static void LoadOrFreeMiscSpritePalettesAndSheets(bool8 free) { - if (!r0) + if (!free) { FreeAllSpritePalettes(); - LoadSpritePalettes(gUnknown_085B7384); - LoadCompressedSpriteSheet(&gUnknown_085B7864); - LoadCompressedSpriteSheet(&gUnknown_085B7978); - LoadCompressedSpriteSheet(&gUnknown_085B7A40); + LoadSpritePalettes(sSpritePalettes); + LoadCompressedSpriteSheet(&sSpriteSheet_Ball); + LoadCompressedSpriteSheet(&sSpriteSheet_ShroomishTaillow); + LoadCompressedSpriteSheet(&sSpriteSheet_Shadow); } else { - FreeSpriteTilesByTag(14); - FreeSpriteTilesByTag(13); - FreeSpriteTilesByTag(12); + // Unused + FreeSpriteTilesByTag(GFXTAG_SHADOW); + FreeSpriteTilesByTag(GFXTAG_SHROOMISH_TAILLOW); + FreeSpriteTilesByTag(GFXTAG_BALL); FreeAllSpritePalettes(); } } -static u8 sub_8142C60(const struct SpriteTemplate *r0, u8 r1, u16 *r2) +static u8 CreateBoardIconSprite(const struct SpriteTemplate *r0, u8 r1, u16 *r2) { u16 temp; u8 spriteId = CreateSprite(r0, 116, 80, r0->oam->y); - gSprites[spriteId].data[0] = *r2; - gSprites[spriteId].data[1] = r1; + gSprites[spriteId].data[0] = *r2; + gSprites[spriteId].data[1] = r1; gSprites[spriteId].coordOffsetEnabled = TRUE; - gSprites[spriteId].animPaused = TRUE; - gSprites[spriteId].affineAnimPaused = TRUE; + gSprites[spriteId].animPaused = TRUE; + gSprites[spriteId].affineAnimPaused = TRUE; temp = *r2; *r2 += 30; if (*r2 >= 360) @@ -3210,170 +3411,173 @@ static u8 sub_8142C60(const struct SpriteTemplate *r0, u8 r1, u16 *r2) return spriteId; } -static void sub_8142CD0(void) +static void CreateGridSprites(void) { u8 i, j; u8 spriteId; struct SpriteSheet s; - LZ77UnCompWram(gUnknown_085B7488.data, gDecompressionBuffer); + LZ77UnCompWram(sSpriteSheet_Headers.data, gDecompressionBuffer); s.data = gDecompressionBuffer; - s.size = gUnknown_085B7488.size; - s.tag = gUnknown_085B7488.tag; + s.size = sSpriteSheet_Headers.size; + s.tag = sSpriteSheet_Headers.tag; LoadSpriteSheet(&s); - LZ77UnCompWram(gUnknown_085B7490.data, gDecompressionBuffer); + LZ77UnCompWram(sSpriteSheet_PokeIcons.data, gDecompressionBuffer); s.data = gDecompressionBuffer; - s.size = gUnknown_085B7490.size; - s.tag = gUnknown_085B7490.tag; + s.size = sSpriteSheet_PokeIcons.size; + s.tag = sSpriteSheet_PokeIcons.tag; LoadSpriteSheet(&s); - for (i = 0; i < 3; i++) + for (i = 0; i < NUM_BOARD_COLORS; i++) { u8 o = i * 24; - for (j = 0; j < 4; j++) + for (j = 0; j < NUM_BOARD_POKES; j++) { - spriteId = gUnknown_0203AB88->var3C[(i * 4) + 29 + j] = CreateSprite(&gSpriteTemplate_85B75B0[j], (j * 24) + 148, o + 92, 30); + spriteId = sRoulette->spriteIds[(i * NUM_BOARD_POKES) + SPR_GRID_ICONS + j] = CreateSprite(&sSpriteTemplate_GridIcons[j], (j * 24) + 148, o + 92, 30); gSprites[spriteId].animPaused = TRUE; o += 24; if (o >= 72) o = 0; } } - for (i = 0; i < 4; i++) + for (i = 0; i < ARRAY_COUNT(sSpriteTemplates_PokeHeaders); i++) { - spriteId = gUnknown_0203AB88->var3C[i + 41] = CreateSprite(&gSpriteTemplate_85B7508[i], (i * 24) + 148, 70, 30); + spriteId = sRoulette->spriteIds[i + SPR_POKE_HEADER_1] = CreateSprite(&sSpriteTemplates_PokeHeaders[i], (i * 24) + 148, 70, 30); gSprites[spriteId].animPaused = TRUE; } - for (i = 0; i < 3; i++) + for (i = 0; i < ARRAY_COUNT(sSpriteTemplates_ColorHeaders); i++) { - spriteId = gUnknown_0203AB88->var3C[i + 45] = CreateSprite(&gSpriteTemplate_85B7568[i], 126, (i * 24) + 92, 30); + spriteId = sRoulette->spriteIds[i + SPR_COLOR_HEADER_1] = CreateSprite(&sSpriteTemplates_ColorHeaders[i], 126, (i * 24) + 92, 30); gSprites[spriteId].animPaused = TRUE; } } -static void unref_sub_8142E3C(void) +// Unused +static void DestroyGridSprites(void) { u8 i; - for (i = 0; i < 12; i++) + for (i = 0; i < NUM_ROULETTE_SLOTS; i++) { - DestroySprite(&gSprites[gUnknown_0203AB88->var3C[i + 29]]); + DestroySprite(&gSprites[sRoulette->spriteIds[i + SPR_GRID_ICONS]]); } } -static void sub_8142E70(u8 r0, u8 r1) +static void ShowHideGridIcons(bool8 hideAll, u8 hideSquare) { u8 i; - switch (r0) + switch (hideAll) { - case 1: - for (i = 0; i < 19; i++) + case TRUE: + // Hide grid icons and headers + for (i = 0; i < NUM_GRID_SELECTIONS; i++) { - gSprites[gUnknown_0203AB88->var3C[i + 29]].invisible = TRUE; + gSprites[sRoulette->spriteIds[i + SPR_GRID_ICONS]].invisible = TRUE; } break; - case 0: - for (i = 0; i < 12; i++) + case FALSE: + for (i = 0; i < NUM_ROULETTE_SLOTS; i++) { - if (!(gUnknown_0203AB88->var08 & gUnknown_085B62E4[i].var04)) - gSprites[gUnknown_0203AB88->var3C[i + 29]].invisible = FALSE; - else if (gUnknown_085B62E4[i].var02 != r1) - gSprites[gUnknown_0203AB88->var3C[i + 29]].invisible = TRUE; + if (!(sRoulette->hitFlags & sRouletteSlots[i].flag)) + gSprites[sRoulette->spriteIds[i + SPR_GRID_ICONS]].invisible = FALSE; + else if (sRouletteSlots[i].gridSquare != hideSquare) + gSprites[sRoulette->spriteIds[i + SPR_GRID_ICONS]].invisible = TRUE; else - gSprites[gUnknown_0203AB88->var3C[i + 29]].invisible = FALSE; + gSprites[sRoulette->spriteIds[i + SPR_GRID_ICONS]].invisible = FALSE; } - for (; i < 19; i++) + // Always show grid headers + for (; i < NUM_GRID_SELECTIONS; i++) { - gSprites[gUnknown_0203AB88->var3C[i + 29]].invisible = FALSE; + gSprites[sRoulette->spriteIds[i + SPR_GRID_ICONS]].invisible = FALSE; } break; } } -static void sub_8142F7C(void) +static void CreateGridBallSprites(void) { u8 i; - for (i = 0; i < 6; i++) + for (i = 0; i < BALLS_PER_ROUND; i++) { - gUnknown_0203AB88->var3C[i + 49] = CreateSprite(&gSpriteTemplate_85B7928, 116, 20, 10); - gSprites[gUnknown_0203AB88->var3C[i + 49]].invisible = TRUE; - gSprites[gUnknown_0203AB88->var3C[i + 49]].data[0] = 1; - gSprites[gUnknown_0203AB88->var3C[i + 49]].callback = sub_814390C; - gSprites[gUnknown_0203AB88->var3C[i + 49]].oam.priority = 1; - StartSpriteAnim(&gSprites[gUnknown_0203AB88->var3C[i + 49]], 8); + sRoulette->spriteIds[i + SPR_GRID_BALL_1] = CreateSprite(&sSpriteTemplate_Ball, 116, 20, 10); + gSprites[sRoulette->spriteIds[i + SPR_GRID_BALL_1]].invisible = TRUE; + gSprites[sRoulette->spriteIds[i + SPR_GRID_BALL_1]].data[0] = 1; + gSprites[sRoulette->spriteIds[i + SPR_GRID_BALL_1]].callback = SpriteCB_GridSquare; + gSprites[sRoulette->spriteIds[i + SPR_GRID_BALL_1]].oam.priority = 1; + StartSpriteAnim(&gSprites[sRoulette->spriteIds[i + SPR_GRID_BALL_1]], 8); } } -static void sub_8143038(u8 r0, u8 r1) +static void ShowHideGridBalls(bool8 hideAll, u8 hideBallId) { u8 i = 0; - if (r0) + if (hideAll) { - for ( ; i < 6; i++) + for (; i < BALLS_PER_ROUND; i++) { - gSprites[gUnknown_0203AB88->var3C[i + 49]].invisible = TRUE; + gSprites[sRoulette->spriteIds[i + SPR_GRID_BALL_1]].invisible = TRUE; } } else { - for ( ; i < 6; i++) + for (; i < BALLS_PER_ROUND; i++) { - if (!gUnknown_0203AB88->var0C[i] || i == r1) + if (!sRoulette->hitSquares[i] || i == hideBallId) { - gSprites[gUnknown_0203AB88->var3C[i + 49]].invisible = TRUE; + gSprites[sRoulette->spriteIds[i + SPR_GRID_BALL_1]].invisible = TRUE; } else { - gSprites[gUnknown_0203AB88->var3C[i + 49]].invisible = FALSE; - gSprites[gUnknown_0203AB88->var3C[i + 49]].pos1.x = (gUnknown_085B6154[gUnknown_0203AB88->var0C[i]].var03 + 1) * 8 + 4; - gSprites[gUnknown_0203AB88->var3C[i + 49]].pos1.y = (gUnknown_085B6154[gUnknown_0203AB88->var0C[i]].var04 + 1) * 8 + 3; + gSprites[sRoulette->spriteIds[i + SPR_GRID_BALL_1]].invisible = FALSE; + gSprites[sRoulette->spriteIds[i + SPR_GRID_BALL_1]].pos1.x = (sGridSelections[sRoulette->hitSquares[i]].x + 1) * 8 + 4; + gSprites[sRoulette->spriteIds[i + SPR_GRID_BALL_1]].pos1.y = (sGridSelections[sRoulette->hitSquares[i]].y + 1) * 8 + 3; } } } } -static void sub_8143150(u8 r0) +static void ShowHideWinSlotCursor(u8 selectionId) { - if (!r0) + if (selectionId == 0) { - gSprites[gUnknown_0203AB88->var3C[48]].invisible = TRUE; + gSprites[sRoulette->spriteIds[SPR_WIN_SLOT_CURSOR]].invisible = TRUE; } else { - gSprites[gUnknown_0203AB88->var3C[48]].invisible = FALSE; - gSprites[gUnknown_0203AB88->var3C[48]].pos1.x = (gUnknown_085B6154[r0].var03 + 2) * 8; - gSprites[gUnknown_0203AB88->var3C[48]].pos1.y = (gUnknown_085B6154[r0].var04 + 2) * 8; + gSprites[sRoulette->spriteIds[SPR_WIN_SLOT_CURSOR]].invisible = FALSE; + gSprites[sRoulette->spriteIds[SPR_WIN_SLOT_CURSOR]].pos1.x = (sGridSelections[selectionId].x + 2) * 8; + gSprites[sRoulette->spriteIds[SPR_WIN_SLOT_CURSOR]].pos1.y = (sGridSelections[selectionId].y + 2) * 8; } } -static void sub_81431E4(void) +static void CreateBoardIconSprites(void) { u8 i, j; u16 k; struct SpriteSheet s; - LZ77UnCompWram(gUnknown_085B741C.data, gDecompressionBuffer); + LZ77UnCompWram(sSpriteSheet_BoardIcons.data, gDecompressionBuffer); s.data = gDecompressionBuffer; - s.size = gUnknown_085B741C.size; - s.tag = gUnknown_085B741C.tag; + s.size = sSpriteSheet_BoardIcons.size; + s.tag = sSpriteSheet_BoardIcons.tag; LoadSpriteSheet(&s); k = 15; - for (i = 0; i < 3; i++) + for (i = 0; i < NUM_BOARD_COLORS; i++) { - for (j = 0; j < 4; j++) + for (j = 0; j < NUM_BOARD_POKES; j++) { u8 spriteId; - spriteId = gUnknown_0203AB88->var3C[(i * 4) + 7 + j] = sub_8142C60(&gSpriteTemplate_85B7610[i * 4 + j], 40, &k); + spriteId = sRoulette->spriteIds[(i * NUM_BOARD_POKES) + SPR_BOARD_ICONS + j] = CreateBoardIconSprite(&sSpriteTemplates_BoardIcons[i * NUM_BOARD_POKES + j], 40, &k); gSprites[spriteId].animPaused = TRUE; gSprites[spriteId].affineAnimPaused = TRUE; } } } -static void sub_8143280(struct Sprite *sprite) +static void SpriteCB_BoardIcon(struct Sprite *sprite) { s16 cos; s16 sin; u32 matrixNum; - s16 angle = gUnknown_0203AB88->var24 + sprite->data[0]; + s16 angle = sRoulette->var24 + sprite->data[0]; if (angle >= 360) angle -= 360; sin = Sin2(angle); @@ -3388,55 +3592,56 @@ static void sub_8143280(struct Sprite *sprite) gOamMatrices[matrixNum].c = -sin; } -static void sub_8143314(void) +static void CreateInterfaceSprites(void) { u8 i; - for (i = 0; i < 5; i++) + for (i = 0; i < ARRAY_COUNT(sSpriteSheets_Interface) - 1; i++) { struct SpriteSheet s; - LZ77UnCompWram(gUnknown_085B7750[i].data, gDecompressionBuffer); + LZ77UnCompWram(sSpriteSheets_Interface[i].data, gDecompressionBuffer); s.data = gDecompressionBuffer; - s.size = gUnknown_085B7750[i].size; - s.tag = gUnknown_085B7750[i].tag; + s.size = sSpriteSheets_Interface[i].size; + s.tag = sSpriteSheets_Interface[i].tag; LoadSpriteSheet(&s); } - gUnknown_0203AB88->var3C[20] = CreateSprite(&gSpriteTemplate_85B77E4, 208, 16, 4); - gSprites[gUnknown_0203AB88->var3C[20]].animPaused = TRUE; - for (i = 0; i < 4; i++) + sRoulette->spriteIds[SPR_CREDIT] = CreateSprite(&sSpriteTemplate_Credit, 208, 16, 4); + gSprites[sRoulette->spriteIds[SPR_CREDIT]].animPaused = TRUE; + for (i = 0; i < MAX_COIN_DIGITS; i++) { - gUnknown_0203AB88->var3C[i + 21] = CreateSprite(&gUnknown_085B77FC, i * 8 + 196, 24, 0); - gSprites[gUnknown_0203AB88->var3C[i + 21]].invisible = TRUE; - gSprites[gUnknown_0203AB88->var3C[i + 21]].animPaused = TRUE; + sRoulette->spriteIds[i + SPR_CREDIT_DIG_1] = CreateSprite(&sSpriteTemplate_CreditDigit, i * 8 + 196, 24, 0); + gSprites[sRoulette->spriteIds[i + SPR_CREDIT_DIG_1]].invisible = TRUE; + gSprites[sRoulette->spriteIds[i + SPR_CREDIT_DIG_1]].animPaused = TRUE; } - gUnknown_0203AB88->var3C[25] = CreateSprite(&gUnknown_085B7814, 120, 68, 4); - gSprites[gUnknown_0203AB88->var3C[25]].animPaused = TRUE; - for (i = 0; i < 3; i++) + sRoulette->spriteIds[SPR_MULTIPLIER] = CreateSprite(&sSpriteTemplate_Multiplier, 120, 68, 4); + gSprites[sRoulette->spriteIds[SPR_MULTIPLIER]].animPaused = TRUE; + for (i = 0; i < BALLS_PER_ROUND / 2; i++) { - gUnknown_0203AB88->var3C[i + 26] = CreateSprite(&gUnknown_085B782C, i * 16 + 192, 36, 4); - gSprites[gUnknown_0203AB88->var3C[i + 26]].invisible = TRUE; - gSprites[gUnknown_0203AB88->var3C[i + 26]].animPaused = TRUE; + // Each ball counter sprite has 2 balls + sRoulette->spriteIds[i + SPR_BALL_COUNTER_1] = CreateSprite(&sSpriteTemplate_BallCounter, i * 16 + 192, 36, 4); + gSprites[sRoulette->spriteIds[i + SPR_BALL_COUNTER_1]].invisible = TRUE; + gSprites[sRoulette->spriteIds[i + SPR_BALL_COUNTER_1]].animPaused = TRUE; } - gUnknown_0203AB88->var3C[48] = CreateSprite(&gUnknown_085B7844, 152, 96, 9); - gSprites[gUnknown_0203AB88->var3C[48]].oam.priority = 1; - gSprites[gUnknown_0203AB88->var3C[48]].animPaused = TRUE; - gSprites[gUnknown_0203AB88->var3C[48]].invisible = TRUE; + sRoulette->spriteIds[SPR_WIN_SLOT_CURSOR] = CreateSprite(&sSpriteTemplate_Cursor, 152, 96, 9); + gSprites[sRoulette->spriteIds[SPR_WIN_SLOT_CURSOR]].oam.priority = 1; + gSprites[sRoulette->spriteIds[SPR_WIN_SLOT_CURSOR]].animPaused = TRUE; + gSprites[sRoulette->spriteIds[SPR_WIN_SLOT_CURSOR]].invisible = TRUE; } -static void sub_8143514(u16 r0) +static void SetCreditDigits(u16 r0) { u8 i; u16 d = 1000; bool8 v = FALSE; - for (i = 0; i < 4; i++) + for (i = 0; i < MAX_COIN_DIGITS; i++) { u8 t = r0 / d; - gSprites[gUnknown_0203AB88->var3C[i + 21]].invisible = TRUE; - if (t > 0 || v || i == 3) + gSprites[sRoulette->spriteIds[i + SPR_CREDIT_DIG_1]].invisible = TRUE; + if (t > 0 || v || i == MAX_COIN_DIGITS - 1) { - gSprites[gUnknown_0203AB88->var3C[i + 21]].invisible = FALSE; - gSprites[gUnknown_0203AB88->var3C[i + 21]].oam.tileNum = - gSprites[gUnknown_0203AB88->var3C[i + 21]].sheetTileStart - + (*gSprites[gUnknown_0203AB88->var3C[i + 21]].anims + t)->type; + gSprites[sRoulette->spriteIds[i + SPR_CREDIT_DIG_1]].invisible = FALSE; + gSprites[sRoulette->spriteIds[i + SPR_CREDIT_DIG_1]].oam.tileNum = + gSprites[sRoulette->spriteIds[i + SPR_CREDIT_DIG_1]].sheetTileStart + + (*gSprites[sRoulette->spriteIds[i + SPR_CREDIT_DIG_1]].anims + t)->type; v = TRUE; } r0 = r0 % d; @@ -3444,143 +3649,145 @@ static void sub_8143514(u16 r0) } } -static u8 sub_8143614(u8 r0) +// Identical to GetMultiplier but with different data array +static u8 GetMultiplierAnimId(u8 selectionId) { - u8 t[5] = {0, 1, 2, 3, 4}; + u8 animIds[5] = {0, 1, 2, 3, 4}; - if (r0 >= 20) - r0 = 0; - switch (gUnknown_085B6154[r0].var01_0) + if (selectionId > NUM_GRID_SELECTIONS) + selectionId = 0; + + switch (sGridSelections[selectionId].baseMultiplier) { - case 3: - r0 = r0 / 5 - 1; - if (gUnknown_0203AB88->var16[r0] > 3) + case NUM_BOARD_COLORS: + selectionId = selectionId / 5 - 1; + if (sRoulette->colorHits[selectionId] > 3) return 0; - return t[gUnknown_0203AB88->var16[r0] + 1]; - case 4: - r0--; - if (gUnknown_0203AB88->var12[r0] > 2) + return animIds[sRoulette->colorHits[selectionId] + 1]; + case NUM_BOARD_POKES: + selectionId--; + if (sRoulette->pokeHits[selectionId] > 2) return 0; - return t[gUnknown_0203AB88->var12[r0] + 2]; - case 12: - if (gUnknown_0203AB88->var08 & gUnknown_085B6154[r0].var08) + return animIds[sRoulette->pokeHits[selectionId] + 2]; + case NUM_ROULETTE_SLOTS: + if (sRoulette->hitFlags & sGridSelections[selectionId].flag) return 0; - return t[4]; + return animIds[4]; } return 0; } -static void sub_81436D0(u8 r0) +static void SetMultiplierSprite(u8 selectionId) { - struct Sprite *s = &gSprites[gUnknown_0203AB88->var3C[25]]; - s->animCmdIndex = sub_8143614(r0); + struct Sprite *s = &gSprites[sRoulette->spriteIds[SPR_MULTIPLIER]]; + s->animCmdIndex = GetMultiplierAnimId(selectionId); s->oam.tileNum = s->sheetTileStart + (*s->anims + s->animCmdIndex)->type; } -static void sub_814372C(u8 r0) +static void SetBallCounterNumLeft(u8 numBalls) { u8 i; u8 t = 0; - if (gUnknown_0203AB88->var19 == 1) + if (sRoulette->minBet == 1) t = 2; - switch (r0) + switch (numBalls) { case 6: - for (i = 0; i < 3; i++) + for (i = 0; i < BALLS_PER_ROUND / 2; i++) { - gSprites[gUnknown_0203AB88->var3C[i + 26]].invisible = FALSE; - gSprites[gUnknown_0203AB88->var3C[i + 26]].oam.tileNum = - gSprites[gUnknown_0203AB88->var3C[i + 26]].sheetTileStart - + (*gSprites[gUnknown_0203AB88->var3C[i + 26]].anims)->type; + gSprites[sRoulette->spriteIds[i + SPR_BALL_COUNTER_1]].invisible = FALSE; + gSprites[sRoulette->spriteIds[i + SPR_BALL_COUNTER_1]].oam.tileNum = + gSprites[sRoulette->spriteIds[i + SPR_BALL_COUNTER_1]].sheetTileStart + + (*gSprites[sRoulette->spriteIds[i + SPR_BALL_COUNTER_1]].anims)->type; } break; case 5: - gSprites[gUnknown_0203AB88->var3C[28]].oam.tileNum = - gSprites[gUnknown_0203AB88->var3C[28]].sheetTileStart - + (*gSprites[gUnknown_0203AB88->var3C[28]].anims + t + 1)->type; + gSprites[sRoulette->spriteIds[SPR_BALL_COUNTER_3]].oam.tileNum = + gSprites[sRoulette->spriteIds[SPR_BALL_COUNTER_3]].sheetTileStart + + (*gSprites[sRoulette->spriteIds[SPR_BALL_COUNTER_3]].anims + t + 1)->type; break; case 4: - gSprites[gUnknown_0203AB88->var3C[28]].oam.tileNum = - gSprites[gUnknown_0203AB88->var3C[28]].sheetTileStart - + (*gSprites[gUnknown_0203AB88->var3C[28]].anims + t + 2)->type; + gSprites[sRoulette->spriteIds[SPR_BALL_COUNTER_3]].oam.tileNum = + gSprites[sRoulette->spriteIds[SPR_BALL_COUNTER_3]].sheetTileStart + + (*gSprites[sRoulette->spriteIds[SPR_BALL_COUNTER_3]].anims + t + 2)->type; break; case 3: - gSprites[gUnknown_0203AB88->var3C[27]].oam.tileNum = - gSprites[gUnknown_0203AB88->var3C[27]].sheetTileStart - + (*gSprites[gUnknown_0203AB88->var3C[27]].anims + t + 1)->type; + gSprites[sRoulette->spriteIds[SPR_BALL_COUNTER_2]].oam.tileNum = + gSprites[sRoulette->spriteIds[SPR_BALL_COUNTER_2]].sheetTileStart + + (*gSprites[sRoulette->spriteIds[SPR_BALL_COUNTER_2]].anims + t + 1)->type; break; case 2: - gSprites[gUnknown_0203AB88->var3C[27]].oam.tileNum = - gSprites[gUnknown_0203AB88->var3C[27]].sheetTileStart - + (*gSprites[gUnknown_0203AB88->var3C[27]].anims + t + 2)->type; + gSprites[sRoulette->spriteIds[SPR_BALL_COUNTER_2]].oam.tileNum = + gSprites[sRoulette->spriteIds[SPR_BALL_COUNTER_2]].sheetTileStart + + (*gSprites[sRoulette->spriteIds[SPR_BALL_COUNTER_2]].anims + t + 2)->type; break; case 1: - gSprites[gUnknown_0203AB88->var3C[26]].oam.tileNum = - gSprites[gUnknown_0203AB88->var3C[26]].sheetTileStart - + (*gSprites[gUnknown_0203AB88->var3C[26]].anims + t + 1)->type; + gSprites[sRoulette->spriteIds[SPR_BALL_COUNTER_1]].oam.tileNum = + gSprites[sRoulette->spriteIds[SPR_BALL_COUNTER_1]].sheetTileStart + + (*gSprites[sRoulette->spriteIds[SPR_BALL_COUNTER_1]].anims + t + 1)->type; break; case 0: default: - for (i = 0; i < 3; i++) + for (i = 0; i < BALLS_PER_ROUND / 2; i++) { - gSprites[gUnknown_0203AB88->var3C[i + 26]].oam.tileNum = - gSprites[gUnknown_0203AB88->var3C[i + 26]].sheetTileStart - + (*gSprites[gUnknown_0203AB88->var3C[i + 26]].anims + t + 2)->type; + gSprites[sRoulette->spriteIds[i + SPR_BALL_COUNTER_1]].oam.tileNum = + gSprites[sRoulette->spriteIds[i + SPR_BALL_COUNTER_1]].sheetTileStart + + (*gSprites[sRoulette->spriteIds[i + SPR_BALL_COUNTER_1]].anims + t + 2)->type; } } } -static void sub_814390C(struct Sprite *sprite) +static void SpriteCB_GridSquare(struct Sprite *sprite) { - sprite->pos2.x = gUnknown_0203AB88->var26; + sprite->pos2.x = sRoulette->var26; } -static void sub_814391C(void) +static void CreateBoardCenterSprite(void) { u8 spriteId; struct SpriteSheet s; - LZ77UnCompWram(gUnknown_085B7948.data, gDecompressionBuffer); + LZ77UnCompWram(sSpriteSheet_BoardCenter.data, gDecompressionBuffer); s.data = gDecompressionBuffer; - s.size = gUnknown_085B7948.size; - s.tag = gUnknown_085B7948.tag; + s.size = sSpriteSheet_BoardCenter.size; + s.tag = sSpriteSheet_BoardCenter.tag; LoadSpriteSheet(&s); - spriteId = CreateSprite(&gSpriteTemplate_85B7950, 116, 80, 81); - gSprites[spriteId].data[0] = gUnknown_0203AB88->var24; + spriteId = CreateSprite(&sSpriteTemplate_BoardCenter, 116, 80, 81); + gSprites[spriteId].data[0] = sRoulette->var24; gSprites[spriteId].data[1] = 0; gSprites[spriteId].animPaused = TRUE; gSprites[spriteId].affineAnimPaused = TRUE; gSprites[spriteId].coordOffsetEnabled = TRUE; } -static void sub_814399C(struct Sprite *sprite) +static void SpriteCB_BoardCenter(struct Sprite *sprite) { u32 t = sprite->oam.matrixNum; struct OamMatrix *m = &gOamMatrices[0]; - m[t].d = gUnknown_0203AB88->var2C.a; - m[t].a = gUnknown_0203AB88->var2C.a; - m[t].b = gUnknown_0203AB88->var2C.b; - m[t].c = gUnknown_0203AB88->var2C.c; + m[t].d = sRoulette->var2C.a; + m[t].a = sRoulette->var2C.a; + m[t].b = sRoulette->var2C.b; + m[t].c = sRoulette->var2C.c; } -static void sub_81439C8(void) +static void CreateBoardBallSprites(void) { u8 i; - for (i = 0; i < 6; i++) + for (i = 0; i < BALLS_PER_ROUND; i++) { - gUnknown_0203AB88->var3C[i] = CreateSprite(&gSpriteTemplate_85B7928, 116, 80, 57 - i); - if (gUnknown_0203AB88->var3C[i] != MAX_SPRITES) + sRoulette->spriteIds[i] = CreateSprite(&sSpriteTemplate_Ball, 116, 80, 57 - i); + if (sRoulette->spriteIds[i] != MAX_SPRITES) { - gSprites[gUnknown_0203AB88->var3C[i]].invisible = TRUE; - gSprites[gUnknown_0203AB88->var3C[i]].coordOffsetEnabled = TRUE; + gSprites[sRoulette->spriteIds[i]].invisible = TRUE; + gSprites[sRoulette->spriteIds[i]].coordOffsetEnabled = TRUE; } } } -static void sub_8143A40(void) +static void HideBoardBalls(void) { - u8 t = gUnknown_0203AB88->var3C[0]; + u8 t = sRoulette->spriteIds[SPR_BALL_1]; u8 i; - for (i = 0; i < 6; i++) + for (i = 0; i < BALLS_PER_ROUND; i++) { u8 j; gSprites[t].invisible = TRUE; @@ -3596,15 +3803,15 @@ static void sub_8143A40(void) static s16 sub_8143AC8(struct Sprite *sprite) { - if (gUnknown_0203AB88->var24 > sprite->data[3]) + if (sRoulette->var24 > sprite->data[3]) { - sprite->data[6] = 360 - gUnknown_0203AB88->var24 + sprite->data[3]; + sprite->data[6] = 360 - sRoulette->var24 + sprite->data[3]; if (sprite->data[6] >= 360) sprite->data[6] -= 360; } else { - sprite->data[6] = sprite->data[3] - gUnknown_0203AB88->var24; + sprite->data[6] = sprite->data[3] - sRoulette->var24; } return sprite->data[6]; @@ -3612,8 +3819,8 @@ static s16 sub_8143AC8(struct Sprite *sprite) static u8 sub_8143B14(struct Sprite *sprite) { - gUnknown_0203AB88->var7E = sub_8143AC8(sprite) / 30.0f; - return gUnknown_0203AB88->var7E; + sRoulette->var7E = sub_8143AC8(sprite) / 30.0f; + return sRoulette->var7E; } static s16 sub_8143B48(struct Sprite *sprite) @@ -3641,18 +3848,18 @@ static void sub_8143B84(struct Sprite *sprite) { s16 sin, cos; - gUnknown_0203AB88->var8C += gUnknown_0203AB88->var90; - gUnknown_0203AB88->var88 += gUnknown_0203AB88->var8C; + sRoulette->var8C += sRoulette->var90; + sRoulette->var88 += sRoulette->var8C; - if (gUnknown_0203AB88->var88 >= 360) - gUnknown_0203AB88->var88 -= 360.0f; - else if (gUnknown_0203AB88->var88 < 0.0f) - gUnknown_0203AB88->var88 += 360.0f; + if (sRoulette->var88 >= 360) + sRoulette->var88 -= 360.0f; + else if (sRoulette->var88 < 0.0f) + sRoulette->var88 += 360.0f; - sprite->data[3] = gUnknown_0203AB88->var88; - gUnknown_0203AB88->var98 += gUnknown_0203AB88->var9C; - gUnknown_0203AB88->var94 += gUnknown_0203AB88->var98; - sprite->data[4] = gUnknown_0203AB88->var94; + sprite->data[3] = sRoulette->var88; + sRoulette->var98 += sRoulette->var9C; + sRoulette->var94 += sRoulette->var98; + sprite->data[4] = sRoulette->var94; sin = Sin2(sprite->data[3]); cos = Cos2(sprite->data[3]); sprite->pos2.x = sin * sprite->data[4] >> 12; @@ -3667,7 +3874,7 @@ static void sub_8143B84(struct Sprite *sprite) static void sub_8143C90(struct Sprite *sprite) { s16 sin, cos; - sprite->data[3] = gUnknown_0203AB88->var24 + sprite->data[6]; + sprite->data[3] = sRoulette->var24 + sprite->data[6]; if (sprite->data[3] >= 360) sprite->data[3] -= 360; sin = Sin2(sprite->data[3]); @@ -3690,10 +3897,10 @@ static void sub_8143CFC(struct Sprite *sprite) { if (!sprite->data[0]) { - if (gUnknown_0203AB88->var94 <= gUnknown_0203AB88->varA0 - 2.0f) + if (sRoulette->var94 <= sRoulette->varA0 - 2.0f) { - gUnknown_0203AB88->var7D = 0xFF; - gUnknown_0203AB88->var03_7 = 0; + sRoulette->var7D = 0xFF; + sRoulette->var03_7 = FALSE; StartSpriteAnim(sprite, sprite->animCmdIndex + 0x3); sub_8143B14(sprite); sprite->data[4] = 30; @@ -3701,16 +3908,16 @@ static void sub_8143CFC(struct Sprite *sprite) sprite->data[6] = (sprite->data[6] / 30) * 30 + 15; sprite->callback = sub_8143C90; m4aSongNumStartOrChange(SE_HASHI); - gUnknown_0203AB88->var9C = gUnknown_0203AB88->var98 = 0.0f; - gUnknown_0203AB88->var8C = -1.0f; + sRoulette->var9C = sRoulette->var98 = 0.0f; + sRoulette->var8C = -1.0f; } } else { - if (gUnknown_0203AB88->var94 >= gUnknown_0203AB88->varA0 - 2.0f) + if (sRoulette->var94 >= sRoulette->varA0 - 2.0f) { - gUnknown_0203AB88->var7D = 0xFF; - gUnknown_0203AB88->var03_7 = 0; + sRoulette->var7D = 0xFF; + sRoulette->var03_7 = FALSE; StartSpriteAnim(sprite, sprite->animCmdIndex + 3); sub_8143B14(sprite); sprite->data[4] = 30; @@ -3718,14 +3925,14 @@ static void sub_8143CFC(struct Sprite *sprite) sprite->data[6] = (sprite->data[6] / 30) * 30 + 15; sprite->callback = sub_8143C90; m4aSongNumStartOrChange(SE_HASHI); - gUnknown_0203AB88->var9C = gUnknown_0203AB88->var98 = 0.0f; - gUnknown_0203AB88->var8C = -1.0f; + sRoulette->var9C = sRoulette->var98 = 0.0f; + sRoulette->var8C = -1.0f; } } } } -static void sub_8143E14(struct Sprite *sprite) +static void SpriteCB_Shroomish(struct Sprite *sprite) { float f0, f1, f2; sub_8143B84(sprite); @@ -3736,8 +3943,8 @@ static void sub_8143E14(struct Sprite *sprite) if (sprite->data[0] != 1) { f0 = sprite->data[7]; - f1 = (f0 * gUnknown_085B6348[gUnknown_0203AB88->var04_0].var01 + (gUnknown_085B6348[gUnknown_0203AB88->var04_0].var02 - 1)); - f2 = (f0 / gUnknown_085B6348[gUnknown_0203AB88->var04_0].var0C); + f1 = (f0 * gUnknown_085B6348[sRoulette->tableId].var01 + (gUnknown_085B6348[sRoulette->tableId].var02 - 1)); + f2 = (f0 / gUnknown_085B6348[sRoulette->tableId].var0C); } else { @@ -3748,8 +3955,8 @@ static void sub_8143E14(struct Sprite *sprite) if (sprite->data[0] != 0) { f0 = sprite->data[7]; - f1 = (f0 * gUnknown_085B6348[gUnknown_0203AB88->var04_0].var01 + (gUnknown_085B6348[gUnknown_0203AB88->var04_0].var02 - 1)); - f2 = -(f0 / gUnknown_085B6348[gUnknown_0203AB88->var04_0].var0C); + f1 = (f0 * gUnknown_085B6348[sRoulette->tableId].var01 + (gUnknown_085B6348[sRoulette->tableId].var02 - 1)); + f2 = -(f0 / gUnknown_085B6348[sRoulette->tableId].var0C); } else { @@ -3759,10 +3966,10 @@ static void sub_8143E14(struct Sprite *sprite) default: return; } - gUnknown_0203AB88->varA0 = gUnknown_0203AB88->var94; - gUnknown_0203AB88->var98 = f2; - gUnknown_0203AB88->var9C = -((f2 * 2.0f) / f1 + (2.0f / (f1 * f1))); - gUnknown_0203AB88->var8C = 0.0f; + sRoulette->varA0 = sRoulette->var94; + sRoulette->var98 = f2; + sRoulette->var9C = -((f2 * 2.0f) / f1 + (2.0f / (f1 * f1))); + sRoulette->var8C = 0.0f; sprite->animPaused = FALSE; sprite->animNum = 0; sprite->animBeginning = TRUE; @@ -3777,8 +3984,8 @@ static void sub_8143FA4(struct Sprite *sprite) sprite->data[2]++; if (sprite->data[2] > 29 && sprite->pos2.y >= 0) { - gUnknown_0203AB88->var7D = 0xFF; - gUnknown_0203AB88->var03_7 = FALSE; + sRoulette->var7D = 0xFF; + sRoulette->var03_7 = FALSE; StartSpriteAnim(sprite, sprite->animCmdIndex + 3); sub_8143B14(sprite); sprite->data[4] = 30; @@ -3786,7 +3993,7 @@ static void sub_8143FA4(struct Sprite *sprite) sprite->data[6] = (sprite->data[6] / 30) * 30 + 15; sprite->callback = sub_8143C90; m4aSongNumStartOrChange(SE_HASHI); - gUnknown_0203AB88->var03_6 = TRUE; + sRoulette->var03_6 = TRUE; } } @@ -3797,7 +4004,7 @@ static void sub_8144050(struct Sprite *sprite) sprite->pos2.y--; if (sprite->data[2] == 45) { - if (gSprites[gUnknown_0203AB88->var3C[55]].animCmdIndex == 1) + if (gSprites[sRoulette->spriteIds[SPR_CLEAR_MON]].animCmdIndex == 1) sprite->pos2.y++; } } @@ -3805,9 +4012,9 @@ static void sub_8144050(struct Sprite *sprite) { if (sprite->data[2] < sprite->data[7]) { - if (gSprites[gUnknown_0203AB88->var3C[55]].animDelayCounter == 0) + if (gSprites[sRoulette->spriteIds[SPR_CLEAR_MON]].animDelayCounter == 0) { - if (gSprites[gUnknown_0203AB88->var3C[55]].animCmdIndex == 1) + if (gSprites[sRoulette->spriteIds[SPR_CLEAR_MON]].animCmdIndex == 1) sprite->pos2.y++; else sprite->pos2.y--; @@ -3848,18 +4055,18 @@ static void sub_8144128(struct Sprite *sprite) } } -static void sub_8144168(struct Sprite *sprite) +static void CreateClearSpeciesSprite(struct Sprite *sprite) { sub_8143B84(sprite); - switch (gUnknown_0203AB88->var03_0) + switch (sRoulette->useTaillow) { default: - case 0: - sub_81446DC(sprite); - sprite->callback = sub_8143E14; + case FALSE: + CreateShroomishSprite(sprite); + sprite->callback = SpriteCB_Shroomish; break; - case 1: - sub_81448B8(sprite); + case TRUE: + CreateTaillowSprite(sprite); sprite->callback = sub_8144128; break; } @@ -3869,13 +4076,13 @@ static void prev_quest_read_x24_hm_usage(struct Sprite *sprite) { sub_8143B84(sprite); if (sprite->data[2]-- == 16) - gUnknown_0203AB88->var98 *= -1.0f; + sRoulette->var98 *= -1.0f; if (sprite->data[2] == 0) { if (!sprite->data[0]) { - gUnknown_0203AB88->var7D = 0xFF; - gUnknown_0203AB88->var03_7 = 0; + sRoulette->var7D = 0xFF; + sRoulette->var03_7 = FALSE; StartSpriteAnim(sprite, sprite->animCmdIndex + 3); sub_8143B14(sprite); sprite->data[4] = 30; @@ -3898,10 +4105,10 @@ static void sub_8144264(struct Sprite *sprite) sub_8143B84(sprite); sprite->data[2] = 0; sub_8143B14(sprite); - if (!(gUnknown_085B62E4[gUnknown_0203AB88->var7E].var04 & gUnknown_0203AB88->var08)) + if (!(sRouletteSlots[sRoulette->var7E].flag & sRoulette->hitFlags)) { - gUnknown_0203AB88->var7D = 0xFF; - gUnknown_0203AB88->var03_7 = 0; + sRoulette->var7D = 0xFF; + sRoulette->var03_7 = FALSE; StartSpriteAnim(sprite, sprite->animCmdIndex + 3); sub_8143B14(sprite); sprite->data[4] = 30; @@ -3912,48 +4119,44 @@ static void sub_8144264(struct Sprite *sprite) } else { - u8 t; + u8 slotId; u32 z; m4aSongNumStart(SE_KON); z = Random() & 1; if (z) { - gUnknown_0203AB88->var8C = 0.0f; - gUnknown_0203AB88->var7F = t = (gUnknown_0203AB88->var7E + 1) % 12; + sRoulette->var8C = 0.0f; + sRoulette->var7F = slotId = (sRoulette->var7E + 1) % NUM_ROULETTE_SLOTS; } else { float temp; - gUnknown_0203AB88->var8C = (temp = gUnknown_085B6348[gUnknown_0203AB88->var04_0].var1C) * 2.0f; - t = (gUnknown_0203AB88->var7E + 11) % 12; - gUnknown_0203AB88->var7F = gUnknown_0203AB88->var7E; + sRoulette->var8C = (temp = gUnknown_085B6348[sRoulette->tableId].var1C) * 2.0f; + slotId = (sRoulette->var7E + NUM_ROULETTE_SLOTS - 1) % NUM_ROULETTE_SLOTS; + sRoulette->var7F = sRoulette->var7E; } - if (gUnknown_085B62E4[t].var04 & gUnknown_0203AB88->var08) + if (sRouletteSlots[slotId].flag & sRoulette->hitFlags) { sprite->data[0] = 1; - sprite->data[2] = gUnknown_085B6348[gUnknown_0203AB88->var04_0].var02; + sprite->data[2] = gUnknown_085B6348[sRoulette->tableId].var02; } else { - sprite->data[0] = gUnknown_085B62E4[t].var04 & gUnknown_0203AB88->var08; - if (gUnknown_0203AB88->var04_0) + sprite->data[0] = sRouletteSlots[slotId].flag & sRoulette->hitFlags; + if (sRoulette->tableId) { - sprite->data[2] = gUnknown_085B6348[gUnknown_0203AB88->var04_0].var01; + sprite->data[2] = gUnknown_085B6348[sRoulette->tableId].var01; } else { - sprite->data[2] = gUnknown_085B6348[gUnknown_0203AB88->var04_0].var02; + sprite->data[2] = gUnknown_085B6348[sRoulette->tableId].var02; if (z) - { - gUnknown_0203AB88->var8C = 0.5f; - } + sRoulette->var8C = 0.5f; else - { - gUnknown_0203AB88->var8C = -1.5f; - } + sRoulette->var8C = -1.5f; } } - gUnknown_0203AB88->var98 = 0.085f; + sRoulette->var98 = 0.085f; sprite->callback = prev_quest_read_x24_hm_usage; sprite->data[1] = 5; } @@ -3962,27 +4165,27 @@ static void sub_8144264(struct Sprite *sprite) static void sub_8144410(struct Sprite *sprite) { sub_8143B84(sprite); - if (gUnknown_0203AB88->var8C > 0.5f) + if (sRoulette->var8C > 0.5f) return; sub_8143B14(sprite); if (!sub_8143B48(sprite)) { - gUnknown_0203AB88->var90 = 0.0f; - gUnknown_0203AB88->var8C -= (float)(gUnknown_085B6348[gUnknown_0203AB88->var04_0].var03) - / (gUnknown_085B6348[gUnknown_0203AB88->var04_0].var04 + 1); + sRoulette->var90 = 0.0f; + sRoulette->var8C -= (float)(gUnknown_085B6348[sRoulette->tableId].var03) + / (gUnknown_085B6348[sRoulette->tableId].var04 + 1); sprite->data[1] = 4; sprite->callback = sub_8144264; } else { - if (gUnknown_0203AB88->var90 != 0.0f) + if (sRoulette->var90 != 0.0f) { - if (gUnknown_0203AB88->var8C < 0.0f) + if (sRoulette->var8C < 0.0f) { - gUnknown_0203AB88->var90 = 0.0f; - gUnknown_0203AB88->var8C = 0.0f; - gUnknown_0203AB88->var98 /= 1.2; + sRoulette->var90 = 0.0f; + sRoulette->var8C = 0.0f; + sRoulette->var98 /= 1.2; } } } @@ -3991,11 +4194,11 @@ static void sub_8144410(struct Sprite *sprite) static void sub_8144514(struct Sprite *sprite) { sub_8143B84(sprite); - if (gUnknown_0203AB88->var94 > 40.f) + if (sRoulette->var94 > 40.f) return; - gUnknown_0203AB88->var98 = -(4.0f / (float)(gUnknown_0203AB88->var86)); - gUnknown_0203AB88->var90 = -(gUnknown_0203AB88->var8C / (float)(gUnknown_0203AB88->var86)); + sRoulette->var98 = -(4.0f / (float)(sRoulette->var86)); + sRoulette->var90 = -(sRoulette->var8C / (float)(sRoulette->var86)); sprite->animNum = 2; sprite->animBeginning = TRUE; sprite->animEnded = FALSE; @@ -4006,12 +4209,12 @@ static void sub_8144514(struct Sprite *sprite) static void sub_81445D8(struct Sprite *sprite) { sub_8143B84(sprite); - if (gUnknown_0203AB88->var94 > 60.0f) + if (sRoulette->var94 > 60.0f) return; m4aSongNumStartOrChange(SE_TAMAKORO_E); - gUnknown_0203AB88->var98 = -(20.0f / (float)(gUnknown_0203AB88->var84)); - gUnknown_0203AB88->var90 = ((1.0f - gUnknown_0203AB88->var8C) / (float)(gUnknown_0203AB88->var84)); + sRoulette->var98 = -(20.0f / (float)(sRoulette->var84)); + sRoulette->var90 = ((1.0f - sRoulette->var8C) / (float)(sRoulette->var84)); sprite->animNum = 1; sprite->animBeginning = TRUE; sprite->animEnded = FALSE; @@ -4028,7 +4231,7 @@ static void sub_81446AC(struct Sprite *sprite) sprite->callback = sub_81445D8; } -static void sub_81446DC(struct Sprite *sprite) +static void CreateShroomishSprite(struct Sprite *sprite) { u16 t; u8 i; @@ -4039,29 +4242,29 @@ static void sub_81446DC(struct Sprite *sprite) struct Roulette *p; t = sprite->data[7] - 2; - p = gUnknown_0203AB88; // why??? - gUnknown_0203AB88->var3C[55] = CreateSprite(&gSpriteTemplate_85B79F8, 36, -12, 50); - gUnknown_0203AB88->var3C[56] = CreateSprite(&gSpriteTemplate_85B7ABC[0], s[sprite->data[0]][0], s[sprite->data[0]][1], 59); - gUnknown_0203AB88->var3C[57] = CreateSprite(&gSpriteTemplate_85B7ABC[1], 36, 140, 51); - gSprites[gUnknown_0203AB88->var3C[57]].oam.objMode = ST_OAM_OBJ_BLEND; + p = sRoulette; // why??? + sRoulette->spriteIds[SPR_CLEAR_MON] = CreateSprite(&sSpriteTemplate_Shroomish, 36, -12, 50); + sRoulette->spriteIds[SPR_CLEAR_MON_SHADOW_1] = CreateSprite(&sSpriteTemplate_ShroomishShadow[0], s[sprite->data[0]][0], s[sprite->data[0]][1], 59); + sRoulette->spriteIds[SPR_CLEAR_MON_SHADOW_2] = CreateSprite(&sSpriteTemplate_ShroomishShadow[1], 36, 140, 51); + gSprites[sRoulette->spriteIds[SPR_CLEAR_MON_SHADOW_2]].oam.objMode = ST_OAM_OBJ_BLEND; for (i = 0; i < 3; i++) { - gSprites[gUnknown_0203AB88->var3C[i + 55]].coordOffsetEnabled = FALSE; - gSprites[gUnknown_0203AB88->var3C[i + 55]].invisible = TRUE; - gSprites[gUnknown_0203AB88->var3C[i + 55]].animPaused = TRUE; - gSprites[gUnknown_0203AB88->var3C[i + 55]].affineAnimPaused = TRUE; - gSprites[gUnknown_0203AB88->var3C[i + 55]].data[4] = gUnknown_0203AB88->var3C[55]; - gSprites[gUnknown_0203AB88->var3C[i + 55]].data[5] = gUnknown_0203AB88->var3C[56]; - gSprites[gUnknown_0203AB88->var3C[i + 55]].data[6] = gUnknown_0203AB88->var3C[57]; - gSprites[gUnknown_0203AB88->var3C[i + 55]].data[2] = t; - gSprites[gUnknown_0203AB88->var3C[i + 55]].data[3] = (sprite->data[7] * gUnknown_085B6348[gUnknown_0203AB88->var04_0].var01) + - (gUnknown_085B6348[gUnknown_0203AB88->var04_0].var02 + 0xFFFF); + gSprites[sRoulette->spriteIds[i + SPR_CLEAR_MON]].coordOffsetEnabled = FALSE; + gSprites[sRoulette->spriteIds[i + SPR_CLEAR_MON]].invisible = TRUE; + gSprites[sRoulette->spriteIds[i + SPR_CLEAR_MON]].animPaused = TRUE; + gSprites[sRoulette->spriteIds[i + SPR_CLEAR_MON]].affineAnimPaused = TRUE; + gSprites[sRoulette->spriteIds[i + SPR_CLEAR_MON]].data[4] = sRoulette->spriteIds[SPR_CLEAR_MON]; + gSprites[sRoulette->spriteIds[i + SPR_CLEAR_MON]].data[5] = sRoulette->spriteIds[SPR_CLEAR_MON_SHADOW_1]; + gSprites[sRoulette->spriteIds[i + SPR_CLEAR_MON]].data[6] = sRoulette->spriteIds[SPR_CLEAR_MON_SHADOW_2]; + gSprites[sRoulette->spriteIds[i + SPR_CLEAR_MON]].data[2] = t; + gSprites[sRoulette->spriteIds[i + SPR_CLEAR_MON]].data[3] = (sprite->data[7] * gUnknown_085B6348[sRoulette->tableId].var01) + + (gUnknown_085B6348[sRoulette->tableId].var02 + 0xFFFF); } - gSprites[gUnknown_0203AB88->var3C[56]].coordOffsetEnabled = TRUE; - gUnknown_0203AB88->var38 = sprite; + gSprites[sRoulette->spriteIds[SPR_CLEAR_MON_SHADOW_1]].coordOffsetEnabled = TRUE; + sRoulette->var38 = sprite; } -static void sub_81448B8(struct Sprite *sprite) +static void CreateTaillowSprite(struct Sprite *sprite) { u8 i = 0; s16 t; @@ -4071,21 +4274,21 @@ static void sub_81448B8(struct Sprite *sprite) }; t = sprite->data[7] - 2; - gUnknown_0203AB88->var3C[55] = CreateSprite(&gSpriteTemplate_85B7A10, s[sprite->data[0]][0], s[sprite->data[0]][1], 50); - StartSpriteAnim(&gSprites[gUnknown_0203AB88->var3C[55]], sprite->data[0]); - gUnknown_0203AB88->var3C[56] = CreateSprite(&gUnknown_085B7AEC, s[sprite->data[0]][0], s[sprite->data[0]][1], 51); - gSprites[gUnknown_0203AB88->var3C[56]].affineAnimPaused = TRUE; - gSprites[gUnknown_0203AB88->var3C[56]].animPaused = TRUE; - sprite->data[7] = (t * gUnknown_085B6348[gUnknown_0203AB88->var04_0].var01) + (gUnknown_085B6348[gUnknown_0203AB88->var04_0].var10 + 45); + sRoulette->spriteIds[SPR_CLEAR_MON] = CreateSprite(&sSpriteTemplate_Taillow, s[sprite->data[0]][0], s[sprite->data[0]][1], 50); + StartSpriteAnim(&gSprites[sRoulette->spriteIds[SPR_CLEAR_MON]], sprite->data[0]); + sRoulette->spriteIds[SPR_CLEAR_MON_SHADOW_1] = CreateSprite(&sSpriteTemplate_TaillowShadow, s[sprite->data[0]][0], s[sprite->data[0]][1], 51); + gSprites[sRoulette->spriteIds[SPR_CLEAR_MON_SHADOW_1]].affineAnimPaused = TRUE; + gSprites[sRoulette->spriteIds[SPR_CLEAR_MON_SHADOW_1]].animPaused = TRUE; + sprite->data[7] = (t * gUnknown_085B6348[sRoulette->tableId].var01) + (gUnknown_085B6348[sRoulette->tableId].var10 + 45); for (; i < 2; i++) { - gSprites[gUnknown_0203AB88->var3C[55 + i]].data[4] = gUnknown_0203AB88->var3C[55]; - gSprites[gUnknown_0203AB88->var3C[55 + i]].data[5] = gUnknown_0203AB88->var3C[56]; - gSprites[gUnknown_0203AB88->var3C[55 + i]].data[6] = gUnknown_0203AB88->var3C[56]; - gSprites[gUnknown_0203AB88->var3C[55 + i]].data[2] = t; - gSprites[gUnknown_0203AB88->var3C[55 + i]].data[3] = sprite->data[7] - 45; + gSprites[sRoulette->spriteIds[SPR_CLEAR_MON + i]].data[4] = sRoulette->spriteIds[SPR_CLEAR_MON]; + gSprites[sRoulette->spriteIds[SPR_CLEAR_MON + i]].data[5] = sRoulette->spriteIds[SPR_CLEAR_MON_SHADOW_1]; + gSprites[sRoulette->spriteIds[SPR_CLEAR_MON + i]].data[6] = sRoulette->spriteIds[SPR_CLEAR_MON_SHADOW_1]; + gSprites[sRoulette->spriteIds[SPR_CLEAR_MON + i]].data[2] = t; + gSprites[sRoulette->spriteIds[SPR_CLEAR_MON + i]].data[3] = sprite->data[7] - 45; } - gUnknown_0203AB88->var38 = sprite; + sRoulette->var38 = sprite; } static void sub_8144A24(struct Sprite *sprite) @@ -4100,33 +4303,33 @@ static void sub_8144A24(struct Sprite *sprite) u8 s[10] = {}; u16 rand = Random(); - gUnknown_0203AB88->var7D = 1; - gUnknown_0203AB88->var03_5 = TRUE; - gUnknown_0203AB88->var03_6 = FALSE; - gUnknown_0203AB88->var7E = 0xFF; - gUnknown_0203AB88->var88 = sprite->data[3]; - gUnknown_0203AB88->var98 = 0.0f; - gUnknown_0203AB88->var8C = gUnknown_085B6348[gUnknown_0203AB88->var04_0].var1C; + sRoulette->var7D = 1; + sRoulette->var03_5 = TRUE; + sRoulette->var03_6 = FALSE; + sRoulette->var7E = 0xFF; + sRoulette->var88 = sprite->data[3]; + sRoulette->var98 = 0.0f; + sRoulette->var8C = gUnknown_085B6348[sRoulette->tableId].var1C; - o = (gUnknown_0203AB88->var04_0 * 30 + 33) + (0x1 - gUnknown_0203AB88->var03_0) * 15; + o = (sRoulette->tableId * 30 + 33) + (1 - sRoulette->useTaillow) * 15; for (i = 0; i < 4; i++) { if (o < sprite->data[3] && sprite->data[3] <= o + 90) { sprite->data[0] = i / 2; - gUnknown_0203AB88->var03_0 = i % 2; + sRoulette->useTaillow = i % 2; break; } if (i == 3) { sprite->data[0] = 1; - gUnknown_0203AB88->var03_0 = 1; + sRoulette->useTaillow = TRUE; break; } o += 90; } - if (gUnknown_0203AB88->var03_0) + if (sRoulette->useTaillow) { if (sprite->data[0]) PlayCry1(SPECIES_TAILLOW, -63); @@ -4139,25 +4342,25 @@ static void sub_8144A24(struct Sprite *sprite) } val = 2; - z = (gUnknown_0203AB88->var7F + 2) % 12; + z = (sRoulette->var7F + 2) % 12; - if (gUnknown_0203AB88->var03_0 == 1 && gUnknown_0203AB88->var04_0 == 1) + if (sRoulette->useTaillow == TRUE && sRoulette->tableId == 1) j += 6; else j += val; for (i = val; i < j; i++) { - if (!(gUnknown_0203AB88->var08 & gUnknown_085B62E4[z].var04)) + if (!(sRoulette->hitFlags & sRouletteSlots[z].flag)) { s[h++] = i; - if (p == 0 && (gUnknown_085B62E4[z].var04 & gUnknown_085B6154[gUnknown_0203AB88->var1B[gUnknown_0203AB88->var1A_0]].var0C)) + if (p == 0 && (sRouletteSlots[z].flag & sGridSelections[sRoulette->betSelection[sRoulette->curBallNum]].inSelectionFlags)) p = i; } - z = (z + 1) % 0xC; + z = (z + 1) % 12; } - if ((gUnknown_0203AB88->var03_0 + 1) & gUnknown_0203AB88->var02) + if ((sRoulette->useTaillow + 1) & sRoulette->partySpeciesFlags) { if (p && (rand & 0xFF) < 0xc0) sprite->data[7] = p; @@ -4169,7 +4372,7 @@ static void sub_8144A24(struct Sprite *sprite) sprite->data[7] = s[rand % h]; } - sprite->callback = sub_8144168; + sprite->callback = CreateClearSpeciesSprite; } static const u16 gUnknown_085B7B1A[] = { @@ -4192,11 +4395,11 @@ static void sub_8144C70(struct Sprite *sprite) sprite->pos1.x -= 2; if (sprite->pos1.x < -16) { - if (!gUnknown_0203AB88->var03_6) - gUnknown_0203AB88->var03_6 = TRUE; + if (!sRoulette->var03_6) + sRoulette->var03_6 = TRUE; DestroySprite(sprite); - gUnknown_0203AB88->var01 = 0; - gUnknown_0203AB88->var34 = gUnknown_085B7B1A[0]; + sRoulette->var01 = 0; + sRoulette->var34 = gUnknown_085B7B1A[0]; } } } @@ -4223,7 +4426,7 @@ static void sub_8144CD0(struct Sprite *sprite) else { gSpriteCoordOffsetY = 0; - gSprites[gUnknown_0203AB88->var3C[55]].animPaused = FALSE; + gSprites[sRoulette->spriteIds[SPR_CLEAR_MON]].animPaused = FALSE; DestroySprite(sprite); } } @@ -4234,9 +4437,9 @@ static void sub_8144D94(struct Sprite *sprite) sprite->data[1]++; t = sprite->data[1]; sprite->pos2.y = t * 0.039f * t; - gUnknown_0203AB88->var34 = gUnknown_085B7B1A[(gUnknown_0203AB88->var01 - 1) / 2]; - if (gUnknown_0203AB88->var01 < 19) - gUnknown_0203AB88->var01++; + sRoulette->var34 = gUnknown_085B7B1A[(sRoulette->var01 - 1) / 2]; + if (sRoulette->var01 < 19) + sRoulette->var01++; if (sprite->data[1] > 60) { sprite->data[1] = 0; @@ -4253,37 +4456,37 @@ static void sub_8144E60(struct Sprite *sprite) { if (sprite->data[7] == 0) { - if (gUnknown_0203AB88->var38->data[0] == 0) + if (sRoulette->var38->data[0] == 0) { - if (gUnknown_0203AB88->var38->data[3] != gUnknown_085B6348[gUnknown_0203AB88->var04_0].var08) + if (sRoulette->var38->data[3] != gUnknown_085B6348[sRoulette->tableId].var08) return; } else { - if (gUnknown_0203AB88->var38->data[3] != gUnknown_085B6348[gUnknown_0203AB88->var04_0].var08 + 180) + if (sRoulette->var38->data[3] != gUnknown_085B6348[sRoulette->tableId].var08 + 180) return; } sprite->invisible = FALSE; sprite->data[7]++; m4aSongNumStart(SE_RU_HYUU); - gUnknown_0203AB88->var01 = 1; - gUnknown_0203AB88->var34 = gUnknown_085B7B1A[0]; + sRoulette->var01 = 1; + sRoulette->var34 = gUnknown_085B7B1A[0]; } else { - gUnknown_0203AB88->var34 = gUnknown_085B7B1A[(gUnknown_0203AB88->var01 - 1) / 2]; - if (gUnknown_0203AB88->var01 < 19) - gUnknown_0203AB88->var01++; + sRoulette->var34 = gUnknown_085B7B1A[(sRoulette->var01 - 1) / 2]; + if (sRoulette->var01 < 19) + sRoulette->var01++; - if (gUnknown_0203AB88->var38->data[0] == 0) + if (sRoulette->var38->data[0] == 0) { - if (gUnknown_0203AB88->var38->data[3] != gUnknown_085B6348[gUnknown_0203AB88->var04_0].var0A) + if (sRoulette->var38->data[3] != gUnknown_085B6348[sRoulette->tableId].var0A) return; } else { - if (gUnknown_0203AB88->var38->data[3] != gUnknown_085B6348[gUnknown_0203AB88->var04_0].var0A + 180) + if (sRoulette->var38->data[3] != gUnknown_085B6348[sRoulette->tableId].var0A + 180) return; } @@ -4312,8 +4515,8 @@ static void sub_8144FB0(struct Sprite *sprite) sprite->animPaused = TRUE; m4aSongNumStop(SE_BASABASA); DestroySprite(sprite); - FreeOamMatrix(gSprites[gUnknown_0203AB88->var3C[56]].oam.matrixNum); - DestroySprite(&gSprites[gUnknown_0203AB88->var3C[56]]); + FreeOamMatrix(gSprites[sRoulette->spriteIds[SPR_CLEAR_MON_SHADOW_1]].oam.matrixNum); + DestroySprite(&gSprites[sRoulette->spriteIds[SPR_CLEAR_MON_SHADOW_1]]); } } @@ -4342,7 +4545,7 @@ static void sub_8145030(struct Sprite *sprite) else { m4aSongNumStart(SE_RU_HYUU); - StartSpriteAnim(sprite, gUnknown_0203AB88->var38->data[0] + 4); + StartSpriteAnim(sprite, sRoulette->var38->data[0] + 4); sprite->callback = sub_8144FB0; gSprites[sprite->data[6]].affineAnimPaused = FALSE; } @@ -4365,7 +4568,7 @@ static void sub_81450D8(struct Sprite *sprite) if (sprite->data[1]-- > 7) { - sprite->pos1.x += t[gUnknown_0203AB88->var38->data[0]] * 2; + sprite->pos1.x += t[sRoulette->var38->data[0]] * 2; if (IsSEPlaying()) { s8 pan = -((116 - sprite->pos1.x) / 2); @@ -4377,17 +4580,17 @@ static void sub_81450D8(struct Sprite *sprite) { if (sprite->data[1] >= 0) { - sprite->pos1.x += t[gUnknown_0203AB88->var38->data[0]] * z[7 - sprite->data[1]][0]; + sprite->pos1.x += t[sRoulette->var38->data[0]] * z[7 - sprite->data[1]][0]; sprite->pos1.y += z[7 - sprite->data[1]][1]; } else { m4aSongNumStartOrChange(SE_BASABASA); - if (gUnknown_0203AB88->var38->data[0] == 0) + if (sRoulette->var38->data[0] == 0) PlayCry1(SPECIES_TAILLOW, 63); else PlayCry1(SPECIES_TAILLOW, -63); - StartSpriteAnim(sprite, gUnknown_0203AB88->var38->data[0] + 2); + StartSpriteAnim(sprite, sRoulette->var38->data[0] + 2); sprite->data[1] = 45; sprite->callback = sub_8145030; } @@ -4400,7 +4603,7 @@ static void sub_8145218(struct Sprite *sprite) if (sprite->data[1]-- >= 0) { - sprite->pos1.x += t[gUnknown_0203AB88->var38->data[0]] * 2; + sprite->pos1.x += t[sRoulette->var38->data[0]] * 2; gSprites[sprite->data[6]].invisible ^= 1; } else @@ -4409,11 +4612,11 @@ static void sub_8145218(struct Sprite *sprite) } } -static void sub_8145294(struct Sprite *sprite) +static void SpriteCB_Taillow(struct Sprite *sprite) { - if (gUnknown_0203AB88->var38->data[0] == 0) + if (sRoulette->var38->data[0] == 0) { - if (gUnknown_0203AB88->var38->data[3] == gUnknown_085B6348[gUnknown_0203AB88->var04_0].var12 + 90) + if (sRoulette->var38->data[3] == gUnknown_085B6348[sRoulette->tableId].var12 + 90) { gSprites[sprite->data[6]].data[1] = 52; gSprites[sprite->data[4]].data[1] = 52; @@ -4425,7 +4628,7 @@ static void sub_8145294(struct Sprite *sprite) } else { - if (gUnknown_0203AB88->var38->data[3] == gUnknown_085B6348[gUnknown_0203AB88->var04_0].var14 + 270) + if (sRoulette->var38->data[3] == gUnknown_085B6348[sRoulette->tableId].var14 + 270) { gSprites[sprite->data[6]].data[1] = 46; gSprites[sprite->data[4]].data[1] = 46; diff --git a/src/roulette_util.c b/src/roulette_util.c index f1f04a73a..c51330f21 100755 --- a/src/roulette_util.c +++ b/src/roulette_util.c @@ -429,7 +429,7 @@ void UpdatePulseBlend(struct PulseBlend *pulseBlend) } } -void sub_8152008(u16 *dest, u16 src, u8 left, u8 top, u8 width, u8 height) +void ClearGridSelectionRect(u16 *dest, u16 src, u8 left, u8 top, u8 width, u8 height) { u16 *_dest; u8 i; @@ -446,7 +446,7 @@ void sub_8152008(u16 *dest, u16 src, u8 left, u8 top, u8 width, u8 height) } } -void sub_8152058(u16 *dest, u16 *src, u8 left, u8 top, u8 width, u8 height) +void SetGridSelectionRect(u16 *dest, u16 *src, u8 left, u8 top, u8 width, u8 height) { u16 *_dest; u16 *_src = src; From b40cee540e6e4268dcae990c6a08ebba50b3cec9 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Fri, 31 Jul 2020 14:55:42 -0400 Subject: [PATCH 2/6] Continue documenting roulette --- graphics/roulette/85B5BFC.pal | 259 ------- graphics/roulette/{85B5DFC.bin => grid.bin} | Bin .../roulette/{wheel_map.bin => wheel.bin} | Bin include/roulette_util.h | 4 +- include/strings.h | 13 + src/roulette.c | 701 +++++++++--------- src/roulette_util.c | 9 +- 7 files changed, 389 insertions(+), 597 deletions(-) delete mode 100644 graphics/roulette/85B5BFC.pal rename graphics/roulette/{85B5DFC.bin => grid.bin} (100%) rename graphics/roulette/{wheel_map.bin => wheel.bin} (100%) diff --git a/graphics/roulette/85B5BFC.pal b/graphics/roulette/85B5BFC.pal deleted file mode 100644 index ed68618ff..000000000 --- a/graphics/roulette/85B5BFC.pal +++ /dev/null @@ -1,259 +0,0 @@ -JASC-PAL -0100 -256 -82 156 49 -41 41 41 -98 98 115 -172 180 197 -255 255 255 -255 205 41 -255 172 0 -213 164 65 -205 164 82 -139 106 65 -131 222 189 -74 189 156 -115 189 148 -123 180 172 -74 115 115 -255 255 0 -74 106 156 -41 41 41 -98 98 115 -156 156 164 -255 255 255 -205 156 205 -164 106 164 -172 131 164 -156 123 156 -90 57 106 -255 255 255 -255 255 255 -255 255 255 -255 255 255 -255 255 255 -255 255 255 -74 106 156 -41 41 41 -123 123 131 -172 180 197 -255 255 255 -238 238 156 -189 180 106 -131 90 32 -255 131 90 -189 106 98 -230 222 255 -74 189 156 -255 255 255 -123 180 172 -255 255 255 -255 255 255 -74 106 156 -57 57 65 -98 98 115 -156 156 164 -255 255 255 -106 205 205 -246 98 90 -106 156 255 -255 255 255 -156 255 106 -246 230 74 -255 230 123 -255 255 255 -255 255 156 -156 255 148 -205 156 255 -74 106 156 -41 41 41 -98 98 115 -205 205 213 -255 255 255 -123 238 139 -255 172 139 -16 156 74 -197 164 255 -49 106 32 -115 197 131 -197 139 189 -255 82 57 -255 238 82 -205 180 8 -255 205 8 -74 106 156 -106 139 230 -82 115 205 -255 255 255 -255 255 255 -255 205 41 -255 172 0 -213 164 65 -205 164 82 -139 106 65 -131 222 189 -74 189 156 -115 189 148 -123 180 172 -74 115 115 -255 255 255 -74 106 156 -255 246 65 -255 255 164 -255 246 65 -255 255 255 -205 156 205 -164 106 164 -172 131 164 -156 123 156 -90 57 106 -255 255 255 -255 255 255 -255 255 255 -255 255 255 -255 255 255 -65 65 57 -74 106 156 -172 255 238 -222 255 255 -148 255 238 -255 255 255 -255 205 41 -255 172 0 -213 164 65 -205 164 82 -139 106 65 -131 222 189 -74 189 156 -115 189 148 -123 180 172 -74 115 115 -65 65 57 -74 106 156 -255 205 255 -255 222 255 -255 197 255 -255 255 255 -205 156 205 -164 106 164 -172 131 164 -156 123 156 -90 57 106 -255 255 255 -255 255 255 -255 255 255 -255 255 255 -255 255 255 -65 65 57 -74 106 156 -255 255 255 -255 255 255 -255 255 255 -255 255 255 -255 205 41 -255 172 0 -213 164 65 -205 164 82 -139 106 65 -131 222 189 -74 189 156 -115 189 148 -123 180 172 -74 115 115 -255 255 255 -74 106 156 -255 255 255 -255 255 255 -255 255 255 -255 255 255 -205 156 205 -164 106 164 -172 131 164 -156 123 156 -90 57 106 -255 255 255 -255 255 255 -255 255 255 -255 255 255 -255 255 255 -255 255 255 -74 106 156 -255 246 82 -164 255 222 -172 180 197 -255 255 255 -255 246 65 -246 205 24 -238 197 98 -205 172 90 -164 131 90 -156 246 222 -90 213 180 -131 222 172 -115 189 156 -98 148 148 -65 65 57 -74 106 156 -238 189 238 -156 148 148 -172 180 197 -255 255 255 -255 205 255 -222 156 230 -197 156 197 -172 139 172 -139 106 148 -205 205 230 -255 255 255 -255 255 255 -255 255 255 -255 255 255 -65 65 57 -74 106 156 -238 230 246 -205 205 230 -172 180 197 -255 255 255 -255 255 230 -255 255 164 -255 255 255 -222 255 255 -255 246 255 -255 222 255 -255 255 255 -255 255 255 -255 255 255 -255 255 255 -65 65 57 -255 255 255 -255 255 255 -255 255 255 -255 255 255 -255 255 255 -255 255 255 -255 255 255 -255 255 255 -255 255 255 -255 255 255 -255 255 255 -255 255 255 -255 255 255 -255 255 255 -255 255 255 -255 255 255 -255 255 255 -255 255 255 -255 255 255 -255 255 255 -255 255 255 -255 255 255 -255 255 255 -255 255 255 -255 255 255 -255 255 255 -255 255 255 -255 255 255 -255 255 255 -255 255 255 -255 255 255 -255 255 255 diff --git a/graphics/roulette/85B5DFC.bin b/graphics/roulette/grid.bin similarity index 100% rename from graphics/roulette/85B5DFC.bin rename to graphics/roulette/grid.bin diff --git a/graphics/roulette/wheel_map.bin b/graphics/roulette/wheel.bin similarity index 100% rename from graphics/roulette/wheel_map.bin rename to graphics/roulette/wheel.bin diff --git a/include/roulette_util.h b/include/roulette_util.h index 85b8de1f3..2153b19f6 100644 --- a/include/roulette_util.h +++ b/include/roulette_util.h @@ -41,8 +41,8 @@ void MarkUsedPulseBlendPalettes(struct PulseBlend *, u16, u8); void UnloadUsedPulseBlendPalettes(struct PulseBlend *, u16, u8); void UnmarkUsedPulseBlendPalettes(struct PulseBlend *, u16, u8); void UpdatePulseBlend(struct PulseBlend *); -void ClearGridSelectionRect(u16 *dest, u16 src, u8 left, u8 top, u8 width, u8 height); -void SetGridSelectionRect(u16 *dest, u16 *src, u8 left, u8 top, u8 width, u8 height); +void ClearTilemapRect(u16 *dest, u16 src, u8 left, u8 top, u8 width, u8 height); +void SetTilemapRect(u16 *dest, u16 *src, u8 left, u8 top, u8 width, u8 height); void task_tutorial_controls_fadein(struct UnkStruct0 *r0); void sub_8151678(struct UnkStruct0 *r0); u8 sub_815168C(struct UnkStruct0 *r0, u8 r1, const struct UnkStruct1 *r2); diff --git a/include/strings.h b/include/strings.h index 702392efa..31ab2023e 100644 --- a/include/strings.h +++ b/include/strings.h @@ -84,6 +84,19 @@ extern const u8 gText_SoSo[]; extern const u8 gText_Bad[]; extern const u8 gText_TheWorst[]; +extern const u8 Roulette_Text_ControlsInstruction[]; +extern const u8 Roulette_Text_KeepPlaying[]; +extern const u8 Roulette_Text_Jackpot[]; +extern const u8 Roulette_Text_ItsAHit[]; +extern const u8 Roulette_Text_NothingDoing[]; +extern const u8 Roulette_Text_YouveWonXCoins[]; +extern const u8 Roulette_Text_BoardWillBeCleared[]; +extern const u8 Roulette_Text_CoinCaseIsFull[]; +extern const u8 Roulette_Text_NoCoinsLeft[]; +extern const u8 Roulette_Text_PlayMinimumWagerIsX[]; +extern const u8 Roulette_Text_SpecialRateTable[]; +extern const u8 Roulette_Text_NotEnoughCoins[]; + extern const u8 gText_Slots[]; extern const u8 gText_Roulette[]; extern const u8 gText_Jackpot[]; diff --git a/src/roulette.c b/src/roulette.c index 983a96e3f..20868f4ba 100644 --- a/src/roulette.c +++ b/src/roulette.c @@ -22,6 +22,7 @@ #include "sound.h" #include "sprite.h" #include "string_util.h" +#include "strings.h" #include "task.h" #include "trig.h" #include "tv.h" @@ -61,9 +62,16 @@ #define SQU_PURPLE_MAKUHITA (ROW_PURPLE + COL_MAKUHITA) #define NUM_GRID_SELECTIONS SQU_PURPLE_MAKUHITA +// Get the id of the col/row from the selection ID +// e.g. GET_ROW(SQU_PURPLE_SKITTY) is ROW_PURPLE #define GET_COL(selectionId)((selectionId) % (NUM_BOARD_POKES + 1)) #define GET_ROW(selectionId)((selectionId) / (NUM_BOARD_POKES + 1) * (NUM_BOARD_POKES + 1)) +// Get the col/row index from the selection ID +// e.g. GET_ROW_IDX(SQU_PURPLE_SKITTY) is 2 +#define GET_COL_IDX(selectionId)(selectionId - 1) +#define GET_ROW_IDX(selectionId)(selectionId / 5 - 1) + // Flags for the above selections, used to set which spaces have been hit or bet on #define F_WYNAUT_COL (1 << COL_WYNAUT) #define F_AZURILL_COL (1 << COL_AZURILL) @@ -119,6 +127,19 @@ #define HAS_SHROOMISH (1 << 0) #define HAS_TAILLOW (1 << 1) +enum { + BALL_STATE_ROLLING, + BALL_STATE_STUCK, + BALL_STATE_LANDED = 0xFF, +}; + +enum { + SELECT_STATE_WAIT, + SELECT_STATE_DRAW, + SELECT_STATE_UPDATE, + SELECT_STATE_ERASE = 0xFF, +}; + enum { SPR_BALL_1, SPR_BALL_2, @@ -150,17 +171,17 @@ enum { SPR_BALL_COUNTER_2, SPR_BALL_COUNTER_3, SPR_GRID_ICON_ORANGE_WYNAUT, - SPR_GRID_ICON_2, - SPR_GRID_ICON_3, - SPR_GRID_ICON_4, - SPR_GRID_ICON_5, - SPR_GRID_ICON_6, - SPR_GRID_ICON_7, - SPR_GRID_ICON_8, - SPR_GRID_ICON_9, - SPR_GRID_ICON_10, - SPR_GRID_ICON_11, - SPR_GRID_ICON_12, + SPR_GRID_ICON_GREEN_AZURILL, + SPR_GRID_ICON_PURPLE_SKITTY, + SPR_GRID_ICON_ORANGE_MAKUHITA, + SPR_GRID_ICON_GREEN_WYNAUT, + SPR_GRID_ICON_PURPLE_AZURILL, + SPR_GRID_ICON_ORANGE_SKITTY, + SPR_GRID_ICON_GREEN_MAKUHITA, + SPR_GRID_ICON_PURPLE_WYNAUT, + SPR_GRID_ICON_ORANGE_AZURILL, + SPR_GRID_ICON_GREEN_SKITTY, + SPR_GRID_ICON_PURPLE_MAKUHITA, SPR_POKE_HEADER_1, SPR_POKE_HEADER_2, SPR_POKE_HEADER_3, @@ -188,15 +209,18 @@ enum { // Start points for sprite IDs that are looped over #define SPR_BOARD_ICONS SPR_BOARD_ICON_ORANGE_WYNAUT +#define SPR_BALL_COUNTER SPR_BALL_COUNTER_1 +#define SPR_CREDIT_DIGITS SPR_CREDIT_DIG_1 #define SPR_GRID_ICONS SPR_GRID_ICON_ORANGE_WYNAUT +#define SPR_POKE_HEADERS SPR_POKE_HEADER_1 -struct StructgUnknown_083F8DF4 +struct RouletteTable { - u8 var00; + u8 minBet; // Never read u8 var01; u8 var02; - u8 var03; - u8 var04; + u8 wheelSpeed; + u8 wheelDelay; u8 filler_05[3]; u16 var08; u16 var0A; @@ -236,15 +260,15 @@ struct RouletteSlot static EWRAM_DATA struct Roulette { - u8 var00; + u8 unk0; // Never read u8 var01; u8 partySpeciesFlags; bool8 useTaillow:5; - bool8 var03_5:1; - bool8 var03_6:1; - bool8 var03_7:1; + bool8 ballStuck:1; + bool8 ballUnstuck:1; + bool8 ballRolling:1; // Never read u8 tableId:2; - u8 var04_2:5; + u8 unused:5; bool8 isSpecialRate:1; u32 hitFlags; u8 hitSquares[BALLS_PER_ROUND]; @@ -254,22 +278,22 @@ static EWRAM_DATA struct Roulette u8 curBallNum:4; // Never actually gets incremented u8 unk:4; // Never read u8 betSelection[BALLS_PER_ROUND]; // Because curBallNum is used as the only index, only the first element is ever used (prev bet selections are never needed) - u8 var21; - u8 var22; - u8 var23; - s16 var24; - s16 var26; - s16 var28; - s16 var2A; - struct OamMatrix var2C; + u8 wheelDelayTimer; + u8 wheelSpeed; + u8 wheelDelay; + s16 wheelAngle; + s16 gridX; + s16 selectionRectDrawState; + s16 updateGridHighlight; + struct OamMatrix wheelRotation; u16 var34; struct Sprite *var38; - u8 spriteIds[MAX_SPRITES]; // Sprite IDs - u8 var7C; - u8 var7D; - u8 var7E; + u8 spriteIds[MAX_SPRITES]; + u8 curBallSpriteId; + u8 ballState; + u8 hitSlot; u8 var7F; - s16 var80; + s16 var80; // Never read s16 var82; u16 var84; u16 var86; @@ -280,33 +304,33 @@ static EWRAM_DATA struct Roulette float var98; float var9C; float varA0; - u8 varA4; - u8 varA5; - u8 v51[2]; + u8 playTaskId; + u8 spinTaskId; + u8 filler_1[2]; u16 taskWaitDelay; u16 taskWaitKey; TaskFunc nextTask; - u8 v46[4]; - TaskFunc varB4; - struct UnkStruct0 varB8; + u8 filler_2[4]; + TaskFunc prevTask; + struct UnkStruct0 flashUtil; u16 tilemapBuffers[7][0x400]; - u16 *unk_397C; + u16 *gridTilemap; } *sRoulette = NULL; static EWRAM_DATA u8 sTextWindowId = 0; -static void Task_SpinBoard(u8); +static void Task_SpinWheel(u8); static void Task_StartPlaying(u8); static void Task_ContinuePlaying(u8); static void Task_StopPlaying(u8); static void Task_SelectFirstEmptySquare(u8); static void Task_HandleBetGridInput(u8); static void Task_SlideGridOffscreen(u8); +static void Task_InitBallRoll(u8); static void Task_RollBall(u8); -static void Task_EndBallRoll(u8); static void Task_RecordBallHit(u8); static void Task_SlideGridOnscreen(u8); -static void sub_8141778(u8); +static void Task_FlashBallOnWinningSquare(u8); static void Task_PrintSpinResult(u8); static void Task_PrintPayout(u8); static void Task_EndTurn(u8); @@ -324,7 +348,7 @@ static bool8 IsHitInBetSelection(u8, u8); static void FlashSelectionOnWheel(u8); static void DrawGridBackground(u8); static u8 GetMultiplier(u8); -static void sub_8142814(void); +static void UpdateWheelPosition(void); static void LoadOrFreeMiscSpritePalettesAndSheets(u8); static void CreateGridSprites(void); static void ShowHideGridIcons(bool8, u8); @@ -349,24 +373,12 @@ static void sub_8144A24(struct Sprite *); static void sub_8144E60(struct Sprite *); static void SpriteCB_Taillow(struct Sprite *); -extern const u8 Roulette_Text_ControlsInstruction[]; -extern const u8 Roulette_Text_KeepPlaying[]; -extern const u8 Roulette_Text_Jackpot[]; -extern const u8 Roulette_Text_ItsAHit[]; -extern const u8 Roulette_Text_NothingDoing[]; -extern const u8 Roulette_Text_YouveWonXCoins[]; -extern const u8 Roulette_Text_BoardWillBeCleared[]; -extern const u8 Roulette_Text_CoinCaseIsFull[]; -extern const u8 Roulette_Text_NoCoinsLeft[]; -extern const u8 Roulette_Text_PlayMinimumWagerIsX[]; -extern const u8 Roulette_Text_SpecialRateTable[]; -extern const u8 Roulette_Text_NotEnoughCoins[]; - -static const u16 gUnknown_085B5BFC[] = INCBIN_U16("graphics/roulette/85B5BFC.gbapal"); -static const u32 gUnknown_085B5DFC[] = INCBIN_U32("graphics/roulette/85B5DFC.bin.lz"); -static const u32 sWheel_Tilemap[] = INCBIN_U32("graphics/roulette/wheel_map.bin.lz"); +static const u16 sWheel_Pal[] = INCBIN_U16("graphics/roulette/wheel.gbapal"); // also palette for grid +static const u32 sGrid_Tilemap[] = INCBIN_U32("graphics/roulette/grid.bin.lz"); +static const u32 sWheel_Tilemap[] = INCBIN_U32("graphics/roulette/wheel.bin.lz"); static const struct BgTemplate sBgTemplates[] = { + // Text box { .bg = 0, .charBaseIndex = 2, @@ -376,6 +388,7 @@ static const struct BgTemplate sBgTemplates[] = .priority = 0, .baseTile = 0 }, + // Selection grid { .bg = 1, .charBaseIndex = 0, @@ -385,6 +398,7 @@ static const struct BgTemplate sBgTemplates[] = .priority = 1, .baseTile = 0 }, + // Wheel { .bg = 2, .charBaseIndex = 1, @@ -752,14 +766,15 @@ static const struct RouletteSlot sRouletteSlots[] = }; static const u8 sTableMinBets[] = {1, 3, 1, 6}; -static const struct StructgUnknown_083F8DF4 gUnknown_085B6348[] = +static const struct RouletteTable sRouletteTables[] = { + // Left table { - .var00 = 1, + .minBet = 1, .var01 = 60, .var02 = 30, - .var03 = 1, - .var04 = 1, + .wheelSpeed = 1, + .wheelDelay = 1, .var08 = 45, .var0A = 30, .var0C = 1, @@ -770,12 +785,13 @@ static const struct StructgUnknown_083F8DF4 gUnknown_085B6348[] = .var1A = 360, .var1C = -0.5f }, + // Right table { - .var00 = 3, + .minBet = 3, .var01 = 30, .var02 = 15, - .var03 = 1, - .var04 = 0, + .wheelSpeed = 1, + .wheelDelay = 0, .var08 = 75, .var0A = 60, .var0C = 2, @@ -788,7 +804,7 @@ static const struct StructgUnknown_083F8DF4 gUnknown_085B6348[] = } }; -static const struct UnkStruct1 gUnknown_085B6388[] = +static const struct UnkStruct1 gUnknown_085B6388[NUM_ROULETTE_SLOTS + 1] = { { .var00 = 0x8000, @@ -973,8 +989,8 @@ static void CB2_Roulette(void) RunTasks(); AnimateSprites(); BuildOamBuffer(); - if (sRoulette->varB8.var00) - task_tutorial_controls_fadein(&sRoulette->varB8); + if (sRoulette->flashUtil.var00) + task_tutorial_controls_fadein(&sRoulette->flashUtil); } static void VBlankCB_Roulette(void) @@ -982,32 +998,34 @@ static void VBlankCB_Roulette(void) LoadOam(); ProcessSpriteCopyRequests(); TransferPlttBuffer(); - sub_8142814(); - SetGpuReg(REG_OFFSET_BG1HOFS, 0x200 - sRoulette->var26); + UpdateWheelPosition(); + SetGpuReg(REG_OFFSET_BG1HOFS, 0x200 - sRoulette->gridX); + if (sRoulette->var01) SetGpuReg(REG_OFFSET_BLDALPHA, sRoulette->var34); - if (sRoulette->var2A != 0) + + if (sRoulette->updateGridHighlight) { DmaCopy16(3, &sRoulette->tilemapBuffers[2][0xE0], (void *)BG_SCREEN_ADDR(4) + 0x1C0, 0x340); - sRoulette->var2A = 0; + sRoulette->updateGridHighlight = FALSE; } - switch (sRoulette->var28) + switch (sRoulette->selectionRectDrawState) { - case 1: + case SELECT_STATE_DRAW: SetBgAttribute(0, BG_ATTR_CHARBASEINDEX, 0); ShowBg(0); DmaCopy16(3, &sRoulette->tilemapBuffers[0][0xE0], (void *)BG_SCREEN_ADDR(31) + 0x1C0, 0x340); - sRoulette->var28 = 2; + sRoulette->selectionRectDrawState = SELECT_STATE_UPDATE; break; - case 2: + case SELECT_STATE_UPDATE: DmaCopy16(3, &sRoulette->tilemapBuffers[0][0xE0], (void *)BG_SCREEN_ADDR(31) + 0x1C0, 0x340); break; - case 0xFF: + case SELECT_STATE_ERASE: SetBgAttribute(0, BG_ATTR_CHARBASEINDEX, 2); ShowBg(0); DmaFill16(3, 0, (void *)BG_SCREEN_ADDR(31) + 0x1C0, 0x340); - sRoulette->var28 = 0; - case 0: + sRoulette->selectionRectDrawState = SELECT_STATE_WAIT; + case SELECT_STATE_WAIT: break; } } @@ -1025,12 +1043,12 @@ static void InitRouletteBgAndWindows(void) InitWindows(sWindowTemplates); InitTextBoxGfxAndPrinters(); sTextWindowId = 0; - sRoulette->unk_397C = malloc_and_decompress(gUnknown_085B5DFC, &size); + sRoulette->gridTilemap = malloc_and_decompress(sGrid_Tilemap, &size); } static void FreeRoulette(void) { - FREE_AND_SET_NULL(sRoulette->unk_397C); + FREE_AND_SET_NULL(sRoulette->gridTilemap); FreeAllWindowBuffers(); UnsetBgTilemapBuffer(0); UnsetBgTilemapBuffer(1); @@ -1043,28 +1061,30 @@ static void FreeRoulette(void) static void sub_8140470(void) { u8 i; - u16 arr[3] = {RGB(24, 4, 10), RGB(10, 19, 6), RGB(24, 4, 10)}; // the third is never used ? + u16 bgColors[3] = {RGB(24, 4, 10), RGB(10, 19, 6), RGB(24, 4, 10)}; // 3rd is never used, same as 1st sRoulette->tableId = (gSpecialVar_0x8004 & 1); if (gSpecialVar_0x8004 & ROULETTE_SPECIAL_RATE) sRoulette->isSpecialRate = TRUE; - sRoulette->var22 = gUnknown_085B6348[sRoulette->tableId].var03; - sRoulette->var23 = gUnknown_085B6348[sRoulette->tableId].var04; + sRoulette->wheelSpeed = sRouletteTables[sRoulette->tableId].wheelSpeed; + sRoulette->wheelDelay = sRouletteTables[sRoulette->tableId].wheelDelay; sRoulette->minBet = sTableMinBets[sRoulette->tableId + sRoulette->isSpecialRate * 2]; sRoulette->unk = 1; + // Left table (with min bet of 1) has red background, other table has green if (sRoulette->minBet == 1) - gPlttBufferUnfaded[0] = gPlttBufferUnfaded[0x51] = gPlttBufferFaded[0] = gPlttBufferFaded[0x51] = arr[0]; + gPlttBufferUnfaded[0] = gPlttBufferUnfaded[0x51] = gPlttBufferFaded[0] = gPlttBufferFaded[0x51] = bgColors[0]; else - gPlttBufferUnfaded[0] = gPlttBufferUnfaded[0x51] = gPlttBufferFaded[0] = gPlttBufferFaded[0x51] = arr[1]; + gPlttBufferUnfaded[0] = gPlttBufferUnfaded[0x51] = gPlttBufferFaded[0] = gPlttBufferFaded[0x51] = bgColors[1]; - sub_8151678(&sRoulette->varB8); + sub_8151678(&sRoulette->flashUtil); - for (i = 0; i < 13; i++) + // Init flash util for flashing the selected colors on the wheel + for (i = 0; i < NUM_ROULETTE_SLOTS + 1; i++) { - sub_815168C(&sRoulette->varB8, i, &gUnknown_085B6388[i]); + sub_815168C(&sRoulette->flashUtil, i, &gUnknown_085B6388[i]); } for (i = 0; i < PARTY_SIZE; i++) @@ -1119,7 +1139,7 @@ static void CB2_LoadRoulette(void) ResetTempTileDataBuffers(); break; case 3: - LoadPalette(&gUnknown_085B5BFC, 0, 0x1C0); + LoadPalette(&sWheel_Pal, 0, 0x1C0); DecompressAndCopyTileDataToVram(1, gRouletteMenu_Gfx, 0, 0, 0); DecompressAndCopyTileDataToVram(2, gRouletteWheel_Gfx, 0, 0, 0); break; @@ -1166,34 +1186,34 @@ static void CB2_LoadRoulette(void) EnableInterrupts(INTR_FLAG_VBLANK); SetVBlankCallback(VBlankCB_Roulette); BeginHardwarePaletteFade(0xFF, 0, 16, 0, 1); - taskId = sRoulette->varA4 = CreateTask(Task_StartPlaying, 0); + taskId = sRoulette->playTaskId = CreateTask(Task_StartPlaying, 0); gTasks[taskId].tBallNum = BALLS_PER_ROUND; gTasks[taskId].tCoins = GetCoins(); AlertTVThatPlayerPlayedRoulette(GetCoins()); - sRoulette->varA5 = CreateTask(Task_SpinBoard, 1); + sRoulette->spinTaskId = CreateTask(Task_SpinWheel, 1); SetMainCallback2(CB2_Roulette); return; } gMain.state++; } -static void Task_SpinBoard(u8 taskId) +static void Task_SpinWheel(u8 taskId) { s16 sin; s16 cos; - if (sRoulette->var21++ == sRoulette->var23) + if (sRoulette->wheelDelayTimer++ == sRoulette->wheelDelay) { - sRoulette->var21 = 0; - if ((sRoulette->var24 -= sRoulette->var22) < 0) - sRoulette->var24 = 360 - sRoulette->var22; + sRoulette->wheelDelayTimer = 0; + if ((sRoulette->wheelAngle -= sRoulette->wheelSpeed) < 0) + sRoulette->wheelAngle = 360 - sRoulette->wheelSpeed; } - sin = Sin2(sRoulette->var24); - cos = Cos2(sRoulette->var24); + sin = Sin2(sRoulette->wheelAngle); + cos = Cos2(sRoulette->wheelAngle); sin = sin / 16; - sRoulette->var2C.a = sRoulette->var2C.d = cos / 16; - sRoulette->var2C.b = sin; - sRoulette->var2C.c = -sin; + sRoulette->wheelRotation.a = sRoulette->wheelRotation.d = cos / 16; + sRoulette->wheelRotation.b = sin; + sRoulette->wheelRotation.c = -sin; } static void Task_StartPlaying(u8 taskId) @@ -1231,7 +1251,7 @@ static void Task_ContinuePlaying(u8 taskId) static void Task_StopPlaying(u8 taskId) { - DestroyTask(sRoulette->varA5); + DestroyTask(sRoulette->spinTaskId); ExitRoulette(taskId); } @@ -1241,29 +1261,29 @@ static void UpdateGridSelectionRect(u8 selectionId) switch (selectionId) { case SELECTION_NONE: - ClearGridSelectionRect(&sRoulette->tilemapBuffers[0][0], 0, 14, 7, 16, 13); + ClearTilemapRect(&sRoulette->tilemapBuffers[0][0], 0, 14, 7, 16, 13); break; case COL_WYNAUT: case COL_AZURILL: case COL_SKITTY: case COL_MAKUHITA: temp0 = (selectionId * 3 + 14); - ClearGridSelectionRect(&sRoulette->tilemapBuffers[0][0], 0, 14, 7, 16, 13); - SetGridSelectionRect(&sRoulette->tilemapBuffers[0][0], &sRoulette->unk_397C[281], temp0, 7, 3, 13); + ClearTilemapRect(&sRoulette->tilemapBuffers[0][0], 0, 14, 7, 16, 13); + SetTilemapRect(&sRoulette->tilemapBuffers[0][0], &sRoulette->gridTilemap[281], temp0, 7, 3, 13); break; case ROW_ORANGE: case ROW_GREEN: case ROW_PURPLE: temp1 = ((selectionId - 1) / 5 * 3 + 10); - ClearGridSelectionRect(&sRoulette->tilemapBuffers[0][0], 0, 14, 7, 16, 13); - SetGridSelectionRect(&sRoulette->tilemapBuffers[0][0], &sRoulette->unk_397C[320], 14, temp1, 16, 3); + ClearTilemapRect(&sRoulette->tilemapBuffers[0][0], 0, 14, 7, 16, 13); + SetTilemapRect(&sRoulette->tilemapBuffers[0][0], &sRoulette->gridTilemap[320], 14, temp1, 16, 3); break; // Individual square default: temp0 = GET_COL(selectionId) * 3 + 14; temp1 = ((selectionId - 1) / 5 * 3 + 7); - ClearGridSelectionRect(&sRoulette->tilemapBuffers[0][0], 0, 14, 7, 16, 13); - SetGridSelectionRect(&sRoulette->tilemapBuffers[0][0], &sRoulette->unk_397C[272], temp0, temp1, 3, 3); + ClearTilemapRect(&sRoulette->tilemapBuffers[0][0], 0, 14, 7, 16, 13); + SetTilemapRect(&sRoulette->tilemapBuffers[0][0], &sRoulette->gridTilemap[272], temp0, temp1, 3, 3); break; } } @@ -1276,10 +1296,10 @@ static void UpdateGridSelection(u8 taskId) static void Task_StartHandleBetGridInput(u8 taskId) { - sRoulette->var28 = 1; + sRoulette->selectionRectDrawState = SELECT_STATE_DRAW; UpdateGridSelectionRect(gTasks[taskId].tSelectionId); - sRoulette->var23 = 2; - sRoulette->var21 = 0; + sRoulette->wheelDelay = 2; + sRoulette->wheelDelayTimer = 0; gTasks[taskId].func = Task_HandleBetGridInput; } @@ -1356,49 +1376,52 @@ static bool8 CanMoveSelectionInDir(s16 *selectionId, u8 dir) static void ProcessBetGridInput(u8 taskId) { - u8 z = 0; + u8 headerOffset = 0; bool8 dirPressed = FALSE; - if ((!(JOY_NEW(DPAD_UP)) || ((dirPressed = TRUE), CanMoveSelectionInDir(&gTasks[taskId].tSelectionId, 0))) - && (!(JOY_NEW(DPAD_DOWN)) || ((dirPressed = TRUE), CanMoveSelectionInDir(&gTasks[taskId].tSelectionId, 1))) - && (!(JOY_NEW(DPAD_LEFT)) || ((dirPressed = TRUE), CanMoveSelectionInDir(&gTasks[taskId].tSelectionId, 2))) - && (!(JOY_NEW(DPAD_RIGHT)) || ((dirPressed = TRUE), CanMoveSelectionInDir(&gTasks[taskId].tSelectionId, 3))) + if ((!(JOY_NEW(DPAD_UP)) || ((dirPressed = TRUE) && CanMoveSelectionInDir(&gTasks[taskId].tSelectionId, 0))) + && (!(JOY_NEW(DPAD_DOWN)) || ((dirPressed = TRUE) && CanMoveSelectionInDir(&gTasks[taskId].tSelectionId, 1))) + && (!(JOY_NEW(DPAD_LEFT)) || ((dirPressed = TRUE) && CanMoveSelectionInDir(&gTasks[taskId].tSelectionId, 2))) + && (!(JOY_NEW(DPAD_RIGHT)) || ((dirPressed = TRUE) && CanMoveSelectionInDir(&gTasks[taskId].tSelectionId, 3))) && (dirPressed)) { u8 i; DrawGridBackground(gTasks[taskId].tSelectionId); UpdateGridSelection(taskId); - gTasks[taskId].data[1] = z; + gTasks[taskId].data[1] = 0; PlaySE(SE_SELECT); - sub_8151A9C(&sRoulette->varB8, 0xFFFF); - sRoulette->varB8.var04[13].var00_7 = sRoulette->varB8.var04[14].var00_7 = sRoulette->varB8.var04[15].var00_7 = 0; + sub_8151A9C(&sRoulette->flashUtil, 0xFFFF); // Reset previous flashing wheel selections + sRoulette->flashUtil.var04[13].var00_7 = sRoulette->flashUtil.var04[14].var00_7 = sRoulette->flashUtil.var04[15].var00_7 = 0; FlashSelectionOnWheel(gTasks[taskId].tSelectionId); + + // Switch all the poke (column) headers to gray outlines for (i = 0; i < NUM_BOARD_POKES; i++) { - gSprites[sRoulette->spriteIds[i + SPR_POKE_HEADER_1]].oam.tileNum = - gSprites[sRoulette->spriteIds[i + SPR_POKE_HEADER_1]].sheetTileStart - + (*gSprites[sRoulette->spriteIds[i + SPR_POKE_HEADER_1]].anims)->type; + gSprites[sRoulette->spriteIds[i + SPR_POKE_HEADERS]].oam.tileNum = + gSprites[sRoulette->spriteIds[i + SPR_POKE_HEADERS]].sheetTileStart + + (*gSprites[sRoulette->spriteIds[i + SPR_POKE_HEADERS]].anims)->type; } - if ((u16)(gTasks[taskId].tSelectionId - 1) < 4 && !(sRoulette->hitFlags & sGridSelections[gTasks[taskId].tSelectionId].flag) ) + // If the current selection is a column with at least 1 unhit space, fill in the header + if ((u16)(gTasks[taskId].tSelectionId - 1) < COL_MAKUHITA && !(sRoulette->hitFlags & sGridSelections[gTasks[taskId].tSelectionId].flag) ) { - z = gTasks[taskId].tSelectionId - 1; - gSprites[sRoulette->spriteIds[z + SPR_POKE_HEADER_1]].oam.tileNum = - gSprites[sRoulette->spriteIds[z + SPR_POKE_HEADER_1]].sheetTileStart - + (*gSprites[sRoulette->spriteIds[z + SPR_POKE_HEADER_1]].anims + 1)->type; + headerOffset = gTasks[taskId].tSelectionId - 1; + gSprites[sRoulette->spriteIds[headerOffset + SPR_POKE_HEADERS]].oam.tileNum = + gSprites[sRoulette->spriteIds[headerOffset + SPR_POKE_HEADERS]].sheetTileStart + + (*gSprites[sRoulette->spriteIds[headerOffset + SPR_POKE_HEADERS]].anims + 1)->type; } } } -static void sub_8140F6C(u8 r0) +static void Task_StartRound(u8 taskId) { IncrementDailyRouletteUses(); - sRoulette->var28 = 0xFF; + sRoulette->selectionRectDrawState = SELECT_STATE_ERASE; if (sRoulette->minBet == 1) - sRoulette->var23 = 1; + sRoulette->wheelDelay = 1; else - sRoulette->var23 = 0; - sRoulette->var21 = 0; - gTasks[r0].data[1] = 32; - gTasks[r0].func = Task_SlideGridOffscreen; + sRoulette->wheelDelay = 0; + sRoulette->wheelDelayTimer = 0; + gTasks[taskId].data[1] = 32; + gTasks[taskId].func = Task_SlideGridOffscreen; } static void Task_PlaceBet(u8 taskId) @@ -1409,7 +1432,7 @@ static void Task_PlaceBet(u8 taskId) if ((gTasks[taskId].tCoins -= sRoulette->minBet) < 0) gTasks[taskId].tCoins = 0; SetCreditDigits(gTasks[taskId].tCoins); - gTasks[taskId].func = sub_8140F6C; + gTasks[taskId].func = Task_StartRound; } static void Task_HandleBetGridInput(u8 taskId) @@ -1455,14 +1478,14 @@ static void Task_SlideGridOffscreen(u8 taskId) { if (gTasks[taskId].data[1] > 2) gSpriteCoordOffsetX += 2; - if ((sRoulette->var26 += 4) == 104) + if ((sRoulette->gridX += 4) == 104) gSprites[sRoulette->spriteIds[SPR_MULTIPLIER]].callback = &SpriteCallbackDummy; } else { ShowHideGridIcons(TRUE, -1); ShowHideGridBalls(TRUE, -1); - gTasks[taskId].func = Task_RollBall; + gTasks[taskId].func = Task_InitBallRoll; gTasks[taskId].data[1] = 0; } } @@ -1477,17 +1500,17 @@ static u8 sub_814118C(u16 r0, u16 r1) if (gLocalTime.hours > 3 && gLocalTime.hours < 10) { if (r0 < 12 || (r1 & 1)) - return gUnknown_085B6348[sRoulette->tableId].var02 / 2; + return sRouletteTables[sRoulette->tableId].var02 / 2; else return 1; } - else if (!(r1 & 0x3)) + else if (!(r1 & 3)) { - return gUnknown_085B6348[sRoulette->tableId].var02 / 2; + return sRouletteTables[sRoulette->tableId].var02 / 2; } else { - return gUnknown_085B6348[sRoulette->tableId].var02; + return sRouletteTables[sRoulette->tableId].var02; } break; case HAS_SHROOMISH | HAS_TAILLOW: @@ -1495,17 +1518,17 @@ static u8 sub_814118C(u16 r0, u16 r1) if (gLocalTime.hours > 3 && gLocalTime.hours < 11) { if (r0 < 6 || (r1 & 1)) - return gUnknown_085B6348[sRoulette->tableId].var02 / 2; + return sRouletteTables[sRoulette->tableId].var02 / 2; else return 1; } else if ((r1 & 1) && r0 > 6) { - return gUnknown_085B6348[sRoulette->tableId].var02 / 4; + return sRouletteTables[sRoulette->tableId].var02 / 4; } else { - return gUnknown_085B6348[sRoulette->tableId].var02 / 2; + return sRouletteTables[sRoulette->tableId].var02 / 2; } break; case 0: @@ -1516,31 +1539,31 @@ static u8 sub_814118C(u16 r0, u16 r1) if (!(r1 & 3)) return 1; else - return gUnknown_085B6348[sRoulette->tableId].var02 / 2; + return sRouletteTables[sRoulette->tableId].var02 / 2; } else if (!(r1 & 3)) { if (r0 > 12) - return gUnknown_085B6348[sRoulette->tableId].var02 / 2; + return sRouletteTables[sRoulette->tableId].var02 / 2; else - return gUnknown_085B6348[sRoulette->tableId].var02; + return sRouletteTables[sRoulette->tableId].var02; } else if (r1 & 0x8000) { if (r0 > 12) - return gUnknown_085B6348[sRoulette->tableId].var02; + return sRouletteTables[sRoulette->tableId].var02; else - return gUnknown_085B6348[sRoulette->tableId].var01; + return sRouletteTables[sRoulette->tableId].var01; } else { - return gUnknown_085B6348[sRoulette->tableId].var01 * 2; + return sRouletteTables[sRoulette->tableId].var01 * 2; } break; } } -static void Task_RollBall(u8 taskId) +static void Task_InitBallRoll(u8 taskId) { u8 randf; s8 randfinal; @@ -1552,8 +1575,8 @@ static void Task_RollBall(u8 taskId) rand = Random(); randmod = rand % 100; - sRoulette->var7C = gTasks[taskId].tBallNum; - sRoulette->var7D = sRoulette->var7E = sRoulette->var7F = g; + sRoulette->curBallSpriteId = gTasks[taskId].tBallNum; + sRoulette->ballState = sRoulette->hitSlot = sRoulette->var7F = BALL_STATE_ROLLING; randf = sub_814118C(gTasks[taskId].data[8], rand); randfinal = (rand % randf) - (randf / 2); @@ -1567,28 +1590,26 @@ static void Task_RollBall(u8 taskId) else r5 = (1 - r5) * 2; - sRoulette->var80 = g = gUnknown_085B6348[sRoulette->tableId].var1A + randfinal; + sRoulette->var80 = g = sRouletteTables[sRoulette->tableId].var1A + randfinal; g = S16TOPOSFLOAT(g) / 5.0f; sRoulette->var82 = g * 3; sRoulette->var86 = sRoulette->var84 = g; sRoulette->var88 = S16TOPOSFLOAT(angles[(rand & 1) + r5]); - sRoulette->var8C = S16TOPOSFLOAT(gUnknown_085B6348[sRoulette->tableId].var18); + sRoulette->var8C = S16TOPOSFLOAT(sRouletteTables[sRoulette->tableId].var18); sRoulette->var90 = ((sRoulette->var8C * 0.5f) - sRoulette->var8C) / S16TOPOSFLOAT(sRoulette->var82); sRoulette->var94 = 68.0f; sRoulette->var9C = 0.0f; sRoulette->var98 = -(8.0f / S16TOPOSFLOAT(sRoulette->var82)); sRoulette->varA0 = 36.0f; - gTasks[taskId].func = Task_EndBallRoll; + gTasks[taskId].func = Task_RollBall; } -static void Task_EndBallRoll(u8 taskId) +static void Task_RollBall(u8 taskId) { - u8 index; - sRoulette->var03_7 = TRUE; - index = sRoulette->spriteIds[sRoulette->var7C]; - sRoulette->var38 = &gSprites[index]; + sRoulette->ballRolling = TRUE; + sRoulette->var38 = &gSprites[sRoulette->spriteIds[sRoulette->curBallSpriteId]]; sRoulette->var38->callback = sub_81446AC; gTasks[taskId].tBallNum++; gTasks[taskId].data[8]++; @@ -1599,24 +1620,26 @@ static void Task_EndBallRoll(u8 taskId) static void Task_RecordBallHit(u8 taskId) { - if (sRoulette->var7D) + // Wait for ball to finish rolling + if (sRoulette->ballState != BALL_STATE_ROLLING) { - if (sRoulette->var03_5) + // If the ball got stuck, wait for it to be unstuck + if (sRoulette->ballStuck) { - if (sRoulette->var03_6) + if (sRoulette->ballUnstuck) { - sRoulette->var03_6 = FALSE; - sRoulette->var03_5 = FALSE; + sRoulette->ballUnstuck = FALSE; + sRoulette->ballStuck = FALSE; } } else { - if (!gTasks[taskId].data[1]) + if (gTasks[taskId].data[1] == 0) { - bool8 temp = IsHitInBetSelection(RecordHit(taskId, sRoulette->var7E), sRoulette->betSelection[sRoulette->curBallNum]); - gTasks[taskId].tWonBet = temp; - if (temp == TRUE) - sub_8151A48(&sRoulette->varB8, 0x1000); + bool8 won = IsHitInBetSelection(RecordHit(taskId, sRoulette->hitSlot), sRoulette->betSelection[sRoulette->curBallNum]); + gTasks[taskId].tWonBet = won; + if (won == TRUE) + sub_8151A48(&sRoulette->flashUtil, 0x1000); // Flash outer edges of wheel } if (gTasks[taskId].data[1] <= 60) { @@ -1642,7 +1665,7 @@ static void Task_SlideGridOnscreen(u8 taskId) { if (gTasks[taskId].data[1] > 2) gSpriteCoordOffsetX -= 2; - if ((sRoulette->var26 -= 4) == 104) + if ((sRoulette->gridX -= 4) == 104) gSprites[sRoulette->spriteIds[SPR_MULTIPLIER]].callback = SpriteCB_GridSquare; } else @@ -1652,21 +1675,23 @@ static void Task_SlideGridOnscreen(u8 taskId) gTasks[taskId].data[1] = 121; else gTasks[taskId].data[1] = 61; - gTasks[taskId].func = sub_8141778; + gTasks[taskId].func = Task_FlashBallOnWinningSquare; } } -static void sub_8141778(u8 taskId) +static void Task_FlashBallOnWinningSquare(u8 taskId) { if (gTasks[taskId].data[1]-- > 1) { switch (gTasks[taskId].data[1] % 16) { case 8: + // Winning square uncovered ShowHideGridIcons(FALSE, -1); ShowHideGridBalls(FALSE, -1); break; case 0: + // Winning square occluded by ball ShowHideGridIcons(FALSE, gTasks[taskId].tWinningSquare); ShowHideGridBalls(FALSE, gTasks[taskId].tBallNum - 1); break; @@ -1784,8 +1809,8 @@ static void Task_PrintPayout(u8 taskId) static void Task_EndTurn(u8 taskId) { - sub_8151A9C(&sRoulette->varB8, 0xFFFF); - sRoulette->varB8.var04[13].var00_7 = sRoulette->varB8.var04[14].var00_7 = sRoulette->varB8.var04[15].var00_7 = 0; + sub_8151A9C(&sRoulette->flashUtil, 0xFFFF); + sRoulette->flashUtil.var04[13].var00_7 = sRoulette->flashUtil.var04[14].var00_7 = sRoulette->flashUtil.var04[15].var00_7 = 0; gSprites[sRoulette->spriteIds[SPR_BOARD_ICONS + sGridSelections[gTasks[taskId].tWinningSquare].var00]].invisible = TRUE; gTasks[taskId].func = Task_TryPrintEndTurnMsg; } @@ -1799,9 +1824,9 @@ static void Task_TryPrintEndTurnMsg(u8 taskId) gSprites[sRoulette->spriteIds[SPR_WIN_SLOT_CURSOR]].invisible = TRUE; for (i = 0; i < NUM_BOARD_POKES; i++) { - gSprites[sRoulette->spriteIds[i + SPR_POKE_HEADER_1]].oam.tileNum = - gSprites[sRoulette->spriteIds[i + SPR_POKE_HEADER_1]].sheetTileStart - + (*gSprites[sRoulette->spriteIds[i + SPR_POKE_HEADER_1]].anims)->type; + gSprites[sRoulette->spriteIds[i + SPR_POKE_HEADERS]].oam.tileNum = + gSprites[sRoulette->spriteIds[i + SPR_POKE_HEADERS]].sheetTileStart + + (*gSprites[sRoulette->spriteIds[i + SPR_POKE_HEADERS]].anims)->type; } if (gTasks[taskId].tCoins >= sRoulette->minBet) { @@ -1868,8 +1893,8 @@ static void Task_ClearBoard(u8 taskId) static void ExitRoulette(u8 taskId) { - sub_8151A9C(&sRoulette->varB8, 0xFFFF); - sub_8151678(&sRoulette->varB8); + sub_8151A9C(&sRoulette->flashUtil, 0xFFFF); + sub_8151678(&sRoulette->flashUtil); SetCoins(gTasks[taskId].tCoins); if (GetCoins() < sRoulette->minBet) gSpecialVar_0x8004 = TRUE; @@ -1918,9 +1943,9 @@ static void Task_WaitForNextTask(u8 taskId) static void StartTaskAfterDelayOrInput(u8 taskId, TaskFunc task, u16 delay, u16 key) { - sRoulette->varB4 = gTasks[taskId].func; + sRoulette->prevTask = gTasks[taskId].func; if (task == NULL) - task = sRoulette->varB4; + task = sRoulette->prevTask; sRoulette->nextTask = task; sRoulette->taskWaitDelay = delay; if (delay == 0xFFFF && key == 0) @@ -1933,10 +1958,10 @@ static void StartTaskAfterDelayOrInput(u8 taskId, TaskFunc task, u16 delay, u16 static void sub_8141FF4(u8 taskId) { u8 i = 0; - sRoulette->var00 = i; - sRoulette->var03_7 = FALSE; - sRoulette->var03_5 = FALSE; - sRoulette->var03_6 = FALSE; + sRoulette->unk0 = FALSE; + sRoulette->ballRolling = FALSE; + sRoulette->ballStuck = FALSE; + sRoulette->ballUnstuck = FALSE; sRoulette->useTaillow = FALSE; for (i = 0; i < BALLS_PER_ROUND; i++) @@ -2040,7 +2065,7 @@ static bool8 IsHitInBetSelection(u8 gridSquare, u8 betSelection) static void FlashSelectionOnWheel(u8 selectionId) { u16 var0 = 0; - u8 var2; + u8 numSelected; u16 var3; u8 i; @@ -2049,23 +2074,26 @@ static void FlashSelectionOnWheel(u8 selectionId) case ROW_ORANGE: case ROW_GREEN: case ROW_PURPLE: + // Flash colors of row selection for (i = (selectionId + 1); i < (selectionId + 5); i++) { if (!(sRoulette->hitFlags & sGridSelections[i].flag)) var0 |= sGridSelections[i].var10; } - sub_8151A48(&sRoulette->varB8, var0 &= 0xDFFF); + sub_8151A48(&sRoulette->flashUtil, var0 &= 0xDFFF); break; default: { - struct UnkStruct1 var1[3]; + // Selection is either a column or individual square + struct UnkStruct1 var1[NUM_BOARD_COLORS]; memcpy(var1, gUnknown_085B63F0, sizeof(var1)); - if (selectionId >= COL_WYNAUT && selectionId <= COL_MAKUHITA) - var2 = 3; - else - var2 = 1; - var3 = selectionId / 5 - 1; + if (selectionId >= COL_WYNAUT && selectionId <= COL_MAKUHITA) + numSelected = NUM_BOARD_COLORS; // Selection is full column + else + numSelected = 1; + + var3 = GET_ROW_IDX(selectionId); switch (GET_COL(selectionId)) { // The specific color of the poke it references doesn't matter, because the icons themelves all share a palette @@ -2083,36 +2111,42 @@ static void FlashSelectionOnWheel(u8 selectionId) var3 = gSprites[sRoulette->spriteIds[SPR_BOARD_ICON_ORANGE_MAKUHITA]].oam.paletteNum * 16; break; } - if (var2 == 1) + if (numSelected == 1) { + // Selection is individual square if (!(sRoulette->hitFlags & sGridSelections[selectionId].flag)) { - var1[selectionId / 5 - 1].var02 += var3; - sub_815168C(&sRoulette->varB8, 13, &var1[selectionId / 5 - 1]); + // Set poke icon of selected square to flash + var1[GET_ROW_IDX(selectionId)].var02 += var3; + sub_815168C(&sRoulette->flashUtil, 13, &var1[GET_ROW_IDX(selectionId)]); } else { + // Square was already hit, don't flash it break; } } else { - for (i = 0; i < 3; i++) + // Selection is full column + for (i = 0; i < NUM_BOARD_COLORS; i++) { u8 var4 = i * 5 + selectionId + 5; if (!(sRoulette->hitFlags & sGridSelections[var4].flag)) { - var1[var4 / 5 - 1].var02 += var3; - sub_815168C(&sRoulette->varB8, i + 13, &var1[var4 / 5 - 1]); - if (var2 == 3) + // Set poke icons of selected squares to flash + var1[GET_ROW_IDX(var4)].var02 += var3; + sub_815168C(&sRoulette->flashUtil, i + 13, &var1[GET_ROW_IDX(var4)]); + if (numSelected == 3) var0 = sGridSelections[var4].var10; - var2--; + numSelected--; } } - if (var2 != 2) + if (numSelected != 2) var0 = 0; } - sub_8151A48(&sRoulette->varB8, var0 |= sGridSelections[selectionId].var10); + // Do flash + sub_8151A48(&sRoulette->flashUtil, var0 |= sGridSelections[selectionId].var10); break; } } @@ -2127,9 +2161,9 @@ static void DrawGridBackground(u8 selectionId) vu8 var0; u8 v[5]; u8 l; - sRoulette->var2A = 1; + sRoulette->updateGridHighlight = TRUE; ShowHideGridIcons(FALSE, 0); - SetGridSelectionRect(sRoulette->tilemapBuffers[2], sRoulette->unk_397C, 14, 7, 16, 13); + SetTilemapRect(sRoulette->tilemapBuffers[2], sRoulette->gridTilemap, 14, 7, 16, 13); switch (selectionId) { case SELECTION_NONE: @@ -2141,7 +2175,7 @@ static void DrawGridBackground(u8 selectionId) l = 4; for (i = 0; i < l; i++) { - v[i] = i * 5 + selectionId; + v[i] = i * ROW_ORANGE + selectionId; } break; case ROW_ORANGE: @@ -2165,16 +2199,16 @@ static void DrawGridBackground(u8 selectionId) for (z = 0; z < 3; z++) { var2 = (sGridSelections[v[i]].y + z) * 32; - sRoulette->tilemapBuffers[2][var1 + var2 + 0] = sRoulette->unk_397C[(var0 + z) * 3 + 208]; - sRoulette->tilemapBuffers[2][var1 + var2 + 1] = sRoulette->unk_397C[(var0 + z) * 3 + 209]; - sRoulette->tilemapBuffers[2][var1 + var2 + 2] = sRoulette->unk_397C[(var0 + z) * 3 + 210]; + sRoulette->tilemapBuffers[2][var1 + var2 + 0] = sRoulette->gridTilemap[(var0 + z) * 3 + 208]; + sRoulette->tilemapBuffers[2][var1 + var2 + 1] = sRoulette->gridTilemap[(var0 + z) * 3 + 209]; + sRoulette->tilemapBuffers[2][var1 + var2 + 2] = sRoulette->gridTilemap[(var0 + z) * 3 + 210]; } } } static u8 GetMultiplier(u8 selectionId) { - u8 multipliers[5] = {0, 3, 4, 6, 12}; + u8 multipliers[5] = {0, 3, 4, 6, MAX_MULTIPLIER}; if (selectionId > NUM_GRID_SELECTIONS) selectionId = 0; @@ -2182,13 +2216,13 @@ static u8 GetMultiplier(u8 selectionId) switch (sGridSelections[selectionId].baseMultiplier) { case NUM_BOARD_COLORS: - selectionId = selectionId / 5 - 1; + selectionId = GET_ROW_IDX(selectionId); // If already hit all pokes of this color, multiplier is 0 if (sRoulette->colorHits[selectionId] >= NUM_BOARD_POKES) return 0; return multipliers[sRoulette->colorHits[selectionId] + 1]; case NUM_BOARD_POKES: - selectionId--; + selectionId = GET_COL_IDX(selectionId); // If already hit all colors of this poke, multiplier is 0 if (sRoulette->pokeHits[selectionId] >= NUM_BOARD_COLORS) return 0; @@ -2197,27 +2231,27 @@ static u8 GetMultiplier(u8 selectionId) // If square has been hit already, multiplier is 0 if (sRoulette->hitFlags & sGridSelections[selectionId].flag) return 0; - return multipliers[4]; + return multipliers[ARRAY_COUNT(multipliers) - 1]; } return 0; } -static void sub_8142814(void) +static void UpdateWheelPosition(void) { - s32 x1; - s32 x2; - SetGpuReg(REG_OFFSET_BG2PA, sRoulette->var2C.a); - SetGpuReg(REG_OFFSET_BG2PB, sRoulette->var2C.b); - SetGpuReg(REG_OFFSET_BG2PC, sRoulette->var2C.c); - SetGpuReg(REG_OFFSET_BG2PD, sRoulette->var2C.d); - x1 = 0x7400 - sRoulette->var2C.a * (gSpriteCoordOffsetX + 116) - - sRoulette->var2C.b * (gSpriteCoordOffsetY + 80); - x2 = 0x5400 - sRoulette->var2C.c * (gSpriteCoordOffsetX + 116) - - sRoulette->var2C.d * (gSpriteCoordOffsetY + 80); - SetGpuReg(REG_OFFSET_BG2X_L, x1); - SetGpuReg(REG_OFFSET_BG2X_H, (x1 & 0x0fff0000) >> 16); - SetGpuReg(REG_OFFSET_BG2Y_L, x2); - SetGpuReg(REG_OFFSET_BG2Y_H, (x2 & 0x0fff0000) >> 16); + s32 bg2x; + s32 bg2y; + SetGpuReg(REG_OFFSET_BG2PA, sRoulette->wheelRotation.a); + SetGpuReg(REG_OFFSET_BG2PB, sRoulette->wheelRotation.b); + SetGpuReg(REG_OFFSET_BG2PC, sRoulette->wheelRotation.c); + SetGpuReg(REG_OFFSET_BG2PD, sRoulette->wheelRotation.d); + bg2x = 0x7400 - sRoulette->wheelRotation.a * (gSpriteCoordOffsetX + 116) + - sRoulette->wheelRotation.b * (gSpriteCoordOffsetY + 80); + bg2y = 0x5400 - sRoulette->wheelRotation.c * (gSpriteCoordOffsetX + 116) + - sRoulette->wheelRotation.d * (gSpriteCoordOffsetY + 80); + SetGpuReg(REG_OFFSET_BG2X_L, bg2x); + SetGpuReg(REG_OFFSET_BG2X_H, (bg2x & 0x0fff0000) >> 16); + SetGpuReg(REG_OFFSET_BG2Y_L, bg2y); + SetGpuReg(REG_OFFSET_BG2Y_H, (bg2y & 0x0fff0000) >> 16); } static const u8 sFiller[3] = {}; @@ -2262,7 +2296,7 @@ static const struct SpritePalette sSpritePalettes[] = {} }; -static const struct OamData gOamData_85B73EC = +static const struct OamData sOam_GridHeader = { .affineMode = ST_OAM_AFFINE_OFF, .objMode = ST_OAM_OBJ_NORMAL, @@ -2494,7 +2528,7 @@ static const struct SpriteTemplate sSpriteTemplates_PokeHeaders[NUM_BOARD_POKES] { .tileTag = GFXTAG_HEADERS, .paletteTag = PALTAG_GRID_ICONS, - .oam = &gOamData_85B73EC, + .oam = &sOam_GridHeader, .anims = sAnim_WynautHeader, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, @@ -2503,7 +2537,7 @@ static const struct SpriteTemplate sSpriteTemplates_PokeHeaders[NUM_BOARD_POKES] { .tileTag = GFXTAG_HEADERS, .paletteTag = PALTAG_GRID_ICONS, - .oam = &gOamData_85B73EC, + .oam = &sOam_GridHeader, .anims = sAnim_AzurillHeader, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, @@ -2512,7 +2546,7 @@ static const struct SpriteTemplate sSpriteTemplates_PokeHeaders[NUM_BOARD_POKES] { .tileTag = GFXTAG_HEADERS, .paletteTag = PALTAG_GRID_ICONS, - .oam = &gOamData_85B73EC, + .oam = &sOam_GridHeader, .anims = sAnim_SkittyHeader, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, @@ -2521,7 +2555,7 @@ static const struct SpriteTemplate sSpriteTemplates_PokeHeaders[NUM_BOARD_POKES] { .tileTag = GFXTAG_HEADERS, .paletteTag = PALTAG_GRID_ICONS, - .oam = &gOamData_85B73EC, + .oam = &sOam_GridHeader, .anims = sAnim_MakuhitaHeader, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, @@ -2534,7 +2568,7 @@ static const struct SpriteTemplate sSpriteTemplates_ColorHeaders[NUM_BOARD_COLOR { .tileTag = GFXTAG_HEADERS, .paletteTag = PALTAG_GRID_ICONS, - .oam = &gOamData_85B73EC, + .oam = &sOam_GridHeader, .anims = sAnim_OrangeHeader, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, @@ -2543,7 +2577,7 @@ static const struct SpriteTemplate sSpriteTemplates_ColorHeaders[NUM_BOARD_COLOR { .tileTag = GFXTAG_HEADERS, .paletteTag = PALTAG_GRID_ICONS, - .oam = &gOamData_85B73EC, + .oam = &sOam_GridHeader, .anims = sAnim_GreenHeader, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, @@ -2552,7 +2586,7 @@ static const struct SpriteTemplate sSpriteTemplates_ColorHeaders[NUM_BOARD_COLOR { .tileTag = GFXTAG_HEADERS, .paletteTag = PALTAG_GRID_ICONS, - .oam = &gOamData_85B73EC, + .oam = &sOam_GridHeader, .anims = sAnim_PurpleHeader, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, @@ -2880,7 +2914,7 @@ static const struct SpriteTemplate sSpriteTemplate_Cursor = { .tileTag = GFXTAG_CURSOR, .paletteTag = PALTAG_INTERFACE, - .oam = &gOamData_85B73EC, + .oam = &sOam_GridHeader, .anims = gDummySpriteAnimTable, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, @@ -3440,7 +3474,7 @@ static void CreateGridSprites(void) } for (i = 0; i < ARRAY_COUNT(sSpriteTemplates_PokeHeaders); i++) { - spriteId = sRoulette->spriteIds[i + SPR_POKE_HEADER_1] = CreateSprite(&sSpriteTemplates_PokeHeaders[i], (i * 24) + 148, 70, 30); + spriteId = sRoulette->spriteIds[i + SPR_POKE_HEADERS] = CreateSprite(&sSpriteTemplates_PokeHeaders[i], (i * 24) + 148, 70, 30); gSprites[spriteId].animPaused = TRUE; } for (i = 0; i < ARRAY_COUNT(sSpriteTemplates_ColorHeaders); i++) @@ -3577,7 +3611,7 @@ static void SpriteCB_BoardIcon(struct Sprite *sprite) s16 cos; s16 sin; u32 matrixNum; - s16 angle = sRoulette->var24 + sprite->data[0]; + s16 angle = sRoulette->wheelAngle + sprite->data[0]; if (angle >= 360) angle -= 360; sin = Sin2(angle); @@ -3608,18 +3642,18 @@ static void CreateInterfaceSprites(void) gSprites[sRoulette->spriteIds[SPR_CREDIT]].animPaused = TRUE; for (i = 0; i < MAX_COIN_DIGITS; i++) { - sRoulette->spriteIds[i + SPR_CREDIT_DIG_1] = CreateSprite(&sSpriteTemplate_CreditDigit, i * 8 + 196, 24, 0); - gSprites[sRoulette->spriteIds[i + SPR_CREDIT_DIG_1]].invisible = TRUE; - gSprites[sRoulette->spriteIds[i + SPR_CREDIT_DIG_1]].animPaused = TRUE; + sRoulette->spriteIds[i + SPR_CREDIT_DIGITS] = CreateSprite(&sSpriteTemplate_CreditDigit, i * 8 + 196, 24, 0); + gSprites[sRoulette->spriteIds[i + SPR_CREDIT_DIGITS]].invisible = TRUE; + gSprites[sRoulette->spriteIds[i + SPR_CREDIT_DIGITS]].animPaused = TRUE; } sRoulette->spriteIds[SPR_MULTIPLIER] = CreateSprite(&sSpriteTemplate_Multiplier, 120, 68, 4); gSprites[sRoulette->spriteIds[SPR_MULTIPLIER]].animPaused = TRUE; for (i = 0; i < BALLS_PER_ROUND / 2; i++) { // Each ball counter sprite has 2 balls - sRoulette->spriteIds[i + SPR_BALL_COUNTER_1] = CreateSprite(&sSpriteTemplate_BallCounter, i * 16 + 192, 36, 4); - gSprites[sRoulette->spriteIds[i + SPR_BALL_COUNTER_1]].invisible = TRUE; - gSprites[sRoulette->spriteIds[i + SPR_BALL_COUNTER_1]].animPaused = TRUE; + sRoulette->spriteIds[i + SPR_BALL_COUNTER] = CreateSprite(&sSpriteTemplate_BallCounter, i * 16 + 192, 36, 4); + gSprites[sRoulette->spriteIds[i + SPR_BALL_COUNTER]].invisible = TRUE; + gSprites[sRoulette->spriteIds[i + SPR_BALL_COUNTER]].animPaused = TRUE; } sRoulette->spriteIds[SPR_WIN_SLOT_CURSOR] = CreateSprite(&sSpriteTemplate_Cursor, 152, 96, 9); gSprites[sRoulette->spriteIds[SPR_WIN_SLOT_CURSOR]].oam.priority = 1; @@ -3627,24 +3661,24 @@ static void CreateInterfaceSprites(void) gSprites[sRoulette->spriteIds[SPR_WIN_SLOT_CURSOR]].invisible = TRUE; } -static void SetCreditDigits(u16 r0) +static void SetCreditDigits(u16 num) { u8 i; u16 d = 1000; - bool8 v = FALSE; + bool8 printZero = FALSE; for (i = 0; i < MAX_COIN_DIGITS; i++) { - u8 t = r0 / d; - gSprites[sRoulette->spriteIds[i + SPR_CREDIT_DIG_1]].invisible = TRUE; - if (t > 0 || v || i == MAX_COIN_DIGITS - 1) + u8 digit = num / d; + gSprites[sRoulette->spriteIds[i + SPR_CREDIT_DIGITS]].invisible = TRUE; + if (digit > 0 || printZero || i == MAX_COIN_DIGITS - 1) { - gSprites[sRoulette->spriteIds[i + SPR_CREDIT_DIG_1]].invisible = FALSE; - gSprites[sRoulette->spriteIds[i + SPR_CREDIT_DIG_1]].oam.tileNum = - gSprites[sRoulette->spriteIds[i + SPR_CREDIT_DIG_1]].sheetTileStart - + (*gSprites[sRoulette->spriteIds[i + SPR_CREDIT_DIG_1]].anims + t)->type; - v = TRUE; + gSprites[sRoulette->spriteIds[i + SPR_CREDIT_DIGITS]].invisible = FALSE; + gSprites[sRoulette->spriteIds[i + SPR_CREDIT_DIGITS]].oam.tileNum = + gSprites[sRoulette->spriteIds[i + SPR_CREDIT_DIGITS]].sheetTileStart + + (*gSprites[sRoulette->spriteIds[i + SPR_CREDIT_DIGITS]].anims + digit)->type; + printZero = TRUE; } - r0 = r0 % d; + num = num % d; d = d / 10; } } @@ -3660,12 +3694,12 @@ static u8 GetMultiplierAnimId(u8 selectionId) switch (sGridSelections[selectionId].baseMultiplier) { case NUM_BOARD_COLORS: - selectionId = selectionId / 5 - 1; + selectionId = GET_ROW_IDX(selectionId); if (sRoulette->colorHits[selectionId] > 3) return 0; return animIds[sRoulette->colorHits[selectionId] + 1]; case NUM_BOARD_POKES: - selectionId--; + selectionId = GET_COL_IDX(selectionId); if (sRoulette->pokeHits[selectionId] > 2) return 0; return animIds[sRoulette->pokeHits[selectionId] + 2]; @@ -3695,10 +3729,10 @@ static void SetBallCounterNumLeft(u8 numBalls) case 6: for (i = 0; i < BALLS_PER_ROUND / 2; i++) { - gSprites[sRoulette->spriteIds[i + SPR_BALL_COUNTER_1]].invisible = FALSE; - gSprites[sRoulette->spriteIds[i + SPR_BALL_COUNTER_1]].oam.tileNum = - gSprites[sRoulette->spriteIds[i + SPR_BALL_COUNTER_1]].sheetTileStart - + (*gSprites[sRoulette->spriteIds[i + SPR_BALL_COUNTER_1]].anims)->type; + gSprites[sRoulette->spriteIds[i + SPR_BALL_COUNTER]].invisible = FALSE; + gSprites[sRoulette->spriteIds[i + SPR_BALL_COUNTER]].oam.tileNum = + gSprites[sRoulette->spriteIds[i + SPR_BALL_COUNTER]].sheetTileStart + + (*gSprites[sRoulette->spriteIds[i + SPR_BALL_COUNTER]].anims)->type; } break; case 5: @@ -3730,16 +3764,16 @@ static void SetBallCounterNumLeft(u8 numBalls) default: for (i = 0; i < BALLS_PER_ROUND / 2; i++) { - gSprites[sRoulette->spriteIds[i + SPR_BALL_COUNTER_1]].oam.tileNum = - gSprites[sRoulette->spriteIds[i + SPR_BALL_COUNTER_1]].sheetTileStart - + (*gSprites[sRoulette->spriteIds[i + SPR_BALL_COUNTER_1]].anims + t + 2)->type; + gSprites[sRoulette->spriteIds[i + SPR_BALL_COUNTER]].oam.tileNum = + gSprites[sRoulette->spriteIds[i + SPR_BALL_COUNTER]].sheetTileStart + + (*gSprites[sRoulette->spriteIds[i + SPR_BALL_COUNTER]].anims + t + 2)->type; } } } static void SpriteCB_GridSquare(struct Sprite *sprite) { - sprite->pos2.x = sRoulette->var26; + sprite->pos2.x = sRoulette->gridX; } static void CreateBoardCenterSprite(void) @@ -3752,7 +3786,7 @@ static void CreateBoardCenterSprite(void) s.tag = sSpriteSheet_BoardCenter.tag; LoadSpriteSheet(&s); spriteId = CreateSprite(&sSpriteTemplate_BoardCenter, 116, 80, 81); - gSprites[spriteId].data[0] = sRoulette->var24; + gSprites[spriteId].data[0] = sRoulette->wheelAngle; gSprites[spriteId].data[1] = 0; gSprites[spriteId].animPaused = TRUE; gSprites[spriteId].affineAnimPaused = TRUE; @@ -3763,10 +3797,10 @@ static void SpriteCB_BoardCenter(struct Sprite *sprite) { u32 t = sprite->oam.matrixNum; struct OamMatrix *m = &gOamMatrices[0]; - m[t].d = sRoulette->var2C.a; - m[t].a = sRoulette->var2C.a; - m[t].b = sRoulette->var2C.b; - m[t].c = sRoulette->var2C.c; + m[t].d = sRoulette->wheelRotation.a; + m[t].a = sRoulette->wheelRotation.a; + m[t].b = sRoulette->wheelRotation.b; + m[t].c = sRoulette->wheelRotation.c; } static void CreateBoardBallSprites(void) @@ -3785,33 +3819,32 @@ static void CreateBoardBallSprites(void) static void HideBoardBalls(void) { - u8 t = sRoulette->spriteIds[SPR_BALL_1]; + u8 spriteId = sRoulette->spriteIds[SPR_BALL_1]; u8 i; for (i = 0; i < BALLS_PER_ROUND; i++) { u8 j; - gSprites[t].invisible = TRUE; - gSprites[t].callback = &SpriteCallbackDummy; - StartSpriteAnim(&gSprites[t], 0); + gSprites[spriteId].invisible = TRUE; + gSprites[spriteId].callback = &SpriteCallbackDummy; + StartSpriteAnim(&gSprites[spriteId], 0); for (j = 0; j < 8; j++) - { - gSprites[t].data[j] = 0; - } - t++; + gSprites[spriteId].data[j] = 0; + + spriteId++; } } static s16 sub_8143AC8(struct Sprite *sprite) { - if (sRoulette->var24 > sprite->data[3]) + if (sRoulette->wheelAngle > sprite->data[3]) { - sprite->data[6] = 360 - sRoulette->var24 + sprite->data[3]; + sprite->data[6] = 360 - sRoulette->wheelAngle + sprite->data[3]; if (sprite->data[6] >= 360) sprite->data[6] -= 360; } else { - sprite->data[6] = sprite->data[3] - sRoulette->var24; + sprite->data[6] = sprite->data[3] - sRoulette->wheelAngle; } return sprite->data[6]; @@ -3819,8 +3852,8 @@ static s16 sub_8143AC8(struct Sprite *sprite) static u8 sub_8143B14(struct Sprite *sprite) { - sRoulette->var7E = sub_8143AC8(sprite) / 30.0f; - return sRoulette->var7E; + sRoulette->hitSlot = sub_8143AC8(sprite) / 30.0f; + return sRoulette->hitSlot; } static s16 sub_8143B48(struct Sprite *sprite) @@ -3874,7 +3907,7 @@ static void sub_8143B84(struct Sprite *sprite) static void sub_8143C90(struct Sprite *sprite) { s16 sin, cos; - sprite->data[3] = sRoulette->var24 + sprite->data[6]; + sprite->data[3] = sRoulette->wheelAngle + sprite->data[6]; if (sprite->data[3] >= 360) sprite->data[3] -= 360; sin = Sin2(sprite->data[3]); @@ -3899,9 +3932,9 @@ static void sub_8143CFC(struct Sprite *sprite) { if (sRoulette->var94 <= sRoulette->varA0 - 2.0f) { - sRoulette->var7D = 0xFF; - sRoulette->var03_7 = FALSE; - StartSpriteAnim(sprite, sprite->animCmdIndex + 0x3); + sRoulette->ballState = BALL_STATE_LANDED; + sRoulette->ballRolling = FALSE; + StartSpriteAnim(sprite, sprite->animCmdIndex + 3); sub_8143B14(sprite); sprite->data[4] = 30; sub_8143AC8(sprite); @@ -3916,8 +3949,8 @@ static void sub_8143CFC(struct Sprite *sprite) { if (sRoulette->var94 >= sRoulette->varA0 - 2.0f) { - sRoulette->var7D = 0xFF; - sRoulette->var03_7 = FALSE; + sRoulette->ballState = BALL_STATE_LANDED; + sRoulette->ballRolling = FALSE; StartSpriteAnim(sprite, sprite->animCmdIndex + 3); sub_8143B14(sprite); sprite->data[4] = 30; @@ -3943,8 +3976,8 @@ static void SpriteCB_Shroomish(struct Sprite *sprite) if (sprite->data[0] != 1) { f0 = sprite->data[7]; - f1 = (f0 * gUnknown_085B6348[sRoulette->tableId].var01 + (gUnknown_085B6348[sRoulette->tableId].var02 - 1)); - f2 = (f0 / gUnknown_085B6348[sRoulette->tableId].var0C); + f1 = (f0 * sRouletteTables[sRoulette->tableId].var01 + (sRouletteTables[sRoulette->tableId].var02 - 1)); + f2 = (f0 / sRouletteTables[sRoulette->tableId].var0C); } else { @@ -3955,8 +3988,8 @@ static void SpriteCB_Shroomish(struct Sprite *sprite) if (sprite->data[0] != 0) { f0 = sprite->data[7]; - f1 = (f0 * gUnknown_085B6348[sRoulette->tableId].var01 + (gUnknown_085B6348[sRoulette->tableId].var02 - 1)); - f2 = -(f0 / gUnknown_085B6348[sRoulette->tableId].var0C); + f1 = (f0 * sRouletteTables[sRoulette->tableId].var01 + (sRouletteTables[sRoulette->tableId].var02 - 1)); + f2 = -(f0 / sRouletteTables[sRoulette->tableId].var0C); } else { @@ -3984,8 +4017,8 @@ static void sub_8143FA4(struct Sprite *sprite) sprite->data[2]++; if (sprite->data[2] > 29 && sprite->pos2.y >= 0) { - sRoulette->var7D = 0xFF; - sRoulette->var03_7 = FALSE; + sRoulette->ballState = BALL_STATE_LANDED; + sRoulette->ballRolling = FALSE; StartSpriteAnim(sprite, sprite->animCmdIndex + 3); sub_8143B14(sprite); sprite->data[4] = 30; @@ -3993,7 +4026,7 @@ static void sub_8143FA4(struct Sprite *sprite) sprite->data[6] = (sprite->data[6] / 30) * 30 + 15; sprite->callback = sub_8143C90; m4aSongNumStartOrChange(SE_HASHI); - sRoulette->var03_6 = TRUE; + sRoulette->ballUnstuck = TRUE; } } @@ -4081,8 +4114,8 @@ static void prev_quest_read_x24_hm_usage(struct Sprite *sprite) { if (!sprite->data[0]) { - sRoulette->var7D = 0xFF; - sRoulette->var03_7 = FALSE; + sRoulette->ballState = BALL_STATE_LANDED; + sRoulette->ballRolling = FALSE; StartSpriteAnim(sprite, sprite->animCmdIndex + 3); sub_8143B14(sprite); sprite->data[4] = 30; @@ -4105,10 +4138,10 @@ static void sub_8144264(struct Sprite *sprite) sub_8143B84(sprite); sprite->data[2] = 0; sub_8143B14(sprite); - if (!(sRouletteSlots[sRoulette->var7E].flag & sRoulette->hitFlags)) + if (!(sRouletteSlots[sRoulette->hitSlot].flag & sRoulette->hitFlags)) { - sRoulette->var7D = 0xFF; - sRoulette->var03_7 = FALSE; + sRoulette->ballState = BALL_STATE_LANDED; + sRoulette->ballRolling = FALSE; StartSpriteAnim(sprite, sprite->animCmdIndex + 3); sub_8143B14(sprite); sprite->data[4] = 30; @@ -4126,30 +4159,30 @@ static void sub_8144264(struct Sprite *sprite) if (z) { sRoulette->var8C = 0.0f; - sRoulette->var7F = slotId = (sRoulette->var7E + 1) % NUM_ROULETTE_SLOTS; + sRoulette->var7F = slotId = (sRoulette->hitSlot + 1) % NUM_ROULETTE_SLOTS; } else { float temp; - sRoulette->var8C = (temp = gUnknown_085B6348[sRoulette->tableId].var1C) * 2.0f; - slotId = (sRoulette->var7E + NUM_ROULETTE_SLOTS - 1) % NUM_ROULETTE_SLOTS; - sRoulette->var7F = sRoulette->var7E; + sRoulette->var8C = (temp = sRouletteTables[sRoulette->tableId].var1C) * 2.0f; + slotId = (sRoulette->hitSlot + NUM_ROULETTE_SLOTS - 1) % NUM_ROULETTE_SLOTS; + sRoulette->var7F = sRoulette->hitSlot; } if (sRouletteSlots[slotId].flag & sRoulette->hitFlags) { sprite->data[0] = 1; - sprite->data[2] = gUnknown_085B6348[sRoulette->tableId].var02; + sprite->data[2] = sRouletteTables[sRoulette->tableId].var02; } else { sprite->data[0] = sRouletteSlots[slotId].flag & sRoulette->hitFlags; if (sRoulette->tableId) { - sprite->data[2] = gUnknown_085B6348[sRoulette->tableId].var01; + sprite->data[2] = sRouletteTables[sRoulette->tableId].var01; } else { - sprite->data[2] = gUnknown_085B6348[sRoulette->tableId].var02; + sprite->data[2] = sRouletteTables[sRoulette->tableId].var02; if (z) sRoulette->var8C = 0.5f; else @@ -4172,8 +4205,8 @@ static void sub_8144410(struct Sprite *sprite) if (!sub_8143B48(sprite)) { sRoulette->var90 = 0.0f; - sRoulette->var8C -= (float)(gUnknown_085B6348[sRoulette->tableId].var03) - / (gUnknown_085B6348[sRoulette->tableId].var04 + 1); + sRoulette->var8C -= (float)(sRouletteTables[sRoulette->tableId].wheelSpeed) + / (sRouletteTables[sRoulette->tableId].wheelDelay + 1); sprite->data[1] = 4; sprite->callback = sub_8144264; } @@ -4257,8 +4290,8 @@ static void CreateShroomishSprite(struct Sprite *sprite) gSprites[sRoulette->spriteIds[i + SPR_CLEAR_MON]].data[5] = sRoulette->spriteIds[SPR_CLEAR_MON_SHADOW_1]; gSprites[sRoulette->spriteIds[i + SPR_CLEAR_MON]].data[6] = sRoulette->spriteIds[SPR_CLEAR_MON_SHADOW_2]; gSprites[sRoulette->spriteIds[i + SPR_CLEAR_MON]].data[2] = t; - gSprites[sRoulette->spriteIds[i + SPR_CLEAR_MON]].data[3] = (sprite->data[7] * gUnknown_085B6348[sRoulette->tableId].var01) + - (gUnknown_085B6348[sRoulette->tableId].var02 + 0xFFFF); + gSprites[sRoulette->spriteIds[i + SPR_CLEAR_MON]].data[3] = (sprite->data[7] * sRouletteTables[sRoulette->tableId].var01) + + (sRouletteTables[sRoulette->tableId].var02 + 0xFFFF); } gSprites[sRoulette->spriteIds[SPR_CLEAR_MON_SHADOW_1]].coordOffsetEnabled = TRUE; sRoulette->var38 = sprite; @@ -4279,7 +4312,7 @@ static void CreateTaillowSprite(struct Sprite *sprite) sRoulette->spriteIds[SPR_CLEAR_MON_SHADOW_1] = CreateSprite(&sSpriteTemplate_TaillowShadow, s[sprite->data[0]][0], s[sprite->data[0]][1], 51); gSprites[sRoulette->spriteIds[SPR_CLEAR_MON_SHADOW_1]].affineAnimPaused = TRUE; gSprites[sRoulette->spriteIds[SPR_CLEAR_MON_SHADOW_1]].animPaused = TRUE; - sprite->data[7] = (t * gUnknown_085B6348[sRoulette->tableId].var01) + (gUnknown_085B6348[sRoulette->tableId].var10 + 45); + sprite->data[7] = (t * sRouletteTables[sRoulette->tableId].var01) + (sRouletteTables[sRoulette->tableId].var10 + 45); for (; i < 2; i++) { gSprites[sRoulette->spriteIds[SPR_CLEAR_MON + i]].data[4] = sRoulette->spriteIds[SPR_CLEAR_MON]; @@ -4303,13 +4336,13 @@ static void sub_8144A24(struct Sprite *sprite) u8 s[10] = {}; u16 rand = Random(); - sRoulette->var7D = 1; - sRoulette->var03_5 = TRUE; - sRoulette->var03_6 = FALSE; - sRoulette->var7E = 0xFF; + sRoulette->ballState = BALL_STATE_STUCK; + sRoulette->ballStuck = TRUE; + sRoulette->ballUnstuck = FALSE; + sRoulette->hitSlot = 0xFF; sRoulette->var88 = sprite->data[3]; sRoulette->var98 = 0.0f; - sRoulette->var8C = gUnknown_085B6348[sRoulette->tableId].var1C; + sRoulette->var8C = sRouletteTables[sRoulette->tableId].var1C; o = (sRoulette->tableId * 30 + 33) + (1 - sRoulette->useTaillow) * 15; for (i = 0; i < 4; i++) @@ -4342,7 +4375,7 @@ static void sub_8144A24(struct Sprite *sprite) } val = 2; - z = (sRoulette->var7F + 2) % 12; + z = (sRoulette->var7F + 2) % NUM_ROULETTE_SLOTS; if (sRoulette->useTaillow == TRUE && sRoulette->tableId == 1) j += 6; @@ -4395,8 +4428,8 @@ static void sub_8144C70(struct Sprite *sprite) sprite->pos1.x -= 2; if (sprite->pos1.x < -16) { - if (!sRoulette->var03_6) - sRoulette->var03_6 = TRUE; + if (!sRoulette->ballUnstuck) + sRoulette->ballUnstuck = TRUE; DestroySprite(sprite); sRoulette->var01 = 0; sRoulette->var34 = gUnknown_085B7B1A[0]; @@ -4458,12 +4491,12 @@ static void sub_8144E60(struct Sprite *sprite) { if (sRoulette->var38->data[0] == 0) { - if (sRoulette->var38->data[3] != gUnknown_085B6348[sRoulette->tableId].var08) + if (sRoulette->var38->data[3] != sRouletteTables[sRoulette->tableId].var08) return; } else { - if (sRoulette->var38->data[3] != gUnknown_085B6348[sRoulette->tableId].var08 + 180) + if (sRoulette->var38->data[3] != sRouletteTables[sRoulette->tableId].var08 + 180) return; } @@ -4481,12 +4514,12 @@ static void sub_8144E60(struct Sprite *sprite) if (sRoulette->var38->data[0] == 0) { - if (sRoulette->var38->data[3] != gUnknown_085B6348[sRoulette->tableId].var0A) + if (sRoulette->var38->data[3] != sRouletteTables[sRoulette->tableId].var0A) return; } else { - if (sRoulette->var38->data[3] != gUnknown_085B6348[sRoulette->tableId].var0A + 180) + if (sRoulette->var38->data[3] != sRouletteTables[sRoulette->tableId].var0A + 180) return; } @@ -4616,7 +4649,7 @@ static void SpriteCB_Taillow(struct Sprite *sprite) { if (sRoulette->var38->data[0] == 0) { - if (sRoulette->var38->data[3] == gUnknown_085B6348[sRoulette->tableId].var12 + 90) + if (sRoulette->var38->data[3] == sRouletteTables[sRoulette->tableId].var12 + 90) { gSprites[sprite->data[6]].data[1] = 52; gSprites[sprite->data[4]].data[1] = 52; @@ -4628,7 +4661,7 @@ static void SpriteCB_Taillow(struct Sprite *sprite) } else { - if (sRoulette->var38->data[3] == gUnknown_085B6348[sRoulette->tableId].var14 + 270) + if (sRoulette->var38->data[3] == sRouletteTables[sRoulette->tableId].var14 + 270) { gSprites[sprite->data[6]].data[1] = 46; gSprites[sprite->data[4]].data[1] = 46; diff --git a/src/roulette_util.c b/src/roulette_util.c index c51330f21..4e6977675 100755 --- a/src/roulette_util.c +++ b/src/roulette_util.c @@ -4,6 +4,10 @@ #include "roulette_util.h" #include "util.h" +// "Roulette Util" is perhaps more accurately a general flashing util +// e.g. it handles fading the palettes for the color selections on the Roulette wheel +// but it also handles the "pulse blend" effect of Mirage Tower + void sub_8151678(struct UnkStruct0 *r0) { r0->var00 = 0; @@ -429,7 +433,8 @@ void UpdatePulseBlend(struct PulseBlend *pulseBlend) } } -void ClearGridSelectionRect(u16 *dest, u16 src, u8 left, u8 top, u8 width, u8 height) +// Below used for the Roulette grid +void ClearTilemapRect(u16 *dest, u16 src, u8 left, u8 top, u8 width, u8 height) { u16 *_dest; u8 i; @@ -446,7 +451,7 @@ void ClearGridSelectionRect(u16 *dest, u16 src, u8 left, u8 top, u8 width, u8 he } } -void SetGridSelectionRect(u16 *dest, u16 *src, u8 left, u8 top, u8 width, u8 height) +void SetTilemapRect(u16 *dest, u16 *src, u8 left, u8 top, u8 width, u8 height) { u16 *_dest; u16 *_src = src; From 868f831167cc20d47cd26292cf55f58dd862d4ae Mon Sep 17 00:00:00 2001 From: GriffinR Date: Mon, 3 Aug 2020 17:31:34 -0400 Subject: [PATCH 3/6] More roulette doc --- graphics_file_rules.mk | 2 +- include/roulette.h | 30 +- include/roulette_util.h | 32 +- src/roulette.c | 1597 ++++++++++++++++++++------------------- src/roulette_util.c | 22 +- 5 files changed, 878 insertions(+), 805 deletions(-) diff --git a/graphics_file_rules.mk b/graphics_file_rules.mk index f2d14ef3c..019f382eb 100644 --- a/graphics_file_rules.mk +++ b/graphics_file_rules.mk @@ -483,7 +483,7 @@ $(ROULETTEGFXDIR)/roulette_tilt.4bpp: $(ROULETTEGFXDIR)/shroomish.4bpp \ $(ROULETTEGFXDIR)/tailow.4bpp @cat $^ >$@ -$(ROULETTEGFXDIR)/board_icons.4bpp: $(ROULETTEGFXDIR)/wynaut.4bpp \ +$(ROULETTEGFXDIR)/wheel_icons.4bpp: $(ROULETTEGFXDIR)/wynaut.4bpp \ $(ROULETTEGFXDIR)/azurill.4bpp \ $(ROULETTEGFXDIR)/skitty.4bpp \ $(ROULETTEGFXDIR)/makuhita.4bpp diff --git a/include/roulette.h b/include/roulette.h index 71100d0d3..c753f671c 100755 --- a/include/roulette.h +++ b/include/roulette.h @@ -1,34 +1,6 @@ #ifndef GUARD_ROULETTE_H #define GUARD_ROULETTE_H -struct UnkStruct1 -{ - u16 var00; - u16 var02; - u8 var04; - u8 var05; - u8 var06; - s8 var07_0:5; - s8 var07_5:2; - s8 var07_7:1; -}; - -struct UnkStruct3 -{ - u8 var00_0:7; - u8 var00_7:1; - u8 var01; - s8 var02; - s8 var03; - struct UnkStruct1 var04; -}; - -struct UnkStruct0 -{ - u8 var00; - u8 var01; - u16 var02; //flag for each UnkStruct3 - struct UnkStruct3 var04[0x10]; -}; +void PlayRoulette(void); #endif // GUARD_ROULETTE_H diff --git a/include/roulette_util.h b/include/roulette_util.h index 2153b19f6..d18d22d0f 100644 --- a/include/roulette_util.h +++ b/include/roulette_util.h @@ -1,8 +1,6 @@ #ifndef GUARD_ROULETTE_UTIL_H #define GUARD_ROULETTE_UTIL_H -#include "roulette.h" - struct PulseBlendSettings { u16 blendColor; @@ -35,6 +33,36 @@ struct PulseBlend struct PulseBlendPalette pulseBlendPalettes[16]; }; +struct UnkStruct1 +{ + u16 var00; + u16 var02; + u8 var04; + u8 var05; + u8 var06; + s8 var07_0:5; + s8 var07_5:2; + s8 var07_7:1; +}; + +struct UnkStruct3 +{ + u8 var00_0:7; + bool8 active:1; + u8 var01; + s8 var02; + s8 var03; + struct UnkStruct1 var04; +}; + +struct UnkStruct0 +{ + u8 var00; + u8 var01; + u16 var02; //flag for each UnkStruct3 + struct UnkStruct3 var04[0x10]; +}; + int InitPulseBlendPaletteSettings(struct PulseBlend *, const struct PulseBlendSettings *); void InitPulseBlend(struct PulseBlend *); void MarkUsedPulseBlendPalettes(struct PulseBlend *, u16, u8); diff --git a/src/roulette.c b/src/roulette.c index 20868f4ba..cc14a67cd 100644 --- a/src/roulette.c +++ b/src/roulette.c @@ -35,10 +35,17 @@ #define BALLS_PER_ROUND 6 -#define NUM_BOARD_COLORS 3 // Grid rows -#define NUM_BOARD_POKES 4 // Grid columns +// "Board" is used in this file to refer to both the wheel and the bet selection grid +#define NUM_BOARD_COLORS 3 // Rows on grid +#define NUM_BOARD_POKES 4 // Columns on grid #define NUM_ROULETTE_SLOTS (NUM_BOARD_COLORS * NUM_BOARD_POKES) +// The degree change between each slot on the roulette wheel +#define DEGREES_PER_SLOT (360 / NUM_ROULETTE_SLOTS) + +// Where in the slot the ball will drop when landing +#define SLOT_MIDPOINT (DEGREES_PER_SLOT / 2 - 1) + // IDs for grid selections when betting #define SELECTION_NONE 0 #define COL_WYNAUT 1 @@ -68,7 +75,7 @@ #define GET_ROW(selectionId)((selectionId) / (NUM_BOARD_POKES + 1) * (NUM_BOARD_POKES + 1)) // Get the col/row index from the selection ID -// e.g. GET_ROW_IDX(SQU_PURPLE_SKITTY) is 2 +// e.g. GET_ROW_IDX(SQU_PURPLE_SKITTY) is 2 (purple being the 3rd row) #define GET_COL_IDX(selectionId)(selectionId - 1) #define GET_ROW_IDX(selectionId)(selectionId / 5 - 1) @@ -98,6 +105,7 @@ #define PALTAG_SHADOW 1 #define PALTAG_BALL 2 #define PALTAG_BALL_COUNTER 3 +#define PALTAG_CURSOR 4 #define PALTAG_INTERFACE 5 #define PALTAG_SHROOMISH 6 #define PALTAG_TAILLOW 7 @@ -107,10 +115,10 @@ #define PALTAG_SKITTY 11 #define PALTAG_MAKUHITA 12 -#define GFXTAG_BOARD_ICONS 0 +#define GFXTAG_WHEEL_ICONS 0 #define GFXTAG_HEADERS 4 #define GFXTAG_GRID_ICONS 5 -#define GFXTAG_BOARD_CENTER 6 +#define GFXTAG_WHEEL_CENTER 6 #define GFXTAG_CREDIT 7 #define GFXTAG_CREDIT_DIGIT 8 #define GFXTAG_MULTIPLIER 9 @@ -122,11 +130,15 @@ // 2 different Roulette tables with 2 different rates (normal vs service day special) // & 1 gets which table, >> 7 gets if ROULETTE_SPECIAL_RATE is set -#define GET_TABLE_ID(var)(((var) & 1) + (((var) >> 7) * 2)) +#define GET_MIN_BET_ID(var)(((var) & 1) + (((var) >> 7) * 2)) +// Having Shroomish or Taillow in the party can make rolls more consistent in length +// It also increases the likelihood that, if they appear to unstick a ball, they'll move it to a slot the player bet on #define HAS_SHROOMISH (1 << 0) #define HAS_TAILLOW (1 << 1) +#define NO_DELAY 0xFFFF + enum { BALL_STATE_ROLLING, BALL_STATE_STUCK, @@ -140,27 +152,29 @@ enum { SELECT_STATE_ERASE = 0xFF, }; +// Roulette uses a large amount of sprites, and stores ids for these in a single array +// Many are looped over rather than referenced directly enum { - SPR_BALL_1, - SPR_BALL_2, - SPR_BALL_3, - SPR_BALL_4, - SPR_BALL_5, - SPR_BALL_6, - SPR_6, - SPR_BOARD_ICON_ORANGE_WYNAUT, - SPR_BOARD_ICON_GREEN_AZURILL, - SPR_BOARD_ICON_PURPLE_SKITTY, - SPR_BOARD_ICON_ORANGE_MAKUHITA, - SPR_BOARD_ICON_GREEN_WYNAUT, - SPR_BOARD_ICON_PURPLE_AZURILL, - SPR_BOARD_ICON_ORANGE_SKITTY, - SPR_BOARD_ICON_GREEN_MAKUHITA, - SPR_BOARD_ICON_PURPLE_WYNAUT, - SPR_BOARD_ICON_ORANGE_AZURILL, - SPR_BOARD_ICON_GREEN_SKITTY, - SPR_BOARD_ICON_PURPLE_MAKUHITA, - SPR_19, + SPR_WHEEL_BALL_1, + SPR_WHEEL_BALL_2, + SPR_WHEEL_BALL_3, + SPR_WHEEL_BALL_4, + SPR_WHEEL_BALL_5, + SPR_WHEEL_BALL_6, + SPR_WHEEL_CENTER, + SPR_WHEEL_ICON_ORANGE_WYNAUT, + SPR_WHEEL_ICON_GREEN_AZURILL, + SPR_WHEEL_ICON_PURPLE_SKITTY, + SPR_WHEEL_ICON_ORANGE_MAKUHITA, + SPR_WHEEL_ICON_GREEN_WYNAUT, + SPR_WHEEL_ICON_PURPLE_AZURILL, + SPR_WHEEL_ICON_ORANGE_SKITTY, + SPR_WHEEL_ICON_GREEN_MAKUHITA, + SPR_WHEEL_ICON_PURPLE_WYNAUT, + SPR_WHEEL_ICON_ORANGE_AZURILL, + SPR_WHEEL_ICON_GREEN_SKITTY, + SPR_WHEEL_ICON_PURPLE_MAKUHITA, + SPR_19, // Unused SPR_CREDIT, SPR_CREDIT_DIG_1, SPR_CREDIT_DIG_10, @@ -199,7 +213,7 @@ enum { SPR_CLEAR_MON, // Shroomish/Taillow SPR_CLEAR_MON_SHADOW_1, SPR_CLEAR_MON_SHADOW_2, - SPR_58, + SPR_58, // Here below unused SPR_59, SPR_60, SPR_61, @@ -208,43 +222,53 @@ enum { }; // Start points for sprite IDs that are looped over -#define SPR_BOARD_ICONS SPR_BOARD_ICON_ORANGE_WYNAUT +#define SPR_WHEEL_BALLS SPR_WHEEL_BALL_1 +#define SPR_WHEEL_ICONS SPR_WHEEL_ICON_ORANGE_WYNAUT #define SPR_BALL_COUNTER SPR_BALL_COUNTER_1 #define SPR_CREDIT_DIGITS SPR_CREDIT_DIG_1 #define SPR_GRID_ICONS SPR_GRID_ICON_ORANGE_WYNAUT #define SPR_POKE_HEADERS SPR_POKE_HEADER_1 +#define SPR_COLOR_HEADERS SPR_COLOR_HEADER_1 +#define SPR_GRID_BALLS SPR_GRID_BALL_1 + +struct Shroomish +{ + u16 startAngle; + u16 dropAngle; + u16 fallSlowdown; +}; + +struct Taillow +{ + u16 baseDropDelay; + u16 rightStartAngle; + u16 leftStartAngle; +}; struct RouletteTable { u8 minBet; // Never read - u8 var01; - u8 var02; + u8 randDistanceHigh; + u8 randDistanceLow; u8 wheelSpeed; u8 wheelDelay; - u8 filler_05[3]; - u16 var08; - u16 var0A; - u16 var0C; - u8 filler_0E[2]; - u16 var10; - u16 var12; - u16 var14; - u8 filler_16[2]; - u16 var18; - u16 var1A; + struct Shroomish shroomish; + struct Taillow taillow; + u16 ballSpeed; + u16 baseTravelDist; float var1C; }; struct GridSelection { - u8 var00; + u8 spriteIdOffset; u8 baseMultiplier:4; u8 column:4; // Never read u8 row; // Never read u8 x; u8 y; u8 var05; // Never read - u8 var06; + u8 tilemapOffset; u32 flag; u32 inSelectionFlags; u16 var10; @@ -261,7 +285,7 @@ struct RouletteSlot static EWRAM_DATA struct Roulette { u8 unk0; // Never read - u8 var01; + u8 shroomishShadowTimer; u8 partySpeciesFlags; bool8 useTaillow:5; bool8 ballStuck:1; @@ -275,8 +299,8 @@ static EWRAM_DATA struct Roulette u8 pokeHits[NUM_BOARD_POKES]; u8 colorHits[NUM_BOARD_COLORS]; u8 minBet; - u8 curBallNum:4; // Never actually gets incremented - u8 unk:4; // Never read + u8 curBallNum:4; // Never actually gets incremented, tracked with tBallNum instead + u8 unk1:4; // Never read u8 betSelection[BALLS_PER_ROUND]; // Because curBallNum is used as the only index, only the first element is ever used (prev bet selections are never needed) u8 wheelDelayTimer; u8 wheelSpeed; @@ -286,23 +310,23 @@ static EWRAM_DATA struct Roulette s16 selectionRectDrawState; s16 updateGridHighlight; struct OamMatrix wheelRotation; - u16 var34; - struct Sprite *var38; + u16 shroomishShadowAlpha; + struct Sprite *ball; u8 spriteIds[MAX_SPRITES]; u8 curBallSpriteId; u8 ballState; u8 hitSlot; - u8 var7F; - s16 var80; // Never read - s16 var82; - u16 var84; - u16 var86; - float var88; - float var8C; - float var90; - float var94; - float var98; - float var9C; + u8 stuckHitSlot; + s16 ballTravelDist; // Never read + s16 ballTravelDistFast; + u16 ballTravelDistMed; + u16 ballTravelDistSlow; + float ballAngle; + float ballAngleSpeed; + float ballAngleAccel; + float ballDistToCenter; + float ballFallSpeed; + float ballFallAccel; float varA0; u8 playTaskId; u8 spinTaskId; @@ -339,7 +363,7 @@ static void Task_ClearBoard(u8); static void ExitRoulette(u8); static void Task_ExitRoulette(u8); static void StartTaskAfterDelayOrInput(u8, TaskFunc, u16, u16); -static void sub_8141FF4(u8); +static void ResetBallDataForNewSpin(u8); static void ResetHits(void); static void Task_AcceptMinBet(u8); static void Task_DeclineMinBet(u8); @@ -355,22 +379,22 @@ static void ShowHideGridIcons(bool8, u8); static void CreateGridBallSprites(void); static void ShowHideGridBalls(bool8, u8); static void ShowHideWinSlotCursor(u8); -static void CreateBoardIconSprites(void); -static void SpriteCB_BoardIcon(struct Sprite *); +static void CreateWheelIconSprites(void); +static void SpriteCB_WheelIcon(struct Sprite *); static void CreateInterfaceSprites(void); static void SetCreditDigits(u16); static void SetMultiplierSprite(u8); static void SetBallCounterNumLeft(u8); static void SpriteCB_GridSquare(struct Sprite *); -static void CreateBoardCenterSprite(void); -static void SpriteCB_BoardCenter(struct Sprite *); -static void CreateBoardBallSprites(void); -static void HideBoardBalls(void); -static void sub_81446AC(struct Sprite *); +static void CreateWheelCenterSprite(void); +static void SpriteCB_WheelCenter(struct Sprite *); +static void CreateWheelBallSprites(void); +static void HideWheelBalls(void); +static void SpriteCB_RollBall_Start(struct Sprite *); static void CreateShroomishSprite(struct Sprite *); static void CreateTaillowSprite(struct Sprite *); -static void sub_8144A24(struct Sprite *); -static void sub_8144E60(struct Sprite *); +static void SetBallStuck(struct Sprite *); +static void SpriteCB_Shroomish(struct Sprite *); static void SpriteCB_Taillow(struct Sprite *); static const u16 sWheel_Pal[] = INCBIN_U16("graphics/roulette/wheel.gbapal"); // also palette for grid @@ -424,265 +448,264 @@ static const struct WindowTemplate sWindowTemplates[] = //DUMMY_WIN_TEMPLATE }; -// var00, sprite id offset (from 7)? static const struct GridSelection sGridSelections[NUM_GRID_SELECTIONS + 1] = { [SELECTION_NONE] = { - .var00 = 0xFF, + .spriteIdOffset = 0xFF, .baseMultiplier = 0, .column = 0, .row = 0, .x = 7, .y = 7, .var05 = 0, - .var06 = 0, + .tilemapOffset = 0, .flag = 0, .inSelectionFlags = 0, .var10 = 0x0, }, [COL_WYNAUT] = { - .var00 = 12, + .spriteIdOffset = 12, .baseMultiplier = NUM_BOARD_POKES, .column = 1, .row = 0, .x = 17, .y = 7, .var05 = 0, - .var06 = 0, + .tilemapOffset = 0, .flag = F_WYNAUT_COL, .inSelectionFlags = F_WYNAUT_COL | F_ORANGE_WYNAUT | F_GREEN_WYNAUT | F_PURPLE_WYNAUT, .var10 = 0xE000, }, [COL_AZURILL] = { - .var00 = 13, + .spriteIdOffset = 13, .baseMultiplier = NUM_BOARD_POKES, .column = 2, .row = 0, .x = 20, .y = 7, .var05 = 0, - .var06 = 0, + .tilemapOffset = 0, .flag = F_AZURILL_COL, .inSelectionFlags = F_AZURILL_COL | F_ORANGE_AZURILL | F_GREEN_AZURILL | F_PURPLE_AZURILL, .var10 = 0xE000, }, [COL_SKITTY] = { - .var00 = 14, + .spriteIdOffset = 14, .baseMultiplier = NUM_BOARD_POKES, .column = 3, .row = 0, .x = 23, .y = 7, .var05 = 0, - .var06 = 0, + .tilemapOffset = 0, .flag = F_SKITTY_COL, .inSelectionFlags = F_SKITTY_COL | F_ORANGE_SKITTY | F_GREEN_SKITTY | F_PURPLE_SKITTY, .var10 = 0xE000, }, [COL_MAKUHITA] = { - .var00 = 15, + .spriteIdOffset = 15, .baseMultiplier = NUM_BOARD_POKES, .column = 4, .row = 0, .x = 26, .y = 7, .var05 = 0, - .var06 = 0, + .tilemapOffset = 0, .flag = F_MAKUHITA_COL, .inSelectionFlags = F_MAKUHITA_COL | F_ORANGE_MAKUHITA | F_GREEN_MAKUHITA | F_PURPLE_MAKUHITA, .var10 = 0xE000, }, [ROW_ORANGE] = { - .var00 = 16, + .spriteIdOffset = 16, .baseMultiplier = NUM_BOARD_COLORS, .column = 0, .row = 1, .x = 14, .y = 10, .var05 = 0, - .var06 = 12, + .tilemapOffset = 12, .flag = F_ORANGE_ROW, .inSelectionFlags = F_ORANGE_ROW | F_ORANGE_WYNAUT | F_ORANGE_AZURILL | F_ORANGE_SKITTY | F_ORANGE_MAKUHITA, .var10 = 0x249, }, [SQU_ORANGE_WYNAUT] = { - .var00 = 0, + .spriteIdOffset = 0, .baseMultiplier = NUM_ROULETTE_SLOTS, .column = 1, .row = 1, .x = 17, .y = 10, .var05 = 3, - .var06 = 3, + .tilemapOffset = 3, .flag = F_ORANGE_WYNAUT, .inSelectionFlags = F_ORANGE_WYNAUT, .var10 = 0x2001, }, [SQU_ORANGE_AZURILL] = { - .var00 = 9, + .spriteIdOffset = 9, .baseMultiplier = NUM_ROULETTE_SLOTS, .column = 2, .row = 1, .x = 20, .y = 10, .var05 = 3, - .var06 = 3, + .tilemapOffset = 3, .flag = F_ORANGE_AZURILL, .inSelectionFlags = F_ORANGE_AZURILL, .var10 = 0x2200, }, [SQU_ORANGE_SKITTY] = { - .var00 = 6, + .spriteIdOffset = 6, .baseMultiplier = NUM_ROULETTE_SLOTS, .column = 3, .row = 1, .x = 23, .y = 10, .var05 = 3, - .var06 = 3, + .tilemapOffset = 3, .flag = F_ORANGE_SKITTY, .inSelectionFlags = F_ORANGE_SKITTY, .var10 = 0x2040, }, [SQU_ORANGE_MAKUHITA] = { - .var00 = 3, + .spriteIdOffset = 3, .baseMultiplier = NUM_ROULETTE_SLOTS, .column = 4, .row = 1, .x = 26, .y = 10, .var05 = 3, - .var06 = 3, + .tilemapOffset = 3, .flag = F_ORANGE_MAKUHITA, .inSelectionFlags = F_ORANGE_MAKUHITA, .var10 = 0x2008, }, [ROW_GREEN] = { - .var00 = 17, + .spriteIdOffset = 17, .baseMultiplier = NUM_BOARD_COLORS, .column = 0, .row = 2, .x = 14, .y = 13, .var05 = 3, - .var06 = 15, + .tilemapOffset = 15, .flag = F_GREEN_ROW, .inSelectionFlags = F_GREEN_ROW | F_GREEN_WYNAUT | F_GREEN_AZURILL | F_GREEN_SKITTY | F_GREEN_MAKUHITA, .var10 = 0x492, }, [SQU_GREEN_WYNAUT] = { - .var00 = 4, + .spriteIdOffset = 4, .baseMultiplier = NUM_ROULETTE_SLOTS, .column = 1, .row = 2, .x = 17, .y = 13, .var05 = 6, - .var06 = 6, + .tilemapOffset = 6, .flag = F_GREEN_WYNAUT, .inSelectionFlags = F_GREEN_WYNAUT, .var10 = 0x2010, }, [SQU_GREEN_AZURILL] = { - .var00 = 1, + .spriteIdOffset = 1, .baseMultiplier = NUM_ROULETTE_SLOTS, .column = 2, .row = 2, .x = 20, .y = 13, .var05 = 6, - .var06 = 6, + .tilemapOffset = 6, .flag = F_GREEN_AZURILL, .inSelectionFlags = F_GREEN_AZURILL, .var10 = 0x2002, }, [SQU_GREEN_SKITTY] = { - .var00 = 10, + .spriteIdOffset = 10, .baseMultiplier = NUM_ROULETTE_SLOTS, .column = 3, .row = 2, .x = 23, .y = 13, .var05 = 6, - .var06 = 6, + .tilemapOffset = 6, .flag = F_GREEN_SKITTY, .inSelectionFlags = F_GREEN_SKITTY, .var10 = 0x2400, }, [SQU_GREEN_MAKUHITA] = { - .var00 = 7, + .spriteIdOffset = 7, .baseMultiplier = NUM_ROULETTE_SLOTS, .column = 4, .row = 2, .x = 26, .y = 13, .var05 = 6, - .var06 = 6, + .tilemapOffset = 6, .flag = F_GREEN_MAKUHITA, .inSelectionFlags = F_GREEN_MAKUHITA, .var10 = 0x2080, }, [ROW_PURPLE] = { - .var00 = 18, + .spriteIdOffset = 18, .baseMultiplier = NUM_BOARD_COLORS, .column = 0, .row = 3, .x = 14, .y = 16, .var05 = 6, - .var06 = 18, + .tilemapOffset = 18, .flag = F_PURPLE_ROW, .inSelectionFlags = F_PURPLE_ROW | F_PURPLE_WYNAUT | F_PURPLE_AZURILL | F_PURPLE_SKITTY | F_PURPLE_MAKUHITA, .var10 = 0x924, }, [SQU_PURPLE_WYNAUT] = { - .var00 = 8, + .spriteIdOffset = 8, .baseMultiplier = NUM_ROULETTE_SLOTS, .column = 1, .row = 3, .x = 17, .y = 16, .var05 = 9, - .var06 = 9, + .tilemapOffset = 9, .flag = F_PURPLE_WYNAUT, .inSelectionFlags = F_PURPLE_WYNAUT, .var10 = 0x2100, }, [SQU_PURPLE_AZURILL] = { - .var00 = 5, + .spriteIdOffset = 5, .baseMultiplier = NUM_ROULETTE_SLOTS, .column = 2, .row = 3, .x = 20, .y = 16, .var05 = 9, - .var06 = 9, + .tilemapOffset = 9, .flag = F_PURPLE_AZURILL, .inSelectionFlags = F_PURPLE_AZURILL, .var10 = 0x2020, }, [SQU_PURPLE_SKITTY] = { - .var00 = 2, + .spriteIdOffset = 2, .baseMultiplier = NUM_ROULETTE_SLOTS, .column = 3, .row = 3, .x = 23, .y = 16, .var05 = 9, - .var06 = 9, + .tilemapOffset = 9, .flag = F_PURPLE_SKITTY, .inSelectionFlags = F_PURPLE_SKITTY, .var10 = 0x2004, }, [SQU_PURPLE_MAKUHITA] = { - .var00 = 11, + .spriteIdOffset = 11, .baseMultiplier = NUM_ROULETTE_SLOTS, .column = 4, .row = 3, .x = 26, .y = 16, .var05 = 9, - .var06 = 9, + .tilemapOffset = 9, .flag = F_PURPLE_MAKUHITA, .inSelectionFlags = F_PURPLE_MAKUHITA, .var10 = 0x2800, @@ -771,35 +794,43 @@ static const struct RouletteTable sRouletteTables[] = // Left table { .minBet = 1, - .var01 = 60, - .var02 = 30, + .randDistanceHigh = DEGREES_PER_SLOT * 2, + .randDistanceLow = DEGREES_PER_SLOT, .wheelSpeed = 1, .wheelDelay = 1, - .var08 = 45, - .var0A = 30, - .var0C = 1, - .var10 = 75, - .var12 = 27, - .var14 = 24, - .var18 = 10, - .var1A = 360, + .shroomish = { + .startAngle = 45, + .dropAngle = 30, + .fallSlowdown = 1, + }, + .taillow = { + .baseDropDelay = 75, + .rightStartAngle = 27, + .leftStartAngle = 24, + }, + .ballSpeed = 10, + .baseTravelDist = 360, .var1C = -0.5f }, // Right table { .minBet = 3, - .var01 = 30, - .var02 = 15, + .randDistanceHigh = DEGREES_PER_SLOT, + .randDistanceLow = DEGREES_PER_SLOT / 2, .wheelSpeed = 1, .wheelDelay = 0, - .var08 = 75, - .var0A = 60, - .var0C = 2, - .var10 = 0, - .var12 = 54, - .var14 = 48, - .var18 = 10, - .var1A = 270, + .shroomish = { + .startAngle = 75, + .dropAngle = 60, + .fallSlowdown = 2, + }, + .taillow = { + .baseDropDelay = 0, + .rightStartAngle = 54, + .leftStartAngle = 48, + }, + .ballSpeed = 10, + .baseTravelDist = 270, .var1C = -1.0f } }; @@ -938,7 +969,7 @@ static const struct UnkStruct1 gUnknown_085B6388[NUM_ROULETTE_SLOTS + 1] = }, }; -static const struct UnkStruct1 gUnknown_085B63F0[] = +static const struct UnkStruct1 gUnknown_085B63F0[NUM_BOARD_COLORS] = { { .var00 = 0x53FF, @@ -1001,8 +1032,8 @@ static void VBlankCB_Roulette(void) UpdateWheelPosition(); SetGpuReg(REG_OFFSET_BG1HOFS, 0x200 - sRoulette->gridX); - if (sRoulette->var01) - SetGpuReg(REG_OFFSET_BLDALPHA, sRoulette->var34); + if (sRoulette->shroomishShadowTimer) + SetGpuReg(REG_OFFSET_BLDALPHA, sRoulette->shroomishShadowAlpha); if (sRoulette->updateGridHighlight) { @@ -1058,7 +1089,7 @@ static void FreeRoulette(void) FREE_AND_SET_NULL(sRoulette); } -static void sub_8140470(void) +static void InitRouletteTableData(void) { u8 i; u16 bgColors[3] = {RGB(24, 4, 10), RGB(10, 19, 6), RGB(24, 4, 10)}; // 3rd is never used, same as 1st @@ -1071,7 +1102,7 @@ static void sub_8140470(void) sRoulette->wheelSpeed = sRouletteTables[sRoulette->tableId].wheelSpeed; sRoulette->wheelDelay = sRouletteTables[sRoulette->tableId].wheelDelay; sRoulette->minBet = sTableMinBets[sRoulette->tableId + sRoulette->isSpecialRate * 2]; - sRoulette->unk = 1; + sRoulette->unk1 = 1; // Left table (with min bet of 1) has red background, other table has green if (sRoulette->minBet == 1) @@ -1107,6 +1138,7 @@ static void sub_8140470(void) #define tSelectionId data[4] #define tWonBet data[5] #define tBallNum data[6] +#define tTotalBallNum data[8] // Same as tBallNum but isn't cleared every 6 balls #define tConsecutiveWins data[11] #define tWinningSquare data[12] #define tCoins data[13] @@ -1147,17 +1179,17 @@ static void CB2_LoadRoulette(void) if (FreeTempTileDataBuffersIfPossible()) return; - sub_8140470(); + InitRouletteTableData(); CopyToBgTilemapBuffer(2, sWheel_Tilemap, 0, 0); break; case 5: LoadOrFreeMiscSpritePalettesAndSheets(FALSE); - CreateBoardBallSprites(); - CreateBoardCenterSprite(); + CreateWheelBallSprites(); + CreateWheelCenterSprite(); CreateInterfaceSprites(); CreateGridSprites(); CreateGridBallSprites(); - CreateBoardIconSprites(); + CreateWheelIconSprites(); break; case 6: AnimateSprites(); @@ -1225,12 +1257,12 @@ static void Task_StartPlaying(u8 taskId) BLDCNT_TGT2_BD); SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(8, 8)); gTasks[taskId].tBallNum = 0; - sub_8141FF4(taskId); + ResetBallDataForNewSpin(taskId); ResetHits(); - HideBoardBalls(); + HideWheelBalls(); DrawGridBackground(SELECTION_NONE); SetBallCounterNumLeft(BALLS_PER_ROUND); - StartTaskAfterDelayOrInput(taskId, Task_ContinuePlaying, 0xFFFF, A_BUTTON | B_BUTTON); + StartTaskAfterDelayOrInput(taskId, Task_ContinuePlaying, NO_DELAY, A_BUTTON | B_BUTTON); } } @@ -1327,7 +1359,7 @@ static void Task_SelectFirstEmptySquare(u8 taskId) } } gTasks[taskId].tSelectionId = i; - sub_8141FF4(taskId); + ResetBallDataForNewSpin(taskId); DrawGridBackground(gTasks[taskId].tSelectionId); SetMultiplierSprite(gTasks[taskId].tSelectionId); FlashSelectionOnWheel(gTasks[taskId].tSelectionId); @@ -1389,8 +1421,8 @@ static void ProcessBetGridInput(u8 taskId) UpdateGridSelection(taskId); gTasks[taskId].data[1] = 0; PlaySE(SE_SELECT); - sub_8151A9C(&sRoulette->flashUtil, 0xFFFF); // Reset previous flashing wheel selections - sRoulette->flashUtil.var04[13].var00_7 = sRoulette->flashUtil.var04[14].var00_7 = sRoulette->flashUtil.var04[15].var00_7 = 0; + sub_8151A9C(&sRoulette->flashUtil, 0xFFFF); // Reset previous flashing wheel color selection + sRoulette->flashUtil.var04[13].active = sRoulette->flashUtil.var04[14].active = sRoulette->flashUtil.var04[15].active = FALSE; // Same as above, but for icon FlashSelectionOnWheel(gTasks[taskId].tSelectionId); // Switch all the poke (column) headers to gray outlines @@ -1401,7 +1433,7 @@ static void ProcessBetGridInput(u8 taskId) + (*gSprites[sRoulette->spriteIds[i + SPR_POKE_HEADERS]].anims)->type; } // If the current selection is a column with at least 1 unhit space, fill in the header - if ((u16)(gTasks[taskId].tSelectionId - 1) < COL_MAKUHITA && !(sRoulette->hitFlags & sGridSelections[gTasks[taskId].tSelectionId].flag) ) + if ((u16)(gTasks[taskId].tSelectionId - 1) < COL_MAKUHITA && !(sRoulette->hitFlags & sGridSelections[gTasks[taskId].tSelectionId].flag)) { headerOffset = gTasks[taskId].tSelectionId - 1; gSprites[sRoulette->spriteIds[headerOffset + SPR_POKE_HEADERS]].oam.tileNum = @@ -1411,7 +1443,7 @@ static void ProcessBetGridInput(u8 taskId) } } -static void Task_StartRound(u8 taskId) +static void Task_StartSpin(u8 taskId) { IncrementDailyRouletteUses(); sRoulette->selectionRectDrawState = SELECT_STATE_ERASE; @@ -1432,7 +1464,7 @@ static void Task_PlaceBet(u8 taskId) if ((gTasks[taskId].tCoins -= sRoulette->minBet) < 0) gTasks[taskId].tCoins = 0; SetCreditDigits(gTasks[taskId].tCoins); - gTasks[taskId].func = Task_StartRound; + gTasks[taskId].func = Task_StartSpin; } static void Task_HandleBetGridInput(u8 taskId) @@ -1476,8 +1508,11 @@ static void Task_SlideGridOffscreen(u8 taskId) { if (gTasks[taskId].data[1]-- > 0) { + // Slide wheel over if (gTasks[taskId].data[1] > 2) gSpriteCoordOffsetX += 2; + + // Slide grid over if ((sRoulette->gridX += 4) == 104) gSprites[sRoulette->spriteIds[SPR_MULTIPLIER]].callback = &SpriteCallbackDummy; } @@ -1490,7 +1525,12 @@ static void Task_SlideGridOffscreen(u8 taskId) } } -static u8 sub_814118C(u16 r0, u16 r1) +// Each table has a set base distance used to determine how far the ball will travel +// Each roll a random value is generated to add onto this distance +// Half the value returned by this function is the max distance that can be added on per roll +// i.e. the lower this value is, the closer the roll will be to a consistent distance +// Odds of a lower value increase as play continues, if the player has Shroomish and/or Taillow in the party, and dependent on the time +static u8 GetRandomForBallTravelDistance(u16 ballNum, u16 rand) { switch (sRoulette->partySpeciesFlags) { @@ -1499,36 +1539,36 @@ static u8 sub_814118C(u16 r0, u16 r1) // one of the two is in party if (gLocalTime.hours > 3 && gLocalTime.hours < 10) { - if (r0 < 12 || (r1 & 1)) - return sRouletteTables[sRoulette->tableId].var02 / 2; + if (ballNum < BALLS_PER_ROUND * 2 || (rand & 1)) + return sRouletteTables[sRoulette->tableId].randDistanceLow / 2; else return 1; } - else if (!(r1 & 3)) + else if (!(rand & 3)) { - return sRouletteTables[sRoulette->tableId].var02 / 2; + return sRouletteTables[sRoulette->tableId].randDistanceLow / 2; } else { - return sRouletteTables[sRoulette->tableId].var02; + return sRouletteTables[sRoulette->tableId].randDistanceLow; } break; case HAS_SHROOMISH | HAS_TAILLOW: // both are in party if (gLocalTime.hours > 3 && gLocalTime.hours < 11) { - if (r0 < 6 || (r1 & 1)) - return sRouletteTables[sRoulette->tableId].var02 / 2; + if (ballNum < BALLS_PER_ROUND || (rand & 1)) + return sRouletteTables[sRoulette->tableId].randDistanceLow / 2; else return 1; } - else if ((r1 & 1) && r0 > 6) + else if ((rand & 1) && ballNum > BALLS_PER_ROUND) { - return sRouletteTables[sRoulette->tableId].var02 / 4; + return sRouletteTables[sRoulette->tableId].randDistanceLow / 4; } else { - return sRouletteTables[sRoulette->tableId].var02 / 2; + return sRouletteTables[sRoulette->tableId].randDistanceLow / 2; } break; case 0: @@ -1536,28 +1576,28 @@ static u8 sub_814118C(u16 r0, u16 r1) // neither is in party if (gLocalTime.hours > 3 && gLocalTime.hours < 10) { - if (!(r1 & 3)) + if (!(rand & 3)) return 1; else - return sRouletteTables[sRoulette->tableId].var02 / 2; + return sRouletteTables[sRoulette->tableId].randDistanceLow / 2; } - else if (!(r1 & 3)) + else if (!(rand & 3)) { - if (r0 > 12) - return sRouletteTables[sRoulette->tableId].var02 / 2; + if (ballNum > BALLS_PER_ROUND * 2) + return sRouletteTables[sRoulette->tableId].randDistanceLow / 2; else - return sRouletteTables[sRoulette->tableId].var02; + return sRouletteTables[sRoulette->tableId].randDistanceLow; } - else if (r1 & 0x8000) + else if (rand & (1 << 15)) { - if (r0 > 12) - return sRouletteTables[sRoulette->tableId].var02; + if (ballNum > BALLS_PER_ROUND * 2) + return sRouletteTables[sRoulette->tableId].randDistanceLow; else - return sRouletteTables[sRoulette->tableId].var01; + return sRouletteTables[sRoulette->tableId].randDistanceHigh; } else { - return sRouletteTables[sRoulette->tableId].var01 * 2; + return sRouletteTables[sRoulette->tableId].randDistanceHigh * 2; } break; } @@ -1565,43 +1605,44 @@ static u8 sub_814118C(u16 r0, u16 r1) static void Task_InitBallRoll(u8 taskId) { - u8 randf; - s8 randfinal; - s8 r5; - u16 g = 0; + u8 randTravelMod; + s8 randTravelDist; + s8 startAngleId; + u16 travelDist = 0; u16 rand; u16 randmod; - u16 angles[4] = {0, 180, 90, 270}; // angles in 90 degree steps + u16 startAngles[4] = {0, 180, 90, 270}; // possible angles to start ball from rand = Random(); randmod = rand % 100; sRoulette->curBallSpriteId = gTasks[taskId].tBallNum; - sRoulette->ballState = sRoulette->hitSlot = sRoulette->var7F = BALL_STATE_ROLLING; - randf = sub_814118C(gTasks[taskId].data[8], rand); - randfinal = (rand % randf) - (randf / 2); + // BALL_STATE_ROLLING set below + sRoulette->ballState = sRoulette->hitSlot = sRoulette->stuckHitSlot = 0; + randTravelMod = GetRandomForBallTravelDistance(gTasks[taskId].tTotalBallNum, rand); + randTravelDist = (rand % randTravelMod) - (randTravelMod / 2); if (gLocalTime.hours < 13) - r5 = 0; + startAngleId = 0; else - r5 = 1; + startAngleId = 1; if (randmod < 80) - r5 *= 2; + startAngleId *= 2; else - r5 = (1 - r5) * 2; + startAngleId = (1 - startAngleId) * 2; - sRoulette->var80 = g = sRouletteTables[sRoulette->tableId].var1A + randfinal; + sRoulette->ballTravelDist = travelDist = sRouletteTables[sRoulette->tableId].baseTravelDist + randTravelDist; - g = S16TOPOSFLOAT(g) / 5.0f; - sRoulette->var82 = g * 3; - sRoulette->var86 = sRoulette->var84 = g; + travelDist = S16TOPOSFLOAT(travelDist) / 5.0f; + sRoulette->ballTravelDistFast = travelDist * 3; + sRoulette->ballTravelDistSlow = sRoulette->ballTravelDistMed = travelDist; - sRoulette->var88 = S16TOPOSFLOAT(angles[(rand & 1) + r5]); - sRoulette->var8C = S16TOPOSFLOAT(sRouletteTables[sRoulette->tableId].var18); - sRoulette->var90 = ((sRoulette->var8C * 0.5f) - sRoulette->var8C) / S16TOPOSFLOAT(sRoulette->var82); - sRoulette->var94 = 68.0f; - sRoulette->var9C = 0.0f; - sRoulette->var98 = -(8.0f / S16TOPOSFLOAT(sRoulette->var82)); + sRoulette->ballAngle = S16TOPOSFLOAT(startAngles[(rand & 1) + startAngleId]); + sRoulette->ballAngleSpeed = S16TOPOSFLOAT(sRouletteTables[sRoulette->tableId].ballSpeed); + sRoulette->ballAngleAccel = ((sRoulette->ballAngleSpeed * 0.5f) - sRoulette->ballAngleSpeed) / S16TOPOSFLOAT(sRoulette->ballTravelDistFast); + sRoulette->ballDistToCenter = 68.0f; + sRoulette->ballFallAccel = 0.0f; + sRoulette->ballFallSpeed = -(8.0f / S16TOPOSFLOAT(sRoulette->ballTravelDistFast)); sRoulette->varA0 = 36.0f; gTasks[taskId].func = Task_RollBall; } @@ -1609,10 +1650,10 @@ static void Task_InitBallRoll(u8 taskId) static void Task_RollBall(u8 taskId) { sRoulette->ballRolling = TRUE; - sRoulette->var38 = &gSprites[sRoulette->spriteIds[sRoulette->curBallSpriteId]]; - sRoulette->var38->callback = sub_81446AC; + sRoulette->ball = &gSprites[sRoulette->spriteIds[sRoulette->curBallSpriteId]]; + sRoulette->ball->callback = SpriteCB_RollBall_Start; gTasks[taskId].tBallNum++; - gTasks[taskId].data[8]++; + gTasks[taskId].tTotalBallNum++; SetBallCounterNumLeft(BALLS_PER_ROUND - gTasks[taskId].tBallNum); m4aSongNumStart(SE_TAMAKORO); gTasks[taskId].func = Task_RecordBallHit; @@ -1663,8 +1704,11 @@ static void Task_SlideGridOnscreen(u8 taskId) { if (gTasks[taskId].data[1]-- > 0) { + // Slide wheel over if (gTasks[taskId].data[1] > 2) gSpriteCoordOffsetX -= 2; + + // Slide grid over if ((sRoulette->gridX -= 4) == 104) gSprites[sRoulette->spriteIds[SPR_MULTIPLIER]].callback = SpriteCB_GridSquare; } @@ -1714,7 +1758,7 @@ static void Task_TryIncrementWins(u8 taskId) u32 wins = GetGameStat(GAME_STAT_CONSECUTIVE_ROULETTE_WINS); if (wins < ++gTasks[taskId].tConsecutiveWins) SetGameStat(GAME_STAT_CONSECUTIVE_ROULETTE_WINS, gTasks[taskId].tConsecutiveWins); - StartTaskAfterDelayOrInput(taskId, Task_PrintPayout, 0xFFFF, A_BUTTON | B_BUTTON); + StartTaskAfterDelayOrInput(taskId, Task_PrintPayout, NO_DELAY, A_BUTTON | B_BUTTON); } break; case FALSE: @@ -1722,7 +1766,7 @@ static void Task_TryIncrementWins(u8 taskId) if (!IsSEPlaying()) { gTasks[taskId].tConsecutiveWins = 0; - StartTaskAfterDelayOrInput(taskId, Task_EndTurn, 0xFFFF, A_BUTTON | B_BUTTON); + StartTaskAfterDelayOrInput(taskId, Task_EndTurn, NO_DELAY, A_BUTTON | B_BUTTON); } break; } @@ -1790,7 +1834,7 @@ static void Task_GivePayout(u8 taskId) break; } if (gTasks[taskId].tPayout == 0) - StartTaskAfterDelayOrInput(taskId, Task_EndTurn, 0xFFFF, A_BUTTON | B_BUTTON); + StartTaskAfterDelayOrInput(taskId, Task_EndTurn, NO_DELAY, A_BUTTON | B_BUTTON); } static void Task_PrintPayout(u8 taskId) @@ -1810,8 +1854,8 @@ static void Task_PrintPayout(u8 taskId) static void Task_EndTurn(u8 taskId) { sub_8151A9C(&sRoulette->flashUtil, 0xFFFF); - sRoulette->flashUtil.var04[13].var00_7 = sRoulette->flashUtil.var04[14].var00_7 = sRoulette->flashUtil.var04[15].var00_7 = 0; - gSprites[sRoulette->spriteIds[SPR_BOARD_ICONS + sGridSelections[gTasks[taskId].tWinningSquare].var00]].invisible = TRUE; + sRoulette->flashUtil.var04[13].active = sRoulette->flashUtil.var04[14].active = sRoulette->flashUtil.var04[15].active = FALSE; + gSprites[sRoulette->spriteIds[SPR_WHEEL_ICONS + sGridSelections[gTasks[taskId].tWinningSquare].spriteIdOffset]].invisible = TRUE; gTasks[taskId].func = Task_TryPrintEndTurnMsg; } @@ -1836,7 +1880,7 @@ static void Task_TryPrintEndTurnMsg(u8 taskId) DrawStdWindowFrame(sTextWindowId, FALSE); AddTextPrinterParameterized(sTextWindowId, 1, Roulette_Text_BoardWillBeCleared, 0, 1, TEXT_SPEED_FF, NULL); CopyWindowToVram(sTextWindowId, 3); - StartTaskAfterDelayOrInput(taskId, Task_ClearBoard, 0xFFFF, A_BUTTON | B_BUTTON); + StartTaskAfterDelayOrInput(taskId, Task_ClearBoard, NO_DELAY, A_BUTTON | B_BUTTON); } else if (gTasks[taskId].tCoins == MAX_COINS) { @@ -1844,7 +1888,7 @@ static void Task_TryPrintEndTurnMsg(u8 taskId) DrawStdWindowFrame(sTextWindowId, FALSE); AddTextPrinterParameterized(sTextWindowId, 1, Roulette_Text_CoinCaseIsFull, 0, 1, TEXT_SPEED_FF, NULL); CopyWindowToVram(sTextWindowId, 3); - StartTaskAfterDelayOrInput(taskId, Task_AskKeepPlaying, 0xFFFF, A_BUTTON | B_BUTTON); + StartTaskAfterDelayOrInput(taskId, Task_AskKeepPlaying, NO_DELAY, A_BUTTON | B_BUTTON); } else { @@ -1867,15 +1911,15 @@ static void Task_ClearBoard(u8 taskId) u8 i = 0; gTasks[taskId].tBallNum = 0; - sub_8141FF4(taskId); + ResetBallDataForNewSpin(taskId); ResetHits(); - HideBoardBalls(); + HideWheelBalls(); DrawGridBackground(SELECTION_NONE); SetBallCounterNumLeft(BALLS_PER_ROUND); for (i = 0; i < NUM_ROULETTE_SLOTS; i++) { - gSprites[sRoulette->spriteIds[i + SPR_BOARD_ICONS]].invisible = FALSE; + gSprites[sRoulette->spriteIds[i + SPR_WHEEL_ICONS]].invisible = FALSE; } if (gTasks[taskId].tCoins == MAX_COINS) @@ -1883,7 +1927,7 @@ static void Task_ClearBoard(u8 taskId) DrawStdWindowFrame(sTextWindowId, FALSE); AddTextPrinterParameterized(sTextWindowId, 1, Roulette_Text_CoinCaseIsFull, 0, 1, TEXT_SPEED_FF, NULL); CopyWindowToVram(sTextWindowId, 3); - StartTaskAfterDelayOrInput(taskId, Task_AskKeepPlaying, 0xFFFF, A_BUTTON | B_BUTTON); + StartTaskAfterDelayOrInput(taskId, Task_AskKeepPlaying, NO_DELAY, A_BUTTON | B_BUTTON); } else { @@ -1937,7 +1981,7 @@ static void Task_WaitForNextTask(u8 taskId) sRoulette->taskWaitKey = 0; sRoulette->taskWaitDelay = 0; } - if (sRoulette->taskWaitDelay != 0xFFFF) + if (sRoulette->taskWaitDelay != NO_DELAY) sRoulette->taskWaitDelay--; } @@ -1948,14 +1992,14 @@ static void StartTaskAfterDelayOrInput(u8 taskId, TaskFunc task, u16 delay, u16 task = sRoulette->prevTask; sRoulette->nextTask = task; sRoulette->taskWaitDelay = delay; - if (delay == 0xFFFF && key == 0) + if (delay == NO_DELAY && key == 0) sRoulette->taskWaitKey = 0xFFFF; else sRoulette->taskWaitKey = key; gTasks[taskId].func = Task_WaitForNextTask; } -static void sub_8141FF4(u8 taskId) +static void ResetBallDataForNewSpin(u8 taskId) { u8 i = 0; sRoulette->unk0 = FALSE; @@ -2099,16 +2143,16 @@ static void FlashSelectionOnWheel(u8 selectionId) // The specific color of the poke it references doesn't matter, because the icons themelves all share a palette // So it just uses the first sprite ID of each case COL_WYNAUT: - var3 = gSprites[sRoulette->spriteIds[SPR_BOARD_ICON_ORANGE_WYNAUT]].oam.paletteNum * 16; + var3 = gSprites[sRoulette->spriteIds[SPR_WHEEL_ICON_ORANGE_WYNAUT]].oam.paletteNum * 16; break; case COL_AZURILL: - var3 = gSprites[sRoulette->spriteIds[SPR_BOARD_ICON_GREEN_AZURILL]].oam.paletteNum * 16; + var3 = gSprites[sRoulette->spriteIds[SPR_WHEEL_ICON_GREEN_AZURILL]].oam.paletteNum * 16; break; case COL_SKITTY: - var3 = gSprites[sRoulette->spriteIds[SPR_BOARD_ICON_PURPLE_SKITTY]].oam.paletteNum * 16; + var3 = gSprites[sRoulette->spriteIds[SPR_WHEEL_ICON_PURPLE_SKITTY]].oam.paletteNum * 16; break; case COL_MAKUHITA: - var3 = gSprites[sRoulette->spriteIds[SPR_BOARD_ICON_ORANGE_MAKUHITA]].oam.paletteNum * 16; + var3 = gSprites[sRoulette->spriteIds[SPR_WHEEL_ICON_ORANGE_MAKUHITA]].oam.paletteNum * 16; break; } if (numSelected == 1) @@ -2154,16 +2198,17 @@ static void FlashSelectionOnWheel(u8 selectionId) static void DrawGridBackground(u8 selectionId) { - vu8 i; - vu8 z; - vu16 var1; - vu16 var2; - vu8 var0; - u8 v[5]; - u8 l; + vu8 i, j; + vu16 x, y; + vu8 tilemapOffset; + u8 selectionIds[NUM_BOARD_POKES >= NUM_BOARD_COLORS ? NUM_BOARD_POKES + 1 : NUM_BOARD_COLORS + 1]; + u8 numSquares; sRoulette->updateGridHighlight = TRUE; ShowHideGridIcons(FALSE, 0); SetTilemapRect(sRoulette->tilemapBuffers[2], sRoulette->gridTilemap, 14, 7, 16, 13); + + // Highlight selected square + // (just buffers the highlight, it's actually drawn in VBlankCB_Roulette) switch (selectionId) { case SELECTION_NONE: @@ -2172,36 +2217,35 @@ static void DrawGridBackground(u8 selectionId) case COL_AZURILL: case COL_SKITTY: case COL_MAKUHITA: - l = 4; - for (i = 0; i < l; i++) - { - v[i] = i * ROW_ORANGE + selectionId; - } + numSquares = NUM_BOARD_COLORS + 1; // For each poke column, 3 colors and a header + for (i = 0; i < numSquares; i++) + selectionIds[i] = i * ROW_ORANGE + selectionId; break; case ROW_ORANGE: case ROW_GREEN: case ROW_PURPLE: - l = 5; - for (i = 0; i < l; i++) - { - v[i] = i + selectionId; - } + numSquares = NUM_BOARD_POKES + 1; // For each color row, 4 pokes and a header + for (i = 0; i < numSquares; i++) + selectionIds[i] = i + selectionId; break; // Individual square default: - l = 1; - v[0] = selectionId; + numSquares = 1; + selectionIds[0] = selectionId; } - for (i = 0; i < l; i++) + for (i = 0; i < numSquares; i++) { - var0 = sGridSelections[v[i]].var06; - var1 = sGridSelections[v[i]].x; - for (z = 0; z < 3; z++) + tilemapOffset = sGridSelections[selectionIds[i]].tilemapOffset; + x = sGridSelections[selectionIds[i]].x; + + // Grid square highlight is drawn in 9 segments, starting from the top left of the square + // Each iteration of this loop draws 3 segments to form a single horizontal segment + for (j = 0; j < 3; j++) { - var2 = (sGridSelections[v[i]].y + z) * 32; - sRoulette->tilemapBuffers[2][var1 + var2 + 0] = sRoulette->gridTilemap[(var0 + z) * 3 + 208]; - sRoulette->tilemapBuffers[2][var1 + var2 + 1] = sRoulette->gridTilemap[(var0 + z) * 3 + 209]; - sRoulette->tilemapBuffers[2][var1 + var2 + 2] = sRoulette->gridTilemap[(var0 + z) * 3 + 210]; + y = (sGridSelections[selectionIds[i]].y + j) * 32; + sRoulette->tilemapBuffers[2][x + y + 0] = sRoulette->gridTilemap[(tilemapOffset + j) * 3 + 208 + 0]; + sRoulette->tilemapBuffers[2][x + y + 1] = sRoulette->gridTilemap[(tilemapOffset + j) * 3 + 208 + 1]; + sRoulette->tilemapBuffers[2][x + y + 2] = sRoulette->gridTilemap[(tilemapOffset + j) * 3 + 208 + 2]; } } } @@ -2275,7 +2319,7 @@ static const u32 sBall_Gfx[] = INCBIN_U32("graphics/roulette/ball.4bpp.lz"); static const u32 sBallCounter_Gfx[] = INCBIN_U32("graphics/roulette/ball_counter.4bpp.lz"); static const u32 sShroomishTaillow_Gfx[] = INCBIN_U32("graphics/roulette/roulette_tilt.4bpp.lz"); static const u32 sGridIcons_Gfx[] = INCBIN_U32("graphics/roulette/grid_icons.4bpp.lz"); -static const u32 sBoardIcons_Gfx[] = INCBIN_U32("graphics/roulette/board_icons.4bpp.lz"); +static const u32 sWheelIcons_Gfx[] = INCBIN_U32("graphics/roulette/wheel_icons.4bpp.lz"); static const u32 sShadow_Gfx[] = INCBIN_U32("graphics/roulette/shadow.4bpp.lz"); static const u32 sCursor_Gfx[] = INCBIN_U32("graphics/roulette/cursor.4bpp.lz"); @@ -2284,7 +2328,7 @@ static const struct SpritePalette sSpritePalettes[] = { .data = sShadow_Pal, .tag = PALTAG_SHADOW }, { .data = sBall_Pal, .tag = PALTAG_BALL }, { .data = sBallCounter_Pal, .tag = PALTAG_BALL_COUNTER }, - { .data = sCursor_Pal, .tag = 4 }, + { .data = sCursor_Pal, .tag = PALTAG_CURSOR }, { .data = sCredit_Pal, .tag = PALTAG_INTERFACE }, { .data = sShroomish_Pal, .tag = PALTAG_SHROOMISH }, { .data = sTaillow_Pal, .tag = PALTAG_TAILLOW }, @@ -2314,7 +2358,7 @@ static const struct OamData sOam_GridIcon = .priority = 1, }; -static const struct OamData sOam_BoardIcon = +static const struct OamData sOam_WheelIcon = { .y = 60, .affineMode = ST_OAM_AFFINE_DOUBLE, @@ -2345,14 +2389,14 @@ static const union AffineAnimCmd *const sAffineAnims_Unused2[] = sAffineAnim_Unused2 }; -static const struct CompressedSpriteSheet sSpriteSheet_BoardIcons = +static const struct CompressedSpriteSheet sSpriteSheet_WheelIcons = { - .data = sBoardIcons_Gfx, + .data = sWheelIcons_Gfx, .size = 0xC00, - .tag = GFXTAG_BOARD_ICONS + .tag = GFXTAG_WHEEL_ICONS }; -static const union AnimCmd sAnim_BoardIcons[] = +static const union AnimCmd sAnim_WheelIcons[] = { ANIMCMD_FRAME(0, 0), ANIMCMD_FRAME(32, 0), @@ -2369,64 +2413,64 @@ static const union AnimCmd sAnim_BoardIcons[] = ANIMCMD_END }; -static const union AnimCmd *const sAnim_BoardIcon_OrangeWynaut[] = +static const union AnimCmd *const sAnim_WheelIcon_OrangeWynaut[] = { - &sAnim_BoardIcons[0] + &sAnim_WheelIcons[0] }; -static const union AnimCmd *const sAnim_BoardIcon_GreenAzurill[] = +static const union AnimCmd *const sAnim_WheelIcon_GreenAzurill[] = { - &sAnim_BoardIcons[1] + &sAnim_WheelIcons[1] }; -static const union AnimCmd *const sAnim_BoardIcon_PurpleSkitty[] = +static const union AnimCmd *const sAnim_WheelIcon_PurpleSkitty[] = { - &sAnim_BoardIcons[2] + &sAnim_WheelIcons[2] }; -static const union AnimCmd *const sAnim_BoardIcon_OrangeMakuhita[] = +static const union AnimCmd *const sAnim_WheelIcon_OrangeMakuhita[] = { - &sAnim_BoardIcons[3] + &sAnim_WheelIcons[3] }; -static const union AnimCmd *const sAnim_BoardIcon_GreenWynaut[] = +static const union AnimCmd *const sAnim_WheelIcon_GreenWynaut[] = { - &sAnim_BoardIcons[4] + &sAnim_WheelIcons[4] }; -static const union AnimCmd *const sAnim_BoardIcon_PurpleAzurill[] = +static const union AnimCmd *const sAnim_WheelIcon_PurpleAzurill[] = { - &sAnim_BoardIcons[5] + &sAnim_WheelIcons[5] }; -static const union AnimCmd *const sAnim_BoardIcon_OrangeSkitty[] = +static const union AnimCmd *const sAnim_WheelIcon_OrangeSkitty[] = { - &sAnim_BoardIcons[6] + &sAnim_WheelIcons[6] }; -static const union AnimCmd *const sAnim_BoardIcon_GreenMakuhita[] = +static const union AnimCmd *const sAnim_WheelIcon_GreenMakuhita[] = { - &sAnim_BoardIcons[7] + &sAnim_WheelIcons[7] }; -static const union AnimCmd *const sAnim_BoardIcon_PurpleWynaut[] = +static const union AnimCmd *const sAnim_WheelIcon_PurpleWynaut[] = { - &sAnim_BoardIcons[8] + &sAnim_WheelIcons[8] }; -static const union AnimCmd *const sAnim_BoardIcon_OrangeAzurill[] = +static const union AnimCmd *const sAnim_WheelIcon_OrangeAzurill[] = { - &sAnim_BoardIcons[9] + &sAnim_WheelIcons[9] }; -static const union AnimCmd *const sAnim_BoardIcon_GreenSkitty[] = +static const union AnimCmd *const sAnim_WheelIcon_GreenSkitty[] = { - &sAnim_BoardIcons[10] + &sAnim_WheelIcons[10] }; -static const union AnimCmd *const sAnim_BoardIcon_PurpleMakuhita[] = +static const union AnimCmd *const sAnim_WheelIcon_PurpleMakuhita[] = { - &sAnim_BoardIcons[11] + &sAnim_WheelIcons[11] }; static const struct CompressedSpriteSheet sSpriteSheet_Headers = @@ -2436,7 +2480,7 @@ static const struct CompressedSpriteSheet sSpriteSheet_Headers = .tag = GFXTAG_HEADERS }; -static const struct CompressedSpriteSheet sSpriteSheet_PokeIcons = +static const struct CompressedSpriteSheet sSpriteSheet_GridIcons = { .data = sGridIcons_Gfx, .size = 0x400, @@ -2634,117 +2678,117 @@ static const struct SpriteTemplate sSpriteTemplate_GridIcons[NUM_BOARD_POKES] = } }; -// Board icons are listed clockwise starting from 1 oclock on the roulette board (with pokeball upside right) +// Wheel icons are listed clockwise starting from 1 oclock on the roulette wheel (with pokeball upside right) // They go Wynaut -> Azurill -> Skitty -> Makuhita, and Orange -> Green -> Purple -static const struct SpriteTemplate sSpriteTemplates_BoardIcons[NUM_ROULETTE_SLOTS] = +static const struct SpriteTemplate sSpriteTemplates_WheelIcons[NUM_ROULETTE_SLOTS] = { { - .tileTag = GFXTAG_BOARD_ICONS, + .tileTag = GFXTAG_WHEEL_ICONS, .paletteTag = PALTAG_WYNAUT, - .oam = &sOam_BoardIcon, - .anims = sAnim_BoardIcon_OrangeWynaut, + .oam = &sOam_WheelIcon, + .anims = sAnim_WheelIcon_OrangeWynaut, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCB_BoardIcon + .callback = SpriteCB_WheelIcon }, { - .tileTag = GFXTAG_BOARD_ICONS, + .tileTag = GFXTAG_WHEEL_ICONS, .paletteTag = PALTAG_AZURILL, - .oam = &sOam_BoardIcon, - .anims = sAnim_BoardIcon_GreenAzurill, + .oam = &sOam_WheelIcon, + .anims = sAnim_WheelIcon_GreenAzurill, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCB_BoardIcon + .callback = SpriteCB_WheelIcon }, { - .tileTag = GFXTAG_BOARD_ICONS, + .tileTag = GFXTAG_WHEEL_ICONS, .paletteTag = PALTAG_SKITTY, - .oam = &sOam_BoardIcon, - .anims = sAnim_BoardIcon_PurpleSkitty, + .oam = &sOam_WheelIcon, + .anims = sAnim_WheelIcon_PurpleSkitty, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCB_BoardIcon + .callback = SpriteCB_WheelIcon }, { - .tileTag = GFXTAG_BOARD_ICONS, + .tileTag = GFXTAG_WHEEL_ICONS, .paletteTag = PALTAG_MAKUHITA, - .oam = &sOam_BoardIcon, - .anims = sAnim_BoardIcon_OrangeMakuhita, + .oam = &sOam_WheelIcon, + .anims = sAnim_WheelIcon_OrangeMakuhita, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCB_BoardIcon + .callback = SpriteCB_WheelIcon }, { - .tileTag = GFXTAG_BOARD_ICONS, + .tileTag = GFXTAG_WHEEL_ICONS, .paletteTag = PALTAG_WYNAUT, - .oam = &sOam_BoardIcon, - .anims = sAnim_BoardIcon_GreenWynaut, + .oam = &sOam_WheelIcon, + .anims = sAnim_WheelIcon_GreenWynaut, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCB_BoardIcon + .callback = SpriteCB_WheelIcon }, { - .tileTag = GFXTAG_BOARD_ICONS, + .tileTag = GFXTAG_WHEEL_ICONS, .paletteTag = PALTAG_AZURILL, - .oam = &sOam_BoardIcon, - .anims = sAnim_BoardIcon_PurpleAzurill, + .oam = &sOam_WheelIcon, + .anims = sAnim_WheelIcon_PurpleAzurill, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCB_BoardIcon + .callback = SpriteCB_WheelIcon }, { - .tileTag = GFXTAG_BOARD_ICONS, + .tileTag = GFXTAG_WHEEL_ICONS, .paletteTag = PALTAG_SKITTY, - .oam = &sOam_BoardIcon, - .anims = sAnim_BoardIcon_OrangeSkitty, + .oam = &sOam_WheelIcon, + .anims = sAnim_WheelIcon_OrangeSkitty, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCB_BoardIcon + .callback = SpriteCB_WheelIcon }, { - .tileTag = GFXTAG_BOARD_ICONS, + .tileTag = GFXTAG_WHEEL_ICONS, .paletteTag = PALTAG_MAKUHITA, - .oam = &sOam_BoardIcon, - .anims = sAnim_BoardIcon_GreenMakuhita, + .oam = &sOam_WheelIcon, + .anims = sAnim_WheelIcon_GreenMakuhita, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCB_BoardIcon + .callback = SpriteCB_WheelIcon }, { - .tileTag = GFXTAG_BOARD_ICONS, + .tileTag = GFXTAG_WHEEL_ICONS, .paletteTag = PALTAG_WYNAUT, - .oam = &sOam_BoardIcon, - .anims = sAnim_BoardIcon_PurpleWynaut, + .oam = &sOam_WheelIcon, + .anims = sAnim_WheelIcon_PurpleWynaut, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCB_BoardIcon + .callback = SpriteCB_WheelIcon }, { - .tileTag = GFXTAG_BOARD_ICONS, + .tileTag = GFXTAG_WHEEL_ICONS, .paletteTag = PALTAG_AZURILL, - .oam = &sOam_BoardIcon, - .anims = sAnim_BoardIcon_OrangeAzurill, + .oam = &sOam_WheelIcon, + .anims = sAnim_WheelIcon_OrangeAzurill, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCB_BoardIcon + .callback = SpriteCB_WheelIcon }, { - .tileTag = GFXTAG_BOARD_ICONS, + .tileTag = GFXTAG_WHEEL_ICONS, .paletteTag = PALTAG_SKITTY, - .oam = &sOam_BoardIcon, - .anims = sAnim_BoardIcon_GreenSkitty, + .oam = &sOam_WheelIcon, + .anims = sAnim_WheelIcon_GreenSkitty, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCB_BoardIcon + .callback = SpriteCB_WheelIcon }, { - .tileTag = GFXTAG_BOARD_ICONS, + .tileTag = GFXTAG_WHEEL_ICONS, .paletteTag = PALTAG_MAKUHITA, - .oam = &sOam_BoardIcon, - .anims = sAnim_BoardIcon_PurpleMakuhita, + .oam = &sOam_WheelIcon, + .anims = sAnim_WheelIcon_PurpleMakuhita, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCB_BoardIcon + .callback = SpriteCB_WheelIcon } }; @@ -2814,25 +2858,26 @@ static const struct CompressedSpriteSheet sSpriteSheets_Interface[] = {} }; -static const union AnimCmd gSpriteAnim_85B7780[] = +static const union AnimCmd sAnim_CreditDigit[] = { - ANIMCMD_FRAME(0, 0), - ANIMCMD_FRAME(2, 0), - ANIMCMD_FRAME(4, 0), - ANIMCMD_FRAME(6, 0), - ANIMCMD_FRAME(8, 0), - ANIMCMD_FRAME(10, 0), - ANIMCMD_FRAME(12, 0), - ANIMCMD_FRAME(14, 0), - ANIMCMD_FRAME(16, 0), - ANIMCMD_FRAME(18, 0), + ANIMCMD_FRAME(0, 0), // 0 + ANIMCMD_FRAME(2, 0), // 1 + ANIMCMD_FRAME(4, 0), // 2 + ANIMCMD_FRAME(6, 0), // 3 + ANIMCMD_FRAME(8, 0), // 4 + ANIMCMD_FRAME(10, 0), // 5 + ANIMCMD_FRAME(12, 0), // 6 + ANIMCMD_FRAME(14, 0), // 7 + ANIMCMD_FRAME(16, 0), // 8 + ANIMCMD_FRAME(18, 0), // 9 // BUG: Animation not terminated properly + // Doesn't matter in practice, the frames are set directly and not looped //ANIMCMD_END }; -static const union AnimCmd *const gSpriteAnimTable_85B77A8[] = +static const union AnimCmd *const sAnims_CreditDigit[] = { - gSpriteAnim_85B7780 + sAnim_CreditDigit }; static const union AnimCmd sAnim_Multiplier[] = @@ -2881,7 +2926,7 @@ static const struct SpriteTemplate sSpriteTemplate_CreditDigit = .tileTag = GFXTAG_CREDIT_DIGIT, .paletteTag = PALTAG_INTERFACE, .oam = &sOam_CreditDigit, - .anims = gSpriteAnimTable_85B77A8, + .anims = sAnims_CreditDigit, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = SpriteCallbackDummy @@ -2936,7 +2981,7 @@ static const struct CompressedSpriteSheet sSpriteSheet_Ball = { .tag = GFXTAG_BALL }; -static const union AnimCmd gSpriteAnim_85B786C[] = +static const union AnimCmd sAnim_Ball_RollFast[] = { ANIMCMD_FRAME(0, 5), ANIMCMD_FRAME(4, 5), @@ -2945,7 +2990,7 @@ static const union AnimCmd gSpriteAnim_85B786C[] = ANIMCMD_JUMP(0) }; -static const union AnimCmd gSpriteAnim_85B7880[] = +static const union AnimCmd sAnim_Ball_RollMedium[] = { ANIMCMD_FRAME(0, 10), ANIMCMD_FRAME(4, 10), @@ -2954,7 +2999,7 @@ static const union AnimCmd gSpriteAnim_85B7880[] = ANIMCMD_JUMP(0) }; -static const union AnimCmd gSpriteAnim_85B7894[] = +static const union AnimCmd sAnim_Ball_RollSlow[] = { ANIMCMD_FRAME(0, 15), ANIMCMD_FRAME(4, 15), @@ -2963,7 +3008,7 @@ static const union AnimCmd gSpriteAnim_85B7894[] = ANIMCMD_JUMP(0) }; -static const union AnimCmd gSpriteAnim_85B78A8[] = +static const union AnimCmd sAnim_Ball_StopOnFrame1[] = { ANIMCMD_FRAME(4, 2), ANIMCMD_FRAME(8, 5), @@ -2972,7 +3017,7 @@ static const union AnimCmd gSpriteAnim_85B78A8[] = ANIMCMD_END }; -static const union AnimCmd gSpriteAnim_85B78BC[] = +static const union AnimCmd sAnim_Ball_StopOnFrame3[] = { ANIMCMD_FRAME(4, 2), ANIMCMD_FRAME(0, 4), @@ -2982,7 +3027,7 @@ static const union AnimCmd gSpriteAnim_85B78BC[] = ANIMCMD_END }; -static const union AnimCmd gSpriteAnim_85B78D4[] = +static const union AnimCmd sAnim_Ball_StopOnFrame4[] = { ANIMCMD_FRAME(0, 2), ANIMCMD_FRAME(4, 5), @@ -2991,13 +3036,13 @@ static const union AnimCmd gSpriteAnim_85B78D4[] = ANIMCMD_END }; -static const union AnimCmd gSpriteAnim_85B78E8[] = +static const union AnimCmd sAnim_Ball_Still[] = { ANIMCMD_FRAME(12, 0), ANIMCMD_END }; -static const union AnimCmd gSpriteAnim_85B78F0[] = +static const union AnimCmd sAnim_Ball_StopOnFrame2[] = { ANIMCMD_FRAME(8, 2), ANIMCMD_FRAME(4, 5), @@ -3008,15 +3053,15 @@ static const union AnimCmd gSpriteAnim_85B78F0[] = static const union AnimCmd *const sAnims_Ball[] = { - gSpriteAnim_85B786C, - gSpriteAnim_85B7880, - gSpriteAnim_85B7894, - gSpriteAnim_85B78A8, - gSpriteAnim_85B78F0, - gSpriteAnim_85B78BC, - gSpriteAnim_85B78D4, - gSpriteAnim_85B78D4, - gSpriteAnim_85B78E8 + sAnim_Ball_RollFast, + sAnim_Ball_RollMedium, + sAnim_Ball_RollSlow, + sAnim_Ball_StopOnFrame1, + sAnim_Ball_StopOnFrame2, + sAnim_Ball_StopOnFrame3, + sAnim_Ball_StopOnFrame4, + sAnim_Ball_StopOnFrame4, + sAnim_Ball_Still }; static const struct SpriteTemplate sSpriteTemplate_Ball = @@ -3030,7 +3075,7 @@ static const struct SpriteTemplate sSpriteTemplate_Ball = .callback = SpriteCallbackDummy }; -static const struct OamData sOam_BoardCenter = +static const struct OamData sOam_WheelCenter = { .y = 81, .affineMode = ST_OAM_AFFINE_DOUBLE, @@ -3040,22 +3085,22 @@ static const struct OamData sOam_BoardCenter = .priority = 2, }; -static const struct CompressedSpriteSheet sSpriteSheet_BoardCenter = +static const struct CompressedSpriteSheet sSpriteSheet_WheelCenter = { .data = gRouletteCenter_Gfx, .size = 0x800, - .tag = GFXTAG_BOARD_CENTER + .tag = GFXTAG_WHEEL_CENTER }; -static const struct SpriteTemplate sSpriteTemplate_BoardCenter = +static const struct SpriteTemplate sSpriteTemplate_WheelCenter = { - .tileTag = GFXTAG_BOARD_CENTER, + .tileTag = GFXTAG_WHEEL_CENTER, .paletteTag = PALTAG_BALL, - .oam = &sOam_BoardCenter, + .oam = &sOam_WheelCenter, .anims = gDummySpriteAnimTable, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCB_BoardCenter + .callback = SpriteCB_WheelCenter }; static const struct OamData sOam_Shroomish = @@ -3094,40 +3139,40 @@ static const union AnimCmd sAnim_Shroomish[] = ANIMCMD_JUMP(2) }; -static const union AnimCmd gSpriteAnim_85B799C[] = +static const union AnimCmd sAnim_Taillow_WingDown_Left[] = { ANIMCMD_FRAME(80, 10), ANIMCMD_END }; -static const union AnimCmd gSpriteAnim_85B79A4[] = +static const union AnimCmd sAnim_Taillow_WingDown_Right[] = { ANIMCMD_FRAME(80, 10, .hFlip = TRUE), ANIMCMD_END }; -static const union AnimCmd gSpriteAnim_85B79AC[] = +static const union AnimCmd sAnim_Taillow_FlapSlow_Left[] = { ANIMCMD_FRAME(80, 20), ANIMCMD_FRAME(96, 20), ANIMCMD_JUMP(0) }; -static const union AnimCmd gSpriteAnim_85B79B8[] = +static const union AnimCmd sAnim_Taillow_FlapSlow_Right[] = { ANIMCMD_FRAME(80, 20, .hFlip = TRUE), ANIMCMD_FRAME(96, 20, .hFlip = TRUE), ANIMCMD_JUMP(0) }; -static const union AnimCmd gSpriteAnim_85B79C4[] = +static const union AnimCmd sAnim_Taillow_FlapFast_Left[] = { ANIMCMD_FRAME(80, 10), ANIMCMD_FRAME(96, 10), ANIMCMD_JUMP(0) }; -static const union AnimCmd gSpriteAnim_85B79D0[] = +static const union AnimCmd sAnim_Taillow_FlapFast_Right[] = { ANIMCMD_FRAME(80, 10, .hFlip = TRUE), ANIMCMD_FRAME(96, 10, .hFlip = TRUE), @@ -3141,12 +3186,12 @@ static const union AnimCmd *const sAnims_Shroomish[] = static const union AnimCmd *const sAnims_Taillow[] = { - gSpriteAnim_85B799C, - gSpriteAnim_85B79A4, - gSpriteAnim_85B79AC, - gSpriteAnim_85B79B8, - gSpriteAnim_85B79C4, - gSpriteAnim_85B79D0 + sAnim_Taillow_WingDown_Left, // While gliding in + sAnim_Taillow_WingDown_Right, + sAnim_Taillow_FlapSlow_Left, // While carrying ball + sAnim_Taillow_FlapSlow_Right, + sAnim_Taillow_FlapFast_Left, // While flying off + sAnim_Taillow_FlapFast_Right }; static const struct SpriteTemplate sSpriteTemplate_Shroomish = @@ -3171,7 +3216,7 @@ static const struct SpriteTemplate sSpriteTemplate_Taillow = .callback = SpriteCB_Taillow }; -static const struct OamData gOamData_85B7A28 = +static const struct OamData sOam_ShroomishBallShadow = { .affineMode = ST_OAM_AFFINE_OFF, .objMode = ST_OAM_OBJ_NORMAL, @@ -3180,7 +3225,7 @@ static const struct OamData gOamData_85B7A28 = .priority = 2, }; -static const struct OamData gOamData_85B7A30 = +static const struct OamData sOam_ShroomishShadow = { .affineMode = ST_OAM_AFFINE_OFF, .objMode = ST_OAM_OBJ_NORMAL, @@ -3205,7 +3250,7 @@ static const struct CompressedSpriteSheet sSpriteSheet_Shadow = .tag = GFXTAG_SHADOW }; -static const union AffineAnimCmd gSpriteAffineAnim_85B7A48[] = +static const union AffineAnimCmd sAffineAnim_Unused3[] = { AFFINEANIMCMD_FRAME(0x80, 0x80, 0, 0), AFFINEANIMCMD_FRAME(2, 2, 0, 60), @@ -3221,9 +3266,9 @@ static const union AffineAnimCmd sAffineAnim_TaillowShadow[] = AFFINEANIMCMD_END }; -static const union AffineAnimCmd *const gSpriteAffineAnimTable_85B7A88[] = +static const union AffineAnimCmd *const sAffineAnims_Unused3[] = { - gSpriteAffineAnim_85B7A48 + sAffineAnim_Unused3 }; static const union AffineAnimCmd *const sAffineAnims_TaillowShadow[] = @@ -3231,58 +3276,60 @@ static const union AffineAnimCmd *const sAffineAnims_TaillowShadow[] = sAffineAnim_TaillowShadow }; -static const union AffineAnimCmd gSpriteAffineAnim_85B7A90[] = +static const union AffineAnimCmd sAffineAnim_Unused4[] = { AFFINEANIMCMD_FRAME(0x100, 0x100, 0, 0), AFFINEANIMCMD_END }; -static const union AffineAnimCmd *const gSpriteAffineAnimTable_85B7AA0[] = +static const union AffineAnimCmd *const sAffineAnims_Unused4[] = { - gSpriteAffineAnim_85B7A90 + sAffineAnim_Unused4 }; -static const union AnimCmd gSpriteAnim_85B7AA4[] = +static const union AnimCmd sAnim_ShroomishBallShadow[] = { ANIMCMD_FRAME(0, 0), ANIMCMD_END }; -static const union AnimCmd gSpriteAnim_85B7AAC[] = +static const union AnimCmd sAnim_UnstickMonShadow[] = { ANIMCMD_FRAME(4, 0), ANIMCMD_END }; -static const union AnimCmd *const gSpriteAnimTable_85B7AB4[] = +static const union AnimCmd *const sAnims_ShroomishBallShadow[] = { - gSpriteAnim_85B7AA4 + sAnim_ShroomishBallShadow }; -static const union AnimCmd *const gSpriteAnimTable_85B7AB8[] = +static const union AnimCmd *const sAnims_UnstickMonShadow[] = { - gSpriteAnim_85B7AAC + sAnim_UnstickMonShadow }; static const struct SpriteTemplate sSpriteTemplate_ShroomishShadow[] = { + // Ball's shadow as it flies up { .tileTag = GFXTAG_SHADOW, .paletteTag = PALTAG_SHADOW, - .oam = &gOamData_85B7A28, - .anims = gSpriteAnimTable_85B7AB4, + .oam = &sOam_ShroomishBallShadow, + .anims = sAnims_ShroomishBallShadow, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = SpriteCallbackDummy }, + // Shroomish's Shadow { .tileTag = GFXTAG_SHADOW, .paletteTag = PALTAG_SHADOW, - .oam = &gOamData_85B7A30, - .anims = gSpriteAnimTable_85B7AB8, + .oam = &sOam_ShroomishShadow, + .anims = sAnims_UnstickMonShadow, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_8144E60 + .callback = SpriteCB_Shroomish } }; @@ -3291,7 +3338,7 @@ static const struct SpriteTemplate sSpriteTemplate_TaillowShadow = .tileTag = GFXTAG_SHADOW, .paletteTag = PALTAG_SHADOW, .oam = &sOam_TaillowShadow, - .anims = gSpriteAnimTable_85B7AB8, + .anims = sAnims_UnstickMonShadow, .images = NULL, .affineAnims = sAffineAnims_TaillowShadow, .callback = SpriteCB_Taillow @@ -3349,7 +3396,7 @@ static void Task_PrintMinBet(u8 taskId) { if (JOY_NEW(A_BUTTON | B_BUTTON)) { - u32 minBet = sTableMinBets[GET_TABLE_ID(gSpecialVar_0x8004)]; + u32 minBet = sTableMinBets[GET_MIN_BET_ID(gSpecialVar_0x8004)]; ConvertIntToDecimalStringN(gStringVar1, minBet, STR_CONV_MODE_LEADING_ZEROS, 1); StringExpandPlaceholders(gStringVar4, Roulette_Text_PlayMinimumWagerIsX); DrawStdWindowFrame(0, FALSE); @@ -3363,7 +3410,7 @@ static void Task_PrintRouletteEntryMsg(u8 taskId) { s32 minBet; PrintCoinsString(gTasks[taskId].tCoins); - minBet = sTableMinBets[GET_TABLE_ID(gSpecialVar_0x8004)]; + minBet = sTableMinBets[GET_MIN_BET_ID(gSpecialVar_0x8004)]; ConvertIntToDecimalStringN(gStringVar1, minBet, STR_CONV_MODE_LEADING_ZEROS, 1); if (gTasks[taskId].tCoins >= minBet) @@ -3402,7 +3449,6 @@ static void Task_PrintRouletteEntryMsg(u8 taskId) void PlayRoulette(void) { u8 taskId; - ScriptContext2_Enable(); ShowCoinsWindow(GetCoins(), 1, 1); taskId = CreateTask(Task_PrintRouletteEntryMsg, 0); @@ -3429,19 +3475,19 @@ static void LoadOrFreeMiscSpritePalettesAndSheets(bool8 free) } } -static u8 CreateBoardIconSprite(const struct SpriteTemplate *r0, u8 r1, u16 *r2) +static u8 CreateWheelIconSprite(const struct SpriteTemplate *template, u8 r1, u16 *angle) { u16 temp; - u8 spriteId = CreateSprite(r0, 116, 80, r0->oam->y); - gSprites[spriteId].data[0] = *r2; + u8 spriteId = CreateSprite(template, 116, 80, template->oam->y); + gSprites[spriteId].data[0] = *angle; gSprites[spriteId].data[1] = r1; gSprites[spriteId].coordOffsetEnabled = TRUE; gSprites[spriteId].animPaused = TRUE; gSprites[spriteId].affineAnimPaused = TRUE; - temp = *r2; - *r2 += 30; - if (*r2 >= 360) - *r2 = temp - 330; + temp = *angle; + *angle += DEGREES_PER_SLOT; + if (*angle >= 360) + *angle = temp - (360 - DEGREES_PER_SLOT); return spriteId; } @@ -3455,21 +3501,21 @@ static void CreateGridSprites(void) s.size = sSpriteSheet_Headers.size; s.tag = sSpriteSheet_Headers.tag; LoadSpriteSheet(&s); - LZ77UnCompWram(sSpriteSheet_PokeIcons.data, gDecompressionBuffer); + LZ77UnCompWram(sSpriteSheet_GridIcons.data, gDecompressionBuffer); s.data = gDecompressionBuffer; - s.size = sSpriteSheet_PokeIcons.size; - s.tag = sSpriteSheet_PokeIcons.tag; + s.size = sSpriteSheet_GridIcons.size; + s.tag = sSpriteSheet_GridIcons.tag; LoadSpriteSheet(&s); for (i = 0; i < NUM_BOARD_COLORS; i++) { - u8 o = i * 24; + u8 y = i * 24; for (j = 0; j < NUM_BOARD_POKES; j++) { - spriteId = sRoulette->spriteIds[(i * NUM_BOARD_POKES) + SPR_GRID_ICONS + j] = CreateSprite(&sSpriteTemplate_GridIcons[j], (j * 24) + 148, o + 92, 30); + spriteId = sRoulette->spriteIds[(i * NUM_BOARD_POKES) + SPR_GRID_ICONS + j] = CreateSprite(&sSpriteTemplate_GridIcons[j], (j * 24) + 148, y + 92, 30); gSprites[spriteId].animPaused = TRUE; - o += 24; - if (o >= 72) - o = 0; + y += 24; + if (y >= 72) + y = 0; } } for (i = 0; i < ARRAY_COUNT(sSpriteTemplates_PokeHeaders); i++) @@ -3479,7 +3525,7 @@ static void CreateGridSprites(void) } for (i = 0; i < ARRAY_COUNT(sSpriteTemplates_ColorHeaders); i++) { - spriteId = sRoulette->spriteIds[i + SPR_COLOR_HEADER_1] = CreateSprite(&sSpriteTemplates_ColorHeaders[i], 126, (i * 24) + 92, 30); + spriteId = sRoulette->spriteIds[i + SPR_COLOR_HEADERS] = CreateSprite(&sSpriteTemplates_ColorHeaders[i], 126, (i * 24) + 92, 30); gSprites[spriteId].animPaused = TRUE; } } @@ -3530,12 +3576,12 @@ static void CreateGridBallSprites(void) u8 i; for (i = 0; i < BALLS_PER_ROUND; i++) { - sRoulette->spriteIds[i + SPR_GRID_BALL_1] = CreateSprite(&sSpriteTemplate_Ball, 116, 20, 10); - gSprites[sRoulette->spriteIds[i + SPR_GRID_BALL_1]].invisible = TRUE; - gSprites[sRoulette->spriteIds[i + SPR_GRID_BALL_1]].data[0] = 1; - gSprites[sRoulette->spriteIds[i + SPR_GRID_BALL_1]].callback = SpriteCB_GridSquare; - gSprites[sRoulette->spriteIds[i + SPR_GRID_BALL_1]].oam.priority = 1; - StartSpriteAnim(&gSprites[sRoulette->spriteIds[i + SPR_GRID_BALL_1]], 8); + sRoulette->spriteIds[i + SPR_GRID_BALLS] = CreateSprite(&sSpriteTemplate_Ball, 116, 20, 10); + gSprites[sRoulette->spriteIds[i + SPR_GRID_BALLS]].invisible = TRUE; + gSprites[sRoulette->spriteIds[i + SPR_GRID_BALLS]].data[0] = 1; + gSprites[sRoulette->spriteIds[i + SPR_GRID_BALLS]].callback = SpriteCB_GridSquare; + gSprites[sRoulette->spriteIds[i + SPR_GRID_BALLS]].oam.priority = 1; + StartSpriteAnim(&gSprites[sRoulette->spriteIds[i + SPR_GRID_BALLS]], 8); } } @@ -3546,7 +3592,7 @@ static void ShowHideGridBalls(bool8 hideAll, u8 hideBallId) { for (; i < BALLS_PER_ROUND; i++) { - gSprites[sRoulette->spriteIds[i + SPR_GRID_BALL_1]].invisible = TRUE; + gSprites[sRoulette->spriteIds[i + SPR_GRID_BALLS]].invisible = TRUE; } } else @@ -3555,13 +3601,13 @@ static void ShowHideGridBalls(bool8 hideAll, u8 hideBallId) { if (!sRoulette->hitSquares[i] || i == hideBallId) { - gSprites[sRoulette->spriteIds[i + SPR_GRID_BALL_1]].invisible = TRUE; + gSprites[sRoulette->spriteIds[i + SPR_GRID_BALLS]].invisible = TRUE; } else { - gSprites[sRoulette->spriteIds[i + SPR_GRID_BALL_1]].invisible = FALSE; - gSprites[sRoulette->spriteIds[i + SPR_GRID_BALL_1]].pos1.x = (sGridSelections[sRoulette->hitSquares[i]].x + 1) * 8 + 4; - gSprites[sRoulette->spriteIds[i + SPR_GRID_BALL_1]].pos1.y = (sGridSelections[sRoulette->hitSquares[i]].y + 1) * 8 + 3; + gSprites[sRoulette->spriteIds[i + SPR_GRID_BALLS]].invisible = FALSE; + gSprites[sRoulette->spriteIds[i + SPR_GRID_BALLS]].pos1.x = (sGridSelections[sRoulette->hitSquares[i]].x + 1) * 8 + 4; + gSprites[sRoulette->spriteIds[i + SPR_GRID_BALLS]].pos1.y = (sGridSelections[sRoulette->hitSquares[i]].y + 1) * 8 + 3; } } } @@ -3581,32 +3627,32 @@ static void ShowHideWinSlotCursor(u8 selectionId) } } -static void CreateBoardIconSprites(void) +static void CreateWheelIconSprites(void) { u8 i, j; - u16 k; + u16 angle; struct SpriteSheet s; - LZ77UnCompWram(sSpriteSheet_BoardIcons.data, gDecompressionBuffer); + LZ77UnCompWram(sSpriteSheet_WheelIcons.data, gDecompressionBuffer); s.data = gDecompressionBuffer; - s.size = sSpriteSheet_BoardIcons.size; - s.tag = sSpriteSheet_BoardIcons.tag; + s.size = sSpriteSheet_WheelIcons.size; + s.tag = sSpriteSheet_WheelIcons.tag; LoadSpriteSheet(&s); - k = 15; + angle = 15; for (i = 0; i < NUM_BOARD_COLORS; i++) { for (j = 0; j < NUM_BOARD_POKES; j++) { u8 spriteId; - spriteId = sRoulette->spriteIds[(i * NUM_BOARD_POKES) + SPR_BOARD_ICONS + j] = CreateBoardIconSprite(&sSpriteTemplates_BoardIcons[i * NUM_BOARD_POKES + j], 40, &k); + spriteId = sRoulette->spriteIds[(i * NUM_BOARD_POKES) + SPR_WHEEL_ICONS + j] = CreateWheelIconSprite(&sSpriteTemplates_WheelIcons[i * NUM_BOARD_POKES + j], 40, &angle); gSprites[spriteId].animPaused = TRUE; gSprites[spriteId].affineAnimPaused = TRUE; } } } -static void SpriteCB_BoardIcon(struct Sprite *sprite) +static void SpriteCB_WheelIcon(struct Sprite *sprite) { s16 cos; s16 sin; @@ -3713,9 +3759,9 @@ static u8 GetMultiplierAnimId(u8 selectionId) static void SetMultiplierSprite(u8 selectionId) { - struct Sprite *s = &gSprites[sRoulette->spriteIds[SPR_MULTIPLIER]]; - s->animCmdIndex = GetMultiplierAnimId(selectionId); - s->oam.tileNum = s->sheetTileStart + (*s->anims + s->animCmdIndex)->type; + struct Sprite *sprite = &gSprites[sRoulette->spriteIds[SPR_MULTIPLIER]]; + sprite->animCmdIndex = GetMultiplierAnimId(selectionId); + sprite->oam.tileNum = sprite->sheetTileStart + (*sprite->anims + sprite->animCmdIndex)->type; } static void SetBallCounterNumLeft(u8 numBalls) @@ -3776,16 +3822,18 @@ static void SpriteCB_GridSquare(struct Sprite *sprite) sprite->pos2.x = sRoulette->gridX; } -static void CreateBoardCenterSprite(void) +static void CreateWheelCenterSprite(void) { u8 spriteId; struct SpriteSheet s; - LZ77UnCompWram(sSpriteSheet_BoardCenter.data, gDecompressionBuffer); + LZ77UnCompWram(sSpriteSheet_WheelCenter.data, gDecompressionBuffer); s.data = gDecompressionBuffer; - s.size = sSpriteSheet_BoardCenter.size; - s.tag = sSpriteSheet_BoardCenter.tag; + s.size = sSpriteSheet_WheelCenter.size; + s.tag = sSpriteSheet_WheelCenter.tag; LoadSpriteSheet(&s); - spriteId = CreateSprite(&sSpriteTemplate_BoardCenter, 116, 80, 81); + // This sprite id isn't saved because it doesn't need to be referenced again + // but by virtue of creation order it's SPR_WHEEL_CENTER + spriteId = CreateSprite(&sSpriteTemplate_WheelCenter, 116, 80, 81); gSprites[spriteId].data[0] = sRoulette->wheelAngle; gSprites[spriteId].data[1] = 0; gSprites[spriteId].animPaused = TRUE; @@ -3793,17 +3841,17 @@ static void CreateBoardCenterSprite(void) gSprites[spriteId].coordOffsetEnabled = TRUE; } -static void SpriteCB_BoardCenter(struct Sprite *sprite) +static void SpriteCB_WheelCenter(struct Sprite *sprite) { - u32 t = sprite->oam.matrixNum; - struct OamMatrix *m = &gOamMatrices[0]; - m[t].d = sRoulette->wheelRotation.a; - m[t].a = sRoulette->wheelRotation.a; - m[t].b = sRoulette->wheelRotation.b; - m[t].c = sRoulette->wheelRotation.c; + u32 matrixNum = sprite->oam.matrixNum; + struct OamMatrix *matrix = &gOamMatrices[0]; + matrix[matrixNum].d = sRoulette->wheelRotation.a; + matrix[matrixNum].a = sRoulette->wheelRotation.a; + matrix[matrixNum].b = sRoulette->wheelRotation.b; + matrix[matrixNum].c = sRoulette->wheelRotation.c; } -static void CreateBoardBallSprites(void) +static void CreateWheelBallSprites(void) { u8 i; for (i = 0; i < BALLS_PER_ROUND; i++) @@ -3817,9 +3865,9 @@ static void CreateBoardBallSprites(void) } } -static void HideBoardBalls(void) +static void HideWheelBalls(void) { - u8 spriteId = sRoulette->spriteIds[SPR_BALL_1]; + u8 spriteId = sRoulette->spriteIds[SPR_WHEEL_BALLS]; u8 i; for (i = 0; i < BALLS_PER_ROUND; i++) { @@ -3834,69 +3882,95 @@ static void HideBoardBalls(void) } } -static s16 sub_8143AC8(struct Sprite *sprite) +// Sprite data for the roulette ball +#define sStuckOnWheelLeft data[0] // if true, ball got stuck in left half of wheel, else got stuck in right half +#define sState data[1] +#define sSlotMidpointDist data[2] +#define sBallAngle data[3] +#define sBallDistToCenter data[4] +#define sBallWheelAngle data[6] + +#define LandBall() \ +{ \ + sRoulette->ballState = BALL_STATE_LANDED; \ + sRoulette->ballRolling = FALSE; \ + StartSpriteAnim(sprite, sprite->animCmdIndex + 3); \ + UpdateSlotBelowBall(sprite); \ + sprite->sBallDistToCenter = 30; \ + UpdateBallRelativeWheelAngle(sprite); \ + sprite->sBallWheelAngle = (sprite->sBallWheelAngle / DEGREES_PER_SLOT) * DEGREES_PER_SLOT + 15; \ + sprite->callback = SpriteCB_BallLandInSlot; \ + m4aSongNumStartOrChange(SE_HASHI); \ +} + +// "wheelAngle" and "sBallAngle" are relative to the screen (e.g. 180 degrees for either is always screen bottom) +// "sBallWheelAngle" is the ball's angle relative to the wheel +// e.g. if the ball is screen right (90), but wheel is upside down (180), sBallWheelAngle is 270 (because the ball is wheel left) +static s16 UpdateBallRelativeWheelAngle(struct Sprite *sprite) { - if (sRoulette->wheelAngle > sprite->data[3]) + if (sRoulette->wheelAngle > sprite->sBallAngle) { - sprite->data[6] = 360 - sRoulette->wheelAngle + sprite->data[3]; - if (sprite->data[6] >= 360) - sprite->data[6] -= 360; + sprite->sBallWheelAngle = 360 - sRoulette->wheelAngle + sprite->sBallAngle; + if (sprite->sBallWheelAngle >= 360) + sprite->sBallWheelAngle -= 360; } else { - sprite->data[6] = sprite->data[3] - sRoulette->wheelAngle; + sprite->sBallWheelAngle = sprite->sBallAngle - sRoulette->wheelAngle; } - return sprite->data[6]; + return sprite->sBallWheelAngle; } -static u8 sub_8143B14(struct Sprite *sprite) +static u8 UpdateSlotBelowBall(struct Sprite *sprite) { - sRoulette->hitSlot = sub_8143AC8(sprite) / 30.0f; + sRoulette->hitSlot = UpdateBallRelativeWheelAngle(sprite) / (float) DEGREES_PER_SLOT; return sRoulette->hitSlot; } -static s16 sub_8143B48(struct Sprite *sprite) +static s16 GetBallDistanceToSlotMidpoint(struct Sprite *sprite) { - s16 t = sub_8143AC8(sprite) % 30; - u16 z; - if (t == 14) + s16 angleIntoSlot = UpdateBallRelativeWheelAngle(sprite) % DEGREES_PER_SLOT; + u16 distanceToMidpoint; + if (angleIntoSlot == SLOT_MIDPOINT) { - z = 0; - return sprite->data[2] = z; + // Ball is at midpoint, ok to drop into slot + distanceToMidpoint = 0; + return sprite->sSlotMidpointDist = distanceToMidpoint; } - else if (t > 13) + else if (angleIntoSlot >= SLOT_MIDPOINT) { - z = 43 - t; - return sprite->data[2] = z; + // Ball has passed midpoint, travel to midpoint of next slot + distanceToMidpoint = (DEGREES_PER_SLOT - 1) + SLOT_MIDPOINT - angleIntoSlot; + return sprite->sSlotMidpointDist = distanceToMidpoint; } else { - z = 14 - t; - return sprite->data[2] = z; + // Ball hasn't reached midpoint of this slot yet + distanceToMidpoint = SLOT_MIDPOINT - angleIntoSlot; + return sprite->sSlotMidpointDist = distanceToMidpoint; } } -static void sub_8143B84(struct Sprite *sprite) +static void UpdateBallPos(struct Sprite *sprite) { s16 sin, cos; + sRoulette->ballAngleSpeed += sRoulette->ballAngleAccel; + sRoulette->ballAngle += sRoulette->ballAngleSpeed; - sRoulette->var8C += sRoulette->var90; - sRoulette->var88 += sRoulette->var8C; + if (sRoulette->ballAngle >= 360) + sRoulette->ballAngle -= 360.0f; + else if (sRoulette->ballAngle < 0.0f) + sRoulette->ballAngle += 360.0f; - if (sRoulette->var88 >= 360) - sRoulette->var88 -= 360.0f; - else if (sRoulette->var88 < 0.0f) - sRoulette->var88 += 360.0f; - - sprite->data[3] = sRoulette->var88; - sRoulette->var98 += sRoulette->var9C; - sRoulette->var94 += sRoulette->var98; - sprite->data[4] = sRoulette->var94; - sin = Sin2(sprite->data[3]); - cos = Cos2(sprite->data[3]); - sprite->pos2.x = sin * sprite->data[4] >> 12; - sprite->pos2.y = -cos * sprite->data[4] >> 12; + sprite->sBallAngle = sRoulette->ballAngle; + sRoulette->ballFallSpeed += sRoulette->ballFallAccel; + sRoulette->ballDistToCenter += sRoulette->ballFallSpeed; + sprite->sBallDistToCenter = sRoulette->ballDistToCenter; + sin = Sin2(sprite->sBallAngle); + cos = Cos2(sprite->sBallAngle); + sprite->pos2.x = sin * sprite->sBallDistToCenter >> 12; + sprite->pos2.y = -cos * sprite->sBallDistToCenter >> 12; if (IsSEPlaying()) { m4aMPlayPanpotControl(&gMPlayInfo_SE1, 0xFFFF, sprite->pos2.x); @@ -3904,80 +3978,65 @@ static void sub_8143B84(struct Sprite *sprite) } } -static void sub_8143C90(struct Sprite *sprite) +// Snap to the bottom of the slot and continue to spin with the wheel +static void SpriteCB_BallLandInSlot(struct Sprite *sprite) { s16 sin, cos; - sprite->data[3] = sRoulette->wheelAngle + sprite->data[6]; - if (sprite->data[3] >= 360) - sprite->data[3] -= 360; - sin = Sin2(sprite->data[3]); - cos = Cos2(sprite->data[3]); - sprite->pos2.x = sin * sprite->data[4] >> 12; - sprite->pos2.y = -cos * sprite->data[4] >> 12; + sprite->sBallAngle = sRoulette->wheelAngle + sprite->sBallWheelAngle; + if (sprite->sBallAngle >= 360) + sprite->sBallAngle -= 360; + sin = Sin2(sprite->sBallAngle); + cos = Cos2(sprite->sBallAngle); + sprite->pos2.x = sin * sprite->sBallDistToCenter >> 12; + sprite->pos2.y = -cos * sprite->sBallDistToCenter >> 12; sprite->pos2.y += gSpriteCoordOffsetY; } -static void sub_8143CFC(struct Sprite *sprite) +static void SpriteCB_UnstickBall_ShroomishBallFall(struct Sprite *sprite) { - sub_8143B84(sprite); + UpdateBallPos(sprite); sprite->data[2]++; - if (sprite->data[4] < -132 || sprite->data[4] > 80) + if (sprite->sBallDistToCenter < -132 || sprite->sBallDistToCenter > 80) sprite->invisible = TRUE; else sprite->invisible = FALSE; - if (sprite->data[2] >= 30) + if (sprite->data[2] >= DEGREES_PER_SLOT) { - if (!sprite->data[0]) + if (!sprite->sStuckOnWheelLeft) { - if (sRoulette->var94 <= sRoulette->varA0 - 2.0f) + if (sRoulette->ballDistToCenter <= sRoulette->varA0 - 2.0f) { - sRoulette->ballState = BALL_STATE_LANDED; - sRoulette->ballRolling = FALSE; - StartSpriteAnim(sprite, sprite->animCmdIndex + 3); - sub_8143B14(sprite); - sprite->data[4] = 30; - sub_8143AC8(sprite); - sprite->data[6] = (sprite->data[6] / 30) * 30 + 15; - sprite->callback = sub_8143C90; - m4aSongNumStartOrChange(SE_HASHI); - sRoulette->var9C = sRoulette->var98 = 0.0f; - sRoulette->var8C = -1.0f; + LandBall() + sRoulette->ballFallAccel = sRoulette->ballFallSpeed = 0.0f; + sRoulette->ballAngleSpeed = -1.0f; } } else { - if (sRoulette->var94 >= sRoulette->varA0 - 2.0f) + if (sRoulette->ballDistToCenter >= sRoulette->varA0 - 2.0f) { - sRoulette->ballState = BALL_STATE_LANDED; - sRoulette->ballRolling = FALSE; - StartSpriteAnim(sprite, sprite->animCmdIndex + 3); - sub_8143B14(sprite); - sprite->data[4] = 30; - sub_8143AC8(sprite); - sprite->data[6] = (sprite->data[6] / 30) * 30 + 15; - sprite->callback = sub_8143C90; - m4aSongNumStartOrChange(SE_HASHI); - sRoulette->var9C = sRoulette->var98 = 0.0f; - sRoulette->var8C = -1.0f; + LandBall() + sRoulette->ballFallAccel = sRoulette->ballFallSpeed = 0.0f; + sRoulette->ballAngleSpeed = -1.0f; } } } } -static void SpriteCB_Shroomish(struct Sprite *sprite) +static void SpriteCB_UnstickBall_Shroomish(struct Sprite *sprite) { - float f0, f1, f2; - sub_8143B84(sprite); + float slotOffset, ballFallDist, ballFallSpeed; + UpdateBallPos(sprite); - switch (sprite->data[3]) + switch (sprite->sBallAngle) { case 0: - if (sprite->data[0] != 1) + if (sprite->sStuckOnWheelLeft != TRUE) { - f0 = sprite->data[7]; - f1 = (f0 * sRouletteTables[sRoulette->tableId].var01 + (sRouletteTables[sRoulette->tableId].var02 - 1)); - f2 = (f0 / sRouletteTables[sRoulette->tableId].var0C); + slotOffset = sprite->data[7]; + ballFallDist = (slotOffset * sRouletteTables[sRoulette->tableId].randDistanceHigh + (sRouletteTables[sRoulette->tableId].randDistanceLow - 1)); + ballFallSpeed = (slotOffset / sRouletteTables[sRoulette->tableId].shroomish.fallSlowdown); } else { @@ -3985,11 +4044,11 @@ static void SpriteCB_Shroomish(struct Sprite *sprite) } break; case 180: - if (sprite->data[0] != 0) + if (sprite->sStuckOnWheelLeft) { - f0 = sprite->data[7]; - f1 = (f0 * sRouletteTables[sRoulette->tableId].var01 + (sRouletteTables[sRoulette->tableId].var02 - 1)); - f2 = -(f0 / sRouletteTables[sRoulette->tableId].var0C); + slotOffset = sprite->data[7]; + ballFallDist = (slotOffset * sRouletteTables[sRoulette->tableId].randDistanceHigh + (sRouletteTables[sRoulette->tableId].randDistanceLow - 1)); + ballFallSpeed = -(slotOffset / sRouletteTables[sRoulette->tableId].shroomish.fallSlowdown); } else { @@ -3999,38 +4058,30 @@ static void SpriteCB_Shroomish(struct Sprite *sprite) default: return; } - sRoulette->varA0 = sRoulette->var94; - sRoulette->var98 = f2; - sRoulette->var9C = -((f2 * 2.0f) / f1 + (2.0f / (f1 * f1))); - sRoulette->var8C = 0.0f; + sRoulette->varA0 = sRoulette->ballDistToCenter; + sRoulette->ballFallSpeed = ballFallSpeed; + sRoulette->ballFallAccel = -((ballFallSpeed * 2.0f) / ballFallDist + (2.0f / (ballFallDist * ballFallDist))); + sRoulette->ballAngleSpeed = 0.0f; sprite->animPaused = FALSE; sprite->animNum = 0; sprite->animBeginning = TRUE; sprite->animEnded = FALSE; - sprite->callback = sub_8143CFC; + sprite->callback = SpriteCB_UnstickBall_ShroomishBallFall; sprite->data[2] = 0; } -static void sub_8143FA4(struct Sprite *sprite) +static void SpriteCB_UnstickBall_TaillowDrop(struct Sprite *sprite) { sprite->pos2.y = (s16)(sprite->data[2] * 0.05f * sprite->data[2]) - 45; sprite->data[2]++; - if (sprite->data[2] > 29 && sprite->pos2.y >= 0) + if (sprite->data[2] >= DEGREES_PER_SLOT && sprite->pos2.y >= 0) { - sRoulette->ballState = BALL_STATE_LANDED; - sRoulette->ballRolling = FALSE; - StartSpriteAnim(sprite, sprite->animCmdIndex + 3); - sub_8143B14(sprite); - sprite->data[4] = 30; - sub_8143AC8(sprite); - sprite->data[6] = (sprite->data[6] / 30) * 30 + 15; - sprite->callback = sub_8143C90; - m4aSongNumStartOrChange(SE_HASHI); + LandBall() sRoulette->ballUnstuck = TRUE; } } -static void sub_8144050(struct Sprite *sprite) +static void SpriteCB_UnstickBall_TaillowPickUp(struct Sprite *sprite) { if (sprite->data[2]++ < 45) { @@ -4060,224 +4111,228 @@ static void sub_8144050(struct Sprite *sprite) sprite->animBeginning = TRUE; sprite->animEnded = FALSE; sprite->data[2] = 0; - sprite->callback = sub_8143FA4; + sprite->callback = SpriteCB_UnstickBall_TaillowDrop; m4aSongNumStart(SE_NAGERU); } } } -static void sub_8144128(struct Sprite *sprite) +static void SpriteCB_UnstickBall_Taillow(struct Sprite *sprite) { - sub_8143B84(sprite); - switch (sprite->data[3]) + UpdateBallPos(sprite); + + switch (sprite->sBallAngle) { case 90: - if (sprite->data[0] != 1) + if (sprite->sStuckOnWheelLeft != TRUE) { - sprite->callback = &sub_8144050; + sprite->callback = &SpriteCB_UnstickBall_TaillowPickUp; sprite->data[2] = 0; } break; case 270: - if (sprite->data[0] != 0) + if (sprite->sStuckOnWheelLeft) { - sprite->callback = &sub_8144050; + sprite->callback = &SpriteCB_UnstickBall_TaillowPickUp; sprite->data[2] = 0; } break; } } -static void CreateClearSpeciesSprite(struct Sprite *sprite) +// The below SpriteCB_UnstickBall_* callbacks handle the ball while its being cleared by Shroomish/Taillow +// For what Shroomish/Taillow do during this sequence, see SpriteCB_Shroomish / SpriteCB_Taillow +static void SpriteCB_UnstickBall(struct Sprite *sprite) { - sub_8143B84(sprite); + UpdateBallPos(sprite); switch (sRoulette->useTaillow) { default: case FALSE: CreateShroomishSprite(sprite); - sprite->callback = SpriteCB_Shroomish; + sprite->callback = SpriteCB_UnstickBall_Shroomish; break; case TRUE: CreateTaillowSprite(sprite); - sprite->callback = sub_8144128; + sprite->callback = SpriteCB_UnstickBall_Taillow; break; } } -static void prev_quest_read_x24_hm_usage(struct Sprite *sprite) +#define sStillStuck data[0] + +static void SpriteCB_RollBall_TryLandAdjacent(struct Sprite *sprite) { - sub_8143B84(sprite); + UpdateBallPos(sprite); + if (sprite->data[2]-- == 16) - sRoulette->var98 *= -1.0f; + sRoulette->ballFallSpeed *= -1.0f; + if (sprite->data[2] == 0) { - if (!sprite->data[0]) + if (!sprite->sStillStuck) { - sRoulette->ballState = BALL_STATE_LANDED; - sRoulette->ballRolling = FALSE; - StartSpriteAnim(sprite, sprite->animCmdIndex + 3); - sub_8143B14(sprite); - sprite->data[4] = 30; - sub_8143AC8(sprite); - sprite->data[6] = (sprite->data[6] / 30) * 30 + 15; - sprite->callback = sub_8143C90; - m4aSongNumStartOrChange(SE_HASHI); + // Ball can successfully fall into adjacent space + LandBall() } else { + // Ball is stuck, need Shroomish/Taillow to clear ball sprite->animPaused = TRUE; m4aSongNumStart(SE_KON); - sub_8144A24(sprite); + SetBallStuck(sprite); } } } -static void sub_8144264(struct Sprite *sprite) +static void SpriteCB_RollBall_TryLand(struct Sprite *sprite) { - sub_8143B84(sprite); + UpdateBallPos(sprite); sprite->data[2] = 0; - sub_8143B14(sprite); + UpdateSlotBelowBall(sprite); if (!(sRouletteSlots[sRoulette->hitSlot].flag & sRoulette->hitFlags)) { - sRoulette->ballState = BALL_STATE_LANDED; - sRoulette->ballRolling = FALSE; - StartSpriteAnim(sprite, sprite->animCmdIndex + 3); - sub_8143B14(sprite); - sprite->data[4] = 30; - sub_8143AC8(sprite); - sprite->data[6] = (sprite->data[6] / 30) * 30 + 15; - sprite->callback = sub_8143C90; - m4aSongNumStartOrChange(SE_HASHI); + // Space is empty, land successfully + LandBall() } else { + // Space has already been landed on, try to fall into adjacent space u8 slotId; - u32 z; + u32 fallRight; m4aSongNumStart(SE_KON); - z = Random() & 1; - if (z) + fallRight = Random() & 1; + if (fallRight) { - sRoulette->var8C = 0.0f; - sRoulette->var7F = slotId = (sRoulette->hitSlot + 1) % NUM_ROULETTE_SLOTS; + sRoulette->ballAngleSpeed = 0.0f; + sRoulette->stuckHitSlot = slotId = (sRoulette->hitSlot + 1) % NUM_ROULETTE_SLOTS; } - else + else // fall left { float temp; - sRoulette->var8C = (temp = sRouletteTables[sRoulette->tableId].var1C) * 2.0f; + sRoulette->ballAngleSpeed = (temp = sRouletteTables[sRoulette->tableId].var1C) * 2.0f; slotId = (sRoulette->hitSlot + NUM_ROULETTE_SLOTS - 1) % NUM_ROULETTE_SLOTS; - sRoulette->var7F = sRoulette->hitSlot; + sRoulette->stuckHitSlot = sRoulette->hitSlot; } if (sRouletteSlots[slotId].flag & sRoulette->hitFlags) { - sprite->data[0] = 1; - sprite->data[2] = sRouletteTables[sRoulette->tableId].var02; + // Attempted adjacent space has also been landed on + sprite->sStillStuck = TRUE; + sprite->data[2] = sRouletteTables[sRoulette->tableId].randDistanceLow; } else { - sprite->data[0] = sRouletteSlots[slotId].flag & sRoulette->hitFlags; + sprite->sStillStuck = FALSE; if (sRoulette->tableId) { - sprite->data[2] = sRouletteTables[sRoulette->tableId].var01; + sprite->data[2] = sRouletteTables[sRoulette->tableId].randDistanceHigh; } else { - sprite->data[2] = sRouletteTables[sRoulette->tableId].var02; - if (z) - sRoulette->var8C = 0.5f; + sprite->data[2] = sRouletteTables[sRoulette->tableId].randDistanceLow; + if (fallRight) + sRoulette->ballAngleSpeed = 0.5f; else - sRoulette->var8C = -1.5f; + sRoulette->ballAngleSpeed = -1.5f; } } - sRoulette->var98 = 0.085f; - sprite->callback = prev_quest_read_x24_hm_usage; - sprite->data[1] = 5; + sRoulette->ballFallSpeed = 0.085f; + sprite->callback = SpriteCB_RollBall_TryLandAdjacent; + sprite->sState = 5; } } -static void sub_8144410(struct Sprite *sprite) +#undef sStillStuck + +static void SpriteCB_RollBall_Slow(struct Sprite *sprite) { - sub_8143B84(sprite); - if (sRoulette->var8C > 0.5f) + UpdateBallPos(sprite); + if (sRoulette->ballAngleSpeed > 0.5f) return; - sub_8143B14(sprite); - if (!sub_8143B48(sprite)) + UpdateSlotBelowBall(sprite); + if (GetBallDistanceToSlotMidpoint(sprite) == 0) { - sRoulette->var90 = 0.0f; - sRoulette->var8C -= (float)(sRouletteTables[sRoulette->tableId].wheelSpeed) + // Reached slot to land in + sRoulette->ballAngleAccel = 0.0f; + sRoulette->ballAngleSpeed -= (float)(sRouletteTables[sRoulette->tableId].wheelSpeed) / (sRouletteTables[sRoulette->tableId].wheelDelay + 1); - sprite->data[1] = 4; - sprite->callback = sub_8144264; + sprite->sState = 4; + sprite->callback = SpriteCB_RollBall_TryLand; } else { - if (sRoulette->var90 != 0.0f) + if (sRoulette->ballAngleAccel != 0.0f) { - if (sRoulette->var8C < 0.0f) + if (sRoulette->ballAngleSpeed < 0.0f) { - sRoulette->var90 = 0.0f; - sRoulette->var8C = 0.0f; - sRoulette->var98 /= 1.2; + sRoulette->ballAngleAccel = 0.0f; + sRoulette->ballAngleSpeed = 0.0f; + sRoulette->ballFallSpeed /= 1.2; } } } } -static void sub_8144514(struct Sprite *sprite) +static void SpriteCB_RollBall_Medium(struct Sprite *sprite) { - sub_8143B84(sprite); - if (sRoulette->var94 > 40.f) + UpdateBallPos(sprite); + if (sRoulette->ballDistToCenter > 40.0f) return; - sRoulette->var98 = -(4.0f / (float)(sRoulette->var86)); - sRoulette->var90 = -(sRoulette->var8C / (float)(sRoulette->var86)); + sRoulette->ballFallSpeed = -(4.0f / (float)(sRoulette->ballTravelDistSlow)); + sRoulette->ballAngleAccel = -(sRoulette->ballAngleSpeed / (float)(sRoulette->ballTravelDistSlow)); sprite->animNum = 2; sprite->animBeginning = TRUE; sprite->animEnded = FALSE; - sprite->data[1] = 3; - sprite->callback = sub_8144410; + sprite->sState = 3; + sprite->callback = SpriteCB_RollBall_Slow; } -static void sub_81445D8(struct Sprite *sprite) +static void SpriteCB_RollBall_Fast(struct Sprite *sprite) { - sub_8143B84(sprite); - if (sRoulette->var94 > 60.0f) + UpdateBallPos(sprite); + if (sRoulette->ballDistToCenter > 60.0f) return; m4aSongNumStartOrChange(SE_TAMAKORO_E); - sRoulette->var98 = -(20.0f / (float)(sRoulette->var84)); - sRoulette->var90 = ((1.0f - sRoulette->var8C) / (float)(sRoulette->var84)); + sRoulette->ballFallSpeed = -(20.0f / (float)(sRoulette->ballTravelDistMed)); + sRoulette->ballAngleAccel = ((1.0f - sRoulette->ballAngleSpeed) / (float)(sRoulette->ballTravelDistMed)); sprite->animNum = 1; sprite->animBeginning = TRUE; sprite->animEnded = FALSE; - sprite->data[1] = 2; - sprite->callback = sub_8144514; + sprite->sState = 2; + sprite->callback = SpriteCB_RollBall_Medium; } -static void sub_81446AC(struct Sprite *sprite) +static void SpriteCB_RollBall_Start(struct Sprite *sprite) { - sprite->data[1] = 1; + sprite->sState = 1; sprite->data[2] = 0; - sub_8143B84(sprite); + UpdateBallPos(sprite); sprite->invisible = FALSE; - sprite->callback = sub_81445D8; + sprite->callback = SpriteCB_RollBall_Fast; } -static void CreateShroomishSprite(struct Sprite *sprite) +// Sprite data for Shroomish / its shadows +#define sMonSpriteId data[4] +#define sBallShadowSpriteId data[5] +#define sMonShadowSpriteId data[6] + +static void CreateShroomishSprite(struct Sprite *ball) { u16 t; u8 i; - s16 s[2][2] = { + s16 coords[2][2] = { {116, 44}, {116, 112} }; - struct Roulette *p; + struct Roulette *roulette; - t = sprite->data[7] - 2; - p = sRoulette; // why??? + t = ball->data[7] - 2; + roulette = sRoulette; // Unnecessary, needed to match sRoulette->spriteIds[SPR_CLEAR_MON] = CreateSprite(&sSpriteTemplate_Shroomish, 36, -12, 50); - sRoulette->spriteIds[SPR_CLEAR_MON_SHADOW_1] = CreateSprite(&sSpriteTemplate_ShroomishShadow[0], s[sprite->data[0]][0], s[sprite->data[0]][1], 59); + sRoulette->spriteIds[SPR_CLEAR_MON_SHADOW_1] = CreateSprite(&sSpriteTemplate_ShroomishShadow[0], coords[ball->sStuckOnWheelLeft][0], coords[ball->sStuckOnWheelLeft][1], 59); sRoulette->spriteIds[SPR_CLEAR_MON_SHADOW_2] = CreateSprite(&sSpriteTemplate_ShroomishShadow[1], 36, 140, 51); gSprites[sRoulette->spriteIds[SPR_CLEAR_MON_SHADOW_2]].oam.objMode = ST_OAM_OBJ_BLEND; for (i = 0; i < 3; i++) @@ -4286,85 +4341,88 @@ static void CreateShroomishSprite(struct Sprite *sprite) gSprites[sRoulette->spriteIds[i + SPR_CLEAR_MON]].invisible = TRUE; gSprites[sRoulette->spriteIds[i + SPR_CLEAR_MON]].animPaused = TRUE; gSprites[sRoulette->spriteIds[i + SPR_CLEAR_MON]].affineAnimPaused = TRUE; - gSprites[sRoulette->spriteIds[i + SPR_CLEAR_MON]].data[4] = sRoulette->spriteIds[SPR_CLEAR_MON]; - gSprites[sRoulette->spriteIds[i + SPR_CLEAR_MON]].data[5] = sRoulette->spriteIds[SPR_CLEAR_MON_SHADOW_1]; - gSprites[sRoulette->spriteIds[i + SPR_CLEAR_MON]].data[6] = sRoulette->spriteIds[SPR_CLEAR_MON_SHADOW_2]; + gSprites[sRoulette->spriteIds[i + SPR_CLEAR_MON]].sMonSpriteId = sRoulette->spriteIds[SPR_CLEAR_MON]; + gSprites[sRoulette->spriteIds[i + SPR_CLEAR_MON]].sBallShadowSpriteId = sRoulette->spriteIds[SPR_CLEAR_MON_SHADOW_1]; + gSprites[sRoulette->spriteIds[i + SPR_CLEAR_MON]].sMonShadowSpriteId = sRoulette->spriteIds[SPR_CLEAR_MON_SHADOW_2]; gSprites[sRoulette->spriteIds[i + SPR_CLEAR_MON]].data[2] = t; - gSprites[sRoulette->spriteIds[i + SPR_CLEAR_MON]].data[3] = (sprite->data[7] * sRouletteTables[sRoulette->tableId].var01) + - (sRouletteTables[sRoulette->tableId].var02 + 0xFFFF); + gSprites[sRoulette->spriteIds[i + SPR_CLEAR_MON]].data[3] = (ball->data[7] * sRouletteTables[sRoulette->tableId].randDistanceHigh) + + (sRouletteTables[sRoulette->tableId].randDistanceLow + 0xFFFF); } gSprites[sRoulette->spriteIds[SPR_CLEAR_MON_SHADOW_1]].coordOffsetEnabled = TRUE; - sRoulette->var38 = sprite; + sRoulette->ball = ball; } -static void CreateTaillowSprite(struct Sprite *sprite) +static void CreateTaillowSprite(struct Sprite *ball) { u8 i = 0; s16 t; - s16 s[2][2] = { - {256, 84}, - {-16, 84} + s16 coords[2][2] = { + {256, 84}, // Right approach + {-16, 84} // Left approach }; - t = sprite->data[7] - 2; - sRoulette->spriteIds[SPR_CLEAR_MON] = CreateSprite(&sSpriteTemplate_Taillow, s[sprite->data[0]][0], s[sprite->data[0]][1], 50); - StartSpriteAnim(&gSprites[sRoulette->spriteIds[SPR_CLEAR_MON]], sprite->data[0]); - sRoulette->spriteIds[SPR_CLEAR_MON_SHADOW_1] = CreateSprite(&sSpriteTemplate_TaillowShadow, s[sprite->data[0]][0], s[sprite->data[0]][1], 51); + t = ball->data[7] - 2; + sRoulette->spriteIds[SPR_CLEAR_MON] = CreateSprite(&sSpriteTemplate_Taillow, coords[ball->sStuckOnWheelLeft][0], coords[ball->sStuckOnWheelLeft][1], 50); + StartSpriteAnim(&gSprites[sRoulette->spriteIds[SPR_CLEAR_MON]], ball->sStuckOnWheelLeft); + sRoulette->spriteIds[SPR_CLEAR_MON_SHADOW_1] = CreateSprite(&sSpriteTemplate_TaillowShadow, coords[ball->sStuckOnWheelLeft][0], coords[ball->sStuckOnWheelLeft][1], 51); gSprites[sRoulette->spriteIds[SPR_CLEAR_MON_SHADOW_1]].affineAnimPaused = TRUE; gSprites[sRoulette->spriteIds[SPR_CLEAR_MON_SHADOW_1]].animPaused = TRUE; - sprite->data[7] = (t * sRouletteTables[sRoulette->tableId].var01) + (sRouletteTables[sRoulette->tableId].var10 + 45); + ball->data[7] = (t * sRouletteTables[sRoulette->tableId].randDistanceHigh) + (sRouletteTables[sRoulette->tableId].taillow.baseDropDelay + 45); for (; i < 2; i++) { - gSprites[sRoulette->spriteIds[SPR_CLEAR_MON + i]].data[4] = sRoulette->spriteIds[SPR_CLEAR_MON]; - gSprites[sRoulette->spriteIds[SPR_CLEAR_MON + i]].data[5] = sRoulette->spriteIds[SPR_CLEAR_MON_SHADOW_1]; - gSprites[sRoulette->spriteIds[SPR_CLEAR_MON + i]].data[6] = sRoulette->spriteIds[SPR_CLEAR_MON_SHADOW_1]; + gSprites[sRoulette->spriteIds[SPR_CLEAR_MON + i]].sMonSpriteId = sRoulette->spriteIds[SPR_CLEAR_MON]; + gSprites[sRoulette->spriteIds[SPR_CLEAR_MON + i]].sBallShadowSpriteId = sRoulette->spriteIds[SPR_CLEAR_MON_SHADOW_1]; + gSprites[sRoulette->spriteIds[SPR_CLEAR_MON + i]].sMonShadowSpriteId = sRoulette->spriteIds[SPR_CLEAR_MON_SHADOW_1]; gSprites[sRoulette->spriteIds[SPR_CLEAR_MON + i]].data[2] = t; - gSprites[sRoulette->spriteIds[SPR_CLEAR_MON + i]].data[3] = sprite->data[7] - 45; + gSprites[sRoulette->spriteIds[SPR_CLEAR_MON + i]].data[3] = ball->data[7] - 45; } - sRoulette->var38 = sprite; + sRoulette->ball = ball; } -static void sub_8144A24(struct Sprite *sprite) +static void SetBallStuck(struct Sprite *sprite) { - u8 z; - u16 o; - u8 h = 0; - u8 j = 5; - u8 p = 0; + u8 slotId; + u16 angle; + u8 numCandidates = 0; + u8 maxSlotToCheck = 5; + u8 betSlotId = 0; u8 i = 0; - u8 val; - u8 s[10] = {}; + u8 slotsToSkip; + u8 slotCandidates[NUM_ROULETTE_SLOTS - 2] = {}; // - 2 because we know at least 2 are already occupied u16 rand = Random(); sRoulette->ballState = BALL_STATE_STUCK; sRoulette->ballStuck = TRUE; sRoulette->ballUnstuck = FALSE; sRoulette->hitSlot = 0xFF; - sRoulette->var88 = sprite->data[3]; - sRoulette->var98 = 0.0f; - sRoulette->var8C = sRouletteTables[sRoulette->tableId].var1C; + sRoulette->ballAngle = sprite->sBallAngle; + sRoulette->ballFallSpeed = 0.0f; + sRoulette->ballAngleSpeed = sRouletteTables[sRoulette->tableId].var1C; - o = (sRoulette->tableId * 30 + 33) + (1 - sRoulette->useTaillow) * 15; + angle = (sRoulette->tableId * DEGREES_PER_SLOT + 33) + (1 - sRoulette->useTaillow) * 15; + + // Determine which quadrant the ball got stuck in + // Use either Shroomish or Taillow to clear the ball depending on where it's stuck for (i = 0; i < 4; i++) { - if (o < sprite->data[3] && sprite->data[3] <= o + 90) + if (angle < sprite->sBallAngle && sprite->sBallAngle <= angle + 90) { - sprite->data[0] = i / 2; + sprite->sStuckOnWheelLeft = i / 2; sRoulette->useTaillow = i % 2; break; } if (i == 3) { - sprite->data[0] = 1; + sprite->sStuckOnWheelLeft = TRUE; sRoulette->useTaillow = TRUE; break; } - o += 90; + angle += 90; } if (sRoulette->useTaillow) { - if (sprite->data[0]) + if (sprite->sStuckOnWheelLeft) PlayCry1(SPECIES_TAILLOW, -63); else PlayCry1(SPECIES_TAILLOW, 63); @@ -4374,41 +4432,47 @@ static void sub_8144A24(struct Sprite *sprite) PlayCry1(SPECIES_SHROOMISH, -63); } - val = 2; - z = (sRoulette->var7F + 2) % NUM_ROULETTE_SLOTS; + slotsToSkip = 2; + slotId = (sRoulette->stuckHitSlot + 2) % NUM_ROULETTE_SLOTS; if (sRoulette->useTaillow == TRUE && sRoulette->tableId == 1) - j += 6; + maxSlotToCheck += 6; // Check all remaining slots else - j += val; + maxSlotToCheck += slotsToSkip; // Check enough slots to guarantee an empty will be found - for (i = val; i < j; i++) + // Identify open slots on the wheel that the stuck ball could be moved to + for (i = slotsToSkip; i < maxSlotToCheck; i++) { - if (!(sRoulette->hitFlags & sRouletteSlots[z].flag)) + if (!(sRoulette->hitFlags & sRouletteSlots[slotId].flag)) { - s[h++] = i; - if (p == 0 && (sRouletteSlots[z].flag & sGridSelections[sRoulette->betSelection[sRoulette->curBallNum]].inSelectionFlags)) - p = i; + slotCandidates[numCandidates++] = i; + if (betSlotId == 0 && (sRouletteSlots[slotId].flag & sGridSelections[sRoulette->betSelection[sRoulette->curBallNum]].inSelectionFlags)) + betSlotId = i; } - z = (z + 1) % 12; + slotId = (slotId + 1) % NUM_ROULETTE_SLOTS; } + // Determine which identified slot the ball should be moved to + // The below slot ids are relative to the slot the ball got stuck on if ((sRoulette->useTaillow + 1) & sRoulette->partySpeciesFlags) { - if (p && (rand & 0xFF) < 0xc0) - sprite->data[7] = p; + // If the player has the corresponding pokemon in their party (HAS_SHROOMISH or HAS_TAILLOW), + // there's a 75% chance that the ball will be moved to a spot they bet on + // assuming it was one of the slots identified as a candidate + if (betSlotId && (rand % 256) < 192) + sprite->data[7] = betSlotId; else - sprite->data[7] = s[rand % h]; + sprite->data[7] = slotCandidates[rand % numCandidates]; } else { - sprite->data[7] = s[rand % h]; + sprite->data[7] = slotCandidates[rand % numCandidates]; } - sprite->callback = CreateClearSpeciesSprite; + sprite->callback = SpriteCB_UnstickBall; } -static const u16 gUnknown_085B7B1A[] = { +static const u16 sShroomishShadowAlphas[] = { 0x907, 0x808, 0x709, @@ -4421,8 +4485,9 @@ static const u16 gUnknown_085B7B1A[] = { 0x010, }; -static void sub_8144C70(struct Sprite *sprite) +static void SpriteCB_ShroomishExit(struct Sprite *sprite) { + // Delay for screen shaking, then exit left if (sprite->data[1]++ >= sprite->data[3]) { sprite->pos1.x -= 2; @@ -4431,16 +4496,17 @@ static void sub_8144C70(struct Sprite *sprite) if (!sRoulette->ballUnstuck) sRoulette->ballUnstuck = TRUE; DestroySprite(sprite); - sRoulette->var01 = 0; - sRoulette->var34 = gUnknown_085B7B1A[0]; + sRoulette->shroomishShadowTimer = 0; + sRoulette->shroomishShadowAlpha = sShroomishShadowAlphas[0]; } } } -static void sub_8144CD0(struct Sprite *sprite) +// Handles both the screen shake and ball shadow effect for when Shroomish unsticks the ball +static void SpriteCB_ShroomishShakeScreen(struct Sprite *sprite) { - int p; - u16 t[][4] = { + int screenShakeIdx; + u16 screenShakeOffsets[][4] = { {-1, 0, 1, 0}, {-2, 0, 2, 0}, {-3, 0, 3, 0}, @@ -4450,10 +4516,12 @@ static void sub_8144CD0(struct Sprite *sprite) { if (sprite->data[1] & 1) { - gSpriteCoordOffsetY = t[sprite->data[2] / 2][sprite->data[7]]; - p = sprite->data[7] + 1; - sprite->data[7] = p - ((p / 4) * 4); + // Shake screen + gSpriteCoordOffsetY = screenShakeOffsets[sprite->data[2] / 2][sprite->data[7]]; + screenShakeIdx = sprite->data[7] + 1; + sprite->data[7] = screenShakeIdx - ((screenShakeIdx / 4) * 4); } + // Flicker shadow sprite->invisible ^= 1; } else @@ -4464,78 +4532,83 @@ static void sub_8144CD0(struct Sprite *sprite) } } -static void sub_8144D94(struct Sprite *sprite) +static void SpriteCB_ShroomishFall(struct Sprite *sprite) { - float t; + float timer; sprite->data[1]++; - t = sprite->data[1]; - sprite->pos2.y = t * 0.039f * t; - sRoulette->var34 = gUnknown_085B7B1A[(sRoulette->var01 - 1) / 2]; - if (sRoulette->var01 < 19) - sRoulette->var01++; + timer = sprite->data[1]; + sprite->pos2.y = timer * 0.039f * timer; + sRoulette->shroomishShadowAlpha = sShroomishShadowAlphas[(sRoulette->shroomishShadowTimer - 1) / 2]; + if (sRoulette->shroomishShadowTimer < ARRAY_COUNT(sShroomishShadowAlphas) * 2 - 1) + sRoulette->shroomishShadowTimer++; if (sprite->data[1] > 60) { sprite->data[1] = 0; - sprite->callback = sub_8144C70; - gSprites[sprite->data[6]].callback = sub_8144C70; - gSprites[sprite->data[6]].data[1] = -2; - gSprites[sprite->data[5]].invisible = FALSE; - gSprites[sprite->data[5]].callback = sub_8144CD0; + sprite->callback = SpriteCB_ShroomishExit; + gSprites[sprite->sMonShadowSpriteId].callback = SpriteCB_ShroomishExit; + gSprites[sprite->sMonShadowSpriteId].data[1] = -2; + gSprites[sprite->sBallShadowSpriteId].invisible = FALSE; + gSprites[sprite->sBallShadowSpriteId].callback = SpriteCB_ShroomishShakeScreen; m4aSongNumStart(SE_W070); } } -static void sub_8144E60(struct Sprite *sprite) +static void SpriteCB_Shroomish(struct Sprite *sprite) { if (sprite->data[7] == 0) { - if (sRoulette->var38->data[0] == 0) + // Wait for the ball to be a specific angle (or its 180 degree opposite) specified by the table + // Once it is, reveal the shadow for Shroomish falling in + if (!sRoulette->ball->sStuckOnWheelLeft) { - if (sRoulette->var38->data[3] != sRouletteTables[sRoulette->tableId].var08) + if (sRoulette->ball->sBallAngle != sRouletteTables[sRoulette->tableId].shroomish.startAngle) return; } else { - if (sRoulette->var38->data[3] != sRouletteTables[sRoulette->tableId].var08 + 180) + if (sRoulette->ball->sBallAngle != sRouletteTables[sRoulette->tableId].shroomish.startAngle + 180) return; } sprite->invisible = FALSE; sprite->data[7]++; m4aSongNumStart(SE_RU_HYUU); - sRoulette->var01 = 1; - sRoulette->var34 = gUnknown_085B7B1A[0]; + sRoulette->shroomishShadowTimer = 1; + sRoulette->shroomishShadowAlpha = sShroomishShadowAlphas[0]; } else { - sRoulette->var34 = gUnknown_085B7B1A[(sRoulette->var01 - 1) / 2]; - if (sRoulette->var01 < 19) - sRoulette->var01++; + sRoulette->shroomishShadowAlpha = sShroomishShadowAlphas[(sRoulette->shroomishShadowTimer - 1) / 2]; + if (sRoulette->shroomishShadowTimer < 19) + sRoulette->shroomishShadowTimer++; - if (sRoulette->var38->data[0] == 0) + // Wait for the ball to be a specific angle (or its 180 degree opposite) specified by the table + // Once it is, have Shroomish begin to fall in + // On both tables this angle is 15 degrees off the "start" angle + if (!sRoulette->ball->sStuckOnWheelLeft) { - if (sRoulette->var38->data[3] != sRouletteTables[sRoulette->tableId].var0A) + if (sRoulette->ball->sBallAngle != sRouletteTables[sRoulette->tableId].shroomish.dropAngle) return; } else { - if (sRoulette->var38->data[3] != sRouletteTables[sRoulette->tableId].var0A + 180) + if (sRoulette->ball->sBallAngle != sRouletteTables[sRoulette->tableId].shroomish.dropAngle + 180) return; } - gSprites[sprite->data[4]].callback = sub_8144D94; - gSprites[sprite->data[4]].invisible = FALSE; + gSprites[sprite->sMonSpriteId].callback = SpriteCB_ShroomishFall; + gSprites[sprite->sMonSpriteId].invisible = FALSE; sprite->callback = &SpriteCallbackDummy; sprite->data[7] = 0; } } -static void sub_8144F94(struct Sprite *sprite) +static void SpriteCB_TaillowShadow_Flash(struct Sprite *sprite) { sprite->invisible ^= 1; } -static void sub_8144FB0(struct Sprite *sprite) +static void SpriteCB_Taillow_FlyAway(struct Sprite *sprite) { if (sprite->pos1.y > -16) { @@ -4553,7 +4626,7 @@ static void sub_8144FB0(struct Sprite *sprite) } } -static void sub_8145030(struct Sprite *sprite) +static void SpriteCB_Taillow_PickUpBall(struct Sprite *sprite) { if (sprite->data[1] >= 0) { @@ -4578,17 +4651,17 @@ static void sub_8145030(struct Sprite *sprite) else { m4aSongNumStart(SE_RU_HYUU); - StartSpriteAnim(sprite, sRoulette->var38->data[0] + 4); - sprite->callback = sub_8144FB0; - gSprites[sprite->data[6]].affineAnimPaused = FALSE; + StartSpriteAnim(sprite, sRoulette->ball->sStuckOnWheelLeft + 4); + sprite->callback = SpriteCB_Taillow_FlyAway; + gSprites[sprite->sMonShadowSpriteId].affineAnimPaused = FALSE; } } } -static void sub_81450D8(struct Sprite *sprite) +static void SpriteCB_Taillow_FlyIn(struct Sprite *sprite) { - s8 t[2] = {-1, 1}; - s8 z[][2] = { + s8 xMoveOffsets[2] = {-1, 1}; + s8 yMoveOffsets[][2] = { {2, 0}, {2, 0}, {2, -1}, @@ -4601,7 +4674,7 @@ static void sub_81450D8(struct Sprite *sprite) if (sprite->data[1]-- > 7) { - sprite->pos1.x += t[sRoulette->var38->data[0]] * 2; + sprite->pos1.x += xMoveOffsets[sRoulette->ball->sStuckOnWheelLeft] * 2; if (IsSEPlaying()) { s8 pan = -((116 - sprite->pos1.x) / 2); @@ -4613,46 +4686,46 @@ static void sub_81450D8(struct Sprite *sprite) { if (sprite->data[1] >= 0) { - sprite->pos1.x += t[sRoulette->var38->data[0]] * z[7 - sprite->data[1]][0]; - sprite->pos1.y += z[7 - sprite->data[1]][1]; + sprite->pos1.x += xMoveOffsets[sRoulette->ball->sStuckOnWheelLeft] * yMoveOffsets[7 - sprite->data[1]][0]; + sprite->pos1.y += yMoveOffsets[7 - sprite->data[1]][1]; } else { m4aSongNumStartOrChange(SE_BASABASA); - if (sRoulette->var38->data[0] == 0) + if (sRoulette->ball->sStuckOnWheelLeft == 0) PlayCry1(SPECIES_TAILLOW, 63); else PlayCry1(SPECIES_TAILLOW, -63); - StartSpriteAnim(sprite, sRoulette->var38->data[0] + 2); + StartSpriteAnim(sprite, sRoulette->ball->sStuckOnWheelLeft + 2); sprite->data[1] = 45; - sprite->callback = sub_8145030; + sprite->callback = SpriteCB_Taillow_PickUpBall; } } } -static void sub_8145218(struct Sprite *sprite) +static void SpriteCB_TaillowShadow_FlyIn(struct Sprite *sprite) { - s8 t[2] = {-1, 1}; + s8 moveDir[2] = {-1, 1}; if (sprite->data[1]-- >= 0) { - sprite->pos1.x += t[sRoulette->var38->data[0]] * 2; - gSprites[sprite->data[6]].invisible ^= 1; + sprite->pos1.x += moveDir[sRoulette->ball->sStuckOnWheelLeft] * 2; + gSprites[sprite->sMonShadowSpriteId].invisible ^= 1; } else { - sprite->callback = sub_8144F94; + sprite->callback = SpriteCB_TaillowShadow_Flash; } } static void SpriteCB_Taillow(struct Sprite *sprite) { - if (sRoulette->var38->data[0] == 0) + if (sRoulette->ball->sStuckOnWheelLeft == FALSE) { - if (sRoulette->var38->data[3] == sRouletteTables[sRoulette->tableId].var12 + 90) + if (sRoulette->ball->sBallAngle == sRouletteTables[sRoulette->tableId].taillow.rightStartAngle + 90) { - gSprites[sprite->data[6]].data[1] = 52; - gSprites[sprite->data[4]].data[1] = 52; + gSprites[sprite->sMonShadowSpriteId].data[1] = 52; + gSprites[sprite->sMonSpriteId].data[1] = 52; } else { @@ -4661,17 +4734,17 @@ static void SpriteCB_Taillow(struct Sprite *sprite) } else { - if (sRoulette->var38->data[3] == sRouletteTables[sRoulette->tableId].var14 + 270) + if (sRoulette->ball->sBallAngle == sRouletteTables[sRoulette->tableId].taillow.leftStartAngle + 270) { - gSprites[sprite->data[6]].data[1] = 46; - gSprites[sprite->data[4]].data[1] = 46; + gSprites[sprite->sMonShadowSpriteId].data[1] = 46; + gSprites[sprite->sMonSpriteId].data[1] = 46; } else { return; } } - gSprites[sprite->data[6]].callback = sub_8145218; - gSprites[sprite->data[4]].callback = sub_81450D8; + gSprites[sprite->sMonShadowSpriteId].callback = SpriteCB_TaillowShadow_FlyIn; + gSprites[sprite->sMonSpriteId].callback = SpriteCB_Taillow_FlyIn; m4aSongNumStart(SE_RU_HYUU); } diff --git a/src/roulette_util.c b/src/roulette_util.c index 4e6977675..ab20e5583 100755 --- a/src/roulette_util.c +++ b/src/roulette_util.c @@ -17,7 +17,7 @@ void sub_8151678(struct UnkStruct0 *r0) u8 sub_815168C(struct UnkStruct0 *r0, u8 r1, const struct UnkStruct1 *r2) { - if (!(r1 < 16) || (r0->var04[r1].var00_7)) + if (!(r1 < 16) || (r0->var04[r1].active)) return 0xFF; r0->var04[r1].var04.var00 = r2->var00; @@ -29,7 +29,7 @@ u8 sub_815168C(struct UnkStruct0 *r0, u8 r1, const struct UnkStruct1 *r2) r0->var04[r1].var04.var07_5 = r2->var07_5; r0->var04[r1].var04.var07_7 = r2->var07_7; r0->var04[r1].var00_0 = 0; - r0->var04[r1].var00_7 = 1; + r0->var04[r1].active = TRUE; r0->var04[r1].var02 = 0; r0->var04[r1].var01 = 0; if (r0->var04[r1].var04.var07_7 < 0) @@ -44,7 +44,7 @@ u8 sub_8151710(struct UnkStruct0 *r0, u8 r1) { if (r1 >= 16) return 0xFF; - if (!r0->var04[r1].var00_7) + if (!r0->var04[r1].active) return 0xFF; memset(&r0->var04[r1], 0, sizeof(r0->var04[r1])); @@ -154,16 +154,16 @@ void task_tutorial_controls_fadein(struct UnkStruct0 *r0) } } -void sub_8151A48(struct UnkStruct0 *r0, u16 r1) +void sub_8151A48(struct UnkStruct0 *r0, u16 flags) { u8 i = 0; r0->var00++; for (i = 0; i < 16; i++) { - if ((r1 >> i) & 1) + if ((flags >> i) & 1) { - if (r0->var04[i].var00_7) + if (r0->var04[i].active) { r0->var02 |= 1 << i; r0->var04[i].var00_0 = 1; @@ -172,7 +172,7 @@ void sub_8151A48(struct UnkStruct0 *r0, u16 r1) } } -void sub_8151A9C(struct UnkStruct0 *r0, u16 r1) +void sub_8151A9C(struct UnkStruct0 *r0, u16 flags) { u8 i; @@ -180,9 +180,9 @@ void sub_8151A9C(struct UnkStruct0 *r0, u16 r1) { if ((r0->var02 >> i) & 1) { - if (r0->var04[i].var00_7) + if (r0->var04[i].active) { - if ((r1 >> i) & 1) + if ((flags >> i) & 1) { u32 offset = r0->var04[i].var04.var02; u16 *faded = &gPlttBufferFaded[offset]; @@ -199,14 +199,14 @@ void sub_8151A9C(struct UnkStruct0 *r0, u16 r1) } } } - if (r1 == 0xFFFF) + if (flags == 0xFFFF) { r0->var00 = 0; r0->var02 = 0; } else { - r0->var02 = r0->var02 & ~r1; + r0->var02 = r0->var02 & ~flags; } } From 8e800e206138d00220c44af8acf69ce79103dc9c Mon Sep 17 00:00:00 2001 From: GriffinR Date: Tue, 4 Aug 2020 19:19:36 -0400 Subject: [PATCH 4/6] Document roulette flash util --- include/roulette_util.h | 55 ++--- src/roulette.c | 432 +++++++++++++++++++++------------------- src/roulette_util.c | 205 +++++++++---------- 3 files changed, 362 insertions(+), 330 deletions(-) diff --git a/include/roulette_util.h b/include/roulette_util.h index d18d22d0f..2864ee464 100644 --- a/include/roulette_util.h +++ b/include/roulette_util.h @@ -33,34 +33,37 @@ struct PulseBlend struct PulseBlendPalette pulseBlendPalettes[16]; }; -struct UnkStruct1 + +#define FLASHUTIL_USE_EXISTING_COLOR (1 << 15) + +struct RouletteFlashSettings { - u16 var00; - u16 var02; - u8 var04; - u8 var05; - u8 var06; - s8 var07_0:5; - s8 var07_5:2; - s8 var07_7:1; + u16 color; + u16 paletteOffset; + u8 numColors; + u8 delay; + s8 unk6; // Set but never used + s8 numFadeCycles:5; + s8 unk7_5:2; // Set but never used + s8 colorDeltaDir:1; }; -struct UnkStruct3 +struct RouletteFlashPalette { - u8 var00_0:7; - bool8 active:1; - u8 var01; - s8 var02; - s8 var03; - struct UnkStruct1 var04; + u8 state:7; + bool8 available:1; + u8 delayCounter; + s8 fadeCycleCounter; + s8 colorDelta; + struct RouletteFlashSettings settings; }; -struct UnkStruct0 +struct RouletteFlashUtil { - u8 var00; - u8 var01; - u16 var02; //flag for each UnkStruct3 - struct UnkStruct3 var04[0x10]; + u8 enabled; + u8 unused; + u16 flags; + struct RouletteFlashPalette palettes[16]; }; int InitPulseBlendPaletteSettings(struct PulseBlend *, const struct PulseBlendSettings *); @@ -71,10 +74,10 @@ void UnmarkUsedPulseBlendPalettes(struct PulseBlend *, u16, u8); void UpdatePulseBlend(struct PulseBlend *); void ClearTilemapRect(u16 *dest, u16 src, u8 left, u8 top, u8 width, u8 height); void SetTilemapRect(u16 *dest, u16 *src, u8 left, u8 top, u8 width, u8 height); -void task_tutorial_controls_fadein(struct UnkStruct0 *r0); -void sub_8151678(struct UnkStruct0 *r0); -u8 sub_815168C(struct UnkStruct0 *r0, u8 r1, const struct UnkStruct1 *r2); -void sub_8151A9C(struct UnkStruct0 *r0, u16 r1); -void sub_8151A48(struct UnkStruct0 *r0, u16 r1); +void RouletteFlash_Run(struct RouletteFlashUtil *r0); +void RouletteFlash_Reset(struct RouletteFlashUtil *r0); +u8 RouletteFlash_Add(struct RouletteFlashUtil *r0, u8 r1, const struct RouletteFlashSettings *r2); +void RouletteFlash_Stop(struct RouletteFlashUtil *r0, u16 r1); +void RouletteFlash_Enable(struct RouletteFlashUtil *r0, u16 r1); #endif // GUARD_ROULETTE_UTIL_H diff --git a/src/roulette.c b/src/roulette.c index cc14a67cd..0923ea2d3 100644 --- a/src/roulette.c +++ b/src/roulette.c @@ -100,6 +100,26 @@ #define F_PURPLE_SKITTY (1 << SQU_PURPLE_SKITTY) #define F_PURPLE_MAKUHITA (1 << SQU_PURPLE_MAKUHITA) +// Flags for flashing selections on the roulette wheel +#define F_FLASH_COLOR_O_WYNAUT (1 << 0) +#define F_FLASH_COLOR_G_AZURILL (1 << 1) +#define F_FLASH_COLOR_P_SKITTY (1 << 2) +#define F_FLASH_COLOR_O_MAKUHITA (1 << 3) +#define F_FLASH_COLOR_G_WYNAUT (1 << 4) +#define F_FLASH_COLOR_P_AZURILL (1 << 5) +#define F_FLASH_COLOR_O_SKITTY (1 << 6) +#define F_FLASH_COLOR_G_MAKUHITA (1 << 7) +#define F_FLASH_COLOR_P_WYNAUT (1 << 8) +#define F_FLASH_COLOR_O_AZURILL (1 << 9) +#define F_FLASH_COLOR_G_SKITTY (1 << 10) +#define F_FLASH_COLOR_P_MAKUHITA (1 << 11) +#define F_FLASH_OUTER_EDGES (1 << 12) // when the player wins +#define FLASH_ICON (NUM_ROULETTE_SLOTS + 1) +#define FLASH_ICON_2 (FLASH_ICON + 1) +#define FLASH_ICON_3 (FLASH_ICON + 2) +#define F_FLASH_ICON (1 << FLASH_ICON) +#define F_FLASH_COLUMN (1 << FLASH_ICON | 1 << FLASH_ICON_2 | 1 << FLASH_ICON_3) + #define MAX_MULTIPLIER 12 #define PALTAG_SHADOW 1 @@ -271,7 +291,7 @@ struct GridSelection u8 tilemapOffset; u32 flag; u32 inSelectionFlags; - u16 var10; + u16 flashFlags; }; struct RouletteSlot @@ -336,7 +356,7 @@ static EWRAM_DATA struct Roulette TaskFunc nextTask; u8 filler_2[4]; TaskFunc prevTask; - struct UnkStruct0 flashUtil; + struct RouletteFlashUtil flashUtil; u16 tilemapBuffers[7][0x400]; u16 *gridTilemap; } *sRoulette = NULL; @@ -461,7 +481,7 @@ static const struct GridSelection sGridSelections[NUM_GRID_SELECTIONS + 1] = .tilemapOffset = 0, .flag = 0, .inSelectionFlags = 0, - .var10 = 0x0, + .flashFlags = 0, }, [COL_WYNAUT] = { .spriteIdOffset = 12, @@ -474,7 +494,7 @@ static const struct GridSelection sGridSelections[NUM_GRID_SELECTIONS + 1] = .tilemapOffset = 0, .flag = F_WYNAUT_COL, .inSelectionFlags = F_WYNAUT_COL | F_ORANGE_WYNAUT | F_GREEN_WYNAUT | F_PURPLE_WYNAUT, - .var10 = 0xE000, + .flashFlags = F_FLASH_COLUMN, }, [COL_AZURILL] = { .spriteIdOffset = 13, @@ -487,7 +507,7 @@ static const struct GridSelection sGridSelections[NUM_GRID_SELECTIONS + 1] = .tilemapOffset = 0, .flag = F_AZURILL_COL, .inSelectionFlags = F_AZURILL_COL | F_ORANGE_AZURILL | F_GREEN_AZURILL | F_PURPLE_AZURILL, - .var10 = 0xE000, + .flashFlags = F_FLASH_COLUMN, }, [COL_SKITTY] = { .spriteIdOffset = 14, @@ -500,7 +520,7 @@ static const struct GridSelection sGridSelections[NUM_GRID_SELECTIONS + 1] = .tilemapOffset = 0, .flag = F_SKITTY_COL, .inSelectionFlags = F_SKITTY_COL | F_ORANGE_SKITTY | F_GREEN_SKITTY | F_PURPLE_SKITTY, - .var10 = 0xE000, + .flashFlags = F_FLASH_COLUMN, }, [COL_MAKUHITA] = { .spriteIdOffset = 15, @@ -513,7 +533,7 @@ static const struct GridSelection sGridSelections[NUM_GRID_SELECTIONS + 1] = .tilemapOffset = 0, .flag = F_MAKUHITA_COL, .inSelectionFlags = F_MAKUHITA_COL | F_ORANGE_MAKUHITA | F_GREEN_MAKUHITA | F_PURPLE_MAKUHITA, - .var10 = 0xE000, + .flashFlags = F_FLASH_COLUMN, }, [ROW_ORANGE] = { .spriteIdOffset = 16, @@ -526,7 +546,7 @@ static const struct GridSelection sGridSelections[NUM_GRID_SELECTIONS + 1] = .tilemapOffset = 12, .flag = F_ORANGE_ROW, .inSelectionFlags = F_ORANGE_ROW | F_ORANGE_WYNAUT | F_ORANGE_AZURILL | F_ORANGE_SKITTY | F_ORANGE_MAKUHITA, - .var10 = 0x249, + .flashFlags = F_FLASH_COLOR_O_WYNAUT | F_FLASH_COLOR_O_AZURILL | F_FLASH_COLOR_O_SKITTY | F_FLASH_COLOR_O_MAKUHITA, }, [SQU_ORANGE_WYNAUT] = { .spriteIdOffset = 0, @@ -539,7 +559,7 @@ static const struct GridSelection sGridSelections[NUM_GRID_SELECTIONS + 1] = .tilemapOffset = 3, .flag = F_ORANGE_WYNAUT, .inSelectionFlags = F_ORANGE_WYNAUT, - .var10 = 0x2001, + .flashFlags = F_FLASH_ICON | F_FLASH_COLOR_O_WYNAUT, }, [SQU_ORANGE_AZURILL] = { .spriteIdOffset = 9, @@ -552,7 +572,7 @@ static const struct GridSelection sGridSelections[NUM_GRID_SELECTIONS + 1] = .tilemapOffset = 3, .flag = F_ORANGE_AZURILL, .inSelectionFlags = F_ORANGE_AZURILL, - .var10 = 0x2200, + .flashFlags = F_FLASH_ICON | F_FLASH_COLOR_O_AZURILL, }, [SQU_ORANGE_SKITTY] = { .spriteIdOffset = 6, @@ -565,7 +585,7 @@ static const struct GridSelection sGridSelections[NUM_GRID_SELECTIONS + 1] = .tilemapOffset = 3, .flag = F_ORANGE_SKITTY, .inSelectionFlags = F_ORANGE_SKITTY, - .var10 = 0x2040, + .flashFlags = F_FLASH_ICON | F_FLASH_COLOR_O_SKITTY, }, [SQU_ORANGE_MAKUHITA] = { .spriteIdOffset = 3, @@ -578,7 +598,7 @@ static const struct GridSelection sGridSelections[NUM_GRID_SELECTIONS + 1] = .tilemapOffset = 3, .flag = F_ORANGE_MAKUHITA, .inSelectionFlags = F_ORANGE_MAKUHITA, - .var10 = 0x2008, + .flashFlags = F_FLASH_ICON | F_FLASH_COLOR_O_MAKUHITA, }, [ROW_GREEN] = { .spriteIdOffset = 17, @@ -591,7 +611,7 @@ static const struct GridSelection sGridSelections[NUM_GRID_SELECTIONS + 1] = .tilemapOffset = 15, .flag = F_GREEN_ROW, .inSelectionFlags = F_GREEN_ROW | F_GREEN_WYNAUT | F_GREEN_AZURILL | F_GREEN_SKITTY | F_GREEN_MAKUHITA, - .var10 = 0x492, + .flashFlags = F_FLASH_COLOR_G_WYNAUT | F_FLASH_COLOR_G_AZURILL | F_FLASH_COLOR_G_SKITTY | F_FLASH_COLOR_G_MAKUHITA, }, [SQU_GREEN_WYNAUT] = { .spriteIdOffset = 4, @@ -604,7 +624,7 @@ static const struct GridSelection sGridSelections[NUM_GRID_SELECTIONS + 1] = .tilemapOffset = 6, .flag = F_GREEN_WYNAUT, .inSelectionFlags = F_GREEN_WYNAUT, - .var10 = 0x2010, + .flashFlags = F_FLASH_ICON | F_FLASH_COLOR_G_WYNAUT, }, [SQU_GREEN_AZURILL] = { .spriteIdOffset = 1, @@ -617,7 +637,7 @@ static const struct GridSelection sGridSelections[NUM_GRID_SELECTIONS + 1] = .tilemapOffset = 6, .flag = F_GREEN_AZURILL, .inSelectionFlags = F_GREEN_AZURILL, - .var10 = 0x2002, + .flashFlags = F_FLASH_ICON | F_FLASH_COLOR_G_AZURILL, }, [SQU_GREEN_SKITTY] = { .spriteIdOffset = 10, @@ -630,7 +650,7 @@ static const struct GridSelection sGridSelections[NUM_GRID_SELECTIONS + 1] = .tilemapOffset = 6, .flag = F_GREEN_SKITTY, .inSelectionFlags = F_GREEN_SKITTY, - .var10 = 0x2400, + .flashFlags = F_FLASH_ICON | F_FLASH_COLOR_G_SKITTY, }, [SQU_GREEN_MAKUHITA] = { .spriteIdOffset = 7, @@ -643,7 +663,7 @@ static const struct GridSelection sGridSelections[NUM_GRID_SELECTIONS + 1] = .tilemapOffset = 6, .flag = F_GREEN_MAKUHITA, .inSelectionFlags = F_GREEN_MAKUHITA, - .var10 = 0x2080, + .flashFlags = F_FLASH_ICON | F_FLASH_COLOR_G_MAKUHITA, }, [ROW_PURPLE] = { .spriteIdOffset = 18, @@ -656,7 +676,7 @@ static const struct GridSelection sGridSelections[NUM_GRID_SELECTIONS + 1] = .tilemapOffset = 18, .flag = F_PURPLE_ROW, .inSelectionFlags = F_PURPLE_ROW | F_PURPLE_WYNAUT | F_PURPLE_AZURILL | F_PURPLE_SKITTY | F_PURPLE_MAKUHITA, - .var10 = 0x924, + .flashFlags = F_FLASH_COLOR_P_WYNAUT | F_FLASH_COLOR_P_AZURILL | F_FLASH_COLOR_P_SKITTY | F_FLASH_COLOR_P_MAKUHITA, }, [SQU_PURPLE_WYNAUT] = { .spriteIdOffset = 8, @@ -669,7 +689,7 @@ static const struct GridSelection sGridSelections[NUM_GRID_SELECTIONS + 1] = .tilemapOffset = 9, .flag = F_PURPLE_WYNAUT, .inSelectionFlags = F_PURPLE_WYNAUT, - .var10 = 0x2100, + .flashFlags = F_FLASH_ICON | F_FLASH_COLOR_P_WYNAUT, }, [SQU_PURPLE_AZURILL] = { .spriteIdOffset = 5, @@ -682,7 +702,7 @@ static const struct GridSelection sGridSelections[NUM_GRID_SELECTIONS + 1] = .tilemapOffset = 9, .flag = F_PURPLE_AZURILL, .inSelectionFlags = F_PURPLE_AZURILL, - .var10 = 0x2020, + .flashFlags = F_FLASH_ICON | F_FLASH_COLOR_P_AZURILL, }, [SQU_PURPLE_SKITTY] = { .spriteIdOffset = 2, @@ -695,7 +715,7 @@ static const struct GridSelection sGridSelections[NUM_GRID_SELECTIONS + 1] = .tilemapOffset = 9, .flag = F_PURPLE_SKITTY, .inSelectionFlags = F_PURPLE_SKITTY, - .var10 = 0x2004, + .flashFlags = F_FLASH_ICON | F_FLASH_COLOR_P_SKITTY, }, [SQU_PURPLE_MAKUHITA] = { .spriteIdOffset = 11, @@ -708,7 +728,7 @@ static const struct GridSelection sGridSelections[NUM_GRID_SELECTIONS + 1] = .tilemapOffset = 9, .flag = F_PURPLE_MAKUHITA, .inSelectionFlags = F_PURPLE_MAKUHITA, - .var10 = 0x2800, + .flashFlags = F_FLASH_ICON | F_FLASH_COLOR_P_MAKUHITA, }, }; @@ -835,171 +855,174 @@ static const struct RouletteTable sRouletteTables[] = } }; -static const struct UnkStruct1 gUnknown_085B6388[NUM_ROULETTE_SLOTS + 1] = +// Data to flash the color indicator for each slot on the roulette wheel +static const struct RouletteFlashSettings sFlashData_Colors[NUM_ROULETTE_SLOTS + 1] = { - { - .var00 = 0x8000, - .var02 = 0x0005, - .var04 = 1, - .var05 = 1, - .var06 = 0xFF, - .var07_0 = 8, - .var07_5 = -2, - .var07_7 = 0 + { // F_FLASH_COLOR_O_WYNAUT + .color = FLASHUTIL_USE_EXISTING_COLOR, + .paletteOffset = 0x5, + .numColors = 1, + .delay = 1, + .unk6 = -1, + .numFadeCycles = 8, + .unk7_5 = -2, + .colorDeltaDir = 0, }, - { - .var00 = 0x8000, - .var02 = 0x000A, - .var04 = 1, - .var05 = 1, - .var06 = 0xFF, - .var07_0 = 8, - .var07_5 = -2, - .var07_7 = 0 + { // F_FLASH_COLOR_G_AZURILL + .color = FLASHUTIL_USE_EXISTING_COLOR, + .paletteOffset = 0xA, + .numColors = 1, + .delay = 1, + .unk6 = -1, + .numFadeCycles = 8, + .unk7_5 = -2, + .colorDeltaDir = 0, }, - { - .var00 = 0x8000, - .var02 = 0x0015, - .var04 = 1, - .var05 = 1, - .var06 = 0xFF, - .var07_0 = 8, - .var07_5 = -2, - .var07_7 = 0 + { // F_FLASH_COLOR_P_SKITTY + .color = FLASHUTIL_USE_EXISTING_COLOR, + .paletteOffset = 0x15, + .numColors = 1, + .delay = 1, + .unk6 = -1, + .numFadeCycles = 8, + .unk7_5 = -2, + .colorDeltaDir = 0, }, - { - .var00 = 0x8000, - .var02 = 0x0055, - .var04 = 1, - .var05 = 1, - .var06 = 0xFF, - .var07_0 = 8, - .var07_5 = -2, - .var07_7 = 0 + { // F_FLASH_COLOR_O_MAKUHITA + .color = FLASHUTIL_USE_EXISTING_COLOR, + .paletteOffset = 0x55, + .numColors = 1, + .delay = 1, + .unk6 = -1, + .numFadeCycles = 8, + .unk7_5 = -2, + .colorDeltaDir = 0, }, - { - .var00 = 0x8000, - .var02 = 0x005A, - .var04 = 1, - .var05 = 1, - .var06 = 0xFF, - .var07_0 = 8, - .var07_5 = -2, - .var07_7 = 0 + { // F_FLASH_COLOR_G_WYNAUT + .color = FLASHUTIL_USE_EXISTING_COLOR, + .paletteOffset = 0x5A, + .numColors = 1, + .delay = 1, + .unk6 = -1, + .numFadeCycles = 8, + .unk7_5 = -2, + .colorDeltaDir = 0, }, - { - .var00 = 0x8000, - .var02 = 0x0065, - .var04 = 1, - .var05 = 1, - .var06 = 0xFF, - .var07_0 = 8, - .var07_5 = -2, - .var07_7 = 0 + { // F_FLASH_COLOR_P_AZURILL + .color = FLASHUTIL_USE_EXISTING_COLOR, + .paletteOffset = 0x65, + .numColors = 1, + .delay = 1, + .unk6 = -1, + .numFadeCycles = 8, + .unk7_5 = -2, + .colorDeltaDir = 0, }, - { - .var00 = 0x8000, - .var02 = 0x0075, - .var04 = 1, - .var05 = 1, - .var06 = 0xFF, - .var07_0 = 8, - .var07_5 = -2, - .var07_7 = 0 + { // F_FLASH_COLOR_O_SKITTY + .color = FLASHUTIL_USE_EXISTING_COLOR, + .paletteOffset = 0x75, + .numColors = 1, + .delay = 1, + .unk6 = -1, + .numFadeCycles = 8, + .unk7_5 = -2, + .colorDeltaDir = 0, }, - { - .var00 = 0x8000, - .var02 = 0x007A, - .var04 = 1, - .var05 = 1, - .var06 = 0xFF, - .var07_0 = 8, - .var07_5 = -2, - .var07_7 = 0 + { // F_FLASH_COLOR_G_MAKUHITA + .color = FLASHUTIL_USE_EXISTING_COLOR, + .paletteOffset = 0x7A, + .numColors = 1, + .delay = 1, + .unk6 = -1, + .numFadeCycles = 8, + .unk7_5 = -2, + .colorDeltaDir = 0, }, - { - .var00 = 0x8000, - .var02 = 0x0085, - .var04 = 1, - .var05 = 1, - .var06 = 0xFF, - .var07_0 = 8, - .var07_5 = -2, - .var07_7 = 0 + { // F_FLASH_COLOR_P_WYNAUT + .color = FLASHUTIL_USE_EXISTING_COLOR, + .paletteOffset = 0x85, + .numColors = 1, + .delay = 1, + .unk6 = -1, + .numFadeCycles = 8, + .unk7_5 = -2, + .colorDeltaDir = 0, }, - { - .var00 = 0x8000, - .var02 = 0x0095, - .var04 = 1, - .var05 = 1, - .var06 = 0xFF, - .var07_0 = 8, - .var07_5 = -2, - .var07_7 = 0 + { // F_FLASH_COLOR_O_AZURILL + .color = FLASHUTIL_USE_EXISTING_COLOR, + .paletteOffset = 0x95, + .numColors = 1, + .delay = 1, + .unk6 = -1, + .numFadeCycles = 8, + .unk7_5 = -2, + .colorDeltaDir = 0, }, - { - .var00 = 0x8000, - .var02 = 0x009A, - .var04 = 1, - .var05 = 1, - .var06 = 0xFF, - .var07_0 = 8, - .var07_5 = -2, - .var07_7 = 0 + { // F_FLASH_COLOR_G_SKITTY + .color = FLASHUTIL_USE_EXISTING_COLOR, + .paletteOffset = 0x9A, + .numColors = 1, + .delay = 1, + .unk6 = -1, + .numFadeCycles = 8, + .unk7_5 = -2, + .colorDeltaDir = 0, }, - { - .var00 = 0x8000, - .var02 = 0x00A5, - .var04 = 1, - .var05 = 1, - .var06 = 0xFF, - .var07_0 = 8, - .var07_5 = -2, - .var07_7 = 0 + { // F_FLASH_COLOR_P_MAKUHITA + .color = FLASHUTIL_USE_EXISTING_COLOR, + .paletteOffset = 0xA5, + .numColors = 1, + .delay = 1, + .unk6 = -1, + .numFadeCycles = 8, + .unk7_5 = -2, + .colorDeltaDir = 0, }, - { - .var00 = 0x77D6, - .var02 = 0x0028, - .var04 = 2, - .var05 = 10, - .var06 = 0xFF, - .var07_0 = 14, - .var07_5 = -2, - .var07_7 = 0 + { // F_FLASH_OUTER_EDGES + .color = RGB(22, 30, 29), + .paletteOffset = 0x28, + .numColors = 2, + .delay = 10, + .unk6 = -1, + .numFadeCycles = 14, + .unk7_5 = -2, + .colorDeltaDir = 0, }, }; -static const struct UnkStruct1 gUnknown_085B63F0[NUM_BOARD_COLORS] = +// Data to flash any pokemon icon (F_FLASH_ICON) on the roulette wheel. One entry for each color row +// Each poke icon flashes with the tint of the row color it belongs to, so the pokemon itself is irrelevant +static const struct RouletteFlashSettings sFlashData_PokeIcons[NUM_BOARD_COLORS] = { - { - .var00 = 0x53FF, - .var02 = 0x0101, - .var04 = 5, - .var05 = 30, - .var06 = 0xFF, - .var07_0 = 14, - .var07_5 = -2, - .var07_7 = 0 + [GET_ROW_IDX(ROW_ORANGE)] = { + .color = RGB(31, 31, 20), + .paletteOffset = 0x101, + .numColors = 5, + .delay = 30, + .unk6 = -1, + .numFadeCycles = 14, + .unk7_5 = -2, + .colorDeltaDir = 0, }, - { - .var00 = 0x7FFB, - .var02 = 0x0106, - .var04 = 5, - .var05 = 30, - .var06 = 0xFF, - .var07_0 = 14, - .var07_5 = -2, - .var07_7 = 0 + [GET_ROW_IDX(ROW_GREEN)] = { + .color = RGB(27, 31, 31), + .paletteOffset = 0x106, + .numColors = 5, + .delay = 30, + .unk6 = -1, + .numFadeCycles = 14, + .unk7_5 = -2, + .colorDeltaDir = 0, }, - { - .var00 = 0x7F7F, - .var02 = 0x010B, - .var04 = 5, - .var05 = 30, - .var06 = 0xFF, - .var07_0 = 14, - .var07_5 = -2, - .var07_7 = 0 + [GET_ROW_IDX(ROW_PURPLE)] = { + .color = RGB(31, 27, 31), + .paletteOffset = 0x10B, + .numColors = 5, + .delay = 30, + .unk6 = -1, + .numFadeCycles = 14, + .unk7_5 = -2, + .colorDeltaDir = 0, } }; @@ -1020,8 +1043,8 @@ static void CB2_Roulette(void) RunTasks(); AnimateSprites(); BuildOamBuffer(); - if (sRoulette->flashUtil.var00) - task_tutorial_controls_fadein(&sRoulette->flashUtil); + if (sRoulette->flashUtil.enabled) + RouletteFlash_Run(&sRoulette->flashUtil); } static void VBlankCB_Roulette(void) @@ -1110,12 +1133,13 @@ static void InitRouletteTableData(void) else gPlttBufferUnfaded[0] = gPlttBufferUnfaded[0x51] = gPlttBufferFaded[0] = gPlttBufferFaded[0x51] = bgColors[1]; - sub_8151678(&sRoulette->flashUtil); + RouletteFlash_Reset(&sRoulette->flashUtil); // Init flash util for flashing the selected colors on the wheel + // + 1 for the additional entry to flash the outer edges on a win for (i = 0; i < NUM_ROULETTE_SLOTS + 1; i++) { - sub_815168C(&sRoulette->flashUtil, i, &gUnknown_085B6388[i]); + RouletteFlash_Add(&sRoulette->flashUtil, i, &sFlashData_Colors[i]); } for (i = 0; i < PARTY_SIZE; i++) @@ -1421,8 +1445,8 @@ static void ProcessBetGridInput(u8 taskId) UpdateGridSelection(taskId); gTasks[taskId].data[1] = 0; PlaySE(SE_SELECT); - sub_8151A9C(&sRoulette->flashUtil, 0xFFFF); // Reset previous flashing wheel color selection - sRoulette->flashUtil.var04[13].active = sRoulette->flashUtil.var04[14].active = sRoulette->flashUtil.var04[15].active = FALSE; // Same as above, but for icon + RouletteFlash_Stop(&sRoulette->flashUtil, 0xFFFF); + sRoulette->flashUtil.palettes[FLASH_ICON].available = sRoulette->flashUtil.palettes[FLASH_ICON_2].available = sRoulette->flashUtil.palettes[FLASH_ICON_3].available = FALSE; FlashSelectionOnWheel(gTasks[taskId].tSelectionId); // Switch all the poke (column) headers to gray outlines @@ -1680,7 +1704,7 @@ static void Task_RecordBallHit(u8 taskId) bool8 won = IsHitInBetSelection(RecordHit(taskId, sRoulette->hitSlot), sRoulette->betSelection[sRoulette->curBallNum]); gTasks[taskId].tWonBet = won; if (won == TRUE) - sub_8151A48(&sRoulette->flashUtil, 0x1000); // Flash outer edges of wheel + RouletteFlash_Enable(&sRoulette->flashUtil, F_FLASH_OUTER_EDGES); } if (gTasks[taskId].data[1] <= 60) { @@ -1853,8 +1877,8 @@ static void Task_PrintPayout(u8 taskId) static void Task_EndTurn(u8 taskId) { - sub_8151A9C(&sRoulette->flashUtil, 0xFFFF); - sRoulette->flashUtil.var04[13].active = sRoulette->flashUtil.var04[14].active = sRoulette->flashUtil.var04[15].active = FALSE; + RouletteFlash_Stop(&sRoulette->flashUtil, 0xFFFF); + sRoulette->flashUtil.palettes[FLASH_ICON].available = sRoulette->flashUtil.palettes[FLASH_ICON_2].available = sRoulette->flashUtil.palettes[FLASH_ICON_3].available = FALSE; gSprites[sRoulette->spriteIds[SPR_WHEEL_ICONS + sGridSelections[gTasks[taskId].tWinningSquare].spriteIdOffset]].invisible = TRUE; gTasks[taskId].func = Task_TryPrintEndTurnMsg; } @@ -1937,8 +1961,8 @@ static void Task_ClearBoard(u8 taskId) static void ExitRoulette(u8 taskId) { - sub_8151A9C(&sRoulette->flashUtil, 0xFFFF); - sub_8151678(&sRoulette->flashUtil); + RouletteFlash_Stop(&sRoulette->flashUtil, 0xFFFF); + RouletteFlash_Reset(&sRoulette->flashUtil); SetCoins(gTasks[taskId].tCoins); if (GetCoins() < sRoulette->minBet) gSpecialVar_0x8004 = TRUE; @@ -2108,9 +2132,9 @@ static bool8 IsHitInBetSelection(u8 gridSquare, u8 betSelection) static void FlashSelectionOnWheel(u8 selectionId) { - u16 var0 = 0; + u16 flashFlags = 0; u8 numSelected; - u16 var3; + u16 palOffset; u8 i; switch (selectionId) @@ -2122,47 +2146,46 @@ static void FlashSelectionOnWheel(u8 selectionId) for (i = (selectionId + 1); i < (selectionId + 5); i++) { if (!(sRoulette->hitFlags & sGridSelections[i].flag)) - var0 |= sGridSelections[i].var10; + flashFlags |= sGridSelections[i].flashFlags; } - sub_8151A48(&sRoulette->flashUtil, var0 &= 0xDFFF); + RouletteFlash_Enable(&sRoulette->flashUtil, flashFlags &= ~(F_FLASH_ICON)); break; default: { // Selection is either a column or individual square - struct UnkStruct1 var1[NUM_BOARD_COLORS]; - memcpy(var1, gUnknown_085B63F0, sizeof(var1)); + struct RouletteFlashSettings iconFlash[NUM_BOARD_COLORS]; + memcpy(iconFlash, sFlashData_PokeIcons, sizeof(iconFlash)); if (selectionId >= COL_WYNAUT && selectionId <= COL_MAKUHITA) numSelected = NUM_BOARD_COLORS; // Selection is full column else numSelected = 1; - var3 = GET_ROW_IDX(selectionId); + palOffset = GET_ROW_IDX(selectionId); switch (GET_COL(selectionId)) { - // The specific color of the poke it references doesn't matter, because the icons themelves all share a palette + // The specific color of the poke it references doesn't matter, because the icons of a poke share a palette // So it just uses the first sprite ID of each case COL_WYNAUT: - var3 = gSprites[sRoulette->spriteIds[SPR_WHEEL_ICON_ORANGE_WYNAUT]].oam.paletteNum * 16; + palOffset = gSprites[sRoulette->spriteIds[SPR_WHEEL_ICON_ORANGE_WYNAUT]].oam.paletteNum * 16; break; case COL_AZURILL: - var3 = gSprites[sRoulette->spriteIds[SPR_WHEEL_ICON_GREEN_AZURILL]].oam.paletteNum * 16; + palOffset = gSprites[sRoulette->spriteIds[SPR_WHEEL_ICON_GREEN_AZURILL]].oam.paletteNum * 16; break; case COL_SKITTY: - var3 = gSprites[sRoulette->spriteIds[SPR_WHEEL_ICON_PURPLE_SKITTY]].oam.paletteNum * 16; + palOffset = gSprites[sRoulette->spriteIds[SPR_WHEEL_ICON_PURPLE_SKITTY]].oam.paletteNum * 16; break; case COL_MAKUHITA: - var3 = gSprites[sRoulette->spriteIds[SPR_WHEEL_ICON_ORANGE_MAKUHITA]].oam.paletteNum * 16; + palOffset = gSprites[sRoulette->spriteIds[SPR_WHEEL_ICON_ORANGE_MAKUHITA]].oam.paletteNum * 16; break; } if (numSelected == 1) { - // Selection is individual square + // Selection is individual square, add entry in flash util for its icon if (!(sRoulette->hitFlags & sGridSelections[selectionId].flag)) { - // Set poke icon of selected square to flash - var1[GET_ROW_IDX(selectionId)].var02 += var3; - sub_815168C(&sRoulette->flashUtil, 13, &var1[GET_ROW_IDX(selectionId)]); + iconFlash[GET_ROW_IDX(selectionId)].paletteOffset += palOffset; + RouletteFlash_Add(&sRoulette->flashUtil, NUM_ROULETTE_SLOTS + 1, &iconFlash[GET_ROW_IDX(selectionId)]); } else { @@ -2172,25 +2195,26 @@ static void FlashSelectionOnWheel(u8 selectionId) } else { - // Selection is full column + // Selection is full column, add entry in flash util for each unhit space's icon + // If there is only 1 unhit space, also add its flags so its color will flash as well for (i = 0; i < NUM_BOARD_COLORS; i++) { - u8 var4 = i * 5 + selectionId + 5; - if (!(sRoulette->hitFlags & sGridSelections[var4].flag)) + u8 columnSlotId = i * 5 + selectionId + 5; + if (!(sRoulette->hitFlags & sGridSelections[columnSlotId].flag)) { - // Set poke icons of selected squares to flash - var1[GET_ROW_IDX(var4)].var02 += var3; - sub_815168C(&sRoulette->flashUtil, i + 13, &var1[GET_ROW_IDX(var4)]); + iconFlash[GET_ROW_IDX(columnSlotId)].paletteOffset += palOffset; + RouletteFlash_Add(&sRoulette->flashUtil, i + NUM_ROULETTE_SLOTS + 1, &iconFlash[GET_ROW_IDX(columnSlotId)]); if (numSelected == 3) - var0 = sGridSelections[var4].var10; + flashFlags = sGridSelections[columnSlotId].flashFlags; numSelected--; } } + // If there was more than 1 space in the column, reset flags; only icons will flash if (numSelected != 2) - var0 = 0; + flashFlags = 0; } // Do flash - sub_8151A48(&sRoulette->flashUtil, var0 |= sGridSelections[selectionId].var10); + RouletteFlash_Enable(&sRoulette->flashUtil, flashFlags |= sGridSelections[selectionId].flashFlags); break; } } diff --git a/src/roulette_util.c b/src/roulette_util.c index ab20e5583..15a0c5bba 100755 --- a/src/roulette_util.c +++ b/src/roulette_util.c @@ -1,212 +1,217 @@ #include "global.h" #include "palette.h" -#include "roulette.h" #include "roulette_util.h" #include "util.h" -// "Roulette Util" is perhaps more accurately a general flashing util -// e.g. it handles fading the palettes for the color selections on the Roulette wheel +// "RouletteFlash" is more accurately a general flashing/fading util +// this file handles fading the palettes for the color/icon selections on the Roulette wheel // but it also handles the "pulse blend" effect of Mirage Tower -void sub_8151678(struct UnkStruct0 *r0) +void RouletteFlash_Reset(struct RouletteFlashUtil *flash) { - r0->var00 = 0; - r0->var02 = 0; - memset(&r0->var04, 0, sizeof(r0->var04)); + flash->enabled = 0; + flash->flags = 0; + memset(&flash->palettes, 0, sizeof(flash->palettes)); } -u8 sub_815168C(struct UnkStruct0 *r0, u8 r1, const struct UnkStruct1 *r2) +u8 RouletteFlash_Add(struct RouletteFlashUtil *flash, u8 id, const struct RouletteFlashSettings *settings) { - if (!(r1 < 16) || (r0->var04[r1].active)) + if (id >= ARRAY_COUNT(flash->palettes) || flash->palettes[id].available) return 0xFF; - r0->var04[r1].var04.var00 = r2->var00; - r0->var04[r1].var04.var02 = r2->var02; - r0->var04[r1].var04.var04 = r2->var04; - r0->var04[r1].var04.var05 = r2->var05; - r0->var04[r1].var04.var06 = r2->var06; - r0->var04[r1].var04.var07_0 = r2->var07_0; - r0->var04[r1].var04.var07_5 = r2->var07_5; - r0->var04[r1].var04.var07_7 = r2->var07_7; - r0->var04[r1].var00_0 = 0; - r0->var04[r1].active = TRUE; - r0->var04[r1].var02 = 0; - r0->var04[r1].var01 = 0; - if (r0->var04[r1].var04.var07_7 < 0) - r0->var04[r1].var03 = 0xFF; + flash->palettes[id].settings.color = settings->color; + flash->palettes[id].settings.paletteOffset = settings->paletteOffset; + flash->palettes[id].settings.numColors = settings->numColors; + flash->palettes[id].settings.delay = settings->delay; + flash->palettes[id].settings.unk6 = settings->unk6; + flash->palettes[id].settings.numFadeCycles = settings->numFadeCycles; + flash->palettes[id].settings.unk7_5 = settings->unk7_5; + flash->palettes[id].settings.colorDeltaDir = settings->colorDeltaDir; + flash->palettes[id].state = 0; + flash->palettes[id].available = TRUE; + flash->palettes[id].fadeCycleCounter = 0; + flash->palettes[id].delayCounter = 0; + if (flash->palettes[id].settings.colorDeltaDir < 0) + flash->palettes[id].colorDelta = -1; else - r0->var04[r1].var03 = 1; + flash->palettes[id].colorDelta = 1; - return r1; + return id; } -u8 sub_8151710(struct UnkStruct0 *r0, u8 r1) +// Unused +static u8 RouletteFlash_Remove(struct RouletteFlashUtil *flash, u8 id) { - if (r1 >= 16) + if (id >= ARRAY_COUNT(flash->palettes)) return 0xFF; - if (!r0->var04[r1].active) + if (!flash->palettes[id].available) return 0xFF; - memset(&r0->var04[r1], 0, sizeof(r0->var04[r1])); - return r1; + memset(&flash->palettes[id], 0, sizeof(flash->palettes[id])); + return id; } -u8 sub_8151744(struct UnkStruct3 *r0) +static u8 RouletteFlash_FadePalette(struct RouletteFlashPalette *pal) { u8 i; u8 returnval; - for (i = 0; i < r0->var04.var04; i++) + for (i = 0; i < pal->settings.numColors; i++) { - struct PlttData *faded = (struct PlttData *)&gPlttBufferFaded[r0->var04.var02 + i]; - struct PlttData *unfaded = (struct PlttData *)&gPlttBufferUnfaded[r0->var04.var02 + i]; + struct PlttData *faded = (struct PlttData *)&gPlttBufferFaded[pal->settings.paletteOffset + i]; + struct PlttData *unfaded = (struct PlttData *)&gPlttBufferUnfaded[pal->settings.paletteOffset + i]; - switch (r0->var00_0) + switch (pal->state) { case 1: - if (faded->r + r0->var03 >= 0 && faded->r + r0->var03 < 32) - faded->r += r0->var03; - if (faded->g + r0->var03 >= 0 && faded->g + r0->var03 < 32) - faded->g += r0->var03; - if (faded->b + r0->var03 >= 0 && faded->b + r0->var03 < 32) - faded->b += r0->var03; + // Fade color + if (faded->r + pal->colorDelta >= 0 && faded->r + pal->colorDelta < 32) + faded->r += pal->colorDelta; + if (faded->g + pal->colorDelta >= 0 && faded->g + pal->colorDelta < 32) + faded->g += pal->colorDelta; + if (faded->b + pal->colorDelta >= 0 && faded->b + pal->colorDelta < 32) + faded->b += pal->colorDelta; break; case 2: - if (r0->var03 < 0) + // Fade back to original color + if (pal->colorDelta < 0) { - if (faded->r + r0->var03 >= unfaded->r) - faded->r += r0->var03; - if (faded->g + r0->var03 >= unfaded->g) - faded->g += r0->var03; - if (faded->b + r0->var03 >= unfaded->b) - faded->b += r0->var03; + if (faded->r + pal->colorDelta >= unfaded->r) + faded->r += pal->colorDelta; + if (faded->g + pal->colorDelta >= unfaded->g) + faded->g += pal->colorDelta; + if (faded->b + pal->colorDelta >= unfaded->b) + faded->b += pal->colorDelta; } else { - if (faded->r + r0->var03 <= unfaded->r) - faded->r += r0->var03; - if (faded->g + r0->var03 <= unfaded->g) - faded->g += r0->var03; - if (faded->b + r0->var03 <= unfaded->b) - faded->b += r0->var03; + if (faded->r + pal->colorDelta <= unfaded->r) + faded->r += pal->colorDelta; + if (faded->g + pal->colorDelta <= unfaded->g) + faded->g += pal->colorDelta; + if (faded->b + pal->colorDelta <= unfaded->b) + faded->b += pal->colorDelta; } break; } } - if ((u32)r0->var02++ != r0->var04.var07_0) + if ((u32)pal->fadeCycleCounter++ != pal->settings.numFadeCycles) { returnval = 0; } else { - r0->var02 = 0; - r0->var03 *= -1; - if (r0->var00_0 == 1) - r0->var00_0++; + pal->fadeCycleCounter = 0; + pal->colorDelta *= -1; + if (pal->state == 1) + pal->state++; else - r0->var00_0--; + pal->state--; returnval = 1; } return returnval; } -u8 sub_815194C(struct UnkStruct3 *r0) +static u8 RouletteFlash_FlashPalette(struct RouletteFlashPalette *pal) { - u8 rg2 = 0; - - switch (r0->var00_0) + u8 i = 0; + switch (pal->state) { case 1: - for (rg2 = 0; rg2 < r0->var04.var04; rg2++) - gPlttBufferFaded[r0->var04.var02 + rg2] = r0->var04.var00; - r0->var00_0++; + // Flash to color + for (; i < pal->settings.numColors; i++) + gPlttBufferFaded[pal->settings.paletteOffset + i] = pal->settings.color; + pal->state++; break; case 2: - for (rg2 = 0; rg2 < r0->var04.var04; rg2++) - gPlttBufferFaded[r0->var04.var02 + rg2] = gPlttBufferUnfaded[r0->var04.var02 + rg2]; - r0->var00_0--; + // Restore to original color + for (; i < pal->settings.numColors; i++) + gPlttBufferFaded[pal->settings.paletteOffset + i] = gPlttBufferUnfaded[pal->settings.paletteOffset + i]; + pal->state--; break; } return 1; } -void task_tutorial_controls_fadein(struct UnkStruct0 *r0) +void RouletteFlash_Run(struct RouletteFlashUtil *flash) { u8 i = 0; - if (r0->var00) + if (flash->enabled) { - for (i = 0; i < 16; i++) + for (i = 0; i < ARRAY_COUNT(flash->palettes); i++) { - if ((r0->var02 >> i) & 1) + if ((flash->flags >> i) & 1) { - if (--r0->var04[i].var01 == 0xFF) // if underflow ? + if (--flash->palettes[i].delayCounter == (u8)-1) { - if (r0->var04[i].var04.var00 & 0x8000) // PlttData->unused_15 ? - sub_8151744(&r0->var04[i]); + if (flash->palettes[i].settings.color & FLASHUTIL_USE_EXISTING_COLOR) + RouletteFlash_FadePalette(&flash->palettes[i]); else - sub_815194C(&r0->var04[i]); + RouletteFlash_FlashPalette(&flash->palettes[i]); - r0->var04[i].var01 = r0->var04[i].var04.var05; + flash->palettes[i].delayCounter = flash->palettes[i].settings.delay; } } } } } -void sub_8151A48(struct UnkStruct0 *r0, u16 flags) +void RouletteFlash_Enable(struct RouletteFlashUtil *flash, u16 flags) { u8 i = 0; - r0->var00++; - for (i = 0; i < 16; i++) + flash->enabled++; + for (i = 0; i < ARRAY_COUNT(flash->palettes); i++) { if ((flags >> i) & 1) { - if (r0->var04[i].active) + if (flash->palettes[i].available) { - r0->var02 |= 1 << i; - r0->var04[i].var00_0 = 1; + flash->flags |= 1 << i; + flash->palettes[i].state = 1; } } } } -void sub_8151A9C(struct UnkStruct0 *r0, u16 flags) +void RouletteFlash_Stop(struct RouletteFlashUtil *flash, u16 flags) { u8 i; - for (i = 0; i < 16; i++) + for (i = 0; i < ARRAY_COUNT(flash->palettes); i++) { - if ((r0->var02 >> i) & 1) + if ((flash->flags >> i) & 1) { - if (r0->var04[i].active) + if (flash->palettes[i].available) { if ((flags >> i) & 1) { - u32 offset = r0->var04[i].var04.var02; + u32 offset = flash->palettes[i].settings.paletteOffset; u16 *faded = &gPlttBufferFaded[offset]; u16 *unfaded = &gPlttBufferUnfaded[offset]; - memcpy(faded, unfaded, r0->var04[i].var04.var04 * 2); - r0->var04[i].var00_0 = 0; - r0->var04[i].var02 = 0; - r0->var04[i].var01 = 0; - if (r0->var04[i].var04.var07_7 < 0) - r0->var04[i].var03 = 0xFF; + memcpy(faded, unfaded, flash->palettes[i].settings.numColors * 2); + flash->palettes[i].state = 0; + flash->palettes[i].fadeCycleCounter = 0; + flash->palettes[i].delayCounter = 0; + if (flash->palettes[i].settings.colorDeltaDir < 0) + flash->palettes[i].colorDelta = -1; else - r0->var04[i].var03 = 0x1; + flash->palettes[i].colorDelta = 1; } } } } + if (flags == 0xFFFF) { - r0->var00 = 0; - r0->var02 = 0; + // Stopped all + flash->enabled = 0; + flash->flags = 0; } else { - r0->var02 = r0->var02 & ~flags; + flash->flags &= ~flags; } } From f8f6575360e6ef4c27a5b65dcbda342ec9665f32 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Tue, 4 Aug 2020 19:24:36 -0400 Subject: [PATCH 5/6] Rename roulette_util to palette_util --- include/{roulette_util.h => palette_util.h} | 6 +++--- ld_script.txt | 2 +- src/mirage_tower.c | 2 +- src/{roulette_util.c => palette_util.c} | 2 +- src/roulette.c | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) rename include/{roulette_util.h => palette_util.h} (95%) rename src/{roulette_util.c => palette_util.c} (99%) diff --git a/include/roulette_util.h b/include/palette_util.h similarity index 95% rename from include/roulette_util.h rename to include/palette_util.h index 2864ee464..46468c0a6 100644 --- a/include/roulette_util.h +++ b/include/palette_util.h @@ -1,5 +1,5 @@ -#ifndef GUARD_ROULETTE_UTIL_H -#define GUARD_ROULETTE_UTIL_H +#ifndef GUARD_PALETTE_UTIL_H +#define GUARD_PALETTE_UTIL_H struct PulseBlendSettings { @@ -80,4 +80,4 @@ u8 RouletteFlash_Add(struct RouletteFlashUtil *r0, u8 r1, const struct RouletteF void RouletteFlash_Stop(struct RouletteFlashUtil *r0, u16 r1); void RouletteFlash_Enable(struct RouletteFlashUtil *r0, u16 r1); -#endif // GUARD_ROULETTE_UTIL_H +#endif // GUARD_PALETTE_UTIL_H diff --git a/ld_script.txt b/ld_script.txt index f3e418c08..724f01328 100644 --- a/ld_script.txt +++ b/ld_script.txt @@ -237,7 +237,7 @@ SECTIONS { src/battle_message.o(.text); src/cable_car.o(.text); src/math_util.o(.text); - src/roulette_util.o(.text); + src/palette_util.o(.text); src/confetti_util.o(.text); src/save.o(.text); src/mystery_event_script.o(.text); diff --git a/src/mirage_tower.c b/src/mirage_tower.c index c1323c784..02cccf2a5 100644 --- a/src/mirage_tower.c +++ b/src/mirage_tower.c @@ -8,7 +8,7 @@ #include "gpu_regs.h" #include "menu.h" #include "random.h" -#include "roulette_util.h" +#include "palette_util.h" #include "script.h" #include "sound.h" #include "sprite.h" diff --git a/src/roulette_util.c b/src/palette_util.c similarity index 99% rename from src/roulette_util.c rename to src/palette_util.c index 15a0c5bba..5364ff6d9 100755 --- a/src/roulette_util.c +++ b/src/palette_util.c @@ -1,6 +1,6 @@ #include "global.h" #include "palette.h" -#include "roulette_util.h" +#include "palette_util.h" #include "util.h" // "RouletteFlash" is more accurately a general flashing/fading util diff --git a/src/roulette.c b/src/roulette.c index 0923ea2d3..b3e07233a 100644 --- a/src/roulette.c +++ b/src/roulette.c @@ -13,9 +13,9 @@ #include "menu_helpers.h" #include "overworld.h" #include "palette.h" +#include "palette_util.h" #include "random.h" #include "roulette.h" -#include "roulette_util.h" #include "rtc.h" #include "scanline_effect.h" #include "script.h" From 4bf43311f0b2cf78cb69b71485fce61ed8c21786 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Mon, 10 Aug 2020 17:09:17 -0400 Subject: [PATCH 6/6] Remove redundant parens --- src/roulette.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/roulette.c b/src/roulette.c index b3e07233a..4ca892912 100644 --- a/src/roulette.c +++ b/src/roulette.c @@ -1515,7 +1515,7 @@ static void Task_HandleBetGridInput(u8 taskId) if (JOY_NEW(A_BUTTON)) { - if ((sRoulette->hitFlags & sGridSelections[gTasks[taskId].tSelectionId].flag)) + if (sRoulette->hitFlags & sGridSelections[gTasks[taskId].tSelectionId].flag) { // Ball has already landed on this space PlaySE(SE_BOO);