diff options
-rw-r--r-- | graphics/link/321start.png (renamed from graphics/misc/unk_846B008.png) | bin | 757 -> 757 bytes | |||
-rw-r--r-- | graphics/link_games/pkmnjump_bg.png | bin | 582 -> 0 bytes | |||
-rw-r--r-- | graphics/link_games/pkmnjump_results.png | bin | 2401 -> 0 bytes | |||
-rw-r--r-- | graphics/pokemon_jump/bg.bin (renamed from graphics/link_games/pkmnjump_bg.bin) | bin | 1280 -> 1280 bytes | |||
-rw-r--r-- | graphics/pokemon_jump/bg.pal (renamed from graphics/link_games/pkmnjump_bg.pal) | 0 | ||||
-rw-r--r-- | graphics/pokemon_jump/bg.png | bin | 0 -> 532 bytes | |||
-rw-r--r-- | graphics/pokemon_jump/bonuses.bin (renamed from graphics/link_games/pkmnjump_results.bin) | bin | 8192 -> 8192 bytes | |||
-rw-r--r-- | graphics/pokemon_jump/bonuses.pal (renamed from graphics/link_games/pkmnjump_results.pal) | 0 | ||||
-rw-r--r-- | graphics/pokemon_jump/bonuses.png | bin | 0 -> 2129 bytes | |||
-rw-r--r-- | graphics/pokemon_jump/interface.pal (renamed from graphics/link_games/pkmnjump_pal3.pal) | 0 | ||||
-rw-r--r-- | graphics/pokemon_jump/pal1.pal (renamed from graphics/link_games/pkmnjump_pal1.pal) | 0 | ||||
-rw-r--r-- | graphics/pokemon_jump/pal2.pal (renamed from graphics/link_games/pkmnjump_pal2.pal) | 0 | ||||
-rw-r--r-- | graphics/pokemon_jump/star.png (renamed from graphics/link_games/pkmnjump_star.png) | bin | 335 -> 335 bytes | |||
-rw-r--r-- | graphics/pokemon_jump/venusaur.bin (renamed from graphics/link_games/pkmnjump_venusaur.bin) | bin | 4096 -> 4096 bytes | |||
-rw-r--r-- | graphics/pokemon_jump/venusaur.pal (renamed from graphics/link_games/pkmnjump_venusaur.pal) | 0 | ||||
-rw-r--r-- | graphics/pokemon_jump/venusaur.png (renamed from graphics/link_games/pkmnjump_venusaur.png) | bin | 2082 -> 2082 bytes | |||
-rw-r--r-- | graphics/pokemon_jump/vine1.png (renamed from graphics/link_games/pkmnjump_rope1.png) | bin | 284 -> 284 bytes | |||
-rw-r--r-- | graphics/pokemon_jump/vine2.png (renamed from graphics/link_games/pkmnjump_rope2.png) | bin | 322 -> 322 bytes | |||
-rw-r--r-- | graphics/pokemon_jump/vine3.png (renamed from graphics/link_games/pkmnjump_rope3.png) | bin | 338 -> 338 bytes | |||
-rw-r--r-- | graphics/pokemon_jump/vine4.png (renamed from graphics/link_games/pkmnjump_rope4.png) | bin | 256 -> 256 bytes | |||
-rw-r--r-- | graphics_file_rules.mk | 4 | ||||
-rw-r--r-- | include/bg.h | 7 | ||||
-rw-r--r-- | include/constants/pokemon.h | 4 | ||||
-rw-r--r-- | include/link.h | 1 | ||||
-rw-r--r-- | include/link_rfu.h | 2 | ||||
-rw-r--r-- | include/pokemon_jump.h | 2 | ||||
-rw-r--r-- | include/random.h | 5 | ||||
-rw-r--r-- | include/task.h | 1 | ||||
-rw-r--r-- | include/window.h | 2 | ||||
-rw-r--r-- | src/new_game.c | 2 | ||||
-rw-r--r-- | src/pokemon_jump.c | 4343 | ||||
-rw-r--r-- | src/random.c | 3 |
32 files changed, 2374 insertions, 2002 deletions
diff --git a/graphics/misc/unk_846B008.png b/graphics/link/321start.png Binary files differindex 4fed89d24..4fed89d24 100644 --- a/graphics/misc/unk_846B008.png +++ b/graphics/link/321start.png diff --git a/graphics/link_games/pkmnjump_bg.png b/graphics/link_games/pkmnjump_bg.png Binary files differdeleted file mode 100644 index ceef49004..000000000 --- a/graphics/link_games/pkmnjump_bg.png +++ /dev/null diff --git a/graphics/link_games/pkmnjump_results.png b/graphics/link_games/pkmnjump_results.png Binary files differdeleted file mode 100644 index b87d50659..000000000 --- a/graphics/link_games/pkmnjump_results.png +++ /dev/null diff --git a/graphics/link_games/pkmnjump_bg.bin b/graphics/pokemon_jump/bg.bin Binary files differindex 68303ba7e..68303ba7e 100644 --- a/graphics/link_games/pkmnjump_bg.bin +++ b/graphics/pokemon_jump/bg.bin diff --git a/graphics/link_games/pkmnjump_bg.pal b/graphics/pokemon_jump/bg.pal index aed4bcc8b..aed4bcc8b 100644 --- a/graphics/link_games/pkmnjump_bg.pal +++ b/graphics/pokemon_jump/bg.pal diff --git a/graphics/pokemon_jump/bg.png b/graphics/pokemon_jump/bg.png Binary files differnew file mode 100644 index 000000000..449bbf627 --- /dev/null +++ b/graphics/pokemon_jump/bg.png diff --git a/graphics/link_games/pkmnjump_results.bin b/graphics/pokemon_jump/bonuses.bin Binary files differindex b17c5052c..b17c5052c 100644 --- a/graphics/link_games/pkmnjump_results.bin +++ b/graphics/pokemon_jump/bonuses.bin diff --git a/graphics/link_games/pkmnjump_results.pal b/graphics/pokemon_jump/bonuses.pal index aca961de3..aca961de3 100644 --- a/graphics/link_games/pkmnjump_results.pal +++ b/graphics/pokemon_jump/bonuses.pal diff --git a/graphics/pokemon_jump/bonuses.png b/graphics/pokemon_jump/bonuses.png Binary files differnew file mode 100644 index 000000000..fe1cb2609 --- /dev/null +++ b/graphics/pokemon_jump/bonuses.png diff --git a/graphics/link_games/pkmnjump_pal3.pal b/graphics/pokemon_jump/interface.pal index 6b73be372..6b73be372 100644 --- a/graphics/link_games/pkmnjump_pal3.pal +++ b/graphics/pokemon_jump/interface.pal diff --git a/graphics/link_games/pkmnjump_pal1.pal b/graphics/pokemon_jump/pal1.pal index 936a2b39f..936a2b39f 100644 --- a/graphics/link_games/pkmnjump_pal1.pal +++ b/graphics/pokemon_jump/pal1.pal diff --git a/graphics/link_games/pkmnjump_pal2.pal b/graphics/pokemon_jump/pal2.pal index d7fc1394b..d7fc1394b 100644 --- a/graphics/link_games/pkmnjump_pal2.pal +++ b/graphics/pokemon_jump/pal2.pal diff --git a/graphics/link_games/pkmnjump_star.png b/graphics/pokemon_jump/star.png Binary files differindex 96abce388..96abce388 100644 --- a/graphics/link_games/pkmnjump_star.png +++ b/graphics/pokemon_jump/star.png diff --git a/graphics/link_games/pkmnjump_venusaur.bin b/graphics/pokemon_jump/venusaur.bin Binary files differindex 093c0a5a5..093c0a5a5 100644 --- a/graphics/link_games/pkmnjump_venusaur.bin +++ b/graphics/pokemon_jump/venusaur.bin diff --git a/graphics/link_games/pkmnjump_venusaur.pal b/graphics/pokemon_jump/venusaur.pal index a3514b004..a3514b004 100644 --- a/graphics/link_games/pkmnjump_venusaur.pal +++ b/graphics/pokemon_jump/venusaur.pal diff --git a/graphics/link_games/pkmnjump_venusaur.png b/graphics/pokemon_jump/venusaur.png Binary files differindex d555d324d..d555d324d 100644 --- a/graphics/link_games/pkmnjump_venusaur.png +++ b/graphics/pokemon_jump/venusaur.png diff --git a/graphics/link_games/pkmnjump_rope1.png b/graphics/pokemon_jump/vine1.png Binary files differindex 03d2f2778..03d2f2778 100644 --- a/graphics/link_games/pkmnjump_rope1.png +++ b/graphics/pokemon_jump/vine1.png diff --git a/graphics/link_games/pkmnjump_rope2.png b/graphics/pokemon_jump/vine2.png Binary files differindex 6e397966e..6e397966e 100644 --- a/graphics/link_games/pkmnjump_rope2.png +++ b/graphics/pokemon_jump/vine2.png diff --git a/graphics/link_games/pkmnjump_rope3.png b/graphics/pokemon_jump/vine3.png Binary files differindex 907169a4c..907169a4c 100644 --- a/graphics/link_games/pkmnjump_rope3.png +++ b/graphics/pokemon_jump/vine3.png diff --git a/graphics/link_games/pkmnjump_rope4.png b/graphics/pokemon_jump/vine4.png Binary files differindex b238382a0..b238382a0 100644 --- a/graphics/link_games/pkmnjump_rope4.png +++ b/graphics/pokemon_jump/vine4.png diff --git a/graphics_file_rules.mk b/graphics_file_rules.mk index 859b7b8d6..8e5cd789f 100644 --- a/graphics_file_rules.mk +++ b/graphics_file_rules.mk @@ -97,7 +97,7 @@ $(FONTGFXDIR)/font9_jap.fwjpnfont: $(FONTGFXDIR)/font9_jap.png graphics/title_screen/pokemon_logo.gbapal: %.gbapal: %.pal $(GFX) $< $@ -num_colors 224 -graphics/link_games/pkmnjump_bg.4bpp: %.4bpp: %.png +graphics/pokemon_jump/bg.4bpp: %.4bpp: %.png $(GFX) $< $@ -num_tiles 63 $(MISCGFXDIR)/japanese_hof.4bpp: %.4bpp: %.png @@ -482,7 +482,7 @@ $(FAMECHECKERGFXDIR)/bg.4bpp: %.4bpp: %.png graphics/seagallop/water.4bpp: %.4bpp: %.png $(GFX) $< $@ -num_tiles 41 -$(MISCGFXDIR)/unk_846B008.4bpp: %.4bpp: %.png +graphics/link/321start.4bpp: %.4bpp: %.png $(GFX) $< $@ -mwidth 4 -mheight 4 $(TEXTWINDOWGFXDIR)/unk_8470B0C.4bpp: %.4bpp: %.png diff --git a/include/bg.h b/include/bg.h index f6c307146..ca6264ca8 100644 --- a/include/bg.h +++ b/include/bg.h @@ -39,6 +39,13 @@ enum BG_ATTR_BASETILE = 10 }; +// Modes for ChangeBgX / ChangeBgY +enum { + BG_COORD_SET, + BG_COORD_ADD, + BG_COORD_SUB, +}; + enum AdjustBgMosaicMode { BG_MOSAIC_SET, diff --git a/include/constants/pokemon.h b/include/constants/pokemon.h index 43a6231ca..43a3a59d4 100644 --- a/include/constants/pokemon.h +++ b/include/constants/pokemon.h @@ -225,6 +225,10 @@ #define EVO_MODE_ITEM_USE 2 #define EVO_MODE_ITEM_CHECK 3 // If an Everstone is being held, still want to show that the stone *could* be used on that Pokémon to evolve +#define MON_PIC_WIDTH 64 +#define MON_PIC_HEIGHT 64 +#define MON_PIC_SIZE (MON_PIC_WIDTH * MON_PIC_HEIGHT / 2) + // used by ShouldIgnoreDeoxysForm #define DEOXYS_CHECK_BATTLE_SPRITE 1 #define DEOXYS_CHECK_TRADE_MAIN 3 diff --git a/include/link.h b/include/link.h index e009c2724..e7dafadf6 100644 --- a/include/link.h +++ b/include/link.h @@ -58,6 +58,7 @@ #define LINKCMD_0x5FFF 0x5FFF #define LINKCMD_0x6666 0x6666 #define LINKCMD_0x7777 0x7777 +#define LINKCMD_COUNTDOWN 0x7FFF #define LINKCMD_CONT_BLOCK 0x8888 #define LINKCMD_0xAAAA 0xAAAA #define LINKCMD_0xAAAB 0xAAAB diff --git a/include/link_rfu.h b/include/link_rfu.h index 6d7e54129..7dac12fbb 100644 --- a/include/link_rfu.h +++ b/include/link_rfu.h @@ -6,6 +6,8 @@ #include "link.h" #include "AgbRfu_LinkManager.h" +#define RFUCMD_MASK 0xFF00 + #define RFUCMD_SEND_PACKET 0x2F00 #define RFUCMD_READY_CLOSE_LINK 0x5f00 #define RFUCMD_READY_EXIT_STANDBY 0x6600 diff --git a/include/pokemon_jump.h b/include/pokemon_jump.h index fa4105a0e..20f96ec10 100644 --- a/include/pokemon_jump.h +++ b/include/pokemon_jump.h @@ -3,7 +3,7 @@ #include "main.h" -void ResetPokeJumpResults(void); +void ResetPokemonJumpRecords(void); bool32 IsSpeciesAllowedInPokemonJump(u16 species); void StartPokemonJump(u16 species, MainCallback callback); diff --git a/include/random.h b/include/random.h index 139316f9d..bf4af42d0 100644 --- a/include/random.h +++ b/include/random.h @@ -13,6 +13,11 @@ u16 Random2(void); //Returns a 32-bit pseudorandom number #define Random32() (Random() | (Random() << 16)) +// The number 1103515245 comes from the example implementation of rand and srand +// in the ISO C standard. +#define ISO_RANDOMIZE1(val)(1103515245 * (val) + 24691) +#define ISO_RANDOMIZE2(val)(1103515245 * (val) + 12345) + //Sets the initial seed value of the pseudorandom number generator void SeedRng(u16 seed); void SeedRng2(u16 seed); diff --git a/include/task.h b/include/task.h index fd7f5a4e1..2f9f1c0d8 100644 --- a/include/task.h +++ b/include/task.h @@ -5,6 +5,7 @@ #define HEAD_SENTINEL 0xFE #define TAIL_SENTINEL 0xFF +#define TASK_NONE TAIL_SENTINEL #define NUM_TASKS 16 #define NUM_TASK_DATA 16 diff --git a/include/window.h b/include/window.h index 3cb904626..1c3d9be9c 100644 --- a/include/window.h +++ b/include/window.h @@ -41,6 +41,8 @@ struct WindowTemplate 0, \ } +#define WINDOW_NONE 0xFF + struct Window { struct WindowTemplate window; diff --git a/src/new_game.c b/src/new_game.c index d570e3886..741d1d602 100644 --- a/src/new_game.c +++ b/src/new_game.c @@ -155,6 +155,6 @@ static void ResetMiniGamesResults(void) { CpuFill16(0, &gSaveBlock2Ptr->berryCrush, sizeof(struct BerryCrush)); SetBerryPowder(&gSaveBlock2Ptr->berryCrush.berryPowderAmount, 0); - ResetPokeJumpResults(); + ResetPokemonJumpRecords(); CpuFill16(0, &gSaveBlock2Ptr->berryPick, sizeof(struct BerryPickingResults)); } diff --git a/src/pokemon_jump.c b/src/pokemon_jump.c index 26f2e18f1..7cd7223a2 100644 --- a/src/pokemon_jump.c +++ b/src/pokemon_jump.c @@ -22,812 +22,991 @@ #include "constants/items.h" #include "constants/songs.h" -struct PokemonJump1_MonInfo +#define MAX_JUMP_SCORE 99990 +#define MAX_JUMPS 9999 + +#define JUMP_PEAK (-30) + +enum { + BG_INTERFACE, + BG_BONUSES, + BG_VENUSAUR, + BG_SCENERY, +}; + +// IDs for persistent windows +enum { + WIN_POINTS, + WIN_TIMES, + NUM_WINDOWS +}; + +enum { + PACKET_MON_INFO = 1, + PACKET_UNUSED, + PACKET_LEADER_STATE, + PACKET_MEMBER_STATE, +}; + +enum { + JUMP_TYPE_NORMAL, + JUMP_TYPE_FAST, + JUMP_TYPE_SLOW, +}; + +enum { + FUNC_GAME_INTRO, + FUNC_WAIT_ROUND, + FUNC_GAME_ROUND, + FUNC_GAME_OVER, + FUNC_ASK_PLAY_AGAIN, + FUNC_RESET_GAME, + FUNC_EXIT, + FUNC_GIVE_PRIZE, + FUNC_SAVE, + FUNC_NONE +}; + +enum { + GFXFUNC_LOAD, + GFXFUNC_SHOW_NAMES, + GFXFUNC_SHOW_NAMES_HIGHLIGHT, + GFXFUNC_ERASE_NAMES, + GFXFUNC_MSG_PLAY_AGAIN, + GFXFUNC_MSG_SAVING, + GFXFUNC_ERASE_MSG, + GFXFUNC_MSG_PLAYER_DROPPED, + GFXFUNC_MSG_COMM_STANDBY, + GFXFUNC_COUNTDOWN, +}; + +enum { + VINE_HIGHEST, + VINE_DOWNSWING_HIGHER, + VINE_DOWNSWING_HIGH, + VINE_DOWNSWING_LOW, + VINE_DOWNSWING_LOWER, + VINE_LOWEST, + VINE_UPSWING_LOWER, + VINE_UPSWING_LOW, + VINE_UPSWING_HIGH, + VINE_UPSWING_HIGHER, + NUM_VINESTATES +}; + +// Used to compare limits for vineStateTimer +// The upper 8 bits of vineStateTimer are the vine state, +// the lower 8 bits are a timer to the next state. +// When the timer is incremented above 255, it increments +// the vine state and the timer is reset. +#define VINE_STATE_TIMER(vineState)(((vineState) << 8) | 0xFF) + +enum { + MONSTATE_NORMAL, // Pokémon is either on the ground or in the middle of a jump + MONSTATE_JUMP, // Pokémon has begun a jump + MONSTATE_HIT, // Pokémon got hit by the vine +}; + +enum { + JUMPSTATE_NONE, + JUMPSTATE_SUCCESS, // Cleared vine + JUMPSTATE_FAILURE, // Hit vine +}; + +#define PLAY_AGAIN_NO 1 +#define PLAY_AGAIN_YES 2 + +#define TAG_MON1 0 +#define TAG_MON2 1 // MON2-5 used implicitly by adding multiplayer id to tag +#define TAG_MON3 2 +#define TAG_MON4 3 +#define TAG_MON5 4 + +#define GFXTAG_VINE1 5 +#define GFXTAG_VINE2 6 +#define GFXTAG_VINE3 7 +#define GFXTAG_VINE4 8 +#define GFXTAG_COUNTDOWN 9 +#define GFXTAG_STAR 10 + +#define PALTAG_1 5 +#define PALTAG_2 6 +#define PALTAG_COUNTDOWN 7 + +#define TAG_DIGITS 800 + +#define VINE_SPRITES_PER_SIDE 4 // Vine rope is divided into 8 sprites, 4 per side copied and flipped horizontally + +// Used by SetLinkTimeInterval to get a bit mask for capping +// a timer that controls how frequently link data is sent. +#define LINK_INTERVAL_NONE 0 +#define LINK_INTERVAL_SHORT 3 // 3 frame interval +#define LINK_INTERVAL_MEDIUM 4 // 7 frame interval +#define LINK_INTERVAL_LONG 5 // 15 frame interval + +#define LINK_TIMER_STOPPED 0x1111 + +struct PokemonJump_MonInfo { u16 species; u32 otId; u32 personality; }; -struct PokemonJump1_82E4 -{ - int unk0; - int unk4; - u8 filler8[0x4]; - u16 unkC; - u16 unkE; - u16 unk10; - u16 unk12; - int unk14; - int unk18; - u8 unk1C[11]; +struct PokemonJump_Player +{ + int jumpOffset; + int jumpOffsetIdx; + u32 unused; + u16 monJumpType; + u16 jumpTimeStart; + u16 monState; + u16 prevMonState; + int jumpState; + bool32 funcFinished; + u8 name[11]; }; -struct PokemonJump2 -{ - int unk0; - u16 unk4; - u8 unk6; - u8 filler7[0xa - 0x7]; - u8 unkA; - u8 unkB; - u8 unkC; - u8 unkD; - u8 unkE; - u8 unkF; - u16 filler10; - u16 unk12; - u16 unk14; - u32 unk18; - u16 unk1C[5]; - u8 txtBuff[2][0x40]; - u8 strBuff[0x100]; +struct PokemonJumpGfx +{ + bool32 funcFinished; + u16 mainState; + u8 taskId; + u8 unused1[3]; + u8 resetVineState; + u8 resetVineTimer; + u8 vineState; + u8 msgWindowState; + u8 vinePalNumDownswing; + u8 vinePalNumUpswing; + u16 unused2; + u16 msgWindowId; + u16 fanfare; + u32 bonusTimer; + u16 nameWindowIds[MAX_RFU_PLAYERS]; + u8 itemName[64]; + u8 itemQuantityStr[64]; + u8 prizeMsg[256]; u16 tilemapBuffer[0x4000]; // Bug: way larger than it should be - struct Sprite *unk81A8[MAX_RFU_PLAYERS]; - struct Sprite *unk81BC[MAX_RFU_PLAYERS]; - struct Sprite *unk81D0[8]; - u8 filler81F0[0xC]; - u8 unk81FC[MAX_RFU_PLAYERS]; + struct Sprite *monSprites[MAX_RFU_PLAYERS]; + struct Sprite *starSprites[MAX_RFU_PLAYERS]; + struct Sprite *vineSprites[VINE_SPRITES_PER_SIDE * 2]; + u8 unused3[12]; + u8 monSpriteSubpriorities[MAX_RFU_PLAYERS]; }; -struct PokemonJump1Sub +struct PokemonJump_CommData { - u8 unk0; - u8 unk1; - u16 unk2; - u16 unk4; - u32 unk8; + u8 funcId; + u8 receivedBonusFlags; + u16 data; // Multi-use + u16 jumpsInRow; + u32 jumpScore; }; -struct MonInfoPacket +struct PokemonJump { - u8 id; // packet id - u16 species; - u32 personality; - u32 otId; -}; - -struct PokemonJump1 -{ - MainCallback returnCallback; - u8 unk4; - u8 unk5; - u8 unk6; - u8 unk7; - u16 unk8; - u16 unkA; - u16 unkC; - u16 unkE; - int unk10; - u32 unk14; - u32 unk18; - int unk1C; - u32 unk20; - u32 unk24; - u32 unk28; - int unk2C; - u32 unk30; - u16 unk34; - u16 unk36; - u8 filler38[0x2]; - u16 unk3A; - u16 unk3C; - u16 unk3E; - u16 unk40; - u16 unk42; - u8 unk44; - u8 unk45; - u8 unk46; - u8 isLeader; - u8 unk48; - u8 unk49; - u16 unk4A; - u8 unk4C; - u8 unk4D; - u16 unk4E; - u8 unk50; - u8 unk51; - u8 filler52[0x2]; - int unk54; - int unk58; - int unk5C; - int unk60; - int unk64; - int unk68; - int unk6C; - struct PokemonJump1Sub unk70; - u8 unk7C[MAX_RFU_PLAYERS]; - u8 unk81[MAX_RFU_PLAYERS]; - u8 unk86[MAX_RFU_PLAYERS]; - u8 unk8B[MAX_RFU_PLAYERS]; - u16 unk90[MAX_RFU_PLAYERS]; - u16 unk9A[MAX_RFU_PLAYERS]; - struct PokemonJump2 unkA4; - struct PokemonJump1_MonInfo unk82A8[MAX_RFU_PLAYERS]; - struct PokemonJump1_82E4 unk82E4[MAX_RFU_PLAYERS]; - struct PokemonJump1_82E4 *unk83AC; + MainCallback exitCallback; + u8 taskId; + u8 numPlayers; + u8 multiplayerId; + u8 startDelayTimer; + u16 mainState; + u16 helperState; + u16 excellentsInRow; + u16 excellentsInRowRecord; + bool32 gameOver; + u32 vineState; + u32 prevVineState; + int vineSpeed; + u32 vineSpeedAccel; + u32 rngSeed; + u32 nextVineSpeed; + int linkTimer; + u32 linkTimerLimit; + u16 vineStateTimer; + bool16 ignoreJumpInput; + u16 unused1; + u16 unused2; // Set to 0, never read + u16 timer; + u16 prizeItemId; + u16 prizeItemQuantity; + u16 playAgainComm; + u8 unused3; // Set to 0, never read + u8 playAgainState; + bool8 allowVineUpdates; + bool8 isLeader; + bool8 funcActive; + bool8 allPlayersReady; + u16 vineTimer; + u8 nextFuncId; + bool8 showBonus; + u16 vineSpeedDelay; + u8 vineBaseSpeedIdx; + u8 vineSpeedStage; + int numPlayersAtPeak; + bool32 initScoreUpdate; + bool32 updateScore; + bool32 unused4; // Set to TRUE, never read + bool32 giveBonus; + bool32 skipJumpUpdate; + bool32 atMaxSpeedStage; + struct PokemonJump_CommData comm; + bool8 atJumpPeak[MAX_RFU_PLAYERS]; + bool8 atJumpPeak2[MAX_RFU_PLAYERS]; + bool8 atJumpPeak3[MAX_RFU_PLAYERS]; + u8 memberFuncIds[MAX_RFU_PLAYERS]; + u16 playAgainStates[MAX_RFU_PLAYERS]; + u16 jumpTimeStarts[MAX_RFU_PLAYERS]; + struct PokemonJumpGfx jumpGfx; + struct PokemonJump_MonInfo monInfo[MAX_RFU_PLAYERS]; + struct PokemonJump_Player players[MAX_RFU_PLAYERS]; + struct PokemonJump_Player *player; }; - -static void sub_8147654(u8 taskId); -static void sub_81477C0(u8 taskId); -static void sub_814784C(u8 taskId); -static void sub_81479D4(u8 taskId); -static void sub_8147A34(u8 taskId); -static void sub_8147B60(struct PokemonJump1 *); -static void sub_8147B94(struct PokemonJump1 *); -static void sub_8147C20(void); -static void sub_8147C98(void); +static void Task_StaticCountdown(u8 taskId); +static void Task_StaticCountdown_Init(u8 taskId); +static void Task_StaticCountdown_Free(u8 taskId); +static void Task_StaticCountdown_Start(u8 taskId); +static void Task_StaticCountdown_Run(u8 taskId); +static void InitGame(struct PokemonJump *); +static void ResetForNewGame(struct PokemonJump *); +static void InitPlayerAndJumpTypes(void); +static void ResetPlayersForNewGame(void); static s16 GetPokemonJumpSpeciesIdx(u16 species); -static void sub_8147D2C(struct PokemonJump1_MonInfo *monInfo, struct Pokemon *mon); -static void sub_8147D6C(void); -static void sub_8147DA0(u8 taskId); -static void sub_814807C(u8 taskId); -static void sub_8148104(void); -static void sub_8148290(u8 taskId); -static void sub_81482F8(void); -static bool32 sub_8148344(void); -static bool32 sub_81483D0(void); -static bool32 sub_8148464(void); -static bool32 sub_81484D0(void); -static bool32 sub_814856C(void); -static bool32 sub_81485C8(void); -static bool32 sub_8148664(void); -static bool32 sub_81486C4(void); -static bool32 sub_8148724(void); -static bool32 sub_8148760(void); -static bool32 sub_81487B4(void); -static bool32 sub_8148800(void); -static bool32 sub_814881C(void); -static bool32 sub_81488DC(void); -static bool32 sub_81489C8(void); -static bool32 sub_8148A60(void); -static bool32 sub_8148398(void); -static bool32 sub_8148418(void); -static bool32 sub_81484B0(void); -static bool32 sub_8148B54(void); -static bool32 sub_8148C80(void); -static bool32 sub_8148D5C(void); -static bool32 sub_8148E2C(void); -static void sub_8148E80(u8 taskId); -static void sub_8148F5C(TaskFunc func, u8 taskPriority); -static void sub_8148F7C(void); -static void sub_8148F9C(void); -static void sub_8148FE0(void); -static int sub_8149044(void); -static void sub_8149078(void); -static int sub_8149194(void); -static void sub_81491B4(void); -static void sub_81491E4(void); -static void sub_8149210(void); -static bool32 sub_814922C(u16); -static void sub_8149260(void); -static void sub_81492D8(void); -static void sub_814933C(void); -static void sub_814935C(void); -static void sub_814936C(void); -static void sub_814937C(void); -static void sub_8149490(int); -static void sub_8149534(void); -static bool32 sub_8149630(void); -static bool32 sub_81496D4(void); -static bool32 sub_8149710(void); -static bool32 sub_8149748(void); -static void sub_8149780(int); -static int sub_81497A8(void); -static bool32 sub_8149804(void); -static int sub_8149834(u8 *); -static void sub_8149878(void); -static int sub_8149888(int); -static void sub_8149898(u16); -static bool32 sub_81498B4(void); -static u16 sub_81498D8(void); -static void sub_8149900(u16, u16 *, u16 *); -static u16 sub_8149910(void); -static u16 sub_8149930(void); -static u16 sub_8149978(u16 item, u16 quantity); -static void sub_8149D80(void (*func)(void)); -static void sub_8149DA4(u8 taskId); -static void sub_8149DC8(void); -static void sub_8149F64(void); -static void sub_8149FD0(void); -static void sub_814A03C(void); -static void sub_814A0C8(void); -static void sub_814A174(void); -static void sub_814A218(void); -static void sub_814A264(void); -static void sub_814A308(void); -static void sub_814A3AC(void); -static u32 sub_814A754(u32 left, u32 top, u32 width, u32 height); -static void sub_814A7D0(u16 left, u16 top, u8 cursorPos); -static void sub_814A84C(void); -static void sub_814A8B8(void); -static void sub_814A9C8(void); -static void sub_814AADC(void); -static void sub_814AC30(bool32 arg0); -static void sub_814AC94(void); -static void sub_814ACCC(u8 arg0); -static void sub_814AD50(u8 taskId); -static void sub_8149D34(struct PokemonJump2 *); -static void sub_814AF74(struct Sprite *sprite); -static void sub_814B038(struct Sprite *sprite); -static void sub_814B100(struct Sprite *sprite); -static void sub_814B1CC(struct Sprite *sprite); +static void InitJumpMonInfo(struct PokemonJump_MonInfo *monInfo, struct Pokemon *mon); +static void CB2_PokemonJump(void); +static void Task_StartPokemonJump(u8 taskId); +static void Task_PokemonJump_Leader(u8 taskId); +static void SendLinkData_Leader(void); +static void Task_PokemonJump_Member(u8 taskId); +static void SendLinkData_Member(void); +static bool32 GameIntro_Leader(void); +static bool32 WaitRound_Leader(void); +static bool32 GameRound_Leader(void); +static bool32 GameOver_Leader(void); +static bool32 GameOver_Member(void); +static bool32 AskPlayAgain_Leader(void); +static bool32 AskPlayAgain_Member(void); +static bool32 ResetGame_Leader(void); +static bool32 ResetGame_Member(void); +static bool32 ExitGame(void); +static bool32 GivePrize_Leader(void); +static bool32 GivePrize_Member(void); +static bool32 SavePokeJump(void); +static bool32 DoGameIntro(void); +static bool32 HandleSwingRound(void); +static bool32 DoVineHitEffect(void); +static bool32 GameIntro_Member(void); +static bool32 WaitRound_Member(void); +static bool32 GameRound_Member(void); +static bool32 TryGivePrize(void); +static bool32 DoPlayAgainPrompt(void); +static bool32 ClosePokeJumpLink(void); +static bool32 CloseMessageAndResetScore(void); +static void Task_CommunicateMonInfo(u8 taskId); +static void SetTaskWithPokeJumpStruct(TaskFunc func, u8 taskPriority); +static void InitVineState(void); +static void ResetVineState(void); +static void UpdateVineState(void); +static int GetVineSpeed(void); +static void UpdateVineSpeed(void); +static int PokeJumpRandom(void); +static void ResetVineAfterHit(void); +static void ResetPlayersJumpStates(void); +static void ResetPlayersMonState(void); +static bool32 IsPlayersMonState(u16); +static void SetMonStateJump(void); +static void UpdateGame(void); +static void TryUpdateVineSwing(void); +static void DisallowVineUpdates(void); +static void AllowVineUpdates(void); +static void HandleMonState(void); +static void UpdateJump(int); +static void TryUpdateScore(void); +static bool32 UpdateVineHitStates(void); +static bool32 AllPlayersJumpedOrHit(void); +static bool32 DidAllPlayersClearVine(void); +static bool32 ShouldPlayAgain(void); +static void AddJumpScore(int); +static int GetPlayersAtJumpPeak(void); +static bool32 AreLinkQueuesEmpty(void); +static int GetNumPlayersForBonus(u8 *); +static void ClearUnreadField(void); +static int GetScoreBonus(int); +static void TryUpdateExcellentsRecord(u16); +static bool32 HasEnoughScoreForPrize(void); +static u16 GetPrizeData(void); +static void UnpackPrizeData(u16, u16 *, u16 *); +static u16 GetPrizeItemId(void); +static u16 GetPrizeQuantity(void); +static u16 GetQuantityLimitedByBag(u16 item, u16 quantity); +static void SetUpPokeJumpGfxFunc(void (*func)(void)); +static void Task_RunPokeJumpGfxFunc(u8 taskId); +static void LoadPokeJumpGfx(void); +static void PrintPlayerNamesNoHighlight(void); +static void PrintPlayerNamesWithHighlight(void); +static void ErasePlayerNames(void); +static void Msg_WantToPlayAgain(void); +static void Msg_SavingDontTurnOff(void); +static void EraseMessage(void); +static void Msg_SomeoneDroppedOut(void); +static void Msg_CommunicationStandby(void); +static void DoPokeJumpCountdown(void); +static u32 AddMessageWindow(u32 left, u32 top, u32 width, u32 height); +static void CreatePokeJumpYesNoMenu(u16 left, u16 top, u8 cursorPos); +static void PrintScoreSuffixes(void); +static void CreateJumpMonSprites(void); +static void InitDigitPrinters(void); +static void AddPlayerNameWindows(void); +static void PrintPokeJumpPlayerNames(bool32); +static void DrawPlayerNameWindows(void); +static void ShowBonus(u8); +static void Task_UpdateBonus(u8 taskId); +static void InitPokeJumpGfx(struct PokemonJumpGfx *); +static void SpriteCB_Star(struct Sprite *sprite); +static void SpriteCB_MonHitShake(struct Sprite *sprite); +static void SpriteCB_MonHitFlash(struct Sprite *sprite); +static void SpriteCB_MonIntroBounce(struct Sprite *sprite); static void Task_ShowPokemonJumpRecords(u8 taskId); static void TruncateToFirstWordOnly(u8 *str); -static void sub_814B5C4(u16 windowId); -void sub_814A95C(int id); -void sub_8149CEC(struct PokemonJump2 *); -void sub_8149D24(void); -void sub_8149D40(int); -bool32 sub_8149D68(void); -void sub_814A3E4(void); -bool32 sub_814A408(void); -void sub_814A468(u16 itemId, u16 quantity); -void sub_814A53C(u16 itemId); -void sub_814A5B4(u16 itemId); -bool32 sub_814A62C(void); -void sub_814A6CC(void); -void sub_814A940(u32 id, s16 y); -void sub_814AA48(u8 multiplayerId); -bool32 sub_814A6FC(void); -void sub_814AA24(int); -s8 sub_814A744(void); -int sub_814A98C(u8 flags); -void sub_814AA34(u16); -void sub_814AA60(u8 multiplayerId); -int sub_814AA78(int multiplayerId); -void sub_814AA8C(void); -void sub_814AAA0(void); -void sub_814AAB4(int); -int sub_814AAC8(void); -void sub_8149A6C(struct PokemonJump1_MonInfo *arg0); -bool32 sub_8149A90(int multiplayerId, struct PokemonJump1_MonInfo *arg0); -void sub_8149AF8(struct PokemonJump1_82E4 *arg0, struct PokemonJump1Sub *arg1); -bool32 sub_8149B7C(struct PokemonJump1_82E4 *arg0, struct PokemonJump1Sub *arg1); -void sub_8149BF4(struct PokemonJump1_82E4 *arg0, u8 arg1, u16 arg2); -bool32 sub_8149C24(struct PokemonJump1_82E4 *arg0, int multiplayerId, u8 *arg2, u16 *arg3); -bool32 sub_8149C90(struct PokemonJump1_82E4 *arg0, int multiplayerId); -bool32 sub_814B494(u32 jumpScore, u16 jumpsInRow, u16 excellentsInRow); -void sub_814B4E8(void); -void sub_814AD6C(struct PokemonJump2 *); -void sub_814B294(struct PokemonJump2 *); -void sub_814B43C(struct PokemonJump2 *); -bool32 sub_814B460(void); -void sub_814B348(struct PokemonJump2 *, int); -void sub_814AF0C(struct PokemonJump2 *, int); -void sub_814ADCC(struct PokemonJump2 *, struct PokemonJump1_MonInfo *,s16, s16, u8); -void sub_814B240(struct PokemonJump2 *,s16, s16, u8); -void sub_814AFE8(struct PokemonJump2 *, int multiplayerId); -void sub_814B080(struct PokemonJump2 *, int multiplayerId); -bool32 sub_814B010(struct PokemonJump2 *, int multiplayerId); -void sub_814B0A8(struct PokemonJump2 *); -void sub_814B134(struct PokemonJump2 *); -void sub_814B168(struct PokemonJump2 *, int multiplayerId); -bool32 sub_814B190(struct PokemonJump2 *); - -EWRAM_DATA static struct PokemonJump1 *gUnknown_203F3D4 = NULL; -EWRAM_DATA static struct PokemonJump2 *gUnknown_203F3D8 = NULL; - -static const u16 gUnknown_846AFE8[] = INCBIN_U16("graphics/misc/unk_846B008.gbapal"); -static const u32 gUnknown_846B008[] = INCBIN_U32("graphics/misc/unk_846B008.4bpp.lz"); - -static const struct CompressedSpriteSheet gUnknown_846B42C[] = { - {gUnknown_846B008, 0x0C00, 0x2000}, +static void PrintRecordsText(u16 windowId); +static void UpdateVineSwing(int id); +static void StartPokeJumpGfx(struct PokemonJumpGfx *); +static void FreeWindowsAndDigitObj(void); +static void SetUpPokeJumpGfxFuncById(int); +static bool32 IsPokeJumpGfxFuncFinished(void); +static void SetUpResetVineGfx(void); +static bool32 ResetVineGfx(void); +static void PrintPrizeMessage(u16, u16); +static void PrintPrizeFilledBagMessage(u16); +static void PrintNoRoomForPrizeMessage(u16); +static bool32 DoPrizeMessageAndFanfare(void); +static void ClearMessageWindow(void); +static void SetMonSpriteY(u32 , s16); +static void StartMonHitShake(u8); +static bool32 RemoveMessageWindow(void); +static void PrintScore(int); +static s8 HandlePlayAgainInput(void); +static int DoSameJumpTimeBonus(u8); +static void PrintJumpsInRow(u16); +static void StartMonHitFlash(u8); +static int IsMonHitShakeActive(int); +static void StopMonHitFlash(void); +static void ResetMonSpriteSubpriorities(void); +static void StartMonIntroBounce(int); +static int IsMonIntroBounceActive(void); +static void SendPacket_MonInfo(struct PokemonJump_MonInfo *); +static bool32 RecvPacket_MonInfo(int multiplayerId, struct PokemonJump_MonInfo *); +static void SendPacket_LeaderState(struct PokemonJump_Player *, struct PokemonJump_CommData *); +static bool32 RecvPacket_LeaderState(struct PokemonJump_Player *, struct PokemonJump_CommData *); +static void SendPacket_MemberState(struct PokemonJump_Player *, u8, u16); +static bool32 RecvPacket_MemberStateToLeader(struct PokemonJump_Player *, int, u8 *, u16 *); +static bool32 RecvPacket_MemberStateToMember(struct PokemonJump_Player *, int); +static bool32 TryUpdateRecords(u32, u16, u16); +static void IncrementGamesWithMaxPlayers(void); +static void LoadSpriteSheetsAndPalettes(struct PokemonJumpGfx *); +static void CreateVineSprites(struct PokemonJumpGfx *); +static void StartPokeJumpCountdown(struct PokemonJumpGfx *); +static bool32 IsPokeJumpCountdownRunning(void); +static void UpdateVineAnim(struct PokemonJumpGfx *, int); +static void DoStarAnim(struct PokemonJumpGfx *, int); +static void CreateJumpMonSprite(struct PokemonJumpGfx *, struct PokemonJump_MonInfo *,s16, s16, u8); +static void CreateStarSprite(struct PokemonJumpGfx *,s16, s16, u8); +static void Gfx_StartMonHitShake(struct PokemonJumpGfx *, int); +static void Gfx_StartMonHitFlash(struct PokemonJumpGfx *, int); +static bool32 Gfx_IsMonHitShakeActive(struct PokemonJumpGfx *, int); +static void Gfx_StopMonHitFlash(struct PokemonJumpGfx *); +static void Gfx_ResetMonSpriteSubpriorities(struct PokemonJumpGfx *); +static void Gfx_StartMonIntroBounce(struct PokemonJumpGfx *, int); +static bool32 Gfx_IsMonIntroBounceActive(struct PokemonJumpGfx *); + +EWRAM_DATA static struct PokemonJump *sPokemonJump = NULL; +EWRAM_DATA static struct PokemonJumpGfx *sPokemonJumpGfx = NULL; + +// Unused static version of the wireless minigame countdown + +#define TAG_STATIC_COUNTDOWN 0x2000 + +enum { + STATE_IDLE = 1, + STATE_START, + STATE_RUN, + STATE_END, +}; + +enum { + FUNC_INIT, + FUNC_FREE, + FUNC_START, + FUNC_RUN, +}; + +enum { + ANIM_THREE, + ANIM_TWO, + ANIM_ONE, + ANIM_START_LEFT, + ANIM_START_MID, + ANIM_START_RIGHT, +}; + +static const u16 s321Start_Static_Pal[] = INCBIN_U16("graphics/link/321start.gbapal"); +static const u32 s321Start_Static_Gfx[] = INCBIN_U32("graphics/link/321start.4bpp.lz"); + +static const struct CompressedSpriteSheet sSpriteSheet_321Start_Static[] = { + {s321Start_Static_Gfx, 0xC00, TAG_STATIC_COUNTDOWN}, {} }; -static const struct SpritePalette gUnknown_846B43C[] = { - {gUnknown_846AFE8, 0x2000}, +static const struct SpritePalette sSpritePalette_321Start_Static[] = { + {s321Start_Static_Pal, TAG_STATIC_COUNTDOWN}, {} }; -static const union AnimCmd gUnknown_846B44C[] = { - ANIMCMD_FRAME(0x00, 0), +static const union AnimCmd sAnim_StaticCountdown_Three[] = { + ANIMCMD_FRAME(0, 0), ANIMCMD_END }; -static const union AnimCmd gUnknown_846B454[] = { - ANIMCMD_FRAME(0x10, 0), +static const union AnimCmd sAnim_StaticCountdown_Two[] = { + ANIMCMD_FRAME(16, 0), ANIMCMD_END }; -static const union AnimCmd gUnknown_846B45C[] = { - ANIMCMD_FRAME(0x20, 0), +static const union AnimCmd sAnim_StaticCountdown_One[] = { + ANIMCMD_FRAME(32, 0), ANIMCMD_END }; -static const union AnimCmd gUnknown_846B464[] = { - ANIMCMD_FRAME(0x40, 0), +static const union AnimCmd sAnim_StaticCountdown_StartLeft[] = { + ANIMCMD_FRAME(64, 0), ANIMCMD_END }; -static const union AnimCmd gUnknown_846B46C[] = { - ANIMCMD_FRAME(0x30, 0), +static const union AnimCmd sAnim_StaticCountdown_StartMid[] = { + ANIMCMD_FRAME(48, 0), ANIMCMD_END }; -static const union AnimCmd gUnknown_846B474[] = { - ANIMCMD_FRAME(0x50, 0), +static const union AnimCmd sAnim_StaticCountdown_StartRight[] = { + ANIMCMD_FRAME(80, 0), ANIMCMD_END }; -static const union AnimCmd *const gUnknown_846B47C[] = { - gUnknown_846B44C, - gUnknown_846B454, - gUnknown_846B45C, - gUnknown_846B464, - gUnknown_846B46C, - gUnknown_846B474 +static const union AnimCmd *const sAnims_StaticCountdown[] = { + [ANIM_THREE] = sAnim_StaticCountdown_Three, + [ANIM_TWO] = sAnim_StaticCountdown_Two, + [ANIM_ONE] = sAnim_StaticCountdown_One, + [ANIM_START_LEFT] = sAnim_StaticCountdown_StartLeft, + [ANIM_START_MID] = sAnim_StaticCountdown_StartMid, + [ANIM_START_RIGHT] = sAnim_StaticCountdown_StartRight }; -static const struct SpriteTemplate gUnknown_846B494[] = { +static const struct SpriteTemplate sSpriteTemplate_StaticCountdown[] = { { - .tileTag = 0x2000, - .paletteTag = 0x2000, + .tileTag = TAG_STATIC_COUNTDOWN, + .paletteTag = TAG_STATIC_COUNTDOWN, .oam = &gOamData_AffineOff_ObjNormal_32x32, - .anims = gUnknown_846B47C, + .anims = sAnims_StaticCountdown, .affineAnims = gDummySpriteAffineAnimTable, .callback = SpriteCallbackDummy }, }; -static const TaskFunc gUnknown_846B4AC[][4] = { - { sub_81477C0, sub_814784C, sub_81479D4, sub_8147A34 } -}; - -/* - According to the clerk, the Pokémon allowed in - Pokémon Jump are all <= 28 inches, and do not - only swim, burrow, or fly. -*/ -static const struct PokemonJumpMons +static const TaskFunc sStaticCountdownFuncs[][4] = { - u16 species; - u16 unk2; -} sPkmnJumpSpecies[] = -{ - { .species = SPECIES_BULBASAUR, .unk2 = 2, }, - { .species = SPECIES_CHARMANDER, .unk2 = 1, }, - { .species = SPECIES_SQUIRTLE, .unk2 = 0, }, - { .species = SPECIES_CATERPIE, .unk2 = 1, }, - { .species = SPECIES_METAPOD, .unk2 = 1, }, - { .species = SPECIES_WEEDLE, .unk2 = 1, }, - { .species = SPECIES_KAKUNA, .unk2 = 1, }, - { .species = SPECIES_RATTATA, .unk2 = 1, }, - { .species = SPECIES_RATICATE, .unk2 = 1, }, - { .species = SPECIES_PIKACHU, .unk2 = 0, }, - { .species = SPECIES_SANDSHREW, .unk2 = 0, }, - { .species = SPECIES_NIDORAN_F, .unk2 = 0, }, - { .species = SPECIES_NIDORAN_M, .unk2 = 0, }, - { .species = SPECIES_CLEFAIRY, .unk2 = 0, }, - { .species = SPECIES_VULPIX, .unk2 = 0, }, - { .species = SPECIES_JIGGLYPUFF, .unk2 = 2, }, - { .species = SPECIES_ODDISH, .unk2 = 2, }, - { .species = SPECIES_PARAS, .unk2 = 1, }, - { .species = SPECIES_MEOWTH, .unk2 = 0, }, - { .species = SPECIES_PSYDUCK, .unk2 = 2, }, - { .species = SPECIES_MANKEY, .unk2 = 1, }, - { .species = SPECIES_GROWLITHE, .unk2 = 1, }, - { .species = SPECIES_POLIWAG, .unk2 = 2, }, - { .species = SPECIES_BELLSPROUT, .unk2 = 2, }, - { .species = SPECIES_SHELLDER, .unk2 = 1, }, - { .species = SPECIES_KRABBY, .unk2 = 1, }, - { .species = SPECIES_EXEGGCUTE, .unk2 = 2, }, - { .species = SPECIES_CUBONE, .unk2 = 0, }, - { .species = SPECIES_DITTO, .unk2 = 2, }, - { .species = SPECIES_EEVEE, .unk2 = 0, }, - { .species = SPECIES_OMANYTE, .unk2 = 1, }, - { .species = SPECIES_KABUTO, .unk2 = 1, }, - { .species = SPECIES_CHIKORITA, .unk2 = 2, }, - { .species = SPECIES_CYNDAQUIL, .unk2 = 1, }, - { .species = SPECIES_TOTODILE, .unk2 = 0, }, - { .species = SPECIES_SPINARAK, .unk2 = 1, }, - { .species = SPECIES_PICHU, .unk2 = 0, }, - { .species = SPECIES_CLEFFA, .unk2 = 0, }, - { .species = SPECIES_IGGLYBUFF, .unk2 = 2, }, - { .species = SPECIES_TOGEPI, .unk2 = 2, }, - { .species = SPECIES_MAREEP, .unk2 = 0, }, - { .species = SPECIES_BELLOSSOM, .unk2 = 2, }, - { .species = SPECIES_MARILL, .unk2 = 2, }, - { .species = SPECIES_SUNKERN, .unk2 = 2, }, - { .species = SPECIES_WOOPER, .unk2 = 2, }, - { .species = SPECIES_PINECO, .unk2 = 2, }, - { .species = SPECIES_SNUBBULL, .unk2 = 0, }, - { .species = SPECIES_SHUCKLE, .unk2 = 2, }, - { .species = SPECIES_TEDDIURSA, .unk2 = 0, }, - { .species = SPECIES_SLUGMA, .unk2 = 2, }, - { .species = SPECIES_SWINUB, .unk2 = 0, }, - { .species = SPECIES_HOUNDOUR, .unk2 = 1, }, - { .species = SPECIES_PHANPY, .unk2 = 0, }, - { .species = SPECIES_PORYGON2, .unk2 = 0, }, - { .species = SPECIES_TYROGUE, .unk2 = 1, }, - { .species = SPECIES_SMOOCHUM, .unk2 = 2, }, - { .species = SPECIES_ELEKID, .unk2 = 1, }, - { .species = SPECIES_MAGBY, .unk2 = 1, }, - { .species = SPECIES_LARVITAR, .unk2 = 1, }, - { .species = SPECIES_TREECKO, .unk2 = 1, }, - { .species = SPECIES_TORCHIC, .unk2 = 2, }, - { .species = SPECIES_MUDKIP, .unk2 = 0, }, - { .species = SPECIES_MARSHTOMP, .unk2 = 0, }, - { .species = SPECIES_POOCHYENA, .unk2 = 1, }, - { .species = SPECIES_ZIGZAGOON, .unk2 = 0, }, - { .species = SPECIES_LINOONE, .unk2 = 0, }, - { .species = SPECIES_WURMPLE, .unk2 = 1, }, - { .species = SPECIES_SILCOON, .unk2 = 2, }, - { .species = SPECIES_CASCOON, .unk2 = 2, }, - { .species = SPECIES_LOTAD, .unk2 = 2, }, - { .species = SPECIES_SEEDOT, .unk2 = 1, }, - { .species = SPECIES_RALTS, .unk2 = 0, }, - { .species = SPECIES_KIRLIA, .unk2 = 0, }, - { .species = SPECIES_SURSKIT, .unk2 = 2, }, - { .species = SPECIES_SHROOMISH, .unk2 = 2, }, - { .species = SPECIES_NINCADA, .unk2 = 1, }, - { .species = SPECIES_WHISMUR, .unk2 = 0, }, - { .species = SPECIES_AZURILL, .unk2 = 2, }, - { .species = SPECIES_SKITTY, .unk2 = 0, }, - { .species = SPECIES_SABLEYE, .unk2 = 0, }, - { .species = SPECIES_MAWILE, .unk2 = 0, }, - { .species = SPECIES_ARON, .unk2 = 1, }, - { .species = SPECIES_MEDITITE, .unk2 = 2, }, - { .species = SPECIES_ELECTRIKE, .unk2 = 1, }, - { .species = SPECIES_PLUSLE, .unk2 = 1, }, - { .species = SPECIES_MINUN, .unk2 = 1, }, - { .species = SPECIES_VOLBEAT, .unk2 = 0, }, - { .species = SPECIES_ILLUMISE, .unk2 = 0, }, - { .species = SPECIES_ROSELIA, .unk2 = 2, }, - { .species = SPECIES_GULPIN, .unk2 = 2, }, - { .species = SPECIES_NUMEL, .unk2 = 2, }, - { .species = SPECIES_TORKOAL, .unk2 = 2, }, - { .species = SPECIES_SPOINK, .unk2 = 0, }, - { .species = SPECIES_TRAPINCH, .unk2 = 2, }, - { .species = SPECIES_CACNEA, .unk2 = 2, }, - { .species = SPECIES_ANORITH, .unk2 = 1, }, - { .species = SPECIES_WYNAUT, .unk2 = 0, }, - { .species = SPECIES_SNORUNT, .unk2 = 0, }, - { .species = SPECIES_CLAMPERL, .unk2 = 1, }, - { .species = SPECIES_BAGON, .unk2 = 1, }, -}; - -static bool32 (* const gUnknown_846B64C[])(void) = -{ - sub_8148344, - sub_81483D0, - sub_8148464, - sub_81484D0, - sub_81485C8, - sub_81486C4, - sub_8148760, - sub_81487B4, - sub_814881C, -}; - - -static bool32 (* const gUnknown_846B670[])(void) = -{ - sub_8148398, - sub_8148418, - sub_81484B0, - sub_814856C, - sub_8148664, - sub_8148724, - sub_8148760, - sub_8148800, - sub_814881C, + { + [FUNC_INIT] = Task_StaticCountdown_Init, + [FUNC_FREE] = Task_StaticCountdown_Free, + [FUNC_START] = Task_StaticCountdown_Start, + [FUNC_RUN] = Task_StaticCountdown_Run + }, }; -// Unused, but looks like it was intended to be a hook -UNUSED u8 sub_81475C0(u8 data1, u8 priority) -{ - u8 taskId; - struct Task * task; - - taskId = CreateTask(sub_8147654, priority); - task = &gTasks[taskId]; - task->data[0] = 1; - task->data[1] = data1; - gUnknown_846B4AC[data1][0](taskId); +#define tState data[0] +#define tFuncSetId data[1] // These 4 data elements are indexes into +#define tSpriteTemplateId data[2] // arrays that only have 1 element with +#define tSpriteSheetId data[3] // data. As such their only legal value +#define tSpritePalId data[4] // is 0. Unclear why they were used. +#define tInterval data[5] +#define tPriority data[6] +#define tSubpriority data[7] +#define tNumSprites data[8] +#define tX data[9] +#define tY data[10] +#define tPrevTime data[10] // Re-used +#define tTimer data[11] +#define tLinkTimer data[12] +// 13-15 hold sprite ids +// tSpriteIds(0) is used for the number sprites, and the leftmost part of 'Start' +// tSpriteIds(1) is used for the middle part of 'Start' +// tSpriteIds(2) is used for for the rightmost part of 'Start' +#define tSpriteIds(i) data[13 + i] + +#define sInterval data[1] // Never read +#define sAnimNum data[2] +#define sTaskId data[3] +#define sId data[4] // Never read +#define sNumberSpriteId data[5] // Never read + +// Unused +static u8 CreateStaticCountdownTask(u8 funcSetId, u8 taskPriority) +{ + u8 taskId = CreateTask(Task_StaticCountdown, taskPriority); + struct Task *task = &gTasks[taskId]; + + task->tState = STATE_IDLE; + task->tFuncSetId = funcSetId; + sStaticCountdownFuncs[funcSetId][FUNC_INIT](taskId); return taskId; } -// Unused, but looks like it was intended to be a hook -UNUSED bool32 sub_814760C(void) +// Unused +static bool32 StartStaticCountdown(void) { - u8 taskId; - - taskId = FindTaskIdByFunc(sub_8147654); - if (taskId == 0xFF) + u8 taskId = FindTaskIdByFunc(Task_StaticCountdown); + if (taskId == TASK_NONE) return FALSE; - gTasks[taskId].data[0] = 2; + + gTasks[taskId].tState = STATE_START; return TRUE; } -// Unused, but looks like it was intended to be a hook -UNUSED bool32 sub_8147640(void) +// Unused +static bool32 IsStaticCountdownRunning(void) { - return FuncIsActiveTask(sub_8147654); + return FuncIsActiveTask(Task_StaticCountdown); } -static void sub_8147654(u8 taskId) +static void Task_StaticCountdown(u8 taskId) { s16 *data = gTasks[taskId].data; - switch (data[0]) + switch (tState) { - case 2: - gUnknown_846B4AC[data[1]][2](taskId); - data[0] = 3; + // STATE_IDLE does nothing; wait until started + case STATE_START: + sStaticCountdownFuncs[tFuncSetId][FUNC_START](taskId); + tState = STATE_RUN; break; - case 3: - gUnknown_846B4AC[data[1]][3](taskId); + case STATE_RUN: + sStaticCountdownFuncs[tFuncSetId][FUNC_RUN](taskId); break; - case 4: - gUnknown_846B4AC[data[1]][1](taskId); + case STATE_END: + sStaticCountdownFuncs[tFuncSetId][FUNC_FREE](taskId); DestroyTask(taskId); break; } } -static void sub_81476E0(u8 taskId, s16 *data) +static void StaticCountdown_CreateSprites(u8 taskId, s16 *data) { u8 i; struct Sprite *sprite; - LoadCompressedSpriteSheet(&gUnknown_846B42C[data[3]]); - LoadSpritePalette(&gUnknown_846B43C[data[4]]); - for (i = 0; i < data[8]; i++) - data[13 + i] = CreateSprite(&gUnknown_846B494[data[2]], data[9], data[10], data[7]); - for (i = 0; i < data[8]; i++) + LoadCompressedSpriteSheet(&sSpriteSheet_321Start_Static[tSpriteSheetId]); + LoadSpritePalette(&sSpritePalette_321Start_Static[tSpritePalId]); + for (i = 0; i < tNumSprites; i++) + tSpriteIds(i) = CreateSprite(&sSpriteTemplate_StaticCountdown[tSpriteTemplateId], tX, tY, tSubpriority); + for (i = 0; i < tNumSprites; i++) { - sprite = &gSprites[data[13 + i]]; - sprite->oam.priority = data[6]; + sprite = &gSprites[tSpriteIds(i)]; + sprite->oam.priority = tPriority; sprite->invisible = TRUE; - sprite->data[1] = data[5]; - sprite->data[3] = taskId; - sprite->data[4] = i; - sprite->data[5] = data[13]; + sprite->sInterval = tInterval; + sprite->sTaskId = taskId; + sprite->sId = i; + sprite->sNumberSpriteId = tSpriteIds(0); } } -static void sub_81477C0(u8 taskId) +static void Task_StaticCountdown_Init(u8 taskId) { s16 *data = gTasks[taskId].data; - data[2] = 0; - data[3] = 0; - data[4] = 0; - data[5] = 60; - data[6] = 0; - data[7] = 0; - data[8] = 3; - data[9] = 120; - data[10] = 88; - sub_81476E0(taskId, data); + tSpriteTemplateId = 0; + tSpriteSheetId = 0; + tSpritePalId = 0; + tInterval = 60; + tPriority = 0; + tSubpriority = 0; + tNumSprites = 3; + tX = 120; + tY = 88; + StaticCountdown_CreateSprites(taskId, data); - StartSpriteAnim(&gSprites[data[14]], 4); - gSprites[data[14]].x2 = -32; + StartSpriteAnim(&gSprites[tSpriteIds(1)], ANIM_START_MID); + gSprites[tSpriteIds(1)].x2 = -32; - StartSpriteAnim(&gSprites[data[15]], 5); - gSprites[data[15]].x2 = 32; + StartSpriteAnim(&gSprites[tSpriteIds(2)], ANIM_START_RIGHT); + gSprites[tSpriteIds(2)].x2 = 32; } -static void sub_814784C(u8 taskId) +static void Task_StaticCountdown_Free(u8 taskId) { u8 i = 0; s16 *data = gTasks[taskId].data; - for (i = 0; i < data[8]; i++) - DestroySprite(&gSprites[data[13 + i]]); - FreeSpriteTilesByTag(gUnknown_846B42C[data[3]].tag); - FreeSpritePaletteByTag(gUnknown_846B43C[data[4]].tag); + for (i = 0; i < tNumSprites; i++) + DestroySprite(&gSprites[tSpriteIds(i)]); + FreeSpriteTilesByTag(sSpriteSheet_321Start_Static[tSpriteSheetId].tag); + FreeSpritePaletteByTag(sSpritePalette_321Start_Static[tSpritePalId].tag); } -static void sub_81478BC(struct Sprite *sprite) +static void SpriteCB_StaticCountdown(struct Sprite *sprite) { - s16 *data = gTasks[sprite->data[3]].data; + s16 *data = gTasks[sprite->sTaskId].data; - if (data[11] % data[5] != 0) + if (tTimer % tInterval != 0) return; - if (data[11] == data[10]) + if (tTimer == tPrevTime) return; - data[10] = data[11]; - switch (sprite->data[2]) + tPrevTime = tTimer; + switch (sprite->sAnimNum) { - case 0: + case ANIM_THREE: sprite->invisible = FALSE; - case 1: - case 2: + case ANIM_TWO: + case ANIM_ONE: + // Set sprite to a number PlaySE(SE_BALL_BOUNCE_1); - StartSpriteAnim(sprite, sprite->data[2]); + StartSpriteAnim(sprite, sprite->sAnimNum); break; - case 3: + case ANIM_START_LEFT: + // Set sprite to 'Start' PlaySE(SE_PIN); - StartSpriteAnim(sprite, sprite->data[2]); - gSprites[data[14]].invisible = FALSE; - gSprites[data[15]].invisible = FALSE; + StartSpriteAnim(sprite, sprite->sAnimNum); + gSprites[tSpriteIds(1)].invisible = FALSE; + gSprites[tSpriteIds(2)].invisible = FALSE; break; - case 4: + case ANIM_START_LEFT + 1: // End + // Hide countdown sprite->invisible = TRUE; - gSprites[data[14]].invisible = TRUE; - gSprites[data[15]].invisible = TRUE; - data[0] = 4; + gSprites[tSpriteIds(1)].invisible = TRUE; + gSprites[tSpriteIds(2)].invisible = TRUE; + tState = STATE_END; return; } - sprite->data[2]++; + sprite->sAnimNum++; } -static void sub_81479D4(u8 taskId) +static void Task_StaticCountdown_Start(u8 taskId) { s16 *data = gTasks[taskId].data; PlaySE(SE_BALL_BOUNCE_1); - gSprites[data[13]].callback = sub_81478BC; - gSprites[data[13]].invisible = FALSE; - gTasks[taskId].data[0] = 3; + gSprites[tSpriteIds(0)].callback = SpriteCB_StaticCountdown; + gSprites[tSpriteIds(0)].invisible = FALSE; + gTasks[taskId].tState = STATE_RUN; } -static void sub_8147A34(u8 taskId) +// Increment timer for progressing the countdown. +// If the player is the link leader, increment a +// separate timer and send it to group members for +// them to read and use. +static void Task_StaticCountdown_Run(u8 taskId) { - u16 packet[6]; + u16 packet[RFU_PACKET_SIZE]; s16 *data = gTasks[taskId].data; - if (gReceivedRemoteLinkPlayers) + if (gReceivedRemoteLinkPlayers != 0) { - if (gRecvCmds[0][1] == 0x7FFF) - data[11] = gRecvCmds[0][2]; + // Read link timer + if (gRecvCmds[0][1] == LINKCMD_COUNTDOWN) + tTimer = gRecvCmds[0][2]; + if (GetMultiplayerId() == 0) { - data[12]++; + // Player is link leader. + // Send timer to group members + tLinkTimer++; memset(packet, 0, sizeof(packet)); - packet[0] = 0x7FFF; - packet[1] = data[12]; + packet[0] = LINKCMD_COUNTDOWN; + packet[1] = tLinkTimer; Rfu_SendPacket(packet); } } else { - data[11]++; + // Local, just increment own timer + tTimer++; } } -void StartPokemonJump(u16 partyIndex, MainCallback callback) +#undef tState +#undef tFuncSetId +#undef tSpriteTemplateId +#undef tSpriteSheetId +#undef tSpritePalId +#undef tInterval +#undef tPriority +#undef tSubpriority +#undef tNumSprites +#undef tX +#undef tY +#undef tPrevTime +#undef tTimer +#undef tLinkTimer +#undef tSpriteIds +#undef sInterval +#undef sAnimNum +#undef sTaskId +#undef sId +#undef sNumberSpriteId + +/* + According to the clerk, the Pokémon allowed in + Pokémon Jump are all <= 28 inches, and do not + only swim, burrow, or fly. +*/ +static const struct PokemonJumpMons +{ + u16 species; + u16 jumpType; +} sPokeJumpMons[] = +{ + { .species = SPECIES_BULBASAUR, .jumpType = JUMP_TYPE_SLOW }, + { .species = SPECIES_CHARMANDER, .jumpType = JUMP_TYPE_FAST }, + { .species = SPECIES_SQUIRTLE, .jumpType = JUMP_TYPE_NORMAL }, + { .species = SPECIES_CATERPIE, .jumpType = JUMP_TYPE_FAST }, + { .species = SPECIES_METAPOD, .jumpType = JUMP_TYPE_FAST }, + { .species = SPECIES_WEEDLE, .jumpType = JUMP_TYPE_FAST }, + { .species = SPECIES_KAKUNA, .jumpType = JUMP_TYPE_FAST }, + { .species = SPECIES_RATTATA, .jumpType = JUMP_TYPE_FAST }, + { .species = SPECIES_RATICATE, .jumpType = JUMP_TYPE_FAST }, + { .species = SPECIES_PIKACHU, .jumpType = JUMP_TYPE_NORMAL }, + { .species = SPECIES_SANDSHREW, .jumpType = JUMP_TYPE_NORMAL }, + { .species = SPECIES_NIDORAN_F, .jumpType = JUMP_TYPE_NORMAL }, + { .species = SPECIES_NIDORAN_M, .jumpType = JUMP_TYPE_NORMAL }, + { .species = SPECIES_CLEFAIRY, .jumpType = JUMP_TYPE_NORMAL }, + { .species = SPECIES_VULPIX, .jumpType = JUMP_TYPE_NORMAL }, + { .species = SPECIES_JIGGLYPUFF, .jumpType = JUMP_TYPE_SLOW }, + { .species = SPECIES_ODDISH, .jumpType = JUMP_TYPE_SLOW }, + { .species = SPECIES_PARAS, .jumpType = JUMP_TYPE_FAST }, + { .species = SPECIES_MEOWTH, .jumpType = JUMP_TYPE_NORMAL }, + { .species = SPECIES_PSYDUCK, .jumpType = JUMP_TYPE_SLOW }, + { .species = SPECIES_MANKEY, .jumpType = JUMP_TYPE_FAST }, + { .species = SPECIES_GROWLITHE, .jumpType = JUMP_TYPE_FAST }, + { .species = SPECIES_POLIWAG, .jumpType = JUMP_TYPE_SLOW }, + { .species = SPECIES_BELLSPROUT, .jumpType = JUMP_TYPE_SLOW }, + { .species = SPECIES_SHELLDER, .jumpType = JUMP_TYPE_FAST }, + { .species = SPECIES_KRABBY, .jumpType = JUMP_TYPE_FAST }, + { .species = SPECIES_EXEGGCUTE, .jumpType = JUMP_TYPE_SLOW }, + { .species = SPECIES_CUBONE, .jumpType = JUMP_TYPE_NORMAL }, + { .species = SPECIES_DITTO, .jumpType = JUMP_TYPE_SLOW }, + { .species = SPECIES_EEVEE, .jumpType = JUMP_TYPE_NORMAL }, + { .species = SPECIES_OMANYTE, .jumpType = JUMP_TYPE_FAST }, + { .species = SPECIES_KABUTO, .jumpType = JUMP_TYPE_FAST }, + { .species = SPECIES_CHIKORITA, .jumpType = JUMP_TYPE_SLOW }, + { .species = SPECIES_CYNDAQUIL, .jumpType = JUMP_TYPE_FAST }, + { .species = SPECIES_TOTODILE, .jumpType = JUMP_TYPE_NORMAL }, + { .species = SPECIES_SPINARAK, .jumpType = JUMP_TYPE_FAST }, + { .species = SPECIES_PICHU, .jumpType = JUMP_TYPE_NORMAL }, + { .species = SPECIES_CLEFFA, .jumpType = JUMP_TYPE_NORMAL }, + { .species = SPECIES_IGGLYBUFF, .jumpType = JUMP_TYPE_SLOW }, + { .species = SPECIES_TOGEPI, .jumpType = JUMP_TYPE_SLOW }, + { .species = SPECIES_MAREEP, .jumpType = JUMP_TYPE_NORMAL }, + { .species = SPECIES_BELLOSSOM, .jumpType = JUMP_TYPE_SLOW }, + { .species = SPECIES_MARILL, .jumpType = JUMP_TYPE_SLOW }, + { .species = SPECIES_SUNKERN, .jumpType = JUMP_TYPE_SLOW }, + { .species = SPECIES_WOOPER, .jumpType = JUMP_TYPE_SLOW }, + { .species = SPECIES_PINECO, .jumpType = JUMP_TYPE_SLOW }, + { .species = SPECIES_SNUBBULL, .jumpType = JUMP_TYPE_NORMAL }, + { .species = SPECIES_SHUCKLE, .jumpType = JUMP_TYPE_SLOW }, + { .species = SPECIES_TEDDIURSA, .jumpType = JUMP_TYPE_NORMAL }, + { .species = SPECIES_SLUGMA, .jumpType = JUMP_TYPE_SLOW }, + { .species = SPECIES_SWINUB, .jumpType = JUMP_TYPE_NORMAL }, + { .species = SPECIES_HOUNDOUR, .jumpType = JUMP_TYPE_FAST }, + { .species = SPECIES_PHANPY, .jumpType = JUMP_TYPE_NORMAL }, + { .species = SPECIES_PORYGON2, .jumpType = JUMP_TYPE_NORMAL }, + { .species = SPECIES_TYROGUE, .jumpType = JUMP_TYPE_FAST }, + { .species = SPECIES_SMOOCHUM, .jumpType = JUMP_TYPE_SLOW }, + { .species = SPECIES_ELEKID, .jumpType = JUMP_TYPE_FAST }, + { .species = SPECIES_MAGBY, .jumpType = JUMP_TYPE_FAST }, + { .species = SPECIES_LARVITAR, .jumpType = JUMP_TYPE_FAST }, + { .species = SPECIES_TREECKO, .jumpType = JUMP_TYPE_FAST }, + { .species = SPECIES_TORCHIC, .jumpType = JUMP_TYPE_SLOW }, + { .species = SPECIES_MUDKIP, .jumpType = JUMP_TYPE_NORMAL }, + { .species = SPECIES_MARSHTOMP, .jumpType = JUMP_TYPE_NORMAL }, + { .species = SPECIES_POOCHYENA, .jumpType = JUMP_TYPE_FAST }, + { .species = SPECIES_ZIGZAGOON, .jumpType = JUMP_TYPE_NORMAL }, + { .species = SPECIES_LINOONE, .jumpType = JUMP_TYPE_NORMAL }, + { .species = SPECIES_WURMPLE, .jumpType = JUMP_TYPE_FAST }, + { .species = SPECIES_SILCOON, .jumpType = JUMP_TYPE_SLOW }, + { .species = SPECIES_CASCOON, .jumpType = JUMP_TYPE_SLOW }, + { .species = SPECIES_LOTAD, .jumpType = JUMP_TYPE_SLOW }, + { .species = SPECIES_SEEDOT, .jumpType = JUMP_TYPE_FAST }, + { .species = SPECIES_RALTS, .jumpType = JUMP_TYPE_NORMAL }, + { .species = SPECIES_KIRLIA, .jumpType = JUMP_TYPE_NORMAL }, + { .species = SPECIES_SURSKIT, .jumpType = JUMP_TYPE_SLOW }, + { .species = SPECIES_SHROOMISH, .jumpType = JUMP_TYPE_SLOW }, + { .species = SPECIES_NINCADA, .jumpType = JUMP_TYPE_FAST }, + { .species = SPECIES_WHISMUR, .jumpType = JUMP_TYPE_NORMAL }, + { .species = SPECIES_AZURILL, .jumpType = JUMP_TYPE_SLOW }, + { .species = SPECIES_SKITTY, .jumpType = JUMP_TYPE_NORMAL }, + { .species = SPECIES_SABLEYE, .jumpType = JUMP_TYPE_NORMAL }, + { .species = SPECIES_MAWILE, .jumpType = JUMP_TYPE_NORMAL }, + { .species = SPECIES_ARON, .jumpType = JUMP_TYPE_FAST }, + { .species = SPECIES_MEDITITE, .jumpType = JUMP_TYPE_SLOW }, + { .species = SPECIES_ELECTRIKE, .jumpType = JUMP_TYPE_FAST }, + { .species = SPECIES_PLUSLE, .jumpType = JUMP_TYPE_FAST }, + { .species = SPECIES_MINUN, .jumpType = JUMP_TYPE_FAST }, + { .species = SPECIES_VOLBEAT, .jumpType = JUMP_TYPE_NORMAL }, + { .species = SPECIES_ILLUMISE, .jumpType = JUMP_TYPE_NORMAL }, + { .species = SPECIES_ROSELIA, .jumpType = JUMP_TYPE_SLOW }, + { .species = SPECIES_GULPIN, .jumpType = JUMP_TYPE_SLOW }, + { .species = SPECIES_NUMEL, .jumpType = JUMP_TYPE_SLOW }, + { .species = SPECIES_TORKOAL, .jumpType = JUMP_TYPE_SLOW }, + { .species = SPECIES_SPOINK, .jumpType = JUMP_TYPE_NORMAL }, + { .species = SPECIES_TRAPINCH, .jumpType = JUMP_TYPE_SLOW }, + { .species = SPECIES_CACNEA, .jumpType = JUMP_TYPE_SLOW }, + { .species = SPECIES_ANORITH, .jumpType = JUMP_TYPE_FAST }, + { .species = SPECIES_WYNAUT, .jumpType = JUMP_TYPE_NORMAL }, + { .species = SPECIES_SNORUNT, .jumpType = JUMP_TYPE_NORMAL }, + { .species = SPECIES_CLAMPERL, .jumpType = JUMP_TYPE_FAST }, + { .species = SPECIES_BAGON, .jumpType = JUMP_TYPE_FAST }, +}; + +void StartPokemonJump(u16 partyId, MainCallback exitCallback) { u8 taskId; if (gReceivedRemoteLinkPlayers) { - gUnknown_203F3D4 = Alloc(sizeof(*gUnknown_203F3D4)); - if (gUnknown_203F3D4 != NULL) + sPokemonJump = Alloc(sizeof(*sPokemonJump)); + if (sPokemonJump) { ResetTasks(); - taskId = CreateTask(sub_8147DA0, 1); - gUnknown_203F3D4->unk8 = 0; - gUnknown_203F3D4->returnCallback = callback; - gUnknown_203F3D4->unk4 = taskId; - gUnknown_203F3D4->unk6 = GetMultiplayerId(); - sub_8147D2C(&gUnknown_203F3D4->unk82A8[gUnknown_203F3D4->unk6], &gPlayerParty[partyIndex]); - sub_8147B60(gUnknown_203F3D4); - SetWordTaskArg(taskId, 2, (uintptr_t)gUnknown_203F3D4); - SetMainCallback2(sub_8147D6C); + taskId = CreateTask(Task_StartPokemonJump, 1); + sPokemonJump->mainState = 0; + sPokemonJump->exitCallback = exitCallback; + sPokemonJump->taskId = taskId; + sPokemonJump->multiplayerId = GetMultiplayerId(); + InitJumpMonInfo(&sPokemonJump->monInfo[sPokemonJump->multiplayerId], &gPlayerParty[partyId]); + InitGame(sPokemonJump); + SetWordTaskArg(taskId, 2, (uintptr_t)sPokemonJump); + SetMainCallback2(CB2_PokemonJump); return; } } - SetMainCallback2(callback); + // Exit - Players not connected, or alloc failed + SetMainCallback2(exitCallback); } -static void sub_8147B48(void) +static void FreePokemonJump(void) { - sub_8149D24(); - Free(gUnknown_203F3D4); + FreeWindowsAndDigitObj(); + Free(sPokemonJump); } -static void sub_8147B60(struct PokemonJump1 *arg0) +static void InitGame(struct PokemonJump *jump) { - arg0->unk5 = GetLinkPlayerCount(); - arg0->unk70.unk0 = 5; - arg0->unk70.unk2 = 0; - sub_8147C20(); - sub_8147B94(arg0); - if (arg0->unk5 == MAX_RFU_PLAYERS) - sub_814B4E8(); + jump->numPlayers = GetLinkPlayerCount(); + jump->comm.funcId = FUNC_RESET_GAME; + jump->comm.data = 0; + InitPlayerAndJumpTypes(); + ResetForNewGame(jump); + if (jump->numPlayers == MAX_RFU_PLAYERS) + IncrementGamesWithMaxPlayers(); } -static void sub_8147B94(struct PokemonJump1 *arg0) +static void ResetForNewGame(struct PokemonJump *jump) { int i; - arg0->unk14 = 6; - arg0->unk18 = 6; - arg0->unk4A = 0; - arg0->unk1C = 0; - arg0->unk5C = 0; - arg0->isLeader = GetMultiplayerId() == 0; - arg0->unk8 = 0; - arg0->unkA = 0; - arg0->unkC = 0; - arg0->unkE = 0; - arg0->unk58 = 0; - arg0->unk3A = 0; - arg0->unk44 = 0; - arg0->unk54 = 0; - arg0->unk46 = 0; - arg0->unk49 = 0; - arg0->unk48 = 1; - arg0->unk70.unk8 = 0; - arg0->unk70.unk1 = 0; - arg0->unk70.unk4 = 0; - arg0->unk60 = 1; - arg0->unk4D = 0; - arg0->unk68 = 0; - arg0->unk64 = 0; - arg0->unk2C = 0; - arg0->unk30 = 0; - sub_8147C98(); - sub_81491E4(); + jump->vineState = VINE_UPSWING_LOWER; + jump->prevVineState = VINE_UPSWING_LOWER; + jump->vineTimer = 0; + jump->vineSpeed = 0; + jump->updateScore = FALSE; + jump->isLeader = GetMultiplayerId() == 0; + jump->mainState = 0; + jump->helperState = 0; + jump->excellentsInRow = 0; + jump->excellentsInRowRecord = 0; + jump->initScoreUpdate = FALSE; + jump->unused2 = 0; + jump->unused3 = 0; + jump->numPlayersAtPeak = 0; + jump->allowVineUpdates = FALSE; + jump->allPlayersReady = FALSE; + jump->funcActive = TRUE; + jump->comm.jumpScore = 0; + jump->comm.receivedBonusFlags = 0; + jump->comm.jumpsInRow = 0; + jump->unused4 = TRUE; + jump->showBonus = FALSE; + jump->skipJumpUpdate = FALSE; + jump->giveBonus = FALSE; + jump->linkTimer = 0; + jump->linkTimerLimit = 0; + ResetPlayersForNewGame(); + ResetPlayersJumpStates(); for (i = 0; i < MAX_RFU_PLAYERS; i++) { - arg0->unk7C[i] = 0; - arg0->unk9A[i] = 0; + jump->atJumpPeak[i] = FALSE; + jump->jumpTimeStarts[i] = 0; } } -static void sub_8147C20(void) +static void InitPlayerAndJumpTypes(void) { int i, index; for (i = 0; i < MAX_RFU_PLAYERS; i++) { - index = GetPokemonJumpSpeciesIdx(gUnknown_203F3D4->unk82A8[i].species); - gUnknown_203F3D4->unk82E4[i].unkC = sPkmnJumpSpecies[index].unk2; + index = GetPokemonJumpSpeciesIdx(sPokemonJump->monInfo[i].species); + sPokemonJump->players[i].monJumpType = sPokeJumpMons[index].jumpType; } - gUnknown_203F3D4->unk83AC = &gUnknown_203F3D4->unk82E4[gUnknown_203F3D4->unk6]; + sPokemonJump->player = &sPokemonJump->players[sPokemonJump->multiplayerId]; } -static void sub_8147C98(void) +static void ResetPlayersForNewGame(void) { int i; for (i = 0; i < MAX_RFU_PLAYERS; i++) { - gUnknown_203F3D4->unk82E4[i].unkE = 0; - gUnknown_203F3D4->unk82E4[i].unk10 = 0; - gUnknown_203F3D4->unk82E4[i].unk12 = 0; - gUnknown_203F3D4->unk82E4[i].unk0 = 0; - gUnknown_203F3D4->unk82E4[i].unk4 = 0x7FFFFFFF; - gUnknown_203F3D4->unk82E4[i].unk14 = 0; - gUnknown_203F3D4->unk8B[i] = 9; + sPokemonJump->players[i].jumpTimeStart = 0; + sPokemonJump->players[i].monState = MONSTATE_NORMAL; + sPokemonJump->players[i].prevMonState = MONSTATE_NORMAL; + sPokemonJump->players[i].jumpOffset = 0; + sPokemonJump->players[i].jumpOffsetIdx = INT_MAX; + sPokemonJump->players[i].jumpState = JUMPSTATE_NONE; + sPokemonJump->memberFuncIds[i] = FUNC_NONE; } } static s16 GetPokemonJumpSpeciesIdx(u16 species) { u32 i; - for (i = 0; i < NELEMS(sPkmnJumpSpecies); i++) + for (i = 0; i < ARRAY_COUNT(sPokeJumpMons); i++) { - if (sPkmnJumpSpecies[i].species == species) + if (sPokeJumpMons[i].species == species) return i; } return -1; // species isnt allowed } -static void sub_8147D2C(struct PokemonJump1_MonInfo *monInfo, struct Pokemon *mon) +static void InitJumpMonInfo(struct PokemonJump_MonInfo *monInfo, struct Pokemon *mon) { monInfo->species = GetMonData(mon, MON_DATA_SPECIES); monInfo->otId = GetMonData(mon, MON_DATA_OT_ID); monInfo->personality = GetMonData(mon, MON_DATA_PERSONALITY); } -static void sub_8147D58(void) +static void VBlankCB_PokemonJump(void) { TransferPlttBuffer(); LoadOam(); ProcessSpriteCopyRequests(); } -static void sub_8147D6C(void) +static void CB2_PokemonJump(void) { RunTasks(); AnimateSprites(); @@ -835,254 +1014,283 @@ static void sub_8147D6C(void) UpdatePaletteFade(); } -static void sub_8147D84(TaskFunc func) +static void SetPokeJumpTask(TaskFunc func) { - gUnknown_203F3D4->unk4 = CreateTask(func, 1); - gUnknown_203F3D4->unk8 = 0; + sPokemonJump->taskId = CreateTask(func, 1); + sPokemonJump->mainState = 0; } -static void sub_8147DA0(u8 taskId) +static void Task_StartPokemonJump(u8 taskId) { - switch (gUnknown_203F3D4->unk8) + switch (sPokemonJump->mainState) { case 0: SetVBlankCallback(NULL); ResetSpriteData(); FreeAllSpritePalettes(); - sub_8148F5C(sub_8148E80, 5); + SetTaskWithPokeJumpStruct(Task_CommunicateMonInfo, 5); FadeOutMapMusic(4); - gUnknown_203F3D4->unk8++; + sPokemonJump->mainState++; break; case 1: - if (!FuncIsActiveTask(sub_8148E80)) + if (!FuncIsActiveTask(Task_CommunicateMonInfo)) { - sub_8149CEC(&gUnknown_203F3D4->unkA4); + StartPokeJumpGfx(&sPokemonJump->jumpGfx); LoadWirelessStatusIndicatorSpriteGfx(); CreateWirelessStatusIndicatorSprite(0, 0); - gUnknown_203F3D4->unk8++; + sPokemonJump->mainState++; } break; case 2: - if (!sub_8149D68() && IsNotWaitingForBGMStop() == TRUE) + if (!IsPokeJumpGfxFuncFinished() && IsNotWaitingForBGMStop() == TRUE) { FadeOutAndPlayNewMapMusic(MUS_POKE_JUMP, 8); - gUnknown_203F3D4->unk8++; + sPokemonJump->mainState++; } break; case 3: if (IsLinkTaskFinished()) { - BlendPalettes(0xFFFFFFFF, 16, RGB_BLACK); - BeginNormalPaletteFade(0xFFFFFFFF, -1, 16, 0, RGB_BLACK); - SetVBlankCallback(sub_8147D58); - gUnknown_203F3D4->unk8++; + BlendPalettes(PALETTES_ALL, 16, RGB_BLACK); + BeginNormalPaletteFade(PALETTES_ALL, -1, 16, 0, RGB_BLACK); + SetVBlankCallback(VBlankCB_PokemonJump); + sPokemonJump->mainState++; } break; case 4: UpdatePaletteFade(); if (!gPaletteFade.active) { - gUnknown_203F3D4->unk7 = 0; - gUnknown_203F3D4->unk8++; + sPokemonJump->startDelayTimer = 0; + sPokemonJump->mainState++; } break; case 5: - gUnknown_203F3D4->unk7++; - if (gUnknown_203F3D4->unk7 >= 20) + sPokemonJump->startDelayTimer++; + if (sPokemonJump->startDelayTimer >= 20) { - if (gUnknown_203F3D4->isLeader) - sub_8147D84(sub_814807C); + if (sPokemonJump->isLeader) + SetPokeJumpTask(Task_PokemonJump_Leader); else - sub_8147D84(sub_8148290); + SetPokeJumpTask(Task_PokemonJump_Member); - sub_8148F7C(); + InitVineState(); DestroyTask(taskId); } break; } } -static void sub_8147F10(int arg0) +static void SetLinkTimeInterval(int intervalId) { - if (arg0 == 0) + if (intervalId == LINK_INTERVAL_NONE) { - gUnknown_203F3D4->unk30 = 0x1111; - gUnknown_203F3D4->unk2C = 1; + // Link data is sent when timer reaches 0. + // Set timer to 1 and set limit to special + // 'stopped' value so timer won't change + sPokemonJump->linkTimerLimit = LINK_TIMER_STOPPED; + sPokemonJump->linkTimer = 1; } else { - gUnknown_203F3D4->unk30 = (1 << (arg0 - 1)) - 1; - gUnknown_203F3D4->unk2C = 0; + sPokemonJump->linkTimerLimit = (1 << (intervalId - 1)) - 1; + sPokemonJump->linkTimer = 0; } } -static void sub_8147F4C(u8 arg0) +static void SetFunc_Leader(u8 funcId) { int i; - gUnknown_203F3D4->unk70.unk0 = arg0; - gUnknown_203F3D4->unk8 = 0; - gUnknown_203F3D4->unkA = 0; - gUnknown_203F3D4->unk48 = 1; - gUnknown_203F3D4->unk49 = 0; - for (i = 1; i < gUnknown_203F3D4->unk5; i++) - gUnknown_203F3D4->unk82E4[i].unk18 = 0; + sPokemonJump->comm.funcId = funcId; + sPokemonJump->mainState = 0; + sPokemonJump->helperState = 0; + sPokemonJump->funcActive = TRUE; + sPokemonJump->allPlayersReady = FALSE; + for (i = 1; i < sPokemonJump->numPlayers; i++) + sPokemonJump->players[i].funcFinished = FALSE; } -static void sub_8147FA0(void) +static void RecvLinkData_Leader(void) { int i; - int count; - u16 var0; - u8 var1; - u16 var2; + int numReady; + u16 monState; + u8 funcId; + u16 playAgainState; - for (i = 1, count = 0; i < gUnknown_203F3D4->unk5; i++) + for (i = 1, numReady = 0; i < sPokemonJump->numPlayers; i++) { - var0 = gUnknown_203F3D4->unk82E4[i].unk10; - if (sub_8149C24(&gUnknown_203F3D4->unk82E4[i], i, &var1, &var2)) + monState = sPokemonJump->players[i].monState; + if (RecvPacket_MemberStateToLeader(&sPokemonJump->players[i], i, &funcId, &playAgainState)) { - gUnknown_203F3D4->unk90[i] = var2; - gUnknown_203F3D4->unk8B[i] = var1; - gUnknown_203F3D4->unk82E4[i].unk12 = var0; + sPokemonJump->playAgainStates[i] = playAgainState; + sPokemonJump->memberFuncIds[i] = funcId; + sPokemonJump->players[i].prevMonState = monState; } - if (gUnknown_203F3D4->unk82E4[i].unk18 && gUnknown_203F3D4->unk8B[i] == gUnknown_203F3D4->unk70.unk0) - count++; + if (sPokemonJump->players[i].funcFinished && sPokemonJump->memberFuncIds[i] == sPokemonJump->comm.funcId) + numReady++; } - if (count == gUnknown_203F3D4->unk5 - 1) - gUnknown_203F3D4->unk49 = 1; + if (numReady == sPokemonJump->numPlayers - 1) + sPokemonJump->allPlayersReady = TRUE; } -static void sub_814807C(u8 taskId) +static bool32 (* const sPokeJumpLeaderFuncs[])(void) = +{ + [FUNC_GAME_INTRO] = GameIntro_Leader, + [FUNC_WAIT_ROUND] = WaitRound_Leader, + [FUNC_GAME_ROUND] = GameRound_Leader, + [FUNC_GAME_OVER] = GameOver_Leader, + [FUNC_ASK_PLAY_AGAIN] = AskPlayAgain_Leader, + [FUNC_RESET_GAME] = ResetGame_Leader, + [FUNC_EXIT] = ExitGame, + [FUNC_GIVE_PRIZE] = GivePrize_Leader, + [FUNC_SAVE] = SavePokeJump, +}; + +static void Task_PokemonJump_Leader(u8 taskId) { - sub_8147FA0(); - sub_8149534(); - if (!gUnknown_203F3D4->unk48 && gUnknown_203F3D4->unk49) + RecvLinkData_Leader(); + TryUpdateScore(); + if (!sPokemonJump->funcActive && sPokemonJump->allPlayersReady) { - sub_8147F4C(gUnknown_203F3D4->unk4C); - sub_8147F10(3); + SetFunc_Leader(sPokemonJump->nextFuncId); + SetLinkTimeInterval(LINK_INTERVAL_SHORT); } - if (gUnknown_203F3D4->unk48 == 1) + if (sPokemonJump->funcActive == TRUE) { - if (!gUnknown_846B64C[gUnknown_203F3D4->unk70.unk0]()) + if (!sPokeJumpLeaderFuncs[sPokemonJump->comm.funcId]()) { - gUnknown_203F3D4->unk48 = 0; - gUnknown_203F3D4->unk82E4[gUnknown_203F3D4->unk6].unk18 = 1; + sPokemonJump->funcActive = FALSE; + sPokemonJump->players[sPokemonJump->multiplayerId].funcFinished = TRUE; } } - sub_81492D8(); - sub_8148104(); + UpdateGame(); + SendLinkData_Leader(); } -static void sub_8148104(void) +static void SendLinkData_Leader(void) { - if (!gUnknown_203F3D4->unk2C) - sub_8149AF8(gUnknown_203F3D4->unk82E4, &gUnknown_203F3D4->unk70); + if (!sPokemonJump->linkTimer) + SendPacket_LeaderState(sPokemonJump->players, &sPokemonJump->comm); - if (gUnknown_203F3D4->unk30 != 0x1111) + if (sPokemonJump->linkTimerLimit != LINK_TIMER_STOPPED) { - gUnknown_203F3D4->unk2C++; - gUnknown_203F3D4->unk2C &= gUnknown_203F3D4->unk30; + sPokemonJump->linkTimer++; + sPokemonJump->linkTimer &= sPokemonJump->linkTimerLimit; } } -static void sub_8148140(u8 arg0) +static void SetFunc_Member(u8 funcId) { - gUnknown_203F3D4->unk70.unk0 = arg0; - gUnknown_203F3D4->unk8 = 0; - gUnknown_203F3D4->unkA = 0; - gUnknown_203F3D4->unk48 = 1; - gUnknown_203F3D4->unk82E4[gUnknown_203F3D4->unk6].unk18 = 0; + sPokemonJump->comm.funcId = funcId; + sPokemonJump->mainState = 0; + sPokemonJump->helperState = 0; + sPokemonJump->funcActive = TRUE; + sPokemonJump->players[sPokemonJump->multiplayerId].funcFinished = FALSE; } -static void sub_8148174(void) +static void RecvLinkData_Member(void) { int i; - u16 var0; - struct PokemonJump1Sub sp0; + u16 monState; + struct PokemonJump_CommData leaderData; - var0 = gUnknown_203F3D4->unk82E4[0].unk10; - if (sub_8149B7C(gUnknown_203F3D4->unk82E4, &sp0)) + monState = sPokemonJump->players[0].monState; + if (RecvPacket_LeaderState(sPokemonJump->players, &leaderData)) { - if (gUnknown_203F3D4->unk82E4[gUnknown_203F3D4->unk6].unk18 == 1 - && sp0.unk0 != gUnknown_203F3D4->unk70.unk0) + if (sPokemonJump->players[sPokemonJump->multiplayerId].funcFinished == TRUE + && leaderData.funcId != sPokemonJump->comm.funcId) { - sub_8148140(sp0.unk0); + SetFunc_Member(leaderData.funcId); } - if (gUnknown_203F3D4->unk70.unk8 != sp0.unk8) + if (sPokemonJump->comm.jumpScore != leaderData.jumpScore) { - gUnknown_203F3D4->unk70.unk8 = sp0.unk8; - gUnknown_203F3D4->unk5C = 1; - gUnknown_203F3D4->unk70.unk1 = sp0.unk1; - if (gUnknown_203F3D4->unk70.unk1) - gUnknown_203F3D4->unk4D = 1; + sPokemonJump->comm.jumpScore = leaderData.jumpScore; + sPokemonJump->updateScore = TRUE; + sPokemonJump->comm.receivedBonusFlags = leaderData.receivedBonusFlags; + if (sPokemonJump->comm.receivedBonusFlags) + sPokemonJump->showBonus = TRUE; else - gUnknown_203F3D4->unk4D = 0; + sPokemonJump->showBonus = FALSE; } - gUnknown_203F3D4->unk70.unk2 = sp0.unk2; - gUnknown_203F3D4->unk70.unk4 = sp0.unk4; - gUnknown_203F3D4->unk82E4[0].unk12 = var0; + sPokemonJump->comm.data = leaderData.data; + sPokemonJump->comm.jumpsInRow = leaderData.jumpsInRow; + sPokemonJump->players[0].prevMonState = monState; } - for (i = 1; i < gUnknown_203F3D4->unk5; i++) + for (i = 1; i < sPokemonJump->numPlayers; i++) { - if (i != gUnknown_203F3D4->unk6) + if (i != sPokemonJump->multiplayerId) { - var0 = gUnknown_203F3D4->unk82E4[i].unk10; - if (sub_8149C90(&gUnknown_203F3D4->unk82E4[i], i)) - gUnknown_203F3D4->unk82E4[i].unk12 = var0; + monState = sPokemonJump->players[i].monState; + if (RecvPacket_MemberStateToMember(&sPokemonJump->players[i], i)) + sPokemonJump->players[i].prevMonState = monState; } } } -static void sub_8148290(u8 taskId) +static bool32 (* const sPokeJumpMemberFuncs[])(void) = { - sub_8148174(); - if (gUnknown_203F3D4->unk48) + [FUNC_GAME_INTRO] = GameIntro_Member, + [FUNC_WAIT_ROUND] = WaitRound_Member, + [FUNC_GAME_ROUND] = GameRound_Member, + [FUNC_GAME_OVER] = GameOver_Member, + [FUNC_ASK_PLAY_AGAIN] = AskPlayAgain_Member, + [FUNC_RESET_GAME] = ResetGame_Member, + [FUNC_EXIT] = ExitGame, + [FUNC_GIVE_PRIZE] = GivePrize_Member, + [FUNC_SAVE] = SavePokeJump, +}; + +static void Task_PokemonJump_Member(u8 taskId) +{ + RecvLinkData_Member(); + if (sPokemonJump->funcActive) { - if (!gUnknown_846B670[gUnknown_203F3D4->unk70.unk0]()) + if (!sPokeJumpMemberFuncs[sPokemonJump->comm.funcId]()) { - gUnknown_203F3D4->unk48 = 0; - gUnknown_203F3D4->unk82E4[gUnknown_203F3D4->unk6].unk18 = 1; - sub_8147F10(3); + sPokemonJump->funcActive = FALSE; + sPokemonJump->players[sPokemonJump->multiplayerId].funcFinished = TRUE; + SetLinkTimeInterval(LINK_INTERVAL_SHORT); } } - sub_81492D8(); - sub_81482F8(); + UpdateGame(); + SendLinkData_Member(); } -static void sub_81482F8(void) +static void SendLinkData_Member(void) { - if (!gUnknown_203F3D4->unk2C) - sub_8149BF4(&gUnknown_203F3D4->unk82E4[gUnknown_203F3D4->unk6], gUnknown_203F3D4->unk70.unk0, gUnknown_203F3D4->unk42); + if (!sPokemonJump->linkTimer) + SendPacket_MemberState(&sPokemonJump->players[sPokemonJump->multiplayerId], sPokemonJump->comm.funcId, sPokemonJump->playAgainComm); - if (gUnknown_203F3D4->unk30 != 0x1111) + if (sPokemonJump->linkTimerLimit != LINK_TIMER_STOPPED) { - gUnknown_203F3D4->unk2C++; - gUnknown_203F3D4->unk2C &= gUnknown_203F3D4->unk30; + sPokemonJump->linkTimer++; + sPokemonJump->linkTimer &= sPokemonJump->linkTimerLimit; } } -static bool32 sub_8148344(void) +static bool32 GameIntro_Leader(void) { - switch (gUnknown_203F3D4->unk8) + switch (sPokemonJump->mainState) { case 0: - sub_8147F10(3); - gUnknown_203F3D4->unk8++; + SetLinkTimeInterval(LINK_INTERVAL_SHORT); + sPokemonJump->mainState++; // fall through case 1: - if (!sub_81488DC()) + if (!DoGameIntro()) { - gUnknown_203F3D4->unk70.unk2 = gUnknown_203F3D4->unk4A; - gUnknown_203F3D4->unk4C = 1; + sPokemonJump->comm.data = sPokemonJump->vineTimer; + sPokemonJump->nextFuncId = FUNC_WAIT_ROUND; return FALSE; } break; @@ -1091,35 +1299,35 @@ static bool32 sub_8148344(void) return TRUE; } -static bool32 sub_8148398(void) +static bool32 GameIntro_Member(void) { - switch (gUnknown_203F3D4->unk8) + switch (sPokemonJump->mainState) { case 0: - sub_8147F10(0); - gUnknown_203F3D4->unk24 = gUnknown_203F3D4->unk70.unk2; - gUnknown_203F3D4->unk8++; + SetLinkTimeInterval(LINK_INTERVAL_NONE); + sPokemonJump->rngSeed = sPokemonJump->comm.data; + sPokemonJump->mainState++; // fall through case 1: - return sub_81488DC(); + return DoGameIntro(); } return TRUE; } -static bool32 sub_81483D0(void) +static bool32 WaitRound_Leader(void) { - switch (gUnknown_203F3D4->unk8) + switch (sPokemonJump->mainState) { case 0: - sub_81491E4(); - sub_8147F10(5); - gUnknown_203F3D4->unk8++; + ResetPlayersJumpStates(); + SetLinkTimeInterval(LINK_INTERVAL_LONG); + sPokemonJump->mainState++; break; case 1: - if (gUnknown_203F3D4->unk49) + if (sPokemonJump->allPlayersReady) { - gUnknown_203F3D4->unk4C = 2; + sPokemonJump->nextFuncId = FUNC_GAME_ROUND; return FALSE; } break; @@ -1128,18 +1336,18 @@ static bool32 sub_81483D0(void) return TRUE; } -static bool32 sub_8148418(void) +static bool32 WaitRound_Member(void) { - switch (gUnknown_203F3D4->unk8) + switch (sPokemonJump->mainState) { case 0: - sub_81491E4(); - sub_8147F10(0); - gUnknown_203F3D4->unk4A = gUnknown_203F3D4->unk70.unk2; - gUnknown_203F3D4->unk8++; + ResetPlayersJumpStates(); + SetLinkTimeInterval(LINK_INTERVAL_NONE); + sPokemonJump->vineTimer = sPokemonJump->comm.data; + sPokemonJump->mainState++; // fall through case 1: - if (sub_8149804()) + if (AreLinkQueuesEmpty()) return FALSE; break; } @@ -1147,67 +1355,68 @@ static bool32 sub_8148418(void) return TRUE; } -static bool32 sub_8148464(void) +static bool32 GameRound_Leader(void) { - if (!sub_81489C8()) + if (!HandleSwingRound()) { - gUnknown_203F3D4->unk70.unk2 = gUnknown_203F3D4->unk4A; - gUnknown_203F3D4->unk4C = 1; + sPokemonJump->comm.data = sPokemonJump->vineTimer; + sPokemonJump->nextFuncId = FUNC_WAIT_ROUND; } - else if (sub_8149630()) + else if (UpdateVineHitStates()) { return TRUE; } else { - sub_81491B4(); - gUnknown_203F3D4->unk4C = 3; + // Someone hit the vine + ResetVineAfterHit(); + sPokemonJump->nextFuncId = FUNC_GAME_OVER; } return FALSE; } -static bool32 sub_81484B0(void) +static bool32 GameRound_Member(void) { - if (!sub_81489C8()) + if (!HandleSwingRound()) ; - else if (sub_8149630()) + else if (UpdateVineHitStates()) return TRUE; - else - sub_81491B4(); + else // Someone hit the vine + ResetVineAfterHit(); return FALSE; } -static bool32 sub_81484D0(void) +static bool32 GameOver_Leader(void) { - switch (gUnknown_203F3D4->unk8) + switch (sPokemonJump->mainState) { case 0: - sub_8149630(); - if (sub_81496D4()) - gUnknown_203F3D4->unk8++; + UpdateVineHitStates(); + if (AllPlayersJumpedOrHit()) + sPokemonJump->mainState++; break; case 1: - if (!sub_8148A60()) + if (!DoVineHitEffect()) { - if (sub_81498B4()) + if (HasEnoughScoreForPrize()) { - gUnknown_203F3D4->unk70.unk2 = sub_81498D8(); - gUnknown_203F3D4->unk4C = 7; + sPokemonJump->comm.data = GetPrizeData(); + sPokemonJump->nextFuncId = FUNC_GIVE_PRIZE; } - else if (gUnknown_203F3D4->unk70.unk4 >= 200) + else if (sPokemonJump->comm.jumpsInRow >= 200) { - gUnknown_203F3D4->unk70.unk2 = gUnknown_203F3D4->unkE; - gUnknown_203F3D4->unk4C = 8; + sPokemonJump->comm.data = sPokemonJump->excellentsInRowRecord; + sPokemonJump->nextFuncId = FUNC_SAVE; } else { - gUnknown_203F3D4->unk70.unk2 = gUnknown_203F3D4->unkE; - gUnknown_203F3D4->unk4C = 4; + sPokemonJump->comm.data = sPokemonJump->excellentsInRowRecord; + sPokemonJump->nextFuncId = FUNC_ASK_PLAY_AGAIN; } - gUnknown_203F3D4->unk8++; + sPokemonJump->mainState++; return FALSE; } break; @@ -1218,20 +1427,20 @@ static bool32 sub_81484D0(void) return TRUE; } -static bool32 sub_814856C(void) +static bool32 GameOver_Member(void) { - switch (gUnknown_203F3D4->unk8) + switch (sPokemonJump->mainState) { case 0: - if (!sub_8149630()) - sub_81491B4(); - if (sub_81496D4()) - gUnknown_203F3D4->unk8++; + if (!UpdateVineHitStates()) + ResetVineAfterHit(); + if (AllPlayersJumpedOrHit()) + sPokemonJump->mainState++; break; case 1: - if (!sub_8148A60()) + if (!DoVineHitEffect()) { - gUnknown_203F3D4->unk8++; + sPokemonJump->mainState++; return FALSE; } break; @@ -1242,30 +1451,30 @@ static bool32 sub_814856C(void) return TRUE; } -static bool32 sub_81485C8(void) +static bool32 AskPlayAgain_Leader(void) { - switch (gUnknown_203F3D4->unk8) + switch (sPokemonJump->mainState) { case 0: - sub_8147F10(4); - gUnknown_203F3D4->unk8++; + SetLinkTimeInterval(LINK_INTERVAL_MEDIUM); + sPokemonJump->mainState++; // fall through case 1: - if (!sub_8148C80()) + if (!DoPlayAgainPrompt()) { - sub_814B494(gUnknown_203F3D4->unk70.unk8, gUnknown_203F3D4->unk70.unk4, gUnknown_203F3D4->unk70.unk2); - gUnknown_203F3D4->unk8++; + TryUpdateRecords(sPokemonJump->comm.jumpScore, sPokemonJump->comm.jumpsInRow, sPokemonJump->comm.data); + sPokemonJump->mainState++; } break; case 2: - if (gUnknown_203F3D4->unk49) + if (sPokemonJump->allPlayersReady) { - if (sub_8149748()) - gUnknown_203F3D4->unk4C = 5; + if (ShouldPlayAgain()) + sPokemonJump->nextFuncId = FUNC_RESET_GAME; else - gUnknown_203F3D4->unk4C = 6; + sPokemonJump->nextFuncId = FUNC_EXIT; - gUnknown_203F3D4->unk8++; + sPokemonJump->mainState++; return FALSE; } break; @@ -1276,19 +1485,19 @@ static bool32 sub_81485C8(void) return TRUE; } -static bool32 sub_8148664(void) +static bool32 AskPlayAgain_Member(void) { - switch (gUnknown_203F3D4->unk8) + switch (sPokemonJump->mainState) { case 0: - sub_8147F10(0); - gUnknown_203F3D4->unk8++; + SetLinkTimeInterval(LINK_INTERVAL_NONE); + sPokemonJump->mainState++; // fall through case 1: - if (!sub_8148C80()) + if (!DoPlayAgainPrompt()) { - sub_814B494(gUnknown_203F3D4->unk70.unk8, gUnknown_203F3D4->unk70.unk4, gUnknown_203F3D4->unk70.unk2); - gUnknown_203F3D4->unk42 = gUnknown_203F3D4->unk45; + TryUpdateRecords(sPokemonJump->comm.jumpScore, sPokemonJump->comm.jumpsInRow, sPokemonJump->comm.data); + sPokemonJump->playAgainComm = sPokemonJump->playAgainState; return FALSE; } break; @@ -1297,21 +1506,21 @@ static bool32 sub_8148664(void) return TRUE; } -static bool32 sub_81486C4(void) +static bool32 ResetGame_Leader(void) { - switch (gUnknown_203F3D4->unk8) + switch (sPokemonJump->mainState) { case 0: - if (!sub_8148E2C()) - gUnknown_203F3D4->unk8++; + if (!CloseMessageAndResetScore()) + sPokemonJump->mainState++; break; case 1: - if (gUnknown_203F3D4->unk49) + if (sPokemonJump->allPlayersReady) { - sub_8147B94(gUnknown_203F3D4); - gUnknown_203F3D4->unk24 = Random(); - gUnknown_203F3D4->unk70.unk2 = gUnknown_203F3D4->unk24; - gUnknown_203F3D4->unk4C = 0; + ResetForNewGame(sPokemonJump); + sPokemonJump->rngSeed = Random(); + sPokemonJump->comm.data = sPokemonJump->rngSeed; + sPokemonJump->nextFuncId = FUNC_GAME_INTRO; return FALSE; } break; @@ -1320,15 +1529,15 @@ static bool32 sub_81486C4(void) return TRUE; } -static bool32 sub_8148724(void) +static bool32 ResetGame_Member(void) { - switch (gUnknown_203F3D4->unk8) + switch (sPokemonJump->mainState) { case 0: - if (!sub_8148E2C()) + if (!CloseMessageAndResetScore()) { - sub_8147B94(gUnknown_203F3D4); - gUnknown_203F3D4->unk8++; + ResetForNewGame(sPokemonJump); + sPokemonJump->mainState++; return FALSE; } break; @@ -1339,22 +1548,22 @@ static bool32 sub_8148724(void) return TRUE; } -static bool32 sub_8148760(void) +static bool32 ExitGame(void) { - switch (gUnknown_203F3D4->unk8) + switch (sPokemonJump->mainState) { case 0: - gUnknown_203F3D4->unk8 = 1; + sPokemonJump->mainState = 1; break; case 1: - sub_8147F10(0); - gUnknown_203F3D4->unk8++; + SetLinkTimeInterval(LINK_INTERVAL_NONE); + sPokemonJump->mainState++; break; case 2: - if (!sub_8148D5C()) + if (!ClosePokeJumpLink()) { - SetMainCallback2(gUnknown_203F3D4->returnCallback); - sub_8147B48(); + SetMainCallback2(sPokemonJump->exitCallback); + FreePokemonJump(); } break; } @@ -1362,19 +1571,19 @@ static bool32 sub_8148760(void) return TRUE; } -static bool32 sub_81487B4(void) +static bool32 GivePrize_Leader(void) { - switch (gUnknown_203F3D4->unk8) + switch (sPokemonJump->mainState) { case 0: - sub_8147F10(4); - gUnknown_203F3D4->unk8++; + SetLinkTimeInterval(LINK_INTERVAL_MEDIUM); + sPokemonJump->mainState++; break; case 1: - if (!sub_8148B54()) + if (!TryGivePrize()) { - gUnknown_203F3D4->unk70.unk2 = gUnknown_203F3D4->unkE; - gUnknown_203F3D4->unk4C = 8; + sPokemonJump->comm.data = sPokemonJump->excellentsInRowRecord; + sPokemonJump->nextFuncId = FUNC_SAVE; return FALSE; } break; @@ -1383,49 +1592,49 @@ static bool32 sub_81487B4(void) return TRUE; } -static bool32 sub_8148800(void) +static bool32 GivePrize_Member(void) { - sub_8147F10(0); - if (!sub_8148B54()) + SetLinkTimeInterval(LINK_INTERVAL_NONE); + if (!TryGivePrize()) return FALSE; else return TRUE; } -static bool32 sub_814881C(void) +static bool32 SavePokeJump(void) { - switch (gUnknown_203F3D4->unk8) + switch (sPokemonJump->mainState) { case 0: - sub_814B494(gUnknown_203F3D4->unk70.unk8, gUnknown_203F3D4->unk70.unk4, gUnknown_203F3D4->unk70.unk2); - sub_8149D40(5); - gUnknown_203F3D4->unk8++; + TryUpdateRecords(sPokemonJump->comm.jumpScore, sPokemonJump->comm.jumpsInRow, sPokemonJump->comm.data); + SetUpPokeJumpGfxFuncById(GFXFUNC_MSG_SAVING); + sPokemonJump->mainState++; break; case 1: - if (!sub_8149D68()) + if (!IsPokeJumpGfxFuncFinished()) { - sub_8147F10(0); - gUnknown_203F3D4->unk8++; + SetLinkTimeInterval(LINK_INTERVAL_NONE); + sPokemonJump->mainState++; } break; case 2: - if (sub_8149804()) + if (AreLinkQueuesEmpty()) { CreateTask(Task_LinkSave, 6); - gUnknown_203F3D4->unk8++; + sPokemonJump->mainState++; } break; case 3: if (!FuncIsActiveTask(Task_LinkSave)) { - sub_814A6CC(); - gUnknown_203F3D4->unk8++; + ClearMessageWindow(); + sPokemonJump->mainState++; } break; case 4: - if (!sub_814A6FC()) + if (!RemoveMessageWindow()) { - gUnknown_203F3D4->unk4C = 4; + sPokemonJump->nextFuncId = FUNC_ASK_PLAY_AGAIN; return FALSE; } break; @@ -1434,52 +1643,52 @@ static bool32 sub_814881C(void) return TRUE; } -static bool32 sub_81488DC(void) +static bool32 DoGameIntro(void) { - switch (gUnknown_203F3D4->unkA) + switch (sPokemonJump->helperState) { case 0: - sub_8149D40(2); - sub_814AAA0(); - gUnknown_203F3D4->unkA++; + SetUpPokeJumpGfxFuncById(GFXFUNC_SHOW_NAMES_HIGHLIGHT); + ResetMonSpriteSubpriorities(); + sPokemonJump->helperState++; break; case 1: - if (!sub_8149D68()) + if (!IsPokeJumpGfxFuncFinished()) { - sub_814AAB4(gUnknown_203F3D4->unk6); - gUnknown_203F3D4->unk3C = 0; - gUnknown_203F3D4->unkA++; + StartMonIntroBounce(sPokemonJump->multiplayerId); + sPokemonJump->timer = 0; + sPokemonJump->helperState++; } break; case 2: - if (++gUnknown_203F3D4->unk3C > 120) + if (++sPokemonJump->timer > 120) { - sub_8149D40(3); - gUnknown_203F3D4->unkA++; + SetUpPokeJumpGfxFuncById(GFXFUNC_ERASE_NAMES); + sPokemonJump->helperState++; } break; case 3: - if (sub_8149D68() != 1 && sub_814AAC8() != 1) - gUnknown_203F3D4->unkA++; + if (IsPokeJumpGfxFuncFinished() != TRUE && IsMonIntroBounceActive() != TRUE) + sPokemonJump->helperState++; break; case 4: - sub_8149D40(9); - gUnknown_203F3D4->unkA++; + SetUpPokeJumpGfxFuncById(GFXFUNC_COUNTDOWN); + sPokemonJump->helperState++; break; case 5: - if (!sub_8149D68()) + if (!IsPokeJumpGfxFuncFinished()) { - sub_814935C(); - sub_814A3E4(); - gUnknown_203F3D4->unkA++; + DisallowVineUpdates(); + SetUpResetVineGfx(); + sPokemonJump->helperState++; } break; case 6: - if (!sub_814A408()) + if (!ResetVineGfx()) { - sub_814936C(); - sub_8148F9C(); - gUnknown_203F3D4->unkA++; + AllowVineUpdates(); + ResetVineState(); + sPokemonJump->helperState++; return FALSE; } break; @@ -1490,85 +1699,88 @@ static bool32 sub_81488DC(void) return TRUE; } -static bool32 sub_81489C8(void) +// Update the vine and wait for player to input a jump +// Returns false when vine reaches the 'hit' point, after +// which input is ignored +static bool32 HandleSwingRound(void) { - sub_8148FE0(); - if (gUnknown_203F3D4->unk36) + UpdateVineState(); + if (sPokemonJump->ignoreJumpInput) { - gUnknown_203F3D4->unk36 = 0; + sPokemonJump->ignoreJumpInput = FALSE; return FALSE; } - switch (gUnknown_203F3D4->unkA) + switch (sPokemonJump->helperState) { case 0: - if (sub_814922C(0)) - gUnknown_203F3D4->unkA++; + if (IsPlayersMonState(MONSTATE_NORMAL)) + sPokemonJump->helperState++; else break; // fall through case 1: - if (gMain.newKeys & A_BUTTON) + if (JOY_NEW(A_BUTTON)) { - sub_8149260(); - sub_8147F10(3); - gUnknown_203F3D4->unkA++; + SetMonStateJump(); + SetLinkTimeInterval(LINK_INTERVAL_SHORT); + sPokemonJump->helperState++; } break; case 2: - if (sub_814922C(1) == TRUE) - gUnknown_203F3D4->unkA++; + if (IsPlayersMonState(MONSTATE_JUMP) == TRUE) + sPokemonJump->helperState++; break; case 3: - if (sub_814922C(0) == TRUE) - gUnknown_203F3D4->unkA = 0; + if (IsPlayersMonState(MONSTATE_NORMAL) == TRUE) + sPokemonJump->helperState = 0; break; } return TRUE; } -static bool32 sub_8148A60(void) +static bool32 DoVineHitEffect(void) { int i; - switch (gUnknown_203F3D4->unkA) + switch (sPokemonJump->helperState) { case 0: - for (i = 0; i < gUnknown_203F3D4->unk5; i++) + for (i = 0; i < sPokemonJump->numPlayers; i++) { - if (sub_814AA78(i) == 1) + if (IsMonHitShakeActive(i) == TRUE) return TRUE; } - gUnknown_203F3D4->unkA++; + sPokemonJump->helperState++; break; case 1: - for (i = 0; i < gUnknown_203F3D4->unk5; i++) + for (i = 0; i < sPokemonJump->numPlayers; i++) { - if (gUnknown_203F3D4->unk82E4[i].unk10 == 2) - sub_814AA60(i); + if (sPokemonJump->players[i].monState == MONSTATE_HIT) + StartMonHitFlash(i); } - sub_8149D40(1); - gUnknown_203F3D4->unk3C = 0; - gUnknown_203F3D4->unkA++; + SetUpPokeJumpGfxFuncById(GFXFUNC_SHOW_NAMES); + sPokemonJump->timer = 0; + sPokemonJump->helperState++; break; case 2: - if (++gUnknown_203F3D4->unk3C > 100) + if (++sPokemonJump->timer > 100) { - sub_8149D40(3); - gUnknown_203F3D4->unk3C = 0; - gUnknown_203F3D4->unkA++; + SetUpPokeJumpGfxFuncById(GFXFUNC_ERASE_NAMES); + sPokemonJump->timer = 0; + sPokemonJump->helperState++; } break; case 3: - if (!sub_8149D68()) + if (!IsPokeJumpGfxFuncFinished()) { - sub_814AA8C(); - gUnknown_203F3D4->unk70.unk1 = 0; - sub_8149210(); - gUnknown_203F3D4->unkA++; + StopMonHitFlash(); + sPokemonJump->comm.receivedBonusFlags = 0; + ResetPlayersMonState(); + sPokemonJump->helperState++; return FALSE; } break; @@ -1579,58 +1791,61 @@ static bool32 sub_8148A60(void) return TRUE; } -static bool32 sub_8148B54(void) +static bool32 TryGivePrize(void) { - switch (gUnknown_203F3D4->unkA) + switch (sPokemonJump->helperState) { case 0: - sub_8149900(gUnknown_203F3D4->unk70.unk2, &gUnknown_203F3D4->unk3E, &gUnknown_203F3D4->unk40); - sub_814A468(gUnknown_203F3D4->unk3E, gUnknown_203F3D4->unk40); - gUnknown_203F3D4->unkA++; + UnpackPrizeData(sPokemonJump->comm.data, &sPokemonJump->prizeItemId, &sPokemonJump->prizeItemQuantity); + PrintPrizeMessage(sPokemonJump->prizeItemId, sPokemonJump->prizeItemQuantity); + sPokemonJump->helperState++; break; case 1: case 4: - if (!sub_814A62C()) + if (!DoPrizeMessageAndFanfare()) { - gUnknown_203F3D4->unk3C = 0; - gUnknown_203F3D4->unkA++; + sPokemonJump->timer = 0; + sPokemonJump->helperState++; } break; case 2: case 5: - gUnknown_203F3D4->unk3C++; - if (gMain.newKeys & (A_BUTTON | B_BUTTON) || gUnknown_203F3D4->unk3C > 180) + // Wait to continue after message + sPokemonJump->timer++; + if (JOY_NEW(A_BUTTON | B_BUTTON) || sPokemonJump->timer > 180) { - sub_814A6CC(); - gUnknown_203F3D4->unkA++; + ClearMessageWindow(); + sPokemonJump->helperState++; } break; case 3: - if (!sub_814A6FC()) + if (!RemoveMessageWindow()) { - gUnknown_203F3D4->unk40 = sub_8149978(gUnknown_203F3D4->unk3E, gUnknown_203F3D4->unk40); - if (gUnknown_203F3D4->unk40 && AddBagItem(gUnknown_203F3D4->unk3E, gUnknown_203F3D4->unk40)) + sPokemonJump->prizeItemQuantity = GetQuantityLimitedByBag(sPokemonJump->prizeItemId, sPokemonJump->prizeItemQuantity); + if (sPokemonJump->prizeItemQuantity && AddBagItem(sPokemonJump->prizeItemId, sPokemonJump->prizeItemQuantity)) { - if (!CheckBagHasSpace(gUnknown_203F3D4->unk3E, 1)) + if (!CheckBagHasSpace(sPokemonJump->prizeItemId, 1)) { - sub_814A53C(gUnknown_203F3D4->unk3E); - gUnknown_203F3D4->unkA = 4; + // An item was given successfully, but no room for any more. + // It's possible the full prize quantity had to be limited + PrintPrizeFilledBagMessage(sPokemonJump->prizeItemId); + sPokemonJump->helperState = 4; // Do message } else { - gUnknown_203F3D4->unkA = 6; + sPokemonJump->helperState = 6; // Exit break; } } else { - sub_814A5B4(gUnknown_203F3D4->unk3E); - gUnknown_203F3D4->unkA = 4; + PrintNoRoomForPrizeMessage(sPokemonJump->prizeItemId); + sPokemonJump->helperState = 4; // Do message } } break; case 6: - if (!sub_814A6FC()) + if (!RemoveMessageWindow()) return FALSE; break; } @@ -1638,49 +1853,49 @@ static bool32 sub_8148B54(void) return TRUE; } -static bool32 sub_8148C80(void) +static bool32 DoPlayAgainPrompt(void) { s8 input; - switch (gUnknown_203F3D4->unkA) + switch (sPokemonJump->helperState) { case 0: - sub_8149D40(4); - gUnknown_203F3D4->unkA++; + SetUpPokeJumpGfxFuncById(GFXFUNC_MSG_PLAY_AGAIN); + sPokemonJump->helperState++; break; case 1: - if (!sub_8149D68()) - gUnknown_203F3D4->unkA++; + if (!IsPokeJumpGfxFuncFinished()) + sPokemonJump->helperState++; break; case 2: - input = sub_814A744(); + input = HandlePlayAgainInput(); switch (input) { case MENU_B_PRESSED: - case 1: - gUnknown_203F3D4->unk45 = 1; - sub_8149D40(6); - gUnknown_203F3D4->unkA++; + case 1: // No + sPokemonJump->playAgainState = PLAY_AGAIN_NO; + SetUpPokeJumpGfxFuncById(GFXFUNC_ERASE_MSG); + sPokemonJump->helperState++; break; - case 0: - gUnknown_203F3D4->unk45 = 2; - sub_8149D40(6); - gUnknown_203F3D4->unkA++; + case 0: // Yes + sPokemonJump->playAgainState = PLAY_AGAIN_YES; + SetUpPokeJumpGfxFuncById(GFXFUNC_ERASE_MSG); + sPokemonJump->helperState++; break; } break; case 3: - if (!sub_8149D68()) - gUnknown_203F3D4->unkA++; + if (!IsPokeJumpGfxFuncFinished()) + sPokemonJump->helperState++; break; case 4: - sub_8149D40(8); - gUnknown_203F3D4->unkA++; + SetUpPokeJumpGfxFuncById(GFXFUNC_MSG_COMM_STANDBY); + sPokemonJump->helperState++; break; case 5: - if (!sub_8149D68()) + if (!IsPokeJumpGfxFuncFinished()) { - gUnknown_203F3D4->unkA++; + sPokemonJump->helperState++; return FALSE; } break; @@ -1691,43 +1906,40 @@ static bool32 sub_8148C80(void) return TRUE; } -static bool32 sub_8148D5C(void) +static bool32 ClosePokeJumpLink(void) { - int var0; - - switch (gUnknown_203F3D4->unkA) + switch (sPokemonJump->helperState) { case 0: - sub_814A6CC(); - gUnknown_203F3D4->unkA++; + ClearMessageWindow(); + sPokemonJump->helperState++; break; case 1: - if (!sub_814A6FC()) + if (!RemoveMessageWindow()) { - sub_8149D40(7); - gUnknown_203F3D4->unkA++; + SetUpPokeJumpGfxFuncById(GFXFUNC_MSG_PLAYER_DROPPED); + sPokemonJump->helperState++; } break; case 2: - var0 = sub_8149D68(); - if (!var0) + if (!IsPokeJumpGfxFuncFinished()) { - gUnknown_203F3D4->unk3C = var0; - gUnknown_203F3D4->unkA++; + sPokemonJump->timer = 0; + sPokemonJump->helperState++; } break; case 3: - if (++gUnknown_203F3D4->unk3C > 120) + if (++sPokemonJump->timer > 120) { - BeginNormalPaletteFade(0xFFFFFFFF, -1, 0, 16, RGB_BLACK); - gUnknown_203F3D4->unkA++; + BeginNormalPaletteFade(PALETTES_ALL, -1, 0, 16, RGB_BLACK); + sPokemonJump->helperState++; } break; case 4: if (!gPaletteFade.active) { SetCloseLinkCallback(); - gUnknown_203F3D4->unkA++; + sPokemonJump->helperState++; } break; case 5: @@ -1739,19 +1951,19 @@ static bool32 sub_8148D5C(void) return TRUE; } -static bool32 sub_8148E2C(void) +static bool32 CloseMessageAndResetScore(void) { - switch (gUnknown_203F3D4->unkA) + switch (sPokemonJump->helperState) { case 0: - sub_814A6CC(); - sub_814AA24(0); - gUnknown_203F3D4->unkA++; + ClearMessageWindow(); + PrintScore(0); + sPokemonJump->helperState++; break; case 1: - if (!sub_814A6FC()) + if (!RemoveMessageWindow()) { - gUnknown_203F3D4->unkA++; + sPokemonJump->helperState++; return FALSE; } break; @@ -1762,32 +1974,37 @@ static bool32 sub_8148E2C(void) return TRUE; } -static void sub_8148E80(u8 taskId) +#define tState data[0] +#define tNumReceived data[1] +#define tReceivedPacket(playerId) data[(playerId) + 2] +#define DATAIDX_GAME_STRUCT 14 + +static void Task_CommunicateMonInfo(u8 taskId) { int i; - s16 *taskData = gTasks[taskId].data; - struct PokemonJump1 *ptr = (struct PokemonJump1 *)GetWordTaskArg(taskId, 14); + s16 *data = gTasks[taskId].data; + struct PokemonJump *jump = (struct PokemonJump *)GetWordTaskArg(taskId, DATAIDX_GAME_STRUCT); - switch (taskData[0]) + switch (tState) { case 0: for (i = 0; i < MAX_RFU_PLAYERS; i++) - taskData[i + 2] = 0; + tReceivedPacket(i) = FALSE; - taskData[0]++; + tState++; // fall through case 1: - sub_8149A6C(&ptr->unk82A8[ptr->unk6]); + SendPacket_MonInfo(&jump->monInfo[jump->multiplayerId]); for (i = 0; i < MAX_RFU_PLAYERS; i++) { - if (!taskData[i + 2] && sub_8149A90(i, &ptr->unk82A8[i])) + if (!tReceivedPacket(i) && RecvPacket_MonInfo(i, &jump->monInfo[i])) { - StringCopy(ptr->unk82E4[i].unk1C, gLinkPlayers[i].name); - taskData[i + 2] = 1; - taskData[1]++; - if (taskData[1] == ptr->unk5) + StringCopy(jump->players[i].name, gLinkPlayers[i].name); + tReceivedPacket(i) = TRUE; + tNumReceived++; + if (tNumReceived == jump->numPlayers) { - sub_8147C20(); + InitPlayerAndJumpTypes(); DestroyTask(taskId); break; } @@ -1797,510 +2014,542 @@ static void sub_8148E80(u8 taskId) } } -static void sub_8148F5C(TaskFunc func, u8 taskPriority) +static void SetTaskWithPokeJumpStruct(TaskFunc func, u8 taskPriority) { u8 taskId = CreateTask(func, taskPriority); - SetWordTaskArg(taskId, 14, (uintptr_t)gUnknown_203F3D4); + SetWordTaskArg(taskId, DATAIDX_GAME_STRUCT, (uintptr_t)sPokemonJump); } -static void sub_8148F7C(void) +#undef tState +#undef tNumReceived +#undef tReceivedPacket +#undef DATAIDX_GAME_STRUCT + +static void InitVineState(void) { - gUnknown_203F3D4->unk4A = 0; - gUnknown_203F3D4->unk14 = 6; - gUnknown_203F3D4->unk34 = 0; - gUnknown_203F3D4->unk1C = 0; - gUnknown_203F3D4->unk36 = 0; - gUnknown_203F3D4->unk10 = 0; + sPokemonJump->vineTimer = 0; + sPokemonJump->vineState = VINE_UPSWING_LOWER; + sPokemonJump->vineStateTimer = 0; + sPokemonJump->vineSpeed = 0; + sPokemonJump->ignoreJumpInput = FALSE; + sPokemonJump->gameOver = FALSE; } -static void sub_8148F9C(void) +static void ResetVineState(void) { - gUnknown_203F3D4->unk4A = 0; - gUnknown_203F3D4->unk34 = 0x6FF; - gUnknown_203F3D4->unk14 = 7; - gUnknown_203F3D4->unk36 = 0; - gUnknown_203F3D4->unk10 = 0; - gUnknown_203F3D4->unk51 = 0; - gUnknown_203F3D4->unk50 = 0; - gUnknown_203F3D4->unk20 = 0; - gUnknown_203F3D4->unk4E = 0; - gUnknown_203F3D4->unk6C = 0; - sub_8149078(); + sPokemonJump->vineTimer = 0; + sPokemonJump->vineStateTimer = VINE_STATE_TIMER(VINE_UPSWING_LOWER); + sPokemonJump->vineState = VINE_UPSWING_LOW; + sPokemonJump->ignoreJumpInput = FALSE; + sPokemonJump->gameOver = FALSE; + sPokemonJump->vineSpeedStage = 0; + sPokemonJump->vineBaseSpeedIdx = 0; + sPokemonJump->vineSpeedAccel = 0; + sPokemonJump->vineSpeedDelay = 0; + sPokemonJump->atMaxSpeedStage = FALSE; + UpdateVineSpeed(); } -static void sub_8148FE0(void) +static void UpdateVineState(void) { - if (gUnknown_203F3D4->unk46) + if (sPokemonJump->allowVineUpdates) { - gUnknown_203F3D4->unk4A++; - gUnknown_203F3D4->unk34 += sub_8149044(); - if (gUnknown_203F3D4->unk34 >= 0x9FF) - gUnknown_203F3D4->unk34 -= 0x9FF; - - gUnknown_203F3D4->unk18 = gUnknown_203F3D4->unk14; - gUnknown_203F3D4->unk14 = gUnknown_203F3D4->unk34 >> 8; - if (gUnknown_203F3D4->unk14 > 6 && gUnknown_203F3D4->unk18 < 7) + sPokemonJump->vineTimer++; + sPokemonJump->vineStateTimer += GetVineSpeed(); + if (sPokemonJump->vineStateTimer >= VINE_STATE_TIMER(NUM_VINESTATES - 1)) + sPokemonJump->vineStateTimer -= VINE_STATE_TIMER(NUM_VINESTATES - 1); + + sPokemonJump->prevVineState = sPokemonJump->vineState; + sPokemonJump->vineState = sPokemonJump->vineStateTimer >> 8; + + // If beginning upswing + if (sPokemonJump->vineState > VINE_UPSWING_LOWER && sPokemonJump->prevVineState < VINE_UPSWING_LOW) { - gUnknown_203F3D4->unk36++; - sub_8149078(); + sPokemonJump->ignoreJumpInput++; + UpdateVineSpeed(); } } } -static int sub_8149044(void) +static int GetVineSpeed(void) { - int result; + int speed; - if (gUnknown_203F3D4->unk10) + if (sPokemonJump->gameOver) return 0; - result = gUnknown_203F3D4->unk1C; - if (gUnknown_203F3D4->unk34 <= 0x5FF) + speed = sPokemonJump->vineSpeed; + if (sPokemonJump->vineStateTimer <= VINE_STATE_TIMER(VINE_LOWEST)) { - gUnknown_203F3D4->unk20 += 80; - result += gUnknown_203F3D4->unk20 >> 8; + // If at or below lowest, then vine is in downswing + // Increase speed in downswing + sPokemonJump->vineSpeedAccel += 80; + speed += sPokemonJump->vineSpeedAccel / 256; } - return result; + return speed; } -static const u16 gUnknown_846B694[] = {0x1a, 0x1f, 0x24, 0x29, 0x2e, 0x33, 0x38, 0x3d}; -static const u16 gUnknown_846B6A4[] = {0, 1, 1, 2}; +static const u16 sVineBaseSpeeds[] = {26, 31, 36, 41, 46, 51, 56, 61}; +static const u16 sVineSpeedDelays[] = {0, 1, 1, 2}; -static void sub_8149078(void) +static void UpdateVineSpeed(void) { - int var0; + int baseSpeed; - gUnknown_203F3D4->unk20 = 0; - if (gUnknown_203F3D4->unk4E) + sPokemonJump->vineSpeedAccel = 0; + if (sPokemonJump->vineSpeedDelay) { - gUnknown_203F3D4->unk4E--; - if (gUnknown_203F3D4->unk6C) + sPokemonJump->vineSpeedDelay--; + if (sPokemonJump->atMaxSpeedStage) { - if (sub_8149194() % 4 != 0) + if (PokeJumpRandom() % 4) { - gUnknown_203F3D4->unk1C = gUnknown_203F3D4->unk28; + sPokemonJump->vineSpeed = sPokemonJump->nextVineSpeed; } else { - if (gUnknown_203F3D4->unk28 > 54) - gUnknown_203F3D4->unk1C = 30; + if (sPokemonJump->nextVineSpeed > 54) + sPokemonJump->vineSpeed = 30; else - gUnknown_203F3D4->unk1C = 82; + sPokemonJump->vineSpeed = 82; } } } else { - if (!(gUnknown_203F3D4->unk50 & 8)) + if (!(sPokemonJump->vineBaseSpeedIdx & ARRAY_COUNT(sVineBaseSpeeds))) { - gUnknown_203F3D4->unk28 = gUnknown_846B694[gUnknown_203F3D4->unk50] + (gUnknown_203F3D4->unk51 * 7); - gUnknown_203F3D4->unk4E = gUnknown_846B6A4[sub_8149194() % NELEMS(gUnknown_846B6A4)] + 2; - gUnknown_203F3D4->unk50++; + sPokemonJump->nextVineSpeed = sVineBaseSpeeds[sPokemonJump->vineBaseSpeedIdx] + (sPokemonJump->vineSpeedStage * 7); + sPokemonJump->vineSpeedDelay = sVineSpeedDelays[PokeJumpRandom() % ARRAY_COUNT(sVineSpeedDelays)] + 2; + sPokemonJump->vineBaseSpeedIdx++; } else { - if (gUnknown_203F3D4->unk50 == 8) + if (sPokemonJump->vineBaseSpeedIdx == ARRAY_COUNT(sVineBaseSpeeds)) { - if (gUnknown_203F3D4->unk51 < 3) - gUnknown_203F3D4->unk51++; + if (sPokemonJump->vineSpeedStage < 3) + sPokemonJump->vineSpeedStage++; else - gUnknown_203F3D4->unk6C = 1; + sPokemonJump->atMaxSpeedStage = TRUE; } - var0 = gUnknown_846B694[15 - gUnknown_203F3D4->unk50]; - gUnknown_203F3D4->unk28 = var0 + (gUnknown_203F3D4->unk51 * 7); - if (++gUnknown_203F3D4->unk50 > 15) + baseSpeed = sVineBaseSpeeds[15 - sPokemonJump->vineBaseSpeedIdx]; + sPokemonJump->nextVineSpeed = baseSpeed + (sPokemonJump->vineSpeedStage * 7); + if (++sPokemonJump->vineBaseSpeedIdx > 15) { - if (sub_8149194() % 4 == 0) - gUnknown_203F3D4->unk28 -= 5; + if (PokeJumpRandom() % 4 == 0) + sPokemonJump->nextVineSpeed -= 5; - gUnknown_203F3D4->unk50 = 0; + sPokemonJump->vineBaseSpeedIdx = 0; } } - gUnknown_203F3D4->unk1C = gUnknown_203F3D4->unk28; + sPokemonJump->vineSpeed = sPokemonJump->nextVineSpeed; } } -static int sub_8149194(void) +static int PokeJumpRandom(void) { - // The number 1103515245 comes from the example implementation of rand and srand - gUnknown_203F3D4->unk24 = gUnknown_203F3D4->unk24 * 1103515245 + 24691; - return gUnknown_203F3D4->unk24 >> 16; + sPokemonJump->rngSeed = ISO_RANDOMIZE1(sPokemonJump->rngSeed); + return sPokemonJump->rngSeed >> 16; } -static void sub_81491B4(void) +static void ResetVineAfterHit(void) { - gUnknown_203F3D4->unk10 = 1; - gUnknown_203F3D4->unk14 = 6; - gUnknown_203F3D4->unk34 = 0x5FF; - sub_814936C(); + sPokemonJump->gameOver = TRUE; + sPokemonJump->vineState = VINE_UPSWING_LOWER; + sPokemonJump->vineStateTimer = VINE_STATE_TIMER(VINE_LOWEST); + AllowVineUpdates(); } -static int sub_81491D8(void) +static int IsGameOver(void) { - return gUnknown_203F3D4->unk10; + return sPokemonJump->gameOver; } -static void sub_81491E4(void) +static void ResetPlayersJumpStates(void) { int i; for (i = 0; i < MAX_RFU_PLAYERS; i++) - gUnknown_203F3D4->unk82E4[i].unk14 = 0; + sPokemonJump->players[i].jumpState = JUMPSTATE_NONE; } -static void sub_8149210(void) +static void ResetPlayersMonState(void) { - gUnknown_203F3D4->unk83AC->unk10 = 0; - gUnknown_203F3D4->unk83AC->unk12 = 0; + sPokemonJump->player->monState = MONSTATE_NORMAL; + sPokemonJump->player->prevMonState = MONSTATE_NORMAL; } -static bool32 sub_814922C(u16 arg0) +static bool32 IsPlayersMonState(u16 monState) { - if (gUnknown_203F3D4->unk82E4[gUnknown_203F3D4->unk6].unk10 == arg0) + if (sPokemonJump->players[sPokemonJump->multiplayerId].monState == monState) return TRUE; else return FALSE; } -static void sub_8149260(void) +static void SetMonStateJump(void) { - gUnknown_203F3D4->unk83AC->unkE = gUnknown_203F3D4->unk4A; - gUnknown_203F3D4->unk83AC->unk12 = gUnknown_203F3D4->unk83AC->unk10; - gUnknown_203F3D4->unk83AC->unk10 = 1; + sPokemonJump->player->jumpTimeStart = sPokemonJump->vineTimer; + sPokemonJump->player->prevMonState = sPokemonJump->player->monState; + sPokemonJump->player->monState = MONSTATE_JUMP; } -static void sub_8149288(void) +static void SetMonStateHit(void) { - gUnknown_203F3D4->unk83AC->unk12 = gUnknown_203F3D4->unk83AC->unk10; - gUnknown_203F3D4->unk83AC->unk10 = 2; - gUnknown_203F3D4->unk83AC->unkE = gUnknown_203F3D4->unk4A; - gUnknown_203F3D4->unk83AC->unk14 = 2; + sPokemonJump->player->prevMonState = sPokemonJump->player->monState; + sPokemonJump->player->monState = MONSTATE_HIT; + sPokemonJump->player->jumpTimeStart = sPokemonJump->vineTimer; + sPokemonJump->player->jumpState = JUMPSTATE_FAILURE; } -static void sub_81492B8(void) +static void SetMonStateNormal(void) { - gUnknown_203F3D4->unk83AC->unk12 = gUnknown_203F3D4->unk83AC->unk10; - gUnknown_203F3D4->unk83AC->unk10 = 0; + sPokemonJump->player->prevMonState = sPokemonJump->player->monState; + sPokemonJump->player->monState = MONSTATE_NORMAL; } -static const u16 gUnknown_846B6AC[] = {SE_RS_SHOP, SE_SHINY, SE_M_MORNING_SUN, SE_POKE_JUMP_SUCCESS}; +static const u16 sSoundEffects[MAX_RFU_PLAYERS - 1] = {SE_RS_SHOP, SE_SHINY, SE_M_MORNING_SUN, SE_POKE_JUMP_SUCCESS}; -static void sub_81492D8(void) +static void UpdateGame(void) { - if (gUnknown_203F3D4->unk5C) + if (sPokemonJump->updateScore) { - sub_814AA24(gUnknown_203F3D4->unk70.unk8); - gUnknown_203F3D4->unk5C = 0; - if (gUnknown_203F3D4->unk4D) + PrintScore(sPokemonJump->comm.jumpScore); + sPokemonJump->updateScore = FALSE; + if (sPokemonJump->showBonus) { - int index = sub_814A98C(gUnknown_203F3D4->unk70.unk1); - PlaySE(gUnknown_846B6AC[index - 2]); - gUnknown_203F3D4->unk4D = 0; + int numPlayers = DoSameJumpTimeBonus(sPokemonJump->comm.receivedBonusFlags); + PlaySE(sSoundEffects[numPlayers - 2]); + sPokemonJump->showBonus = FALSE; } } - sub_814AA34(gUnknown_203F3D4->unk70.unk4); - sub_814937C(); - sub_814933C(); + PrintJumpsInRow(sPokemonJump->comm.jumpsInRow); + HandleMonState(); + TryUpdateVineSwing(); } -static void sub_814933C(void) +static void TryUpdateVineSwing(void) { - if (gUnknown_203F3D4->unk46) - sub_814A95C(gUnknown_203F3D4->unk14); + if (sPokemonJump->allowVineUpdates) + UpdateVineSwing(sPokemonJump->vineState); } -static void sub_814935C(void) +static void DisallowVineUpdates(void) { - gUnknown_203F3D4->unk46 = 0; + sPokemonJump->allowVineUpdates = FALSE; } -static void sub_814936C(void) +static void AllowVineUpdates(void) { - gUnknown_203F3D4->unk46 = 1; + sPokemonJump->allowVineUpdates = TRUE; } -static void sub_814937C(void) +#define F_SE_JUMP (1 << 0) +#define F_SE_FAIL (1 << 1) + +static void HandleMonState(void) { int i; - int whichSound = 0; - int numLinkPlayers = gUnknown_203F3D4->unk5; + int soundFlags = 0; + int numPlayers = sPokemonJump->numPlayers; - for (i = 0; i < numLinkPlayers; i++) + for (i = 0; i < numPlayers; i++) { - switch (gUnknown_203F3D4->unk82E4[i].unk10) + switch (sPokemonJump->players[i].monState) { - case 0: - sub_814A940(i, 0); + case MONSTATE_NORMAL: + SetMonSpriteY(i, 0); break; - case 1: - if (gUnknown_203F3D4->unk82E4[i].unk12 != 1 || gUnknown_203F3D4->unk82E4[i].unkE != gUnknown_203F3D4->unk9A[i]) + case MONSTATE_JUMP: + if (sPokemonJump->players[i].prevMonState != MONSTATE_JUMP || sPokemonJump->players[i].jumpTimeStart != sPokemonJump->jumpTimeStarts[i]) { - if (i == gUnknown_203F3D4->unk6) - gUnknown_203F3D4->unk82E4[i].unk12 = 1; + // This is a new jump, play SE and init fields for jump handling + if (i == sPokemonJump->multiplayerId) + sPokemonJump->players[i].prevMonState = MONSTATE_JUMP; - whichSound |= 0x1; - gUnknown_203F3D4->unk82E4[i].unk4 = 0x7FFFFFFF; - gUnknown_203F3D4->unk9A[i] = gUnknown_203F3D4->unk82E4[i].unkE; + soundFlags |= F_SE_JUMP; + sPokemonJump->players[i].jumpOffsetIdx = INT_MAX; + sPokemonJump->jumpTimeStarts[i] = sPokemonJump->players[i].jumpTimeStart; } - sub_8149490(i); + UpdateJump(i); break; - case 2: - if (gUnknown_203F3D4->unk82E4[i].unk12 != 2) + case MONSTATE_HIT: + if (sPokemonJump->players[i].prevMonState != MONSTATE_HIT) { - if (i == gUnknown_203F3D4->unk6) - gUnknown_203F3D4->unk82E4[i].unk12 = 2; + if (i == sPokemonJump->multiplayerId) + sPokemonJump->players[i].prevMonState = MONSTATE_HIT; - whichSound |= 0x2; - sub_814AA48(i); + soundFlags |= F_SE_FAIL; + StartMonHitShake(i); } break; } } - if (whichSound & 0x2) + if (soundFlags & F_SE_FAIL) PlaySE(SE_POKE_JUMP_FAILURE); - else if (whichSound & 0x1) + else if (soundFlags & F_SE_JUMP) PlaySE(SE_LEDGE); } -static const s8 gUnknown_846B6B4[][48] = +static const s8 sJumpOffsets[][48] = { - {-3, -6, -8, -10, -13, -15, -17, -19, -21, -23, -25, -27, -28, -29, -30, -30, -30, -28, -27, - -26, -25, -23, -22, -20, -18, -17, -15, -13, -11, -8, -6, -4, -1}, + [JUMP_TYPE_NORMAL] = { -3, -6, -8, -10, -13, -15, -17, -19, + -21, -23, -25, -27, -28, -29, + JUMP_PEAK, JUMP_PEAK, JUMP_PEAK, + -28, -27, -26, -25, -23, -22, -20, -18, + -17, -15, -13, -11, -8, -6, -4, -1}, - {-3, -6, -9, -11, -14, -16, -18, -20, -22, -24, -26, -28, -29, -30, -30, -28, -26, -24, -22, - -20, -18, -16, -14, -11, -9, -6, -4, -1}, + [JUMP_TYPE_FAST] = { -3, -6, -9, -11, -14, -16, -18, -20, + -22, -24, -26, -28, -29, + JUMP_PEAK, JUMP_PEAK, + -28, -26, -24, -22, -20, -18, -16, -14, + -11, -9, -6, -4, -1}, - {-3, -6, -9, -11, -13, -15, -17, -19, -21, -23, -25, -27, -28, -29, -30, -30, -30, -30, -29, - -29, -28, -28, -27, -27, -26, -25, -24, -22, -20, -18, -16, -14, - -12, -11, -9, -6, -4, -1}, + [JUMP_TYPE_SLOW] = { -3, -6, -9, -11, -13, -15, -17, -19, + -21, -23, -25, -27, -28, -29, + JUMP_PEAK, JUMP_PEAK, JUMP_PEAK, JUMP_PEAK, + -29, -29, -28, -28, -27, -27, -26, -25, + -24, -22, -20, -18, -16, -14, -12, -11, + -9, -6, -4, -1}, }; -static void sub_8149490(int multiplayerId) +static void UpdateJump(int multiplayerId) { - int var0; - int var1; - struct PokemonJump1_82E4 *player; + int jumpOffsetIdx; + int jumpOffset; + struct PokemonJump_Player *player; - if (gUnknown_203F3D4->unk68) + if (sPokemonJump->skipJumpUpdate) // Always false return; - player = &gUnknown_203F3D4->unk82E4[multiplayerId]; - if (player->unk4 != 0x7FFFFFFF) + player = &sPokemonJump->players[multiplayerId]; + if (player->jumpOffsetIdx != INT_MAX) { - player->unk4++; - var0 = player->unk4; + player->jumpOffsetIdx++; + jumpOffsetIdx = player->jumpOffsetIdx; } else { - var0 = gUnknown_203F3D4->unk4A - player->unkE; - if (var0 >= 65000) + jumpOffsetIdx = sPokemonJump->vineTimer - player->jumpTimeStart; + if (jumpOffsetIdx >= 65000) { - var0 -= 65000; - var0 += gUnknown_203F3D4->unk4A; + jumpOffsetIdx -= 65000; + jumpOffsetIdx += sPokemonJump->vineTimer; } - player->unk4 = var0; + player->jumpOffsetIdx = jumpOffsetIdx; } - if (var0 < 4) + if (jumpOffsetIdx < 4) return; - var0 -= 4; - if (var0 < 48) - var1 = gUnknown_846B6B4[player->unkC][var0]; + jumpOffsetIdx -= 4; + if (jumpOffsetIdx < (int)ARRAY_COUNT(sJumpOffsets[0])) + jumpOffset = sJumpOffsets[player->monJumpType][jumpOffsetIdx]; else - var1 = 0; + jumpOffset = 0; - sub_814A940(multiplayerId, var1); - if (!var1 && multiplayerId == gUnknown_203F3D4->unk6) - sub_81492B8(); + SetMonSpriteY(multiplayerId, jumpOffset); + if (jumpOffset == 0 && multiplayerId == sPokemonJump->multiplayerId) + SetMonStateNormal(); - player->unk0 = var1; + player->jumpOffset = jumpOffset; } -static void sub_8149534(void) +static void TryUpdateScore(void) { - if (gUnknown_203F3D4->unk14 == 8 && gUnknown_203F3D4->unk18 == 7) + if (sPokemonJump->vineState == VINE_UPSWING_HIGH && sPokemonJump->prevVineState == VINE_UPSWING_LOW) { - if (gUnknown_203F3D4->unk58 == 0) + // Vine has passed through the point where it + // would hit the players, allow score to update + + if (!sPokemonJump->initScoreUpdate) { - sub_8149878(); - gUnknown_203F3D4->unk54 = 0; - gUnknown_203F3D4->unk58 = 1; - gUnknown_203F3D4->unk70.unk1 = 0; + ClearUnreadField(); + sPokemonJump->numPlayersAtPeak = 0; + sPokemonJump->initScoreUpdate = TRUE; + sPokemonJump->comm.receivedBonusFlags = 0; } else { - if (gUnknown_203F3D4->unk54 == 5) + if (sPokemonJump->numPlayersAtPeak == MAX_RFU_PLAYERS) { - gUnknown_203F3D4->unkC++; - sub_8149898(gUnknown_203F3D4->unkC); + // An 'excellent' is the max 5 players all jumping synchronously + sPokemonJump->excellentsInRow++; + TryUpdateExcellentsRecord(sPokemonJump->excellentsInRow); } else { - gUnknown_203F3D4->unkC = 0; + sPokemonJump->excellentsInRow = 0; } - if (gUnknown_203F3D4->unk54 > 1) + if (sPokemonJump->numPlayersAtPeak > 1) { - gUnknown_203F3D4->unk64 = 1; - memcpy(gUnknown_203F3D4->unk86, gUnknown_203F3D4->unk81, sizeof(u8) * MAX_RFU_PLAYERS); + sPokemonJump->giveBonus = TRUE; + // Unclear why atJumpPeak needed to be copied over twice + memcpy(sPokemonJump->atJumpPeak3, sPokemonJump->atJumpPeak2, sizeof(u8) * MAX_RFU_PLAYERS); } - sub_8149878(); - gUnknown_203F3D4->unk54 = 0; - gUnknown_203F3D4->unk58 = 1; - gUnknown_203F3D4->unk70.unk1 = 0; - if (gUnknown_203F3D4->unk70.unk4 < 9999) - gUnknown_203F3D4->unk70.unk4++; + ClearUnreadField(); + sPokemonJump->numPlayersAtPeak = 0; + sPokemonJump->initScoreUpdate = TRUE; + sPokemonJump->comm.receivedBonusFlags = 0; + if (sPokemonJump->comm.jumpsInRow < MAX_JUMPS) + sPokemonJump->comm.jumpsInRow++; - sub_8149780(10); - sub_8147F10(3); + AddJumpScore(10); + SetLinkTimeInterval(LINK_INTERVAL_SHORT); } } - if (gUnknown_203F3D4->unk64 && (sub_8149710() == TRUE || !gUnknown_203F3D4->unk14)) + if (sPokemonJump->giveBonus && (DidAllPlayersClearVine() == TRUE || sPokemonJump->vineState == VINE_HIGHEST)) { - int var0 = sub_8149834(gUnknown_203F3D4->unk86); - sub_8149780(sub_8149888(var0)); - sub_8147F10(3); - gUnknown_203F3D4->unk64 = 0; + int numPlayers = GetNumPlayersForBonus(sPokemonJump->atJumpPeak3); + AddJumpScore(GetScoreBonus(numPlayers)); + SetLinkTimeInterval(LINK_INTERVAL_SHORT); + sPokemonJump->giveBonus = FALSE; } - if (gUnknown_203F3D4->unk58) + if (sPokemonJump->initScoreUpdate) { - int var1 = sub_81497A8(); - if (var1 > gUnknown_203F3D4->unk54) + int numAtPeak = GetPlayersAtJumpPeak(); + if (numAtPeak > sPokemonJump->numPlayersAtPeak) { - gUnknown_203F3D4->unk54 = var1; - memcpy(gUnknown_203F3D4->unk81, gUnknown_203F3D4->unk7C, sizeof(u8) * MAX_RFU_PLAYERS); + sPokemonJump->numPlayersAtPeak = numAtPeak; + memcpy(sPokemonJump->atJumpPeak2, sPokemonJump->atJumpPeak, sizeof(u8) * MAX_RFU_PLAYERS); } } } -static bool32 sub_8149630(void) +// Returns FALSE if any player was hit by vine +static bool32 UpdateVineHitStates(void) { int i; - if (gUnknown_203F3D4->unk14 == 6 && !gUnknown_203F3D4->unk83AC->unk0) + if (sPokemonJump->vineState == VINE_UPSWING_LOWER && sPokemonJump->player->jumpOffset == 0) { - if (gUnknown_203F3D4->unk83AC->unk12 == 1 && sub_81491D8() == 1) + // Vine is in position to hit the player and jump offset is 0. + // Unless the player had just jumped and has been forced to the ground + // by someone else getting hit, the player has been hit + if (sPokemonJump->player->prevMonState == MONSTATE_JUMP && IsGameOver() == TRUE) { - gUnknown_203F3D4->unk83AC->unk14 = 1; + sPokemonJump->player->jumpState = JUMPSTATE_SUCCESS; } else { - sub_8149288(); - sub_8147F10(3); + // Hit vine + SetMonStateHit(); + SetLinkTimeInterval(LINK_INTERVAL_SHORT); } } - if (gUnknown_203F3D4->unk14 == 7 - && gUnknown_203F3D4->unk18 == 6 - && gUnknown_203F3D4->unk83AC->unk10 != 2) + if (sPokemonJump->vineState == VINE_UPSWING_LOW + && sPokemonJump->prevVineState == VINE_UPSWING_LOWER + && sPokemonJump->player->monState != MONSTATE_HIT) { - gUnknown_203F3D4->unk83AC->unk14 = 1; - sub_8147F10(3); + sPokemonJump->player->jumpState = JUMPSTATE_SUCCESS; + SetLinkTimeInterval(LINK_INTERVAL_SHORT); } - for (i = 0; i < gUnknown_203F3D4->unk5; i++) + for (i = 0; i < sPokemonJump->numPlayers; i++) { - if (gUnknown_203F3D4->unk82E4[i].unk10 == 2) + if (sPokemonJump->players[i].monState == MONSTATE_HIT) return FALSE; } return TRUE; } -static bool32 sub_81496D4(void) +// Has everyone either jumped or been hit by the vine +static bool32 AllPlayersJumpedOrHit(void) { int i; - int numPlayers = gUnknown_203F3D4->unk5; - int count = 0; + int numPlayers = sPokemonJump->numPlayers; + int numJumpedOrHit = 0; for (i = 0; i < numPlayers; i++) { - if (gUnknown_203F3D4->unk82E4[i].unk14) - count++; + if (sPokemonJump->players[i].jumpState != JUMPSTATE_NONE) + numJumpedOrHit++; } - return count == numPlayers; + return numJumpedOrHit == numPlayers; } -static bool32 sub_8149710(void) +static bool32 DidAllPlayersClearVine(void) { int i; - for (i = 0; i < gUnknown_203F3D4->unk5; i++) + for (i = 0; i < sPokemonJump->numPlayers; i++) { - if (gUnknown_203F3D4->unk82E4[i].unk14 != 1) + if (sPokemonJump->players[i].jumpState != JUMPSTATE_SUCCESS) return FALSE; } return TRUE; } -static bool32 sub_8149748(void) +static bool32 ShouldPlayAgain(void) { int i; - if (gUnknown_203F3D4->unk45 == 1) + if (sPokemonJump->playAgainState == PLAY_AGAIN_NO) return FALSE; - for (i = 1; i < gUnknown_203F3D4->unk5; i++) + for (i = 1; i < sPokemonJump->numPlayers; i++) { - if (gUnknown_203F3D4->unk90[i] == 1) + if (sPokemonJump->playAgainStates[i] == PLAY_AGAIN_NO) return FALSE; } return TRUE; } -static void sub_8149780(int arg0) +static void AddJumpScore(int score) { - gUnknown_203F3D4->unk70.unk8 += arg0; - gUnknown_203F3D4->unk5C = 1; - if (gUnknown_203F3D4->unk70.unk8 >= 99990) - gUnknown_203F3D4->unk70.unk8 = 99990; + sPokemonJump->comm.jumpScore += score; + sPokemonJump->updateScore = TRUE; + if (sPokemonJump->comm.jumpScore >= MAX_JUMP_SCORE) + sPokemonJump->comm.jumpScore = MAX_JUMP_SCORE; } -static int sub_81497A8(void) +static int GetPlayersAtJumpPeak(void) { int i; - int count = 0; - int numPlayers = gUnknown_203F3D4->unk5; + int numAtPeak = 0; + int numPlayers = sPokemonJump->numPlayers; for (i = 0; i < numPlayers; i++) { - if (gUnknown_203F3D4->unk82E4[i].unk0 == -30) + if (sPokemonJump->players[i].jumpOffset == JUMP_PEAK) { - gUnknown_203F3D4->unk7C[i] = 1; - count++; + sPokemonJump->atJumpPeak[i] = TRUE; + numAtPeak++; } else { - gUnknown_203F3D4->unk7C[i] = 0; + sPokemonJump->atJumpPeak[i] = FALSE; } } - return count; + return numAtPeak; } -static bool32 sub_8149804(void) +static bool32 AreLinkQueuesEmpty(void) { return !Rfu.recvQueue.count && !Rfu.sendQueue.count; } -static int sub_8149834(u8 *arg0) +static int GetNumPlayersForBonus(u8 *arg0) { - int i; - int flags; - int count; + int i = 0; + int flags = 0; + int count = 0; - for (i = 0, flags = 0, count = 0; i < MAX_RFU_PLAYERS; i++) + for (; i < MAX_RFU_PLAYERS; i++) { if (arg0[i]) { @@ -2309,87 +2558,100 @@ static int sub_8149834(u8 *arg0) } } - gUnknown_203F3D4->unk70.unk1 = flags; + sPokemonJump->comm.receivedBonusFlags = flags; if (flags) - gUnknown_203F3D4->unk4D = 1; + sPokemonJump->showBonus = TRUE; return count; } -static void sub_8149878(void) +static void ClearUnreadField(void) { - gUnknown_203F3D4->unk44 = 0; + sPokemonJump->unused3 = 0; } -static const int gUnknown_846B74C[] = {0, 0, 50, 100, 200, 500}; +// Bonuses given depend on the number of +// players that jumped at the same time +static const int sScoreBonuses[MAX_RFU_PLAYERS + 1] = {0, 0, 50, 100, 200, 500}; -static int sub_8149888(int arg0) +static int GetScoreBonus(int numPlayers) { - return gUnknown_846B74C[arg0]; + return sScoreBonuses[numPlayers]; } -static void sub_8149898(u16 arg0) +static void TryUpdateExcellentsRecord(u16 excellentsInRow) { - if (arg0 > gUnknown_203F3D4->unkE) - gUnknown_203F3D4->unkE = arg0; + if (excellentsInRow > sPokemonJump->excellentsInRowRecord) + sPokemonJump->excellentsInRowRecord = excellentsInRow; } -static const u16 gUnknown_846B764[] = {0x8a, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93}; -static const u32 gUnknown_846B76C[][2] = +static const u16 sPrizeItems[] = { + ITEM_LEPPA_BERRY, + ITEM_LUM_BERRY, + ITEM_SITRUS_BERRY, + ITEM_FIGY_BERRY, + ITEM_WIKI_BERRY, + ITEM_MAGO_BERRY, + ITEM_AGUAV_BERRY, + ITEM_IAPAPA_BERRY +}; + +struct { + u32 score; + u32 quantity; +} static const sPrizeQuantityData[] = { - {0x1388, 1}, - {0x1f40, 2}, - {0x2ee0, 3}, - {0x3e80, 4}, - {0x4e20, 5}, + { .score = 5000, .quantity = 1}, + { .score = 8000, .quantity = 2}, + { .score = 12000, .quantity = 3}, + { .score = 16000, .quantity = 4}, + { .score = 20000, .quantity = 5}, }; -static bool32 sub_81498B4(void) +static bool32 HasEnoughScoreForPrize(void) { - if (gUnknown_203F3D4->unk70.unk8 >= gUnknown_846B76C[0][0]) + if (sPokemonJump->comm.jumpScore >= sPrizeQuantityData[0].score) return TRUE; else return FALSE; } -static u16 sub_81498D8(void) +static u16 GetPrizeData(void) { - u16 lo = sub_8149910(); - u16 hi = sub_8149930(); - return (hi << 12) | (lo & 0xFFF); + u16 itemId = GetPrizeItemId(); + u16 quantity = GetPrizeQuantity(); + return (quantity << 12) | (itemId & 0xFFF); } -static void sub_8149900(u16 arg0, u16 *arg1, u16 *arg2) +static void UnpackPrizeData(u16 data, u16 *itemId, u16 *quantity) { - *arg2 = arg0 >> 12; - *arg1 = arg0 & 0xFFF; + *quantity = data >> 12; + *itemId = data & 0xFFF; } -static u16 sub_8149910(void) +static u16 GetPrizeItemId(void) { - u16 index = Random() % NELEMS(gUnknown_846B764); - return gUnknown_846B764[index]; + u16 index = Random() % ARRAY_COUNT(sPrizeItems); + return sPrizeItems[index]; } -static u16 sub_8149930(void) +static u16 GetPrizeQuantity(void) { - u32 val, i; + u32 quantity, i; - val = 0; - for (i = 0; i < 5; i++) + quantity = 0; + for (i = 0; i < ARRAY_COUNT(sPrizeQuantityData); i++) { - if (gUnknown_203F3D4->unk70.unk8 < gUnknown_846B76C[i][0]) - break; - else if (1) // required to match, see pret/pokeemerald#982 - val = gUnknown_846B76C[i][1]; + if (sPokemonJump->comm.jumpScore >= sPrizeQuantityData[i].score) + quantity = sPrizeQuantityData[i].quantity; else break; } - return val; + return quantity; } -static u16 sub_8149978(u16 item, u16 quantity) +static u16 GetQuantityLimitedByBag(u16 item, u16 quantity) { while (quantity && !CheckBagHasSpace(item, quantity)) quantity--; @@ -2397,24 +2659,24 @@ static u16 sub_8149978(u16 item, u16 quantity) return quantity; } -u16 sub_81499A4(void) +static u16 GetNumPokeJumpPlayers(void) { return GetLinkPlayerCount(); } -u16 sub_81499B4(void) +static u16 GetPokeJumpMultiplayerId(void) { - return gUnknown_203F3D4->unk6; + return sPokemonJump->multiplayerId; } -struct PokemonJump1_MonInfo *sub_81499C0(u8 multiplayerId) +static struct PokemonJump_MonInfo *GetMonInfoByMultiplayerId(u8 multiplayerId) { - return &gUnknown_203F3D4->unk82A8[multiplayerId]; + return &sPokemonJump->monInfo[multiplayerId]; } -u8 *sub_81499E0(u8 multiplayerId) +static u8 *GetPokeJumpPlayerName(u8 multiplayerId) { - return gUnknown_203F3D4->unk82E4[multiplayerId].unk1C; + return sPokemonJump->players[multiplayerId].name; } bool32 IsSpeciesAllowedInPokemonJump(u16 species) @@ -2442,206 +2704,218 @@ void IsPokemonJumpSpeciesInParty(void) gSpecialVar_Result = FALSE; } -void sub_8149A6C(struct PokemonJump1_MonInfo *arg0) +struct MonInfoPacket +{ + u8 id; + u16 species; + u32 personality; + u32 otId; +}; + +static void SendPacket_MonInfo(struct PokemonJump_MonInfo *monInfo) { struct MonInfoPacket packet; - packet.id = 1; - packet.species = arg0->species; - packet.otId = arg0->otId; - packet.personality = arg0->personality; + packet.id = PACKET_MON_INFO; + packet.species = monInfo->species; + packet.otId = monInfo->otId; + packet.personality = monInfo->personality; Rfu_SendPacket(&packet); } -bool32 sub_8149A90(int multiplayerId, struct PokemonJump1_MonInfo *arg0) +static bool32 RecvPacket_MonInfo(int multiplayerId, struct PokemonJump_MonInfo *monInfo) { struct MonInfoPacket packet; - if ((gRecvCmds[multiplayerId][0] & 0xFF00) != 0x2F00) + if ((gRecvCmds[multiplayerId][0] & RFUCMD_MASK) != RFUCMD_SEND_PACKET) return FALSE; memcpy(&packet, &gRecvCmds[multiplayerId][1], sizeof(packet)); - if (packet.id == 1) + if (packet.id == PACKET_MON_INFO) { - arg0->species = packet.species; - arg0->otId = packet.otId; - arg0->personality = packet.personality; + monInfo->species = packet.species; + monInfo->otId = packet.otId; + monInfo->personality = packet.personality; return TRUE; } return FALSE; } -struct UnkPacket2 +struct UnusedPacket { - u8 id; // packet id - u32 unk4; - u32 unk8; + u8 id; + u32 data; + u32 filler; }; -void sub_8149AE0(u32 arg0) +// Data packet that's never sent +// No function to read it either +static void SendPacket_Unused(u32 data) { - struct UnkPacket2 packet; - packet.id = 2; - packet.unk4 = arg0; + struct UnusedPacket packet; + packet.id = PACKET_UNUSED; + packet.data = data; Rfu_SendPacket(&packet); } -struct UnkPacket3 +struct LeaderStatePacket { - u8 id; // packet id - u8 unk1; - u8 unk2; - u8 unk3_0:5; - u8 unk3_1:3; - u16 unk4; - u16 unk6; - u32 unk8_0:15; - u32 unk8_1:17; + u8 id; + u8 funcId; + u8 monState; + u8 receivedBonusFlags:5; // 1 bit for each player (MAX_RFU_PLAYERS) + u8 jumpState:3; + u16 jumpTimeStart; + u16 vineTimer; + u32 jumpsInRow:15; + u32 jumpScore:17; }; -void sub_8149AF8(struct PokemonJump1_82E4 *arg0, struct PokemonJump1Sub *arg1) -{ - struct UnkPacket3 packet; - packet.id = 3; - packet.unk8_1 = arg1->unk8; - packet.unk3_0 = arg1->unk1; - packet.unk1 = arg1->unk0; - packet.unk6 = arg1->unk2; - packet.unk8_0 = arg1->unk4; - packet.unk2 = arg0->unk10; - packet.unk3_1 = arg0->unk14; - packet.unk4 = arg0->unkE; +static void SendPacket_LeaderState(struct PokemonJump_Player *player, struct PokemonJump_CommData *comm) +{ + struct LeaderStatePacket packet; + packet.id = PACKET_LEADER_STATE; + packet.jumpScore = comm->jumpScore; + packet.receivedBonusFlags = comm->receivedBonusFlags; + packet.funcId = comm->funcId; + packet.vineTimer = comm->data; + packet.jumpsInRow = comm->jumpsInRow; + packet.monState = player->monState; + packet.jumpState = player->jumpState; + packet.jumpTimeStart = player->jumpTimeStart; Rfu_SendPacket(&packet); } -bool32 sub_8149B7C(struct PokemonJump1_82E4 *arg0, struct PokemonJump1Sub *arg1) +// Used by group members to read the state of the group leader +static bool32 RecvPacket_LeaderState(struct PokemonJump_Player *player, struct PokemonJump_CommData *comm) { - struct UnkPacket3 packet; + struct LeaderStatePacket packet; - if ((gRecvCmds[0][0] & 0xFF00) != 0x2F00) + if ((gRecvCmds[0][0] & RFUCMD_MASK) != RFUCMD_SEND_PACKET) return FALSE; memcpy(&packet, &gRecvCmds[0][1], sizeof(packet)); - if (packet.id != 3) + if (packet.id != PACKET_LEADER_STATE) return FALSE; - arg1->unk8 = packet.unk8_1; - arg1->unk1 = packet.unk3_0; - arg1->unk0 = packet.unk1; - arg1->unk2 = packet.unk6; - arg1->unk4 = packet.unk8_0; - arg0->unk10 = packet.unk2; - arg0->unk14 = packet.unk3_1; - arg0->unkE = packet.unk4; + comm->jumpScore = packet.jumpScore; + comm->receivedBonusFlags = packet.receivedBonusFlags; + comm->funcId = packet.funcId; + comm->data = packet.vineTimer; + comm->jumpsInRow = packet.jumpsInRow; + player->monState = packet.monState; + player->jumpState = packet.jumpState; + player->jumpTimeStart = packet.jumpTimeStart; return TRUE; } -struct UnkPacket4 +struct MemberStatePacket { - u8 id; // packet id - u8 unk1; - u8 unk2; - u8 unk3; - u16 unk4; - u8 unk6; - u16 unk8; + u8 id; + u8 monState; + u8 jumpState; + bool8 funcFinished; + u16 jumpTimeStart; + u8 funcId; + u16 playAgainState; }; -void sub_8149BF4(struct PokemonJump1_82E4 *arg0, u8 arg1, u16 arg2) +static void SendPacket_MemberState(struct PokemonJump_Player *player, u8 funcId, u16 playAgainState) { - struct UnkPacket4 packet; - packet.id = 4; - packet.unk1 = arg0->unk10; - packet.unk2 = arg0->unk14; - packet.unk3 = arg0->unk18; - packet.unk4 = arg0->unkE; - packet.unk6 = arg1; - packet.unk8 = arg2; + struct MemberStatePacket packet; + packet.id = PACKET_MEMBER_STATE; + packet.monState = player->monState; + packet.jumpState = player->jumpState; + packet.funcFinished = player->funcFinished; + packet.jumpTimeStart = player->jumpTimeStart; + packet.funcId = funcId; + packet.playAgainState = playAgainState; Rfu_SendPacket(&packet); } -bool32 sub_8149C24(struct PokemonJump1_82E4 *arg0, int multiplayerId, u8 *arg2, u16 *arg3) +// Used by the group leader to read the state of group members +static bool32 RecvPacket_MemberStateToLeader(struct PokemonJump_Player *player, int multiplayerId, u8 *funcId, u16 *playAgainState) { - struct UnkPacket4 packet; + struct MemberStatePacket packet; - if ((gRecvCmds[multiplayerId][0] & 0xFF00) != 0x2F00) + if ((gRecvCmds[multiplayerId][0] & RFUCMD_MASK) != RFUCMD_SEND_PACKET) return FALSE; memcpy(&packet, &gRecvCmds[multiplayerId][1], sizeof(packet)); - if (packet.id != 4) + if (packet.id != PACKET_MEMBER_STATE) return FALSE; - arg0->unk10 = packet.unk1; - arg0->unk14 = packet.unk2; - arg0->unk18 = packet.unk3; - arg0->unkE = packet.unk4; - *arg2 = packet.unk6; - *arg3 = packet.unk8; + player->monState = packet.monState; + player->jumpState = packet.jumpState; + player->funcFinished = packet.funcFinished; + player->jumpTimeStart = packet.jumpTimeStart; + *funcId = packet.funcId; + *playAgainState = packet.playAgainState; return TRUE; } -bool32 sub_8149C90(struct PokemonJump1_82E4 *arg0, int multiplayerId) +// Used by group members to read the state of other group members +static bool32 RecvPacket_MemberStateToMember(struct PokemonJump_Player *player, int multiplayerId) { - struct UnkPacket4 packet; + struct MemberStatePacket packet; - if ((gRecvCmds[multiplayerId][0] & 0xFF00) != 0x2F00) + if ((gRecvCmds[multiplayerId][0] & RFUCMD_MASK) != RFUCMD_SEND_PACKET) return FALSE; memcpy(&packet, &gRecvCmds[multiplayerId][1], sizeof(packet)); - if (packet.id != 4) + if (packet.id != PACKET_MEMBER_STATE) return FALSE; - arg0->unk10 = packet.unk1; - arg0->unk14 = packet.unk2; - arg0->unk18 = packet.unk3; - arg0->unkE = packet.unk4; + player->monState = packet.monState; + player->jumpState = packet.jumpState; + player->funcFinished = packet.funcFinished; + player->jumpTimeStart = packet.jumpTimeStart; return TRUE; } -void sub_8149CEC(struct PokemonJump2 *arg0) +static void StartPokeJumpGfx(struct PokemonJumpGfx *jumpGfx) { u8 taskId; - gUnknown_203F3D8 = arg0; - sub_8149D34(gUnknown_203F3D8); - taskId = CreateTask(sub_8149DA4, 3); - gUnknown_203F3D8->unk6 = taskId; - SetWordTaskArg(gUnknown_203F3D8->unk6, 2, (uintptr_t)gUnknown_203F3D8); - sub_8149D80(sub_8149DC8); + sPokemonJumpGfx = jumpGfx; + InitPokeJumpGfx(sPokemonJumpGfx); + taskId = CreateTask(Task_RunPokeJumpGfxFunc, 3); + sPokemonJumpGfx->taskId = taskId; + SetWordTaskArg(sPokemonJumpGfx->taskId, 2, (uintptr_t)sPokemonJumpGfx); + SetUpPokeJumpGfxFunc(LoadPokeJumpGfx); } -void sub_8149D24(void) +static void FreeWindowsAndDigitObj(void) { FreeAllWindowBuffers(); DigitObjUtil_Free(); } -static void sub_8149D34(struct PokemonJump2 *arg0) +static void InitPokeJumpGfx(struct PokemonJumpGfx *jumpGfx) { - arg0->unk4 = 0; - arg0->unk0 = 0; - arg0->unk12 = 0xFF; + jumpGfx->mainState = 0; + jumpGfx->funcFinished = FALSE; + jumpGfx->msgWindowId = WINDOW_NONE; } -// Gfx -static const u16 sPkmnJumpPal3[] = INCBIN_U16("graphics/link_games/pkmnjump_pal3.gbapal"); +static const u16 sInterface_Pal[] = INCBIN_U16("graphics/pokemon_jump/interface.gbapal"); -static const u16 sPkmnJumpBgPal[] = INCBIN_U16("graphics/link_games/pkmnjump_bg.gbapal"); -static const u32 sPkmnJumpBgGfx[] = INCBIN_U32("graphics/link_games/pkmnjump_bg.4bpp.lz"); -static const u32 sPkmnJumpBgTilemap[] = INCBIN_U32("graphics/link_games/pkmnjump_bg.bin.lz"); +static const u16 sBg_Pal[] = INCBIN_U16("graphics/pokemon_jump/bg.gbapal"); +static const u32 sBg_Gfx[] = INCBIN_U32("graphics/pokemon_jump/bg.4bpp.lz"); +static const u32 sBg_Tilemap[] = INCBIN_U32("graphics/pokemon_jump/bg.bin.lz"); -static const u16 sPkmnJumpVenusaurPal[] = INCBIN_U16("graphics/link_games/pkmnjump_venusaur.gbapal"); -static const u32 sPkmnJumpVenusaurGfx[] = INCBIN_U32("graphics/link_games/pkmnjump_venusaur.4bpp.lz"); -static const u32 sPkmnJumpVenusaurTilemap[] = INCBIN_U32("graphics/link_games/pkmnjump_venusaur.bin.lz"); +static const u16 sVenusaur_Pal[] = INCBIN_U16("graphics/pokemon_jump/venusaur.gbapal"); +static const u32 sVenusaur_Gfx[] = INCBIN_U32("graphics/pokemon_jump/venusaur.4bpp.lz"); +static const u32 sVenusaur_Tilemap[] = INCBIN_U32("graphics/pokemon_jump/venusaur.bin.lz"); -static const u16 sPkmnJumpResultsPal[] = INCBIN_U16("graphics/link_games/pkmnjump_results.gbapal"); -static const u32 sPkmnJumpResultsGfx[] = INCBIN_U32("graphics/link_games/pkmnjump_results.4bpp.lz"); -static const u32 sPkmnJumpResultsTilemap[] = INCBIN_U32("graphics/link_games/pkmnjump_results.bin.lz"); +static const u16 sBonuses_Pal[] = INCBIN_U16("graphics/pokemon_jump/bonuses.gbapal"); +static const u32 sBonuses_Gfx[] = INCBIN_U32("graphics/pokemon_jump/bonuses.4bpp.lz"); +static const u32 sBonuses_Tilemap[] = INCBIN_U32("graphics/pokemon_jump/bonuses.bin.lz"); -static const struct BgTemplate gUnknown_846D8D4[] = +static const struct BgTemplate sBgTemplates[] = { { - .bg = 0, + .bg = BG_INTERFACE, .charBaseIndex = 0, .mapBaseIndex = 27, .screenSize = 0, @@ -2650,7 +2924,7 @@ static const struct BgTemplate gUnknown_846D8D4[] = .baseTile = 0 }, { - .bg = 2, + .bg = BG_VENUSAUR, .charBaseIndex = 1, .mapBaseIndex = 30, .screenSize = 2, @@ -2659,7 +2933,7 @@ static const struct BgTemplate gUnknown_846D8D4[] = .baseTile = 0 }, { - .bg = 1, + .bg = BG_BONUSES, .charBaseIndex = 2, .mapBaseIndex = 12, .screenSize = 3, @@ -2668,7 +2942,7 @@ static const struct BgTemplate gUnknown_846D8D4[] = .baseTile = 0 }, { - .bg = 3, + .bg = BG_SCENERY, .charBaseIndex = 3, .mapBaseIndex = 29, .screenSize = 0, @@ -2678,10 +2952,10 @@ static const struct BgTemplate gUnknown_846D8D4[] = }, }; -static const struct WindowTemplate gUnknown_846D8E4[] = +static const struct WindowTemplate sWindowTemplates[] = { - { - .bg = 0, + [WIN_POINTS] = { + .bg = BG_INTERFACE, .tilemapLeft = 19, .tilemapTop = 0, .width = 6, @@ -2689,8 +2963,8 @@ static const struct WindowTemplate gUnknown_846D8E4[] = .paletteNum = 2, .baseBlock = 0x13, }, - { - .bg = 0, + [WIN_TIMES] = { + .bg = BG_INTERFACE, .tilemapLeft = 8, .tilemapTop = 0, .width = 6, @@ -2705,352 +2979,353 @@ struct { int id; void (*func)(void); -} static const gUnknown_846D8FC[] = -{ - {0x00, sub_8149DC8}, - {0x01, sub_8149F64}, - {0x02, sub_8149FD0}, - {0x03, sub_814A03C}, - {0x04, sub_814A0C8}, - {0x05, sub_814A174}, - {0x06, sub_814A218}, - {0x07, sub_814A264}, - {0x09, sub_814A3AC}, - {0x08, sub_814A308}, +} static const sPokeJumpGfxFuncs[] = +{ + {GFXFUNC_LOAD, LoadPokeJumpGfx}, // Element not used, LoadPokeJumpGfx is passed directly to SetUpPokeJumpGfxFunc + {GFXFUNC_SHOW_NAMES, PrintPlayerNamesNoHighlight}, + {GFXFUNC_SHOW_NAMES_HIGHLIGHT, PrintPlayerNamesWithHighlight}, + {GFXFUNC_ERASE_NAMES, ErasePlayerNames}, + {GFXFUNC_MSG_PLAY_AGAIN, Msg_WantToPlayAgain}, + {GFXFUNC_MSG_SAVING, Msg_SavingDontTurnOff}, + {GFXFUNC_ERASE_MSG, EraseMessage}, + {GFXFUNC_MSG_PLAYER_DROPPED, Msg_SomeoneDroppedOut}, + {GFXFUNC_COUNTDOWN, DoPokeJumpCountdown}, + {GFXFUNC_MSG_COMM_STANDBY, Msg_CommunicationStandby}, }; -void sub_8149D40(int arg0) +static void SetUpPokeJumpGfxFuncById(int id) { int i; - for (i = 0; i < NELEMS(gUnknown_846D8FC); i++) + for (i = 0; i < ARRAY_COUNT(sPokeJumpGfxFuncs); i++) { - if (gUnknown_846D8FC[i].id == arg0) - sub_8149D80(gUnknown_846D8FC[i].func); + if (sPokeJumpGfxFuncs[i].id == id) + SetUpPokeJumpGfxFunc(sPokeJumpGfxFuncs[i].func); } } -bool32 sub_8149D68(void) +static bool32 IsPokeJumpGfxFuncFinished(void) { - return (gUnknown_203F3D8->unk0 != 1); + return (sPokemonJumpGfx->funcFinished != TRUE); } -static void sub_8149D80(void (*func)(void)) +static void SetUpPokeJumpGfxFunc(void (*func)(void)) { - SetWordTaskArg(gUnknown_203F3D8->unk6, 0, (uintptr_t)func); - gUnknown_203F3D8->unk4 = 0; - gUnknown_203F3D8->unk0 = 0; + SetWordTaskArg(sPokemonJumpGfx->taskId, 0, (uintptr_t)func); + sPokemonJumpGfx->mainState = 0; + sPokemonJumpGfx->funcFinished = FALSE; } -static void sub_8149DA4(u8 taskId) +static void Task_RunPokeJumpGfxFunc(u8 taskId) { - if (!gUnknown_203F3D8->unk0) + if (!sPokemonJumpGfx->funcFinished) { + // Read the function set in the data by SetUpPokeJumpGfxFunc void (*func)(void) = (void *)(GetWordTaskArg(taskId, 0)); func(); } } -static void sub_8149DC8(void) +static void LoadPokeJumpGfx(void) { - switch (gUnknown_203F3D8->unk4) + switch (sPokemonJumpGfx->mainState) { case 0: ResetBgsAndClearDma3BusyFlags(FALSE); - InitBgsFromTemplates(0, gUnknown_846D8D4, NELEMS(gUnknown_846D8D4)); - InitWindows(gUnknown_846D8E4); + InitBgsFromTemplates(0, sBgTemplates, ARRAY_COUNT(sBgTemplates)); + InitWindows(sWindowTemplates); ResetBgPositions(); ResetTempTileDataBuffers(); - sub_814AD6C(gUnknown_203F3D8); - sub_814A9C8(); - LoadPalette(sPkmnJumpBgPal, 0, 0x20); - DecompressAndCopyTileDataToVram(3, sPkmnJumpBgGfx, 0, 0, 0); - DecompressAndCopyTileDataToVram(3, sPkmnJumpBgTilemap, 0, 0, 1); - LoadPalette(sPkmnJumpVenusaurPal, 0x30, 0x20); - DecompressAndCopyTileDataToVram(2, sPkmnJumpVenusaurGfx, 0, 0, 0); - DecompressAndCopyTileDataToVram(2, sPkmnJumpVenusaurTilemap, 0, 0, 1); - LoadPalette(sPkmnJumpResultsPal, 0x10, 0x20); - DecompressAndCopyTileDataToVram(1, sPkmnJumpResultsGfx, 0, 0, 0); - DecompressAndCopyTileDataToVram(1, sPkmnJumpResultsTilemap, 0, 0, 1); - LoadPalette(sPkmnJumpPal3, 0x20, 0x20); - SetBgTilemapBuffer(0, gUnknown_203F3D8->tilemapBuffer); - FillBgTilemapBufferRect_Palette0(0, 0, 0, 0, 0x20, 0x20); - sub_814A84C(); - sub_814AA24(0); + LoadSpriteSheetsAndPalettes(sPokemonJumpGfx); + InitDigitPrinters(); + LoadPalette(sBg_Pal, 0, 0x20); + DecompressAndCopyTileDataToVram(BG_SCENERY, sBg_Gfx, 0, 0, 0); + DecompressAndCopyTileDataToVram(BG_SCENERY, sBg_Tilemap, 0, 0, 1); + LoadPalette(sVenusaur_Pal, 0x30, 0x20); + DecompressAndCopyTileDataToVram(BG_VENUSAUR, sVenusaur_Gfx, 0, 0, 0); + DecompressAndCopyTileDataToVram(BG_VENUSAUR, sVenusaur_Tilemap, 0, 0, 1); + LoadPalette(sBonuses_Pal, 0x10, 0x20); + DecompressAndCopyTileDataToVram(BG_BONUSES, sBonuses_Gfx, 0, 0, 0); + DecompressAndCopyTileDataToVram(BG_BONUSES, sBonuses_Tilemap, 0, 0, 1); + LoadPalette(sInterface_Pal, 0x20, 0x20); + SetBgTilemapBuffer(BG_INTERFACE, sPokemonJumpGfx->tilemapBuffer); + FillBgTilemapBufferRect_Palette0(BG_INTERFACE, 0, 0, 0, 0x20, 0x20); + PrintScoreSuffixes(); + PrintScore(0); DrawWindowBorderWithStdpal3(0, 1, 0xE0); LoadUserWindowBorderGfx(0, 0x00A, 0xD0); - CopyBgTilemapBufferToVram(0); - CopyBgTilemapBufferToVram(2); - CopyBgTilemapBufferToVram(1); - gUnknown_203F3D8->unk4++; + CopyBgTilemapBufferToVram(BG_INTERFACE); + CopyBgTilemapBufferToVram(BG_VENUSAUR); + CopyBgTilemapBufferToVram(BG_BONUSES); + sPokemonJumpGfx->mainState++; break; case 1: if (!FreeTempTileDataBuffersIfPossible()) { - sub_814A8B8(); - sub_814B294(gUnknown_203F3D8); - sub_814B348(gUnknown_203F3D8, 6); - ShowBg(3); - ShowBg(0); - ShowBg(2); - HideBg(1); - gUnknown_203F3D8->unk4++; + CreateJumpMonSprites(); + CreateVineSprites(sPokemonJumpGfx); + UpdateVineAnim(sPokemonJumpGfx, VINE_UPSWING_LOWER); + ShowBg(BG_SCENERY); + ShowBg(BG_INTERFACE); + ShowBg(BG_VENUSAUR); + HideBg(BG_BONUSES); + sPokemonJumpGfx->mainState++; } break; case 2: - gUnknown_203F3D8->unk0 = 1; + sPokemonJumpGfx->funcFinished = TRUE; break; } } -static void sub_8149F64(void) +static void PrintPlayerNamesNoHighlight(void) { - switch (gUnknown_203F3D8->unk4) + switch (sPokemonJumpGfx->mainState) { case 0: - sub_814AADC(); - gUnknown_203F3D8->unk4++; + AddPlayerNameWindows(); + sPokemonJumpGfx->mainState++; break; case 1: if (!IsDma3ManagerBusyWithBgCopy()) { - sub_814AC30(FALSE); - gUnknown_203F3D8->unk4++; + PrintPokeJumpPlayerNames(FALSE); + sPokemonJumpGfx->mainState++; } break; case 2: if (!IsDma3ManagerBusyWithBgCopy()) { - sub_814AC94(); - gUnknown_203F3D8->unk4++; + DrawPlayerNameWindows(); + sPokemonJumpGfx->mainState++; } break; case 3: if (!IsDma3ManagerBusyWithBgCopy()) - gUnknown_203F3D8->unk0 = 1; + sPokemonJumpGfx->funcFinished = TRUE; break; } } -static void sub_8149FD0(void) +static void PrintPlayerNamesWithHighlight(void) { - switch (gUnknown_203F3D8->unk4) + switch (sPokemonJumpGfx->mainState) { case 0: - sub_814AADC(); - gUnknown_203F3D8->unk4++; + AddPlayerNameWindows(); + sPokemonJumpGfx->mainState++; break; case 1: if (!IsDma3ManagerBusyWithBgCopy()) { - sub_814AC30(TRUE); - gUnknown_203F3D8->unk4++; + PrintPokeJumpPlayerNames(TRUE); + sPokemonJumpGfx->mainState++; } break; case 2: if (!IsDma3ManagerBusyWithBgCopy()) { - sub_814AC94(); - gUnknown_203F3D8->unk4++; + DrawPlayerNameWindows(); + sPokemonJumpGfx->mainState++; } break; case 3: if (!IsDma3ManagerBusyWithBgCopy()) - gUnknown_203F3D8->unk0 = 1; + sPokemonJumpGfx->funcFinished = TRUE; break; } } -static void sub_814A03C(void) +static void ErasePlayerNames(void) { int i, numPlayers; - numPlayers = sub_81499A4(); - switch (gUnknown_203F3D8->unk4) + numPlayers = GetNumPokeJumpPlayers(); + switch (sPokemonJumpGfx->mainState) { case 0: for (i = 0; i < numPlayers; i++) - ClearWindowTilemap(gUnknown_203F3D8->unk1C[i]); + ClearWindowTilemap(sPokemonJumpGfx->nameWindowIds[i]); - CopyBgTilemapBufferToVram(0); - gUnknown_203F3D8->unk4++; + CopyBgTilemapBufferToVram(BG_INTERFACE); + sPokemonJumpGfx->mainState++; break; case 1: if (!IsDma3ManagerBusyWithBgCopy()) { for (i = 0; i < numPlayers; i++) - RemoveWindow(gUnknown_203F3D8->unk1C[i]); + RemoveWindow(sPokemonJumpGfx->nameWindowIds[i]); - gUnknown_203F3D8->unk0 = 1; + sPokemonJumpGfx->funcFinished = TRUE; } break; } } -static void sub_814A0C8(void) +static void Msg_WantToPlayAgain(void) { - switch (gUnknown_203F3D8->unk4) + switch (sPokemonJumpGfx->mainState) { case 0: - gUnknown_203F3D8->unk12 = sub_814A754(1, 8, 20, 2); - AddTextPrinterParameterized(gUnknown_203F3D8->unk12, 2, gText_WantToPlayAgain2, 0, 2, TEXT_SPEED_FF, NULL); - CopyWindowToVram(gUnknown_203F3D8->unk12, COPYWIN_GFX); - gUnknown_203F3D8->unk4++; + sPokemonJumpGfx->msgWindowId = AddMessageWindow(1, 8, 20, 2); + AddTextPrinterParameterized(sPokemonJumpGfx->msgWindowId, 2, gText_WantToPlayAgain2, 0, 2, TEXT_SPEED_FF, NULL); + CopyWindowToVram(sPokemonJumpGfx->msgWindowId, COPYWIN_GFX); + sPokemonJumpGfx->mainState++; break; case 1: if (!IsDma3ManagerBusyWithBgCopy()) { - PutWindowTilemap(gUnknown_203F3D8->unk12); - DrawTextBorderOuter(gUnknown_203F3D8->unk12, 1, 14); - sub_814A7D0(23, 7, 0); - CopyBgTilemapBufferToVram(0); - gUnknown_203F3D8->unk4++; + PutWindowTilemap(sPokemonJumpGfx->msgWindowId); + DrawTextBorderOuter(sPokemonJumpGfx->msgWindowId, 1, 14); + CreatePokeJumpYesNoMenu(23, 7, 0); + CopyBgTilemapBufferToVram(BG_INTERFACE); + sPokemonJumpGfx->mainState++; } break; case 2: if (!IsDma3ManagerBusyWithBgCopy()) - gUnknown_203F3D8->unk0 = 1; + sPokemonJumpGfx->funcFinished = TRUE; break; } } -static void sub_814A174(void) +static void Msg_SavingDontTurnOff(void) { - switch (gUnknown_203F3D8->unk4) + switch (sPokemonJumpGfx->mainState) { case 0: - gUnknown_203F3D8->unk12 = sub_814A754(2, 7, 26, 4); - AddTextPrinterParameterized(gUnknown_203F3D8->unk12, 2, gText_SavingDontTurnOffPower, 0, 2, TEXT_SPEED_FF, NULL); - CopyWindowToVram(gUnknown_203F3D8->unk12, COPYWIN_GFX); - gUnknown_203F3D8->unk4++; + sPokemonJumpGfx->msgWindowId = AddMessageWindow(2, 7, 26, 4); + AddTextPrinterParameterized(sPokemonJumpGfx->msgWindowId, 2, gText_SavingDontTurnOffPower, 0, 2, TEXT_SPEED_FF, NULL); + CopyWindowToVram(sPokemonJumpGfx->msgWindowId, COPYWIN_GFX); + sPokemonJumpGfx->mainState++; break; case 1: if (!IsDma3ManagerBusyWithBgCopy()) { - PutWindowTilemap(gUnknown_203F3D8->unk12); - DrawTextBorderOuter(gUnknown_203F3D8->unk12, 1, 14); - CopyBgTilemapBufferToVram(0); - gUnknown_203F3D8->unk4++; + PutWindowTilemap(sPokemonJumpGfx->msgWindowId); + DrawTextBorderOuter(sPokemonJumpGfx->msgWindowId, 1, 14); + CopyBgTilemapBufferToVram(BG_INTERFACE); + sPokemonJumpGfx->mainState++; } break; case 2: if (!IsDma3ManagerBusyWithBgCopy()) - gUnknown_203F3D8->unk0 = 1; + sPokemonJumpGfx->funcFinished = TRUE; break; } } -static void sub_814A218(void) +static void EraseMessage(void) { - switch (gUnknown_203F3D8->unk4) + switch (sPokemonJumpGfx->mainState) { case 0: - sub_814A6CC(); + ClearMessageWindow(); DestroyYesNoMenu(); - CopyBgTilemapBufferToVram(0); - gUnknown_203F3D8->unk4++; + CopyBgTilemapBufferToVram(BG_INTERFACE); + sPokemonJumpGfx->mainState++; break; case 1: - if (!sub_814A6FC() && !IsDma3ManagerBusyWithBgCopy()) - gUnknown_203F3D8->unk0 = 1; + if (!RemoveMessageWindow() && !IsDma3ManagerBusyWithBgCopy()) + sPokemonJumpGfx->funcFinished = TRUE; break; } } -static void sub_814A264(void) +static void Msg_SomeoneDroppedOut(void) { - switch (gUnknown_203F3D8->unk4) + switch (sPokemonJumpGfx->mainState) { case 0: - gUnknown_203F3D8->unk12 = sub_814A754(2, 8, 22, 4); - AddTextPrinterParameterized(gUnknown_203F3D8->unk12, 2, gText_SomeoneDroppedOut2, 0, 2, TEXT_SPEED_FF, NULL); - CopyWindowToVram(gUnknown_203F3D8->unk12, COPYWIN_GFX); - gUnknown_203F3D8->unk4++; + sPokemonJumpGfx->msgWindowId = AddMessageWindow(2, 8, 22, 4); + AddTextPrinterParameterized(sPokemonJumpGfx->msgWindowId, 2, gText_SomeoneDroppedOut2, 0, 2, TEXT_SPEED_FF, NULL); + CopyWindowToVram(sPokemonJumpGfx->msgWindowId, COPYWIN_GFX); + sPokemonJumpGfx->mainState++; break; case 1: if (!IsDma3ManagerBusyWithBgCopy()) { - PutWindowTilemap(gUnknown_203F3D8->unk12); - DrawTextBorderOuter(gUnknown_203F3D8->unk12, 1, 14); - CopyBgTilemapBufferToVram(0); - gUnknown_203F3D8->unk4++; + PutWindowTilemap(sPokemonJumpGfx->msgWindowId); + DrawTextBorderOuter(sPokemonJumpGfx->msgWindowId, 1, 14); + CopyBgTilemapBufferToVram(BG_INTERFACE); + sPokemonJumpGfx->mainState++; } break; case 2: if (!IsDma3ManagerBusyWithBgCopy()) - gUnknown_203F3D8->unk0 = 1; + sPokemonJumpGfx->funcFinished = TRUE; break; } } -static void sub_814A308(void) +static void Msg_CommunicationStandby(void) { - switch (gUnknown_203F3D8->unk4) + switch (sPokemonJumpGfx->mainState) { case 0: - gUnknown_203F3D8->unk12 = sub_814A754(7, 10, 16, 2); - AddTextPrinterParameterized(gUnknown_203F3D8->unk12, 2, gText_CommunicationStandby4, 0, 2, TEXT_SPEED_FF, NULL); - CopyWindowToVram(gUnknown_203F3D8->unk12, COPYWIN_GFX); - gUnknown_203F3D8->unk4++; + sPokemonJumpGfx->msgWindowId = AddMessageWindow(7, 10, 16, 2); + AddTextPrinterParameterized(sPokemonJumpGfx->msgWindowId, 2, gText_CommunicationStandby4, 0, 2, TEXT_SPEED_FF, NULL); + CopyWindowToVram(sPokemonJumpGfx->msgWindowId, COPYWIN_GFX); + sPokemonJumpGfx->mainState++; break; case 1: if (!IsDma3ManagerBusyWithBgCopy()) { - PutWindowTilemap(gUnknown_203F3D8->unk12); - DrawTextBorderOuter(gUnknown_203F3D8->unk12, 1, 14); - CopyBgTilemapBufferToVram(0); - gUnknown_203F3D8->unk4++; + PutWindowTilemap(sPokemonJumpGfx->msgWindowId); + DrawTextBorderOuter(sPokemonJumpGfx->msgWindowId, 1, 14); + CopyBgTilemapBufferToVram(BG_INTERFACE); + sPokemonJumpGfx->mainState++; } break; case 2: if (!IsDma3ManagerBusyWithBgCopy()) - gUnknown_203F3D8->unk0 = 1; + sPokemonJumpGfx->funcFinished = TRUE; break; } } -static void sub_814A3AC(void) +static void DoPokeJumpCountdown(void) { - switch (gUnknown_203F3D8->unk4) + switch (sPokemonJumpGfx->mainState) { case 0: - sub_814B43C(gUnknown_203F3D8); - gUnknown_203F3D8->unk4++; + StartPokeJumpCountdown(sPokemonJumpGfx); + sPokemonJumpGfx->mainState++; break; case 1: - if (!sub_814B460()) - gUnknown_203F3D8->unk0 = 1; + if (!IsPokeJumpCountdownRunning()) + sPokemonJumpGfx->funcFinished = TRUE; break; } } -void sub_814A3E4(void) +static void SetUpResetVineGfx(void) { - gUnknown_203F3D8->unkA = 0; - gUnknown_203F3D8->unkB = 0; - gUnknown_203F3D8->unkC = 6; - sub_814A95C(gUnknown_203F3D8->unkC); + sPokemonJumpGfx->resetVineState = 0; + sPokemonJumpGfx->resetVineTimer = 0; + sPokemonJumpGfx->vineState = VINE_UPSWING_LOWER; + UpdateVineSwing(sPokemonJumpGfx->vineState); } -bool32 sub_814A408(void) +static bool32 ResetVineGfx(void) { - switch (gUnknown_203F3D8->unkA) + switch (sPokemonJumpGfx->resetVineState) { case 0: - gUnknown_203F3D8->unkB++; - if (gUnknown_203F3D8->unkB > 10) + sPokemonJumpGfx->resetVineTimer++; + if (sPokemonJumpGfx->resetVineTimer > 10) { - gUnknown_203F3D8->unkB = 0; - gUnknown_203F3D8->unkC++; - if (gUnknown_203F3D8->unkC >= 10) + sPokemonJumpGfx->resetVineTimer = 0; + sPokemonJumpGfx->vineState++; + if (sPokemonJumpGfx->vineState >= NUM_VINESTATES) { - gUnknown_203F3D8->unkC = 0; - gUnknown_203F3D8->unkA++; + sPokemonJumpGfx->vineState = VINE_HIGHEST; + sPokemonJumpGfx->resetVineState++; } } - sub_814A95C(gUnknown_203F3D8->unkC); - if (gUnknown_203F3D8->unkC != 7) + UpdateVineSwing(sPokemonJumpGfx->vineState); + if (sPokemonJumpGfx->vineState != VINE_UPSWING_LOW) break; case 1: return FALSE; @@ -3061,87 +3336,87 @@ bool32 sub_814A408(void) static const u8 sPluralTxt[] = _("IES"); -void sub_814A468(u16 itemId, u16 quantity) +static void PrintPrizeMessage(u16 itemId, u16 quantity) { - CopyItemName(itemId, gUnknown_203F3D8->txtBuff[0]); - ConvertIntToDecimalStringN(gUnknown_203F3D8->txtBuff[1], quantity, STR_CONV_MODE_LEFT_ALIGN, 1); + CopyItemName(itemId, sPokemonJumpGfx->itemName); + ConvertIntToDecimalStringN(sPokemonJumpGfx->itemQuantityStr, quantity, STR_CONV_MODE_LEFT_ALIGN, 1); if (itemId >= FIRST_BERRY_INDEX && itemId < LAST_BERRY_INDEX) { if (quantity > 1) { - int endi = StringLength(gUnknown_203F3D8->txtBuff[0]); + int endi = StringLength(sPokemonJumpGfx->itemName); if (endi != 0) { endi--; - endi[gUnknown_203F3D8->txtBuff[0]] = EOS; - StringAppend(gUnknown_203F3D8->txtBuff[0], sPluralTxt); + endi[sPokemonJumpGfx->itemName] = EOS; + StringAppend(sPokemonJumpGfx->itemName, sPluralTxt); } } } DynamicPlaceholderTextUtil_Reset(); - DynamicPlaceholderTextUtil_SetPlaceholderPtr(0, gUnknown_203F3D8->txtBuff[0]); - DynamicPlaceholderTextUtil_SetPlaceholderPtr(1, gUnknown_203F3D8->txtBuff[1]); - DynamicPlaceholderTextUtil_ExpandPlaceholders(gUnknown_203F3D8->strBuff, gText_AwesomeWonF701F700); - gUnknown_203F3D8->unk12 = sub_814A754(4, 8, 22, 4); - AddTextPrinterParameterized(gUnknown_203F3D8->unk12, 2, gUnknown_203F3D8->strBuff, 0, 2, TEXT_SPEED_FF, NULL); - CopyWindowToVram(gUnknown_203F3D8->unk12, COPYWIN_GFX); - gUnknown_203F3D8->unk14 = MUS_LEVEL_UP; - gUnknown_203F3D8->unkD = 0; + DynamicPlaceholderTextUtil_SetPlaceholderPtr(0, sPokemonJumpGfx->itemName); + DynamicPlaceholderTextUtil_SetPlaceholderPtr(1, sPokemonJumpGfx->itemQuantityStr); + DynamicPlaceholderTextUtil_ExpandPlaceholders(sPokemonJumpGfx->prizeMsg, gText_AwesomeWonF701F700); + sPokemonJumpGfx->msgWindowId = AddMessageWindow(4, 8, 22, 4); + AddTextPrinterParameterized(sPokemonJumpGfx->msgWindowId, 2, sPokemonJumpGfx->prizeMsg, 0, 2, TEXT_SPEED_FF, NULL); + CopyWindowToVram(sPokemonJumpGfx->msgWindowId, COPYWIN_GFX); + sPokemonJumpGfx->fanfare = MUS_LEVEL_UP; + sPokemonJumpGfx->msgWindowState = 0; } -void sub_814A53C(u16 itemId) +static void PrintPrizeFilledBagMessage(u16 itemId) { - CopyItemName(itemId, gUnknown_203F3D8->txtBuff[0]); + CopyItemName(itemId, sPokemonJumpGfx->itemName); DynamicPlaceholderTextUtil_Reset(); - DynamicPlaceholderTextUtil_SetPlaceholderPtr(0, gUnknown_203F3D8->txtBuff[0]); - DynamicPlaceholderTextUtil_ExpandPlaceholders(gUnknown_203F3D8->strBuff, gText_FilledStorageSpace2); - gUnknown_203F3D8->unk12 = sub_814A754(4, 8, 22, 4); - AddTextPrinterParameterized(gUnknown_203F3D8->unk12, 2, gUnknown_203F3D8->strBuff, 0, 2, TEXT_SPEED_FF, NULL); - CopyWindowToVram(gUnknown_203F3D8->unk12, COPYWIN_GFX); - gUnknown_203F3D8->unk14 = 0; - gUnknown_203F3D8->unkD = 0; + DynamicPlaceholderTextUtil_SetPlaceholderPtr(0, sPokemonJumpGfx->itemName); + DynamicPlaceholderTextUtil_ExpandPlaceholders(sPokemonJumpGfx->prizeMsg, gText_FilledStorageSpace2); + sPokemonJumpGfx->msgWindowId = AddMessageWindow(4, 8, 22, 4); + AddTextPrinterParameterized(sPokemonJumpGfx->msgWindowId, 2, sPokemonJumpGfx->prizeMsg, 0, 2, TEXT_SPEED_FF, NULL); + CopyWindowToVram(sPokemonJumpGfx->msgWindowId, COPYWIN_GFX); + sPokemonJumpGfx->fanfare = MUS_DUMMY; + sPokemonJumpGfx->msgWindowState = 0; } -void sub_814A5B4(u16 itemId) +static void PrintNoRoomForPrizeMessage(u16 itemId) { - CopyItemName(itemId, gUnknown_203F3D8->txtBuff[0]); + CopyItemName(itemId, sPokemonJumpGfx->itemName); DynamicPlaceholderTextUtil_Reset(); - DynamicPlaceholderTextUtil_SetPlaceholderPtr(0, gUnknown_203F3D8->txtBuff[0]); - DynamicPlaceholderTextUtil_ExpandPlaceholders(gUnknown_203F3D8->strBuff, gText_CantHoldMore); - gUnknown_203F3D8->unk12 = sub_814A754(4, 9, 22, 2); - AddTextPrinterParameterized(gUnknown_203F3D8->unk12, 2, gUnknown_203F3D8->strBuff, 0, 2, TEXT_SPEED_FF, NULL); - CopyWindowToVram(gUnknown_203F3D8->unk12, COPYWIN_GFX); - gUnknown_203F3D8->unk14 = 0; - gUnknown_203F3D8->unkD = 0; + DynamicPlaceholderTextUtil_SetPlaceholderPtr(0, sPokemonJumpGfx->itemName); + DynamicPlaceholderTextUtil_ExpandPlaceholders(sPokemonJumpGfx->prizeMsg, gText_CantHoldMore); + sPokemonJumpGfx->msgWindowId = AddMessageWindow(4, 9, 22, 2); + AddTextPrinterParameterized(sPokemonJumpGfx->msgWindowId, 2, sPokemonJumpGfx->prizeMsg, 0, 2, TEXT_SPEED_FF, NULL); + CopyWindowToVram(sPokemonJumpGfx->msgWindowId, COPYWIN_GFX); + sPokemonJumpGfx->fanfare = MUS_DUMMY; + sPokemonJumpGfx->msgWindowState = 0; } -bool32 sub_814A62C(void) +static bool32 DoPrizeMessageAndFanfare(void) { - switch (gUnknown_203F3D8->unkD) + switch (sPokemonJumpGfx->msgWindowState) { case 0: if (!IsDma3ManagerBusyWithBgCopy()) { - PutWindowTilemap(gUnknown_203F3D8->unk12); - DrawTextBorderOuter(gUnknown_203F3D8->unk12, 1, 14); - CopyBgTilemapBufferToVram(0); - gUnknown_203F3D8->unkD++; + PutWindowTilemap(sPokemonJumpGfx->msgWindowId); + DrawTextBorderOuter(sPokemonJumpGfx->msgWindowId, 1, 14); + CopyBgTilemapBufferToVram(BG_INTERFACE); + sPokemonJumpGfx->msgWindowState++; } break; case 1: if (IsDma3ManagerBusyWithBgCopy()) break; - if (gUnknown_203F3D8->unk14 == 0) + if (sPokemonJumpGfx->fanfare == MUS_DUMMY) { - gUnknown_203F3D8->unkD += 2; + sPokemonJumpGfx->msgWindowState += 2; return FALSE; } - PlayFanfare(gUnknown_203F3D8->unk14); - gUnknown_203F3D8->unkD++; + PlayFanfare(sPokemonJumpGfx->fanfare); + sPokemonJumpGfx->msgWindowState++; case 2: if (!IsFanfareTaskInactive()) break; - gUnknown_203F3D8->unkD++; + sPokemonJumpGfx->msgWindowState++; case 3: return FALSE; } @@ -3149,52 +3424,50 @@ bool32 sub_814A62C(void) return TRUE; } -void sub_814A6CC(void) +static void ClearMessageWindow(void) { - if (gUnknown_203F3D8->unk12 != 0xFF) + if (sPokemonJumpGfx->msgWindowId != WINDOW_NONE) { - rbox_fill_rectangle(gUnknown_203F3D8->unk12); - CopyWindowToVram(gUnknown_203F3D8->unk12, COPYWIN_MAP); - gUnknown_203F3D8->unkD = 0; + rbox_fill_rectangle(sPokemonJumpGfx->msgWindowId); + CopyWindowToVram(sPokemonJumpGfx->msgWindowId, COPYWIN_MAP); + sPokemonJumpGfx->msgWindowState = 0; } } -// Can't match this without the ugly GOTO, oh well. -bool32 sub_814A6FC(void) +static bool32 RemoveMessageWindow(void) { - if (gUnknown_203F3D8->unk12 == 0xFF) - { - RET_FALSE: + if (sPokemonJumpGfx->msgWindowId == WINDOW_NONE) return FALSE; - } - if (gUnknown_203F3D8->unkD == 0) + switch (sPokemonJumpGfx->msgWindowState) { + case 0: if (!IsDma3ManagerBusyWithBgCopy()) { - RemoveWindow(gUnknown_203F3D8->unk12); - gUnknown_203F3D8->unk12 = 0xFF; - gUnknown_203F3D8->unkD++; - goto RET_FALSE; + RemoveWindow(sPokemonJumpGfx->msgWindowId); + sPokemonJumpGfx->msgWindowId = WINDOW_NONE; + sPokemonJumpGfx->msgWindowState++; } + else + break; + case 1: + return FALSE; } - else if (gUnknown_203F3D8->unkD == 1) - goto RET_FALSE; return TRUE; } -s8 sub_814A744(void) +static s8 HandlePlayAgainInput(void) { return Menu_ProcessInputNoWrapClearOnChoose(); } -static u32 sub_814A754(u32 left, u32 top, u32 width, u32 height) +static u32 AddMessageWindow(u32 left, u32 top, u32 width, u32 height) { u32 windowId; struct WindowTemplate window; - window.bg = 0; + window.bg = BG_INTERFACE; window.tilemapLeft = left; window.tilemapTop = top; window.width = width; @@ -3207,12 +3480,12 @@ static u32 sub_814A754(u32 left, u32 top, u32 width, u32 height) return windowId; } -static void sub_814A7D0(u16 left, u16 top, u8 cursorPos) +static void CreatePokeJumpYesNoMenu(u16 left, u16 top, u8 cursorPos) { struct WindowTemplate window; u8 a = cursorPos; - window.bg = 0; + window.bg = BG_INTERFACE; window.tilemapLeft = left; window.tilemapTop = top; window.width = 6; @@ -3223,171 +3496,212 @@ static void sub_814A7D0(u16 left, u16 top, u8 cursorPos) CreateYesNoMenu(&window, 2, 0, 2, 0x00a, 0xD, a); } -static void sub_814A84C(void) +// "Points" for jump score and "times" for number of jumps in a row +static void PrintScoreSuffixes(void) { u8 color[] = {TEXT_COLOR_TRANSPARENT, TEXT_COLOR_DARK_GRAY, TEXT_COLOR_LIGHT_GRAY}; - PutWindowTilemap(0); - PutWindowTilemap(1); - FillWindowPixelBuffer(0, PIXEL_FILL(0)); - FillWindowPixelBuffer(1, PIXEL_FILL(0)); - AddTextPrinterParameterized3(0, 0, 0, 2, color, 0, gText_SpacePoints2); - AddTextPrinterParameterized3(1, 0, 0, 2, color, 0, gText_SpaceTimes3); -} + PutWindowTilemap(WIN_POINTS); + PutWindowTilemap(WIN_TIMES); + FillWindowPixelBuffer(WIN_POINTS, PIXEL_FILL(0)); + FillWindowPixelBuffer(WIN_TIMES, PIXEL_FILL(0)); + AddTextPrinterParameterized3(WIN_POINTS, 0, 0, 2, color, 0, gText_SpacePoints2); + AddTextPrinterParameterized3(WIN_TIMES, 0, 0, 2, color, 0, gText_SpaceTimes3); +} + +// The venusaurs in the background are actually an empty 256x512 bg with 3 pairs of venusaurs on it. +// The below array is used to get values for where to set the bg Y to show the corresponding +// venusaur pair in their state of swinging the vine rope +// NEUTRAL/DOWN/UP refers to which direction the Venusaur is facing as it swings the vine +enum { + VENUSAUR_NEUTRAL, + VENUSAUR_DOWN, + VENUSAUR_UP, +}; -static const u8 gUnknown_846D953[] = {2, 2, 0, 0, 1, 1, 1, 0, 0, 2, 0, 0, 0}; +static const u8 sVenusaurStates[] = { + [VINE_HIGHEST] = VENUSAUR_UP, + [VINE_DOWNSWING_HIGHER] = VENUSAUR_UP, + [VINE_DOWNSWING_HIGH] = VENUSAUR_NEUTRAL, + [VINE_DOWNSWING_LOW] = VENUSAUR_NEUTRAL, + [VINE_DOWNSWING_LOWER] = VENUSAUR_DOWN, + [VINE_LOWEST] = VENUSAUR_DOWN, + [VINE_UPSWING_LOWER] = VENUSAUR_DOWN, + [VINE_UPSWING_LOW] = VENUSAUR_NEUTRAL, + [VINE_UPSWING_HIGH] = VENUSAUR_NEUTRAL, + [VINE_UPSWING_HIGHER] = VENUSAUR_UP, +}; -static const struct CompressedSpriteSheet gUnknown_846D960 = {gUnknown_8479688, 0, 0x320}; -static const struct SpritePalette gUnknown_846D968 = {gUnknown_8479668, 0x320}; +static const struct CompressedSpriteSheet sSpriteSheet_Digits = {gUnknown_8479688, 0, TAG_DIGITS}; +static const struct SpritePalette sSpritePalette_Digits = {gUnknown_8479668, TAG_DIGITS}; -static const u16 gUnknown_846D970[] = {0x06, 0x08, 0x10, 0x08}; -static const u16 gUnknown_846D978[] = {0x06, 0x08, 0x0b, 0x06, 0x10, 0x08}; -static const u16 gUnknown_846D984[] = {0x02, 0x06, 0x06, 0x08, 0x10, 0x08, 0x14, 0x06}; -static const u16 gUnknown_846D994[] = {0x02, 0x06, 0x06, 0x08, 0x0b, 0x06, 0x10, 0x08, 0x14, 0x06}; +static const u16 sPlayerNameWindowCoords_2Players[] = { + 6, 8, + 16, 8 +}; +static const u16 sPlayerNameWindowCoords_3Players[] = { + 6, 8, + 11, 6, + 16, 8 +}; +static const u16 sPlayerNameWindowCoords_4Players[] = { + 2, 6, + 6, 8, + 16, 8, + 20, 6 +}; +static const u16 sPlayerNameWindowCoords_5Players[] = { + 2, 6, + 6, 8, + 11, 6, + 16, 8, + 20, 6 +}; -static const u16 *const gUnknown_846D9A8[] = +static const u16 *const sPlayerNameWindowCoords[MAX_RFU_PLAYERS - 1] = { - gUnknown_846D970, - gUnknown_846D978, - gUnknown_846D984, - gUnknown_846D994, + sPlayerNameWindowCoords_2Players, + sPlayerNameWindowCoords_3Players, + sPlayerNameWindowCoords_4Players, + sPlayerNameWindowCoords_5Players, }; -static const s16 gUnknown_846D9B8[] = {0x0058, 0x0098}; -static const s16 gUnknown_846D9BC[] = {0x0058, 0x0078, 0x0098}; -static const s16 gUnknown_846D9C2[] = {0x0038, 0x0058, 0x0098, 0x00b8}; -static const s16 gUnknown_846D9CA[] = {0x0038, 0x0058, 0x0078, 0x0098, 0x00b8}; +static const s16 sMonXCoords_2Players[] = {88, 152}; +static const s16 sMonXCoords_3Players[] = {88, 120, 152}; +static const s16 sMonXCoords_4Players[] = {56, 88, 152, 184}; +static const s16 sMonXCoords_5Players[] = {56, 88, 120, 152, 184}; -static const s16 *const gUnknown_846D9D4[] = +static const s16 *const sMonXCoords[MAX_RFU_PLAYERS - 1] = { - gUnknown_846D9B8, - gUnknown_846D9BC, - gUnknown_846D9C2, - gUnknown_846D9CA, + sMonXCoords_2Players, + sMonXCoords_3Players, + sMonXCoords_4Players, + sMonXCoords_5Players, }; -static void sub_814A8B8(void) +static void CreateJumpMonSprites(void) { - int i, y, playersCount = sub_81499A4(); - const s16 *xCoords = gUnknown_846D9D4[playersCount - 2]; + int i, y, playersCount = GetNumPokeJumpPlayers(); + const s16 *xCoords = sMonXCoords[playersCount - 2]; for (i = 0; i < playersCount; i++) { - struct PokemonJump1_MonInfo *info = sub_81499C0(i); + struct PokemonJump_MonInfo *info = GetMonInfoByMultiplayerId(i); y = gMonFrontPicCoords[info->species].y_offset; - sub_814ADCC(gUnknown_203F3D8, info, *xCoords, y + 112, i); - sub_814B240(gUnknown_203F3D8, *xCoords, 112, i); + CreateJumpMonSprite(sPokemonJumpGfx, info, *xCoords, y + 112, i); + CreateStarSprite(sPokemonJumpGfx, *xCoords, 112, i); xCoords++; } } -void sub_814A940(u32 id, s16 y) +static void SetMonSpriteY(u32 id, s16 y) { - gUnknown_203F3D8->unk81A8[id]->y2 = y; + sPokemonJumpGfx->monSprites[id]->y2 = y; } -void sub_814A95C(int id) +static void UpdateVineSwing(int vineState) { - sub_814B348(gUnknown_203F3D8, id); - ChangeBgY(2, (gUnknown_846D953[id] * 5) << 0xD, 0); + UpdateVineAnim(sPokemonJumpGfx, vineState); + ChangeBgY(BG_VENUSAUR, (sVenusaurStates[vineState] * 5) << 13, BG_COORD_SET); } -int sub_814A98C(u8 flags) +static int DoSameJumpTimeBonus(u8 flags) { - int i, count; + int i, numPlayers; - for (i = 0, count = 0; i < 5; i++) + for (i = 0, numPlayers = 0; i < MAX_RFU_PLAYERS; i++) { if (flags & 1) { - sub_814AF0C(gUnknown_203F3D8, i); - count++; + // Player was part of a synchronous jump + // Give a bonus to them + DoStarAnim(sPokemonJumpGfx, i); + numPlayers++; } flags >>= 1; } - sub_814ACCC(count - 2); - return count; + ShowBonus(numPlayers - 2); + return numPlayers; } -static void sub_814A9C8(void) +static void InitDigitPrinters(void) { - struct DigitObjUtilTemplate unkStruct; - struct DigitObjUtilTemplate *ptr = &unkStruct; // This temp variable is needed to match, don't ask me why. - - ptr->shape = SPRITE_SHAPE(8x8); - ptr->size = SPRITE_SIZE(8x8); - ptr->strConvMode = 0; - ptr->priority = 1; - ptr->oamCount = 5; - ptr->xDelta = 8; - ptr->x = 108; - ptr->y = 6; - ptr->spriteSheet.compressed = &gUnknown_846D960; - ptr->spritePal = &gUnknown_846D968; + struct DigitObjUtilTemplate template = { + .shape = SPRITE_SHAPE(8x8), + .size = SPRITE_SIZE(8x8), + .strConvMode = 0, + .priority = 1, + .oamCount = 5, + .xDelta = 8, + .x = 108, + .y = 6, + .spriteSheet = {.compressed = &sSpriteSheet_Digits}, + .spritePal = &sSpritePalette_Digits, + }; - DigitObjUtil_Init(2); - DigitObjUtil_CreatePrinter(0, 0, ptr); + DigitObjUtil_Init(NUM_WINDOWS); + DigitObjUtil_CreatePrinter(WIN_POINTS, 0, &template); - unkStruct.oamCount = 4; - unkStruct.x = 30; - unkStruct.y = 6; - DigitObjUtil_CreatePrinter(1, 0, &unkStruct); + template.oamCount = 4; + template.x = 30; + template.y = 6; + DigitObjUtil_CreatePrinter(WIN_TIMES, 0, &template); } -void sub_814AA24(int arg0) +static void PrintScore(int num) { - DigitObjUtil_PrintNumOn(0, arg0); + DigitObjUtil_PrintNumOn(WIN_POINTS, num); } -void sub_814AA34(u16 arg0) +static void PrintJumpsInRow(u16 num) { - DigitObjUtil_PrintNumOn(1, arg0); + DigitObjUtil_PrintNumOn(WIN_TIMES, num); } -void sub_814AA48(u8 multiplayerId) +static void StartMonHitShake(u8 multiplayerId) { - sub_814AFE8(gUnknown_203F3D8, multiplayerId); + Gfx_StartMonHitShake(sPokemonJumpGfx, multiplayerId); } -void sub_814AA60(u8 multiplayerId) +static void StartMonHitFlash(u8 multiplayerId) { - sub_814B080(gUnknown_203F3D8, multiplayerId); + Gfx_StartMonHitFlash(sPokemonJumpGfx, multiplayerId); } -int sub_814AA78(int multiplayerId) +static int IsMonHitShakeActive(int multiplayerId) { - return sub_814B010(gUnknown_203F3D8, multiplayerId); + return Gfx_IsMonHitShakeActive(sPokemonJumpGfx, multiplayerId); } -void sub_814AA8C(void) +static void StopMonHitFlash(void) { - sub_814B0A8(gUnknown_203F3D8); + Gfx_StopMonHitFlash(sPokemonJumpGfx); } -void sub_814AAA0(void) +static void ResetMonSpriteSubpriorities(void) { - sub_814B134(gUnknown_203F3D8); + Gfx_ResetMonSpriteSubpriorities(sPokemonJumpGfx); } -void sub_814AAB4(int multiplayerId) +static void StartMonIntroBounce(int multiplayerId) { - sub_814B168(gUnknown_203F3D8, multiplayerId); + Gfx_StartMonIntroBounce(sPokemonJumpGfx, multiplayerId); } -int sub_814AAC8(void) +static int IsMonIntroBounceActive(void) { - return sub_814B190(gUnknown_203F3D8); + return Gfx_IsMonIntroBounceActive(sPokemonJumpGfx); } -static void sub_814AADC(void) +static void AddPlayerNameWindows(void) { struct WindowTemplate window; - int i, playersCount = sub_81499A4(); - const u16 *winCoords = gUnknown_846D9A8[playersCount - 2]; + int i, playersCount = GetNumPokeJumpPlayers(); + const u16 *winCoords = sPlayerNameWindowCoords[playersCount - 2]; - window.bg = 0; + window.bg = BG_INTERFACE; window.width = 8; window.height = 2; window.paletteNum = 2; @@ -3397,150 +3711,150 @@ static void sub_814AADC(void) { window.tilemapLeft = winCoords[0]; window.tilemapTop = winCoords[1]; - gUnknown_203F3D8->unk1C[i] = AddWindow(&window); - ClearWindowTilemap(gUnknown_203F3D8->unk1C[i]); + sPokemonJumpGfx->nameWindowIds[i] = AddWindow(&window); + ClearWindowTilemap(sPokemonJumpGfx->nameWindowIds[i]); window.baseBlock += 0x10; winCoords += 2; } - CopyBgTilemapBufferToVram(0); + CopyBgTilemapBufferToVram(BG_INTERFACE); } -static void sub_814AB98(int multiplayerId, u8 clr1, u8 clr2, u8 clr3) +static void PrintPokeJumpPlayerName(int multiplayerId, u8 bgColor, u8 fgColor, u8 shadow) { u32 x; - u8 colors[3] = {clr1, clr2, clr3}; + u8 colors[3] = {bgColor, fgColor, shadow}; - FillWindowPixelBuffer(gUnknown_203F3D8->unk1C[multiplayerId], PIXEL_FILL(0)); - x = 64 - GetStringWidth(0, sub_81499E0(multiplayerId), -1); + FillWindowPixelBuffer(sPokemonJumpGfx->nameWindowIds[multiplayerId], PIXEL_FILL(0)); + x = 64 - GetStringWidth(0, GetPokeJumpPlayerName(multiplayerId), -1); x /= 2; - AddTextPrinterParameterized3(gUnknown_203F3D8->unk1C[multiplayerId], 0, x, 2, colors, -1, sub_81499E0(multiplayerId)); - CopyWindowToVram(gUnknown_203F3D8->unk1C[multiplayerId], COPYWIN_GFX); + AddTextPrinterParameterized3(sPokemonJumpGfx->nameWindowIds[multiplayerId], 0, x, 2, colors, TEXT_SPEED_FF, GetPokeJumpPlayerName(multiplayerId)); + CopyWindowToVram(sPokemonJumpGfx->nameWindowIds[multiplayerId], COPYWIN_GFX); } -static void sub_814AC30(bool32 arg0) +static void PrintPokeJumpPlayerNames(bool32 highlightSelf) { - int i, var, playersCount = sub_81499A4(); + int i, multiplayerId, playersCount = GetNumPokeJumpPlayers(); - if (!arg0) + if (!highlightSelf) { for (i = 0; i < playersCount; i++) - sub_814AB98(i, TEXT_COLOR_TRANSPARENT, TEXT_COLOR_DARK_GRAY, TEXT_COLOR_LIGHT_GRAY); + PrintPokeJumpPlayerName(i, TEXT_COLOR_TRANSPARENT, TEXT_COLOR_DARK_GRAY, TEXT_COLOR_LIGHT_GRAY); } else { - var = sub_81499B4(); + // Highlight own name + multiplayerId = GetPokeJumpMultiplayerId(); for (i = 0; i < playersCount; i++) { - if (var != i) - sub_814AB98(i, TEXT_COLOR_TRANSPARENT, TEXT_COLOR_DARK_GRAY, TEXT_COLOR_LIGHT_GRAY); + if (multiplayerId != i) + PrintPokeJumpPlayerName(i, TEXT_COLOR_TRANSPARENT, TEXT_COLOR_DARK_GRAY, TEXT_COLOR_LIGHT_GRAY); else - sub_814AB98(i, TEXT_COLOR_TRANSPARENT, TEXT_COLOR_RED, TEXT_COLOR_LIGHT_RED); + PrintPokeJumpPlayerName(i, TEXT_COLOR_TRANSPARENT, TEXT_COLOR_RED, TEXT_COLOR_LIGHT_RED); } } } -static void sub_814AC94(void) +static void DrawPlayerNameWindows(void) { - int i, playersCount = sub_81499A4(); + int i, playersCount = GetNumPokeJumpPlayers(); for (i = 0; i < playersCount; i++) - PutWindowTilemap(gUnknown_203F3D8->unk1C[i]); - CopyBgTilemapBufferToVram(0); + PutWindowTilemap(sPokemonJumpGfx->nameWindowIds[i]); + CopyBgTilemapBufferToVram(BG_INTERFACE); } -static void sub_814ACCC(u8 arg0) +static void ShowBonus(u8 bonusId) { - gUnknown_203F3D8->unk18 = 0; - ChangeBgX(1, (arg0 / 2) << 16, 0); - ChangeBgY(1, (((arg0 % 2) << 8) - 40) << 8, 0); - ShowBg(1); - CreateTask(sub_814AD50, 4); + sPokemonJumpGfx->bonusTimer = 0; + ChangeBgX(BG_BONUSES, (bonusId / 2) * 256 * 256, BG_COORD_SET); + ChangeBgY(BG_BONUSES, (((bonusId % 2) * 256) - 40) * 256, BG_COORD_SET); + ShowBg(BG_BONUSES); + CreateTask(Task_UpdateBonus, 4); } -static bool32 sub_814AD18(void) +static bool32 UpdateBonus(void) { - if (gUnknown_203F3D8->unk18 >= 32) + if (sPokemonJumpGfx->bonusTimer >= 32) { return FALSE; } else { - ChangeBgY(1, 128, 1); - if (++gUnknown_203F3D8->unk18 >= 32) - HideBg(1); + ChangeBgY(BG_BONUSES, 128, BG_COORD_ADD); + if (++sPokemonJumpGfx->bonusTimer >= 32) + HideBg(BG_BONUSES); return TRUE; } } -static void sub_814AD50(u8 taskId) +static void Task_UpdateBonus(u8 taskId) { - if (!sub_814AD18()) + if (!UpdateBonus()) DestroyTask(taskId); } -static const u16 sPkmnJumpPal1[] = INCBIN_U16("graphics/link_games/pkmnjump_pal1.gbapal"); -static const u16 sPkmnJumpPal2[] = INCBIN_U16("graphics/link_games/pkmnjump_pal2.gbapal"); +static const u16 sPokeJumpPal1[] = INCBIN_U16("graphics/pokemon_jump/pal1.gbapal"); +static const u16 sPokeJumpPal2[] = INCBIN_U16("graphics/pokemon_jump/pal2.gbapal"); -static const u32 sPkmnJumpRopeGfx1[] = INCBIN_U32("graphics/link_games/pkmnjump_rope1.4bpp.lz"); -static const u32 sPkmnJumpRopeGfx2[] = INCBIN_U32("graphics/link_games/pkmnjump_rope2.4bpp.lz"); -static const u32 sPkmnJumpRopeGfx3[] = INCBIN_U32("graphics/link_games/pkmnjump_rope3.4bpp.lz"); -static const u32 sPkmnJumpRopeGfx4[] = INCBIN_U32("graphics/link_games/pkmnjump_rope4.4bpp.lz"); +static const u32 sVine1_Gfx[] = INCBIN_U32("graphics/pokemon_jump/vine1.4bpp.lz"); +static const u32 sVine2_Gfx[] = INCBIN_U32("graphics/pokemon_jump/vine2.4bpp.lz"); +static const u32 sVine3_Gfx[] = INCBIN_U32("graphics/pokemon_jump/vine3.4bpp.lz"); +static const u32 sVine4_Gfx[] = INCBIN_U32("graphics/pokemon_jump/vine4.4bpp.lz"); -static const u32 sPkmnJumpStarGfx[] = INCBIN_U32("graphics/link_games/pkmnjump_star.4bpp.lz"); +static const u32 sStar_Gfx[] = INCBIN_U32("graphics/pokemon_jump/star.4bpp.lz"); -static const struct CompressedSpriteSheet gUnknown_846E0B0[] = +static const struct CompressedSpriteSheet sCompressedSpriteSheets[] = { - {sPkmnJumpRopeGfx1, 0x600, 5}, - {sPkmnJumpRopeGfx2, 0x0c00, 6}, - {sPkmnJumpRopeGfx3, 0x0600, 7}, - {sPkmnJumpRopeGfx4, 0x0600, 8}, - {sPkmnJumpStarGfx, 0x0200, 10}, + {sVine1_Gfx, 0x600, GFXTAG_VINE1}, + {sVine2_Gfx, 0xC00, GFXTAG_VINE2}, + {sVine3_Gfx, 0x600, GFXTAG_VINE3}, + {sVine4_Gfx, 0x600, GFXTAG_VINE4}, + {sStar_Gfx, 0x200, GFXTAG_STAR}, }; -static const struct SpritePalette gUnknown_846E0D8[] = +static const struct SpritePalette sSpritePalettes[] = { - {sPkmnJumpPal1, 5}, - {sPkmnJumpPal2, 6}, + {sPokeJumpPal1, PALTAG_1}, + {sPokeJumpPal2, PALTAG_2}, }; -// Forward declarations. -static const struct OamData sOamData_846E170; -static const struct SpriteTemplate gUnknown_846E220; -static const struct SpriteTemplate gUnknown_846E238; -static const struct SpriteTemplate gUnknown_846E250; -static const struct SpriteTemplate gUnknown_846E268; +static const struct OamData sOamData_JumpMon; +static const struct SpriteTemplate sSpriteTemplate_Vine1; +static const struct SpriteTemplate sSpriteTemplate_Vine2; +static const struct SpriteTemplate sSpriteTemplate_Vine3; +static const struct SpriteTemplate sSpriteTemplate_Vine4; -static const struct SpriteTemplate gUnknown_846E0E8 = +static const struct SpriteTemplate sSpriteTemplate_JumpMon = { - .tileTag = 0, - .paletteTag = 0, - .oam = &sOamData_846E170, + .tileTag = TAG_MON1, + .paletteTag = TAG_MON1, + .oam = &sOamData_JumpMon, .anims = gDummySpriteAnimTable, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = SpriteCallbackDummy, }; -static const s16 gUnknown_846E100[][10] = +static const s16 sVineYCoords[VINE_SPRITES_PER_SIDE][NUM_VINESTATES] = { - {0x60, 0x60, 0x60, 0x72, 0x78, 0x78, 0x78, 0x72, 0x60, 0x60}, - {0x46, 0x50, 0x60, 0x72, 0x78, 0x80, 0x78, 0x72, 0x60, 0x50}, - {0x32, 0x48, 0x60, 0x72, 0x80, 0x88, 0x80, 0x72, 0x60, 0x48}, - {0x2a, 0x48, 0x60, 0x72, 0x80, 0x88, 0x80, 0x72, 0x60, 0x48}, + {96, 96, 96, 114, 120, 120, 120, 114, 96, 96}, + {70, 80, 96, 114, 120, 128, 120, 114, 96, 80}, + {50, 72, 96, 114, 128, 136, 128, 114, 96, 72}, + {42, 72, 96, 114, 128, 136, 128, 114, 96, 72}, }; -static const s16 gUnknown_846E150[] = {0x10, 0x28, 0x48, 0x68, 0x88, 0xa8, 0xc8, 0xe0}; +static const s16 sVineXCoords[VINE_SPRITES_PER_SIDE * 2] = {16, 40, 72, 104, 136, 168, 200, 224}; -static const struct SpriteTemplate *const gUnknown_846E160[] = +static const struct SpriteTemplate *const sSpriteTemplates_Vine[VINE_SPRITES_PER_SIDE] = { - &gUnknown_846E220, - &gUnknown_846E238, - &gUnknown_846E250, - &gUnknown_846E268, + &sSpriteTemplate_Vine1, + &sSpriteTemplate_Vine2, + &sSpriteTemplate_Vine3, + &sSpriteTemplate_Vine4, }; -static const struct OamData sOamData_846E170 = +static const struct OamData sOamData_JumpMon = { .y = 0, .affineMode = ST_OAM_AFFINE_OFF, @@ -3557,7 +3871,7 @@ static const struct OamData sOamData_846E170 = .affineParam = 0 }; -static const struct OamData sOamData_846E178 = +static const struct OamData sOamData_Vine16x32 = { .y = 0, .affineMode = ST_OAM_AFFINE_OFF, @@ -3574,7 +3888,7 @@ static const struct OamData sOamData_846E178 = .affineParam = 0 }; -static const struct OamData sOamData_846E180 = +static const struct OamData sOamData_Vine32x32 = { .y = 0, .affineMode = ST_OAM_AFFINE_OFF, @@ -3591,7 +3905,7 @@ static const struct OamData sOamData_846E180 = .affineParam = 0 }; -static const struct OamData sOamData_846E188 = +static const struct OamData sOamData_Vine32x16 = { .y = 0, .affineMode = ST_OAM_AFFINE_OFF, @@ -3608,143 +3922,144 @@ static const struct OamData sOamData_846E188 = .affineParam = 0 }; -static const union AnimCmd sSpriteAnim_846E190[] = +static const union AnimCmd sAnims_Vine_Highest[] = { ANIMCMD_FRAME(0, 1), ANIMCMD_END }; -static const union AnimCmd sSpriteAnim_846E198[] = +static const union AnimCmd sAnims_Vine_Higher[] = { ANIMCMD_FRAME(8, 1), ANIMCMD_END }; -static const union AnimCmd sSpriteAnim_846E1A0[] = +static const union AnimCmd sAnims_Vine_High[] = { ANIMCMD_FRAME(16, 1), ANIMCMD_END }; -static const union AnimCmd sSpriteAnim_846E1A8[] = +static const union AnimCmd sAnims_Vine_Low[] = { ANIMCMD_FRAME(24, 1), ANIMCMD_END }; -static const union AnimCmd sSpriteAnim_846E1B0[] = +static const union AnimCmd sAnims_Vine_Lower[] = { ANIMCMD_FRAME(32, 1), ANIMCMD_END }; -static const union AnimCmd sSpriteAnim_846E1B8[] = +static const union AnimCmd sAnims_Vine_Lowest[] = { ANIMCMD_FRAME(40, 1), ANIMCMD_END }; -static const union AnimCmd sSpriteAnim_846E1C0[] = +static const union AnimCmd sAnims_VineTall_Highest[] = { ANIMCMD_FRAME(0, 1), ANIMCMD_END }; -static const union AnimCmd sSpriteAnim_846E1C8[] = +static const union AnimCmd sAnims_VineTall_Higher[] = { ANIMCMD_FRAME(16, 1), ANIMCMD_END }; -static const union AnimCmd sSpriteAnim_846E1D0[] = +static const union AnimCmd sAnims_VineTall_High[] = { ANIMCMD_FRAME(32, 1), ANIMCMD_END }; -static const union AnimCmd sSpriteAnim_846E1D8[] = +static const union AnimCmd sAnims_VineTall_Low[] = { ANIMCMD_FRAME(48, 1), ANIMCMD_END }; -static const union AnimCmd sSpriteAnim_846E1E0[] = +static const union AnimCmd sAnims_VineTall_Lower[] = { ANIMCMD_FRAME(64, 1), ANIMCMD_END }; -static const union AnimCmd sSpriteAnim_846E1E8[] = +static const union AnimCmd sAnims_VineTall_Lowest[] = { ANIMCMD_FRAME(80, 1), ANIMCMD_END }; -static const union AnimCmd *const sSpriteAnimTable_846E1F0[] = +static const union AnimCmd *const sAnims_Vine[] = { - sSpriteAnim_846E190, - sSpriteAnim_846E198, - sSpriteAnim_846E1A0, - sSpriteAnim_846E1A8, - sSpriteAnim_846E1B0, - sSpriteAnim_846E1B8 + sAnims_Vine_Highest, + sAnims_Vine_Higher, + sAnims_Vine_High, + sAnims_Vine_Low, + sAnims_Vine_Lower, + sAnims_Vine_Lowest }; -static const union AnimCmd *const sSpriteAnimTable_846E208[] = +// Vine 2 needs its own set of anims because the graphic is twice as large +static const union AnimCmd *const sAnims_VineTall[] = { - sSpriteAnim_846E1C0, - sSpriteAnim_846E1C8, - sSpriteAnim_846E1D0, - sSpriteAnim_846E1D8, - sSpriteAnim_846E1E0, - sSpriteAnim_846E1E8 + sAnims_VineTall_Highest, + sAnims_VineTall_Higher, + sAnims_VineTall_High, + sAnims_VineTall_Low, + sAnims_VineTall_Lower, + sAnims_VineTall_Lowest }; -static const struct SpriteTemplate gUnknown_846E220 = +static const struct SpriteTemplate sSpriteTemplate_Vine1 = { - .tileTag = 5, - .paletteTag = 5, - .oam = &sOamData_846E178, - .anims = sSpriteAnimTable_846E1F0, + .tileTag = GFXTAG_VINE1, + .paletteTag = PALTAG_1, + .oam = &sOamData_Vine16x32, + .anims = sAnims_Vine, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = SpriteCallbackDummy, }; -static const struct SpriteTemplate gUnknown_846E238 = +static const struct SpriteTemplate sSpriteTemplate_Vine2 = { - .tileTag = 6, - .paletteTag = 5, - .oam = &sOamData_846E180, - .anims = sSpriteAnimTable_846E208, + .tileTag = GFXTAG_VINE2, + .paletteTag = PALTAG_1, + .oam = &sOamData_Vine32x32, + .anims = sAnims_VineTall, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = SpriteCallbackDummy, }; -static const struct SpriteTemplate gUnknown_846E250 = +static const struct SpriteTemplate sSpriteTemplate_Vine3 = { - .tileTag = 7, - .paletteTag = 5, - .oam = &sOamData_846E188, - .anims = sSpriteAnimTable_846E1F0, + .tileTag = GFXTAG_VINE3, + .paletteTag = PALTAG_1, + .oam = &sOamData_Vine32x16, + .anims = sAnims_Vine, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = SpriteCallbackDummy, }; -static const struct SpriteTemplate gUnknown_846E268 = +static const struct SpriteTemplate sSpriteTemplate_Vine4 = { - .tileTag = 8, - .paletteTag = 5, - .oam = &sOamData_846E188, - .anims = sSpriteAnimTable_846E1F0, + .tileTag = GFXTAG_VINE4, + .paletteTag = PALTAG_1, + .oam = &sOamData_Vine32x16, + .anims = sAnims_Vine, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = SpriteCallbackDummy, }; -static const struct OamData sOamData_846E280 = +static const struct OamData sOamData_Star = { .y = 0, .affineMode = ST_OAM_AFFINE_OFF, @@ -3761,13 +4076,13 @@ static const struct OamData sOamData_846E280 = .affineParam = 0 }; -static const union AnimCmd sSpriteAnim_846E288[] = +static const union AnimCmd sAnim_Star_Still[] = { ANIMCMD_FRAME(0, 0), ANIMCMD_END }; -static const union AnimCmd sSpriteAnim_846E290[] = +static const union AnimCmd sAnim_Star_Spinning[] = { ANIMCMD_FRAME(0, 4), ANIMCMD_FRAME(4, 4), @@ -3778,45 +4093,45 @@ static const union AnimCmd sSpriteAnim_846E290[] = ANIMCMD_END }; -static const union AnimCmd *const sSpriteAnimTable_846E2AC[] = +static const union AnimCmd *const sAnims_Star[] = { - sSpriteAnim_846E288, - sSpriteAnim_846E290 + sAnim_Star_Still, + sAnim_Star_Spinning }; -static const struct SpriteTemplate gUnknown_846E2B4 = +static const struct SpriteTemplate sSpriteTemplate_Star = { - .tileTag = 10, - .paletteTag = 5, - .oam = &sOamData_846E280, - .anims = sSpriteAnimTable_846E2AC, + .tileTag = GFXTAG_STAR, + .paletteTag = PALTAG_1, + .oam = &sOamData_Star, + .anims = sAnims_Star, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = SpriteCallbackDummy, }; -void sub_814AD6C(struct PokemonJump2 *arg0) +static void LoadSpriteSheetsAndPalettes(struct PokemonJumpGfx *jumpGfx) { int i; - for (i = 0; i < NELEMS(gUnknown_846E0B0); i++) - LoadCompressedSpriteSheet(&gUnknown_846E0B0[i]); + for (i = 0; i < ARRAY_COUNT(sCompressedSpriteSheets); i++) + LoadCompressedSpriteSheet(&sCompressedSpriteSheets[i]); - for (i = 0; i < NELEMS(gUnknown_846E0D8); i++) - LoadSpritePalette(&gUnknown_846E0D8[i]); + for (i = 0; i < ARRAY_COUNT(sSpritePalettes); i++) + LoadSpritePalette(&sSpritePalettes[i]); - arg0->unkE = IndexOfSpritePaletteTag(5); - arg0->unkF = IndexOfSpritePaletteTag(6); + jumpGfx->vinePalNumDownswing = IndexOfSpritePaletteTag(PALTAG_1); + jumpGfx->vinePalNumUpswing = IndexOfSpritePaletteTag(PALTAG_2); } -static void sub_814ADB4(struct Sprite *sprite) +static void ResetPokeJumpSpriteData(struct Sprite *sprite) { int i; - for (i = 0; i < 8; i++) + for (i = 0; i < (int)ARRAY_COUNT(sprite->data); i++) sprite->data[i] = 0; } -void sub_814ADCC(struct PokemonJump2 *arg0, struct PokemonJump1_MonInfo *jumpMon, s16 x, s16 y, u8 multiplayerId) +static void CreateJumpMonSprite(struct PokemonJumpGfx *jumpGfx, struct PokemonJump_MonInfo *monInfo, s16 x, s16 y, u8 multiplayerId) { struct SpriteTemplate spriteTemplate; struct SpriteSheet spriteSheet; @@ -3826,10 +4141,10 @@ void sub_814ADCC(struct PokemonJump2 *arg0, struct PokemonJump1_MonInfo *jumpMon u8 subpriority; u8 spriteId; - spriteTemplate = gUnknown_846E0E8; + spriteTemplate = sSpriteTemplate_JumpMon; buffer = Alloc(0x2000); - unusedBuffer = Alloc(0x800); - if (multiplayerId == sub_81499B4()) + unusedBuffer = Alloc(MON_PIC_SIZE); + if (multiplayerId == GetPokeJumpMultiplayerId()) subpriority = 3; else subpriority = multiplayerId + 4; @@ -3837,17 +4152,17 @@ void sub_814ADCC(struct PokemonJump2 *arg0, struct PokemonJump1_MonInfo *jumpMon if (buffer && unusedBuffer) { HandleLoadSpecialPokePic( - &gMonFrontPicTable[jumpMon->species], + &gMonFrontPicTable[monInfo->species], buffer, - jumpMon->species, - jumpMon->personality); + monInfo->species, + monInfo->personality); spriteSheet.data = buffer; spriteSheet.tag = multiplayerId; - spriteSheet.size = 0x800; + spriteSheet.size = MON_PIC_SIZE; LoadSpriteSheet(&spriteSheet); - spritePalette.data = GetMonSpritePalFromSpeciesAndPersonality(jumpMon->species, jumpMon->otId, jumpMon->personality); + spritePalette.data = GetMonSpritePalFromSpeciesAndPersonality(monInfo->species, monInfo->otId, monInfo->personality); spritePalette.tag = multiplayerId; LoadCompressedSpritePalette(&spritePalette); @@ -3859,28 +4174,32 @@ void sub_814ADCC(struct PokemonJump2 *arg0, struct PokemonJump1_MonInfo *jumpMon spriteId = CreateSprite(&spriteTemplate, x, y, subpriority); if (spriteId != MAX_SPRITES) { - arg0->unk81A8[multiplayerId] = &gSprites[spriteId]; - arg0->unk81FC[multiplayerId] = subpriority; + jumpGfx->monSprites[multiplayerId] = &gSprites[spriteId]; + jumpGfx->monSpriteSubpriorities[multiplayerId] = subpriority; return; } } - arg0->unk81A8[multiplayerId] = NULL; + jumpGfx->monSprites[multiplayerId] = NULL; } -void sub_814AF0C(struct PokemonJump2 *arg0, int multiplayerId) +#define sState data[0] +#define sTimer data[1] +#define sOffset data[7] // Never read + +static void DoStarAnim(struct PokemonJumpGfx *jumpGfx, int multiplayerId) { - sub_814ADB4(arg0->unk81BC[multiplayerId]); - arg0->unk81BC[multiplayerId]->data[7] = arg0->unk81A8[multiplayerId] - gSprites; - arg0->unk81BC[multiplayerId]->invisible = FALSE; - arg0->unk81BC[multiplayerId]->y = 96; - arg0->unk81BC[multiplayerId]->callback = sub_814AF74; - StartSpriteAnim(arg0->unk81BC[multiplayerId], 1); + ResetPokeJumpSpriteData(jumpGfx->starSprites[multiplayerId]); + jumpGfx->starSprites[multiplayerId]->sOffset = jumpGfx->monSprites[multiplayerId] - gSprites; + jumpGfx->starSprites[multiplayerId]->invisible = FALSE; + jumpGfx->starSprites[multiplayerId]->y = 96; + jumpGfx->starSprites[multiplayerId]->callback = SpriteCB_Star; + StartSpriteAnim(jumpGfx->starSprites[multiplayerId], 1); } -static void sub_814AF74(struct Sprite *sprite) +static void SpriteCB_Star(struct Sprite *sprite) { - switch (sprite->data[0]) + switch (sprite->sState) { case 0: if (sprite->animEnded) @@ -3891,15 +4210,15 @@ static void sub_814AF74(struct Sprite *sprite) break; case 1: sprite->y--; - sprite->data[1]++; + sprite->sTimer++; if (sprite->y <= 72) { sprite->y = 72; - sprite->data[0]++; + sprite->sState++; } break; case 2: - if (++sprite->data[1] >= 48) + if (++sprite->sTimer >= 48) { sprite->invisible = TRUE; sprite->callback = SpriteCallbackDummy; @@ -3908,113 +4227,131 @@ static void sub_814AF74(struct Sprite *sprite) } } -void sub_814AFE8(struct PokemonJump2 *arg0, int multiplayerId) +#undef sState +#undef sTimer +#undef sOffset + +static void Gfx_StartMonHitShake(struct PokemonJumpGfx *jumpGfx, int multiplayerId) { - arg0->unk81A8[multiplayerId]->callback = sub_814B038; - arg0->unk81A8[multiplayerId]->y2 = 0; - sub_814ADB4(arg0->unk81A8[multiplayerId]); + jumpGfx->monSprites[multiplayerId]->callback = SpriteCB_MonHitShake; + jumpGfx->monSprites[multiplayerId]->y2 = 0; + ResetPokeJumpSpriteData(jumpGfx->monSprites[multiplayerId]); } -bool32 sub_814B010(struct PokemonJump2 *arg0, int multiplayerId) +static bool32 Gfx_IsMonHitShakeActive(struct PokemonJumpGfx *jumpGfx, int multiplayerId) { - return arg0->unk81A8[multiplayerId]->callback == sub_814B038; + return jumpGfx->monSprites[multiplayerId]->callback == SpriteCB_MonHitShake; } -static void sub_814B038(struct Sprite *sprite) +#define sTimer data[1] +#define sNumShakes data[2] + +static void SpriteCB_MonHitShake(struct Sprite *sprite) { - if (++sprite->data[1] > 1) + if (++sprite->sTimer > 1) { - if (++sprite->data[2] & 1) + if (++sprite->sNumShakes & 1) sprite->y2 = 2; else sprite->y2 = -2; - sprite->data[1] = 0; + sprite->sTimer = 0; } - if (sprite->data[2] > 12) + if (sprite->sNumShakes > 12) { sprite->y2 = 0; sprite->callback = SpriteCallbackDummy; } } -void sub_814B080(struct PokemonJump2 *arg0, int multiplayerId) +#undef sTimer +#undef sNumShakes + +static void Gfx_StartMonHitFlash(struct PokemonJumpGfx *jumpGfx, int multiplayerId) { - sub_814ADB4(arg0->unk81A8[multiplayerId]); - arg0->unk81A8[multiplayerId]->callback = sub_814B100; + ResetPokeJumpSpriteData(jumpGfx->monSprites[multiplayerId]); + jumpGfx->monSprites[multiplayerId]->callback = SpriteCB_MonHitFlash; } -void sub_814B0A8(struct PokemonJump2 *arg0) +static void Gfx_StopMonHitFlash(struct PokemonJumpGfx *jumpGfx) { int i; - u16 numPlayers = sub_81499A4(); + u16 numPlayers = GetNumPokeJumpPlayers(); for (i = 0; i < numPlayers; i++) { - if (arg0->unk81A8[i]->callback == sub_814B100) + if (jumpGfx->monSprites[i]->callback == SpriteCB_MonHitFlash) { - arg0->unk81A8[i]->invisible = FALSE; - arg0->unk81A8[i]->callback = SpriteCallbackDummy; - arg0->unk81A8[i]->subpriority = 10; + jumpGfx->monSprites[i]->invisible = FALSE; + jumpGfx->monSprites[i]->callback = SpriteCallbackDummy; + jumpGfx->monSprites[i]->subpriority = 10; } } } -static void sub_814B100(struct Sprite *sprite) +#define sTimer data[0] + +static void SpriteCB_MonHitFlash(struct Sprite *sprite) { - if (++sprite->data[0] > 3) + if (++sprite->sTimer > 3) { - sprite->data[0] = 0; + sprite->sTimer = 0; sprite->invisible ^= 1; } } -void sub_814B134(struct PokemonJump2 *arg0) +#undef sTimer + +static void Gfx_ResetMonSpriteSubpriorities(struct PokemonJumpGfx *jumpGfx) { int i; - u16 numPlayers = sub_81499A4(); + u16 numPlayers = GetNumPokeJumpPlayers(); for (i = 0; i < numPlayers; i++) - arg0->unk81A8[i]->subpriority = arg0->unk81FC[i]; + jumpGfx->monSprites[i]->subpriority = jumpGfx->monSpriteSubpriorities[i]; } -void sub_814B168(struct PokemonJump2 *arg0, int multiplayerId) +static void Gfx_StartMonIntroBounce(struct PokemonJumpGfx *jumpGfx, int multiplayerId) { - sub_814ADB4(arg0->unk81A8[multiplayerId]); - arg0->unk81A8[multiplayerId]->callback = sub_814B1CC; + ResetPokeJumpSpriteData(jumpGfx->monSprites[multiplayerId]); + jumpGfx->monSprites[multiplayerId]->callback = SpriteCB_MonIntroBounce; } -bool32 sub_814B190(struct PokemonJump2 *arg0) +static bool32 Gfx_IsMonIntroBounceActive(struct PokemonJumpGfx *jumpGfx) { int i; - u16 numPlayers = sub_81499A4(); + u16 numPlayers = GetNumPokeJumpPlayers(); for (i = 0; i < numPlayers; i++) { - if (arg0->unk81A8[i]->callback == sub_814B1CC) + if (jumpGfx->monSprites[i]->callback == SpriteCB_MonIntroBounce) return TRUE; } return FALSE; } -static void sub_814B1CC(struct Sprite *sprite) +#define sState data[0] +#define sHopPos data[1] +#define sNumHops data[2] + +static void SpriteCB_MonIntroBounce(struct Sprite *sprite) { - switch (sprite->data[0]) + switch (sprite->sState) { case 0: PlaySE(SE_BIKE_HOP); - sprite->data[1] = 0; - sprite->data[0]++; + sprite->sHopPos = 0; + sprite->sState++; // fall through case 1: - sprite->data[1] += 4; - if (sprite->data[1] > 0x7F) - sprite->data[1] = 0; + sprite->sHopPos += 4; + if (sprite->sHopPos > 127) + sprite->sHopPos = 0; - sprite->y2 = -(gSineTable[sprite->data[1]] >> 3); - if (sprite->data[1] == 0) + sprite->y2 = -(gSineTable[sprite->sHopPos] >> 3); + if (sprite->sHopPos == 0) { - if (++sprite->data[2] < 2) - sprite->data[0] = 0; + if (++sprite->sNumHops < 2) + sprite->sState = 0; else sprite->callback = SpriteCallbackDummy; } @@ -4022,123 +4359,129 @@ static void sub_814B1CC(struct Sprite *sprite) } } -void sub_814B240(struct PokemonJump2 *arg0, s16 x, s16 y, u8 multiplayerId) +#undef sState +#undef sHopPos +#undef sNumHops + +static void CreateStarSprite(struct PokemonJumpGfx *jumpGfx, s16 x, s16 y, u8 multiplayerId) { - u8 spriteId = CreateSprite(&gUnknown_846E2B4, x, y, 1); + u8 spriteId = CreateSprite(&sSpriteTemplate_Star, x, y, 1); if (spriteId != MAX_SPRITES) { gSprites[spriteId].invisible = TRUE; - arg0->unk81BC[multiplayerId] = &gSprites[spriteId]; + jumpGfx->starSprites[multiplayerId] = &gSprites[spriteId]; } } -void sub_814B294(struct PokemonJump2 *arg0) +static void CreateVineSprites(struct PokemonJumpGfx *jumpGfx) { int i; int count; u8 spriteId; count = 0; - for (i = 0; i < 4; i++) + for (i = 0; i < VINE_SPRITES_PER_SIDE; i++) { - spriteId = CreateSprite(gUnknown_846E160[i], gUnknown_846E150[count], gUnknown_846E100[i][0], 2); - arg0->unk81D0[count] = &gSprites[spriteId]; + spriteId = CreateSprite(sSpriteTemplates_Vine[i], sVineXCoords[count], sVineYCoords[i][0], 2); + jumpGfx->vineSprites[count] = &gSprites[spriteId]; count++; } - for (i = 3; i >= 0; i--) + for (i = VINE_SPRITES_PER_SIDE - 1; i >= 0; i--) { - spriteId = CreateSprite(gUnknown_846E160[i], gUnknown_846E150[count], gUnknown_846E100[i][0], 2); - arg0->unk81D0[count] = &gSprites[spriteId]; - arg0->unk81D0[count]->hFlip = 1; + spriteId = CreateSprite(sSpriteTemplates_Vine[i], sVineXCoords[count], sVineYCoords[i][0], 2); + jumpGfx->vineSprites[count] = &gSprites[spriteId]; + jumpGfx->vineSprites[count]->hFlip = TRUE; count++; } } -void sub_814B348(struct PokemonJump2 *arg0, int arg1) +static void UpdateVineAnim(struct PokemonJumpGfx *jumpGfx, int vineState) { int i, count, palNum; int priority; - if (arg1 > 5) + if (vineState > VINE_LOWEST) { - arg1 = 10 - arg1; - priority = 3; - palNum = arg0->unkF; + // animNums for vine on upswing are same as + // on downswing but in reverse + vineState = NUM_VINESTATES - vineState; + priority = 3; // Set vine behind Pokémon + palNum = jumpGfx->vinePalNumUpswing; } else { - priority = 2; - palNum = arg0->unkE; + priority = 2; // Set vine in front of Pokémon + palNum = jumpGfx->vinePalNumDownswing; } count = 0; - for (i = 0; i < 4; i++) + for (i = 0; i < VINE_SPRITES_PER_SIDE; i++) { - arg0->unk81D0[count]->y = gUnknown_846E100[i][arg1]; - arg0->unk81D0[count]->oam.priority = priority; - arg0->unk81D0[count]->oam.paletteNum = palNum; - StartSpriteAnim(arg0->unk81D0[count], arg1); + jumpGfx->vineSprites[count]->y = sVineYCoords[i][vineState]; + jumpGfx->vineSprites[count]->oam.priority = priority; + jumpGfx->vineSprites[count]->oam.paletteNum = palNum; + StartSpriteAnim(jumpGfx->vineSprites[count], vineState); count++; } - for (i = 3; i >= 0; i--) + for (i = VINE_SPRITES_PER_SIDE - 1; i >= 0; i--) { - arg0->unk81D0[count]->y = gUnknown_846E100[i][arg1]; - arg0->unk81D0[count]->oam.priority = priority; - arg0->unk81D0[count]->oam.paletteNum = palNum; - StartSpriteAnim(arg0->unk81D0[count], arg1); + jumpGfx->vineSprites[count]->y = sVineYCoords[i][vineState]; + jumpGfx->vineSprites[count]->oam.priority = priority; + jumpGfx->vineSprites[count]->oam.paletteNum = palNum; + StartSpriteAnim(jumpGfx->vineSprites[count], vineState); count++; } } -void sub_814B43C(struct PokemonJump2 *arg0) +static void StartPokeJumpCountdown(struct PokemonJumpGfx *jumpGfx) { - StartMinigameCountdown(9, 7, 120, 80, 0); - sub_814B134(arg0); + StartMinigameCountdown(GFXTAG_COUNTDOWN, PALTAG_COUNTDOWN, 120, 80, 0); + Gfx_ResetMonSpriteSubpriorities(jumpGfx); } -bool32 sub_814B460(void) +static bool32 IsPokeJumpCountdownRunning(void) { return IsMinigameCountdownRunning(); } -static struct PokemonJumpRecords *sub_814B46C(void) +static struct PokemonJumpRecords *GetPokeJumpRecords(void) { return &gSaveBlock2Ptr->pokeJump; } -void ResetPokeJumpResults(void) +void ResetPokemonJumpRecords(void) { - struct PokemonJumpRecords *pokeJump = sub_814B46C(); - pokeJump->jumpsInRow = 0; - pokeJump->bestJumpScore = 0; - pokeJump->excellentsInRow = 0; - pokeJump->gamesWithMaxPlayers = 0; - pokeJump->unused2 = 0; - pokeJump->unused1 = 0; + struct PokemonJumpRecords *records = GetPokeJumpRecords(); + records->jumpsInRow = 0; + records->bestJumpScore = 0; + records->excellentsInRow = 0; + records->gamesWithMaxPlayers = 0; + records->unused2 = 0; + records->unused1 = 0; } -bool32 sub_814B494(u32 jumpScore, u16 jumpsInRow, u16 excellentsInRow) +static bool32 TryUpdateRecords(u32 jumpScore, u16 jumpsInRow, u16 excellentsInRow) { - struct PokemonJumpRecords *pokeJump = sub_814B46C(); - bool32 ret = FALSE; + struct PokemonJumpRecords *records = GetPokeJumpRecords(); + bool32 newRecord = FALSE; - if (pokeJump->bestJumpScore < jumpScore && jumpScore <= 99990) - pokeJump->bestJumpScore = jumpScore, ret = TRUE; - if (pokeJump->jumpsInRow < jumpsInRow && jumpsInRow <= 9999) - pokeJump->jumpsInRow = jumpsInRow, ret = TRUE; - if (pokeJump->excellentsInRow < excellentsInRow && excellentsInRow <= 9999) - pokeJump->excellentsInRow = excellentsInRow, ret = TRUE; + if (records->bestJumpScore < jumpScore && jumpScore <= MAX_JUMP_SCORE) + records->bestJumpScore = jumpScore, newRecord = TRUE; + if (records->jumpsInRow < jumpsInRow && jumpsInRow <= MAX_JUMPS) + records->jumpsInRow = jumpsInRow, newRecord = TRUE; + if (records->excellentsInRow < excellentsInRow && excellentsInRow <= MAX_JUMPS) + records->excellentsInRow = excellentsInRow, newRecord = TRUE; - return ret; + return newRecord; } -void sub_814B4E8(void) +static void IncrementGamesWithMaxPlayers(void) { - struct PokemonJumpRecords *pokeJump = sub_814B46C(); - if (pokeJump->gamesWithMaxPlayers < 9999) - pokeJump->gamesWithMaxPlayers++; + struct PokemonJumpRecords *records = GetPokeJumpRecords(); + if (records->gamesWithMaxPlayers < 9999) + records->gamesWithMaxPlayers++; } void ShowPokemonJumpRecords(void) @@ -4147,7 +4490,7 @@ void ShowPokemonJumpRecords(void) Task_ShowPokemonJumpRecords(taskId); } -static const struct WindowTemplate gUnknown_846E2CC = +static const struct WindowTemplate sWindowTemplate_Records = { .bg = 0, .tilemapLeft = 1, @@ -4158,36 +4501,39 @@ static const struct WindowTemplate gUnknown_846E2CC = .baseBlock = 0x1, }; -static const u8 *const gUnknown_846E2D4[] = {gText_JumpsInARow, gText_BestScore2, gText_ExcellentsInARow}; +static const u8 *const sRecordsTexts[] = {gText_JumpsInARow, gText_BestScore2, gText_ExcellentsInARow}; + +#define tState data[0] +#define tWindowId data[1] static void Task_ShowPokemonJumpRecords(u8 taskId) { s16 *data = gTasks[taskId].data; - switch (data[0]) + switch (tState) { case 0: - data[1] = AddWindow(&gUnknown_846E2CC); - sub_814B5C4(data[1]); - CopyWindowToVram(data[1], COPYWIN_BOTH); - data[0]++; + tWindowId = AddWindow(&sWindowTemplate_Records); + PrintRecordsText(tWindowId); + CopyWindowToVram(tWindowId, COPYWIN_BOTH); + tState++; break; case 1: if (!IsDma3ManagerBusyWithBgCopy()) - data[0]++; + tState++; break; case 2: if (JOY_NEW(A_BUTTON | B_BUTTON)) { - rbox_fill_rectangle(data[1]); - CopyWindowToVram(data[1], COPYWIN_MAP); - data[0]++; + rbox_fill_rectangle(tWindowId); + CopyWindowToVram(tWindowId, COPYWIN_MAP); + tState++; } break; case 3: if (!IsDma3ManagerBusyWithBgCopy()) { - RemoveWindow(data[1]); + RemoveWindow(tWindowId); DestroyTask(taskId); EnableBothScriptContexts(); } @@ -4195,24 +4541,27 @@ static void Task_ShowPokemonJumpRecords(u8 taskId) } } -static void sub_814B5C4(u16 windowId) +#undef tState +#undef tWindowId + +static void PrintRecordsText(u16 windowId) { int i, x; - int results[3]; - struct PokemonJumpRecords *pokeJump = sub_814B46C(); + int recordNums[3]; + struct PokemonJumpRecords *records = GetPokeJumpRecords(); u8 strbuf[8]; - results[0] = pokeJump->jumpsInRow; - results[1] = pokeJump->bestJumpScore; - results[2] = pokeJump->excellentsInRow; + recordNums[0] = records->jumpsInRow; + recordNums[1] = records->bestJumpScore; + recordNums[2] = records->excellentsInRow; TextWindow_SetStdFrame0_WithPal(windowId, 0x21D, 0xD0); DrawTextBorderOuter(windowId, 0x21D, 0xD); FillWindowPixelBuffer(windowId, PIXEL_FILL(1)); AddTextPrinterParameterized5(windowId, 2, gText_PkmnJumpRecords, 0, 0, TEXT_SPEED_FF, NULL, 1, 0); - for (i = 0; i < NELEMS(gUnknown_846E2D4); i++) + for (i = 0; i < ARRAY_COUNT(sRecordsTexts); i++) { - AddTextPrinterParameterized5(windowId, 2, gUnknown_846E2D4[i], 0, 20 + (i * 14), TEXT_SPEED_FF, NULL, 1, 0); - ConvertIntToDecimalStringN(strbuf, results[i], STR_CONV_MODE_LEFT_ALIGN, 5); + AddTextPrinterParameterized5(windowId, 2, sRecordsTexts[i], 0, 20 + (i * 14), TEXT_SPEED_FF, NULL, 1, 0); + ConvertIntToDecimalStringN(strbuf, recordNums[i], STR_CONV_MODE_LEFT_ALIGN, 5); TruncateToFirstWordOnly(strbuf); x = 0xDE - GetStringWidth(2, strbuf, 0); AddTextPrinterParameterized5(windowId, 2, strbuf, x, 20 + (i * 14), TEXT_SPEED_FF, NULL, 0, 0); diff --git a/src/random.c b/src/random.c index cb12ec805..413a3e60d 100644 --- a/src/random.c +++ b/src/random.c @@ -1,4 +1,5 @@ #include "global.h" +#include "random.h" // The number 1103515245 comes from the example implementation // of rand and srand in the ISO C standard. @@ -7,7 +8,7 @@ u32 gRngValue; u16 Random(void) { - gRngValue = 1103515245 * gRngValue + 24691; + gRngValue = ISO_RANDOMIZE1(gRngValue); return gRngValue >> 16; } |