diff options
author | GriffinR <griffin.g.richards@gmail.com> | 2021-03-23 22:06:08 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-03-23 22:06:08 -0400 |
commit | d8b76e6fb545efd69bfb18322a67243520e4d11d (patch) | |
tree | 12deeb8f5f21707819f36fa1e86aa73c255b8f65 /src | |
parent | ed16a7409ae9c808a110975dec1930f9f949a6d6 (diff) | |
parent | b280105f527f9cbb1bed2fde5ae006a87b697e23 (diff) |
Merge pull request #405 from Kurausukun/port_matchings
[PARTIALLY LEAK-INFORMED] Port Matchings from Emerald and Fix Other Nonmatchings
Diffstat (limited to 'src')
-rw-r--r-- | src/battle_anim_effects_3.c | 2 | ||||
-rw-r--r-- | src/berry_crush.c | 2982 | ||||
-rw-r--r-- | src/berry_crush_2.c | 1441 | ||||
-rw-r--r-- | src/berry_crush_3.c | 1390 | ||||
-rw-r--r-- | src/clear_save_data_screen.c | 20 | ||||
-rw-r--r-- | src/credits.c | 843 | ||||
-rw-r--r-- | src/dodrio_berry_picking_2.c | 2 | ||||
-rw-r--r-- | src/electric.c | 2 | ||||
-rw-r--r-- | src/event_object_movement.c | 317 | ||||
-rw-r--r-- | src/fldeff_cut.c | 42 | ||||
-rw-r--r-- | src/flying.c | 39 | ||||
-rw-r--r-- | src/menu2.c | 40 | ||||
-rw-r--r-- | src/mystery_gift_menu.c | 18 | ||||
-rw-r--r-- | src/normal.c | 2 | ||||
-rw-r--r-- | src/overworld.c | 61 | ||||
-rw-r--r-- | src/pokemon_special_anim_scene.c | 62 | ||||
-rw-r--r-- | src/quest_log_events.c | 14 | ||||
-rw-r--r-- | src/quest_log_objects.c | 4 | ||||
-rw-r--r-- | src/trainer_see.c | 12 | ||||
-rw-r--r-- | src/vs_seeker.c | 90 |
20 files changed, 3250 insertions, 4133 deletions
diff --git a/src/battle_anim_effects_3.c b/src/battle_anim_effects_3.c index 4778cb55e..ab12c02b4 100644 --- a/src/battle_anim_effects_3.c +++ b/src/battle_anim_effects_3.c @@ -3464,7 +3464,7 @@ void AnimSmokeBallEscapeCloud(struct Sprite *sprite) sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2) + gBattleAnimArgs[1]; sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET) + gBattleAnimArgs[2]; - sprite->callback = sub_80B1D3C; + sprite->callback = DestroyAnimSpriteAfterTimer; } static void sub_80E1990(u8 taskId) diff --git a/src/berry_crush.c b/src/berry_crush.c index 24fdf52a8..87888756e 100644 --- a/src/berry_crush.c +++ b/src/berry_crush.c @@ -1,18 +1,223 @@ #include "global.h" #include "gflib.h" +#include "battle_anim.h" +#include "berry.h" #include "berry_crush.h" #include "berry_pouch.h" #include "berry_powder.h" +#include "decompress.h" +#include "digit_obj_util.h" +#include "dynamic_placeholder_text_util.h" +#include "graphics.h" #include "item.h" #include "item_menu.h" +#include "item_menu_icons.h" #include "link.h" #include "link_rfu.h" #include "math_util.h" +#include "menu.h" +#include "minigame_countdown.h" +#include "new_menu_helpers.h" #include "overworld.h" +#include "random.h" +#include "save.h" +#include "scanline_effect.h" +#include "script.h" +#include "strings.h" #include "task.h" +#include "text_window.h" +#include "trig.h" #include "constants/songs.h" #include "constants/items.h" +#define TAG_COUNTDOWN 0x1000 + +enum { + BCTEXT_AREYOUREADY, + BCTEXT_WAITFOROTHERS, + BCTEXT_GAINEDPOWDER, + BCTEXT_RECORDINGRESULTS, + BCTEXT_ASKPLAYAGAIN, + BCTEXT_CANCEL_NOBERRIES, + BCTEXT_CANCEL_DROPPEDOUT, + BCTEXT_TIMEUP, + BCTEXT_COMMSTANDBY, +}; + +enum { + BCCMD_BeginNormalPaletteFade = 1, + BCCMD_WaitPaletteFade, + BCCMD_PrintMessage, + BCCMD_InitGfx, + BCCMD_TeardownGfx, + BCCMD_SignalReadyToBegin, + BCCMD_AskPickBerry, + BCCMD_GoToBerryPouch, + BCCMD_WaitForOthersToPickBerries, + BCCMD_DropBerriesIntoCrusher, + BCCMD_DropLid, + BCCMD_Countdown, + BCCMD_PlayGame_Master, + BCCMD_PlayGame_Slave, + BCCMD_FinishGame, + BCCMD_HandleTimeUp, + BCCMD_TabulateResults, + BCCMD_ShowResults, + BCCMD_SaveTheGame, + BCCMD_AskPlayAgain, + BCCMD_CommunicatePlayAgainResponses, + BCCMD_FadeOutToPlayAgain, + BCCMD_PlayAgainFailureMessage, + BCCMD_GracefulExit, + BCCMD_Quit, +}; + +struct BerryCrushGame_Player +{ + u8 unk0[PLAYER_NAME_LENGTH + 1 + 4]; + u16 unkC; + u16 unkE; + u16 unk10; + u16 unk12; + u16 unk14; + u16 unk16; + u16 unk18; + u16 unk1A; + u8 unk1B; + u8 unk1C; +}; + +struct BerryCrushGame_4E +{ + u16 unk0; + u16 unk2; + u8 unk4_0:1; + u8 unk4_1:1; + u8 unk4_2:1; + u8 unk4_3:5; + s8 unk5; + u16 unk6; + u16 unk8; + u16 unkA; + u16 unkC; +}; + +struct BerryCrushGame_40 +{ + s16 unk0; + s16 unk2; + s16 unk4; + s16 unk6; + s16 unk8; + s16 unkA; + s16 unkC; + s16 unkE; +}; + +struct BerryCrushGame_5C +{ + u16 unk00; + u8 unk02_0:1; + u8 unk02_1:1; + u8 pushedAButton:1; + u8 unk02_3:5; + s8 unk03; + u16 unk04; + u16 unk06; + u16 unk08; + u16 unk0A; +}; + +struct BerryCrushGame_68 +{ + u32 unk00; + u16 unk04; + u16 unk06; + u16 unk08; + u16 unk0A; + // 0: Number of A presses + // 1: Neatness + u16 stats[2][5]; + u8 unk20[2][8]; +}; + +struct BerryCrushPlayerSeatCoords +{ + u8 unk0; + u8 unk1; + u8 unk2; + s16 unk4; + s16 unk6; + s16 unk8; + s16 unkA; +}; + +struct BerryCrushGame_138 +{ + u8 animBerryIdx; + u8 unk1; + u8 unk2; + u8 unk3; + s16 minutes; + s16 secondsInt; + s16 secondsFrac; + const struct BerryCrushPlayerSeatCoords *seatCoords[5]; + struct Sprite *coreSprite; + struct Sprite *impactSprites[5]; + struct Sprite *berrySprites[5]; + struct Sprite *sparkleSprites[11]; + struct Sprite *timerSprites[2]; + u8 unk80; + u8 filler81; + u8 unk82; + u8 unk83[5]; + u16 bgBuffers[4][0x800]; +}; + +struct BerryCrushGame +{ + MainCallback savedCallback; + u32 (*cmdCallback)(struct BerryCrushGame *, u8 *); + u8 localId; + u8 playerCount; + u8 mainTask; + u8 textSpeed; + u8 cmdState; + u8 unkD; + u8 nextCmd; + u8 afterPalFadeCmd; + u16 unk10; + u16 gameState; + u16 unk14; + u16 pressingSpeed; + s16 unk18; + s16 unk1A; + s32 powder; + s32 unk20; + u8 unk24; + u8 unk25_0:1; + u8 unk25_1:1; + u8 unk25_2:1; + u8 unk25_3:1; + u8 unk25_4:1; + u8 unk25_5:3; + u16 unk26; + u16 timer; + s16 depth; + s16 vibration; + s16 unk2E; + s16 unk30; + s16 unk32; + s16 unk34; + u8 commandParams[0xC]; + u16 sendCmd[6]; + u16 recvCmd[7]; + struct BerryCrushGame_5C localState; + struct BerryCrushGame_68 unk68; + struct BerryCrushGame_Player unk98[5]; + struct BerryCrushGame_138 spritesManager; +}; + static EWRAM_DATA struct BerryCrushGame *sBerryCrushGamePtr = NULL; static void BerryCrush_InitPlayerNamesAndTextSpeed(struct BerryCrushGame *game); @@ -20,6 +225,555 @@ static void CB2_ReturnToBerryCrushGameFromBerryPouch(void); static void VBlankCB_BerryCrush(void); static void CB2_BerryCrush(void); static void Task_RunBerryCrushGame(u8 taskId); +static u32 BerryCrushCommand_BeginNormalPaletteFade(struct BerryCrushGame * game, u8 *params); +static u32 BerryCrushCommand_WaitPaletteFade(struct BerryCrushGame * game, u8 *params); +static u32 BerryCrushCommand_PrintMessage(struct BerryCrushGame * game, u8 *params); +static u32 BerryCrushCommand_InitGfx(struct BerryCrushGame * game, u8 *params); +static u32 BerryCrushCommand_TeardownGfx(struct BerryCrushGame * game, u8 *params); +static u32 BerryCrushCommand_SignalReadyToBegin(struct BerryCrushGame * game, u8 *params); +static u32 BerryCrushCommand_AskPickBerry(struct BerryCrushGame * game, u8 *params); +static u32 BerryCrushCommand_GoToBerryPouch(struct BerryCrushGame * game, u8 *params); +static u32 BerryCrushCommand_WaitForOthersToPickBerries(struct BerryCrushGame * game, u8 *params); +static u32 BerryCrushCommand_DropBerriesIntoCrusher(struct BerryCrushGame * game, u8 *params); +static u32 BerryCrushCommand_DropLid(struct BerryCrushGame * game, u8 *params); +static u32 BerryCrushCommand_Countdown(struct BerryCrushGame * game, u8 *params); +static u32 BerryCrushCommand_PlayGame_Master(struct BerryCrushGame * game, u8 *params); +static u32 BerryCrushCommand_PlayGame_Slave(struct BerryCrushGame * game, u8 *params); +static u32 BerryCrushCommand_FinishGame(struct BerryCrushGame * game, u8 *params); +static u32 BerryCrushCommand_HandleTimeUp(struct BerryCrushGame * game, u8 *params); +static u32 BerryCrushCommand_TabulateResults(struct BerryCrushGame * game, u8 *params); +static u32 BerryCrushCommand_ShowResults(struct BerryCrushGame * game, u8 *params); +static u32 BerryCrushCommand_SaveTheGame(struct BerryCrushGame * game, u8 *params); +static u32 BerryCrushCommand_AskPlayAgain(struct BerryCrushGame * game, u8 *params); +static u32 BerryCrushCommand_CommunicatePlayAgainResponses(struct BerryCrushGame * game, u8 *params); +static u32 BerryCrushCommand_FadeOutToPlayAgain(struct BerryCrushGame * game, u8 *params); +static u32 BerryCrushCommand_PlayAgainFailureMessage(struct BerryCrushGame * game, u8 *params); +static u32 BerryCrushCommand_GracefulExit(struct BerryCrushGame * game, u8 *params); +static u32 BerryCrushCommand_Quit(struct BerryCrushGame * game, u8 *params); +static void sub_814D4D8(struct BerryCrushGame * game); +static void BerryCrush_SetShowMessageParams(u8 *params, u8 stringId, u8 flags, u16 waitKeys, u8 followupCmd); +static void FramesToMinSec(struct BerryCrushGame_138 * arg0, u16 arg1); +static void PrintTextCentered(u8 windowId, u8 left, u8 colorId, const u8 *string); +static void PrintBerryCrushResultWindow(struct BerryCrushGame * sp0C, u8 sp10, u8 sp14, u8 r3); +static void sub_814E32C(struct BerryCrushGame * r8); +static void Task_ShowBerryCrushRankings(u8 r4); +static void BerryCrush_PrintTimeOnSprites(struct BerryCrushGame_138 * r4, u16 r1); +static void sub_814EB38(struct BerryCrushGame * r5); +static void sub_814EBB0(struct BerryCrushGame * r6); +static void sub_814EC80(struct BerryCrushGame * r6); +static void sub_814ECE0(struct BerryCrushGame * r6); +static void sub_814EF10(struct BerryCrushGame * r5); +static void SpriteCB_BerryCrushImpact(struct Sprite * sprite); +static void sub_814EFFC(struct Sprite * sprite); +static void sub_814F044(struct Sprite * sprite); +static void sub_814F0D8(struct Sprite * sprite); +struct BerryCrushGame *GetBerryCrushGame(void); +void StartBerryCrush(MainCallback callback); +u32 ExitBerryCrushWithCallback(MainCallback callback); +void CB2_BerryCrush_GoToBerryPouch(void); +void BerryCrush_SetVBlankCallback(void); +void BerryCrush_UnsetVBlankCallback(void); +void BerryCrush_UpdateSav2Records(void); +void BerryCrush_RunOrScheduleCommand(u16 command, u8 runMode, u8 *params); +void BerryCrush_SetPaletteFadeParams(u8 *params, bool8 communicateAfter, u32 selectedPals, s8 delay, u8 startY, u8 targetY, u16 palette); +int sub_814D9CC(struct BerryCrushGame *arg0); +int BerryCrush_InitBgs(void); +int BerryCrush_TeardownBgs(void); +void BerryCrush_CreateBerrySprites(struct BerryCrushGame *arg0, struct BerryCrushGame_138 *arg1); +void BerryCrushFreeBerrySpriteGfx(struct BerryCrushGame *arg0, struct BerryCrushGame_138 *arg1); +void sub_814DC5C(struct BerryCrushGame *arg0, struct BerryCrushGame_138 *arg1); +bool32 sub_814DE50(struct BerryCrushGame *arg0, struct BerryCrushGame_138 *arg1); +bool32 sub_814E644(struct BerryCrushGame *arg0, struct BerryCrushGame_138 *arg1); +void sub_814E80C(struct BerryCrushGame *arg0); +void sub_814DA04(struct BerryCrushGame *arg0); +void BerryCrush_HideTimerSprites(struct BerryCrushGame_138 *arg0); +void SpriteCB_DropBerryIntoCrusher(struct Sprite * sprite); +void ShowBerryCrushRankings(void); + +static const u8 gUnknown_846E2E0[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80}; +static const u8 gUnknown_846E2E8[] = {0x00, 0x01, 0x02, 0x03, 0x05, 0x00, 0x00, 0x00}; + +static const s8 gUnknown_846E2F0[][7] = { + {0x04, 0x01, 0x00, 0xff, 0x00, 0x00, 0x00}, + {0x04, 0x02, 0x00, 0xff, 0x00, 0x00, 0x00}, + {0x04, 0x02, 0x00, 0xfe, 0x00, 0x00, 0x00}, + {0x06, 0x03, 0x01, 0xff, 0xfd, 0xff, 0x00}, + {0x06, 0x04, 0x01, 0xfe, 0xfc, 0xfe, 0x00}, +}; + +ALIGNED(4) const u8 gUnknown_846E314[][4] = { + {0x03, 0x02, 0x01, 0x00}, + {0x03, 0x03, 0x01, 0x00}, + {0x03, 0x03, 0x02, 0x00}, + {0x03, 0x04, 0x02, 0x00}, + {0x03, 0x05, 0x03, 0x00} +}; + +static const u8 *const sBerryCrushMessages[] = { + gText_BerryCrush_AreYouReady, + gText_BerryCrush_WaitForOthersToChooseBerry, + gText_BerryCrush_GainedXUnitsOfPowder, + gText_BerryCrush_RecordingGameResults, + gText_BerryCrush_WantToPlayAgain, + gText_BerryCrush_NoBerries, + gText_BerryCrush_MemberDroppedOut, + gText_BerryCrush_TimeUp, + gText_BerryCrush_CommunicationStandby +}; + +static u32 (*const sBerryCrushCommands[])(struct BerryCrushGame * berryCrushGame, u8 *params) = { + NULL, + BerryCrushCommand_BeginNormalPaletteFade, + BerryCrushCommand_WaitPaletteFade, + BerryCrushCommand_PrintMessage, + BerryCrushCommand_InitGfx, + BerryCrushCommand_TeardownGfx, + BerryCrushCommand_SignalReadyToBegin, + BerryCrushCommand_AskPickBerry, + BerryCrushCommand_GoToBerryPouch, + BerryCrushCommand_WaitForOthersToPickBerries, + BerryCrushCommand_DropBerriesIntoCrusher, + BerryCrushCommand_DropLid, + BerryCrushCommand_Countdown, + BerryCrushCommand_PlayGame_Master, + BerryCrushCommand_PlayGame_Slave, + BerryCrushCommand_FinishGame, + BerryCrushCommand_HandleTimeUp, + BerryCrushCommand_TabulateResults, + BerryCrushCommand_ShowResults, + BerryCrushCommand_SaveTheGame, + BerryCrushCommand_AskPlayAgain, + BerryCrushCommand_CommunicatePlayAgainResponses, + BerryCrushCommand_FadeOutToPlayAgain, + BerryCrushCommand_PlayAgainFailureMessage, + BerryCrushCommand_GracefulExit, + BerryCrushCommand_Quit +}; + +static const u8 gUnknown_846E3B4[][4] = { + {0x02, 0x04, 0x06, 0x07}, + {0x03, 0x05, 0x08, 0x0b}, + {0x03, 0x07, 0x0b, 0x0f}, + {0x04, 0x08, 0x0c, 0x11} +}; + +static const u8 gUnknown_846E3C4[] = {5, 7, 9, 12}; + +static const u8 sReceivedPlayerBitmasks[] = {0x03, 0x07, 0x0F, 0x1F}; + +static const struct BgTemplate sBgTemplates[] = { + { + .bg = 0, + .charBaseIndex = 2, + .mapBaseIndex = 15, + .screenSize = 0, + .paletteMode = 0, + .priority = 0, + .baseTile = 0x0000 + }, { + .bg = 1, + .charBaseIndex = 0, + .mapBaseIndex = 13, + .screenSize = 2, + .paletteMode = 0, + .priority = 1, + .baseTile = 0x0000 + }, { + .bg = 2, + .charBaseIndex = 0, + .mapBaseIndex = 12, + .screenSize = 0, + .paletteMode = 0, + .priority = 2, + .baseTile = 0x0000 + }, { + .bg = 3, + .charBaseIndex = 0, + .mapBaseIndex = 11, + .screenSize = 0, + .paletteMode = 0, + .priority = 3, + .baseTile = 0x0000 + } +}; + +static const u8 sBerryCrushTextColorTable[][3] = { + { + TEXT_COLOR_WHITE, + TEXT_COLOR_DARK_GREY, + TEXT_COLOR_LIGHT_GREY + }, { + TEXT_COLOR_TRANSPARENT, + TEXT_COLOR_WHITE, + TEXT_COLOR_DARK_GREY + }, { + TEXT_COLOR_TRANSPARENT, + TEXT_COLOR_LIGHT_GREY, + TEXT_COLOR_RED + }, { + TEXT_COLOR_WHITE, + TEXT_COLOR_BLUE, + TEXT_COLOR_LIGHT_BLUE + }, { + TEXT_COLOR_WHITE, + TEXT_COLOR_GREEN, + TEXT_COLOR_LIGHT_GREEN + }, { + TEXT_COLOR_WHITE, + TEXT_COLOR_RED, + TEXT_COLOR_LIGHT_RED + } +}; + +static const struct WindowTemplate sWindowTemplate_BerryCrushRankings = { + .bg = 0, + .tilemapLeft = 3, + .tilemapTop = 4, + .width = 24, + .height = 13, + .paletteNum = 0xF, + .baseBlock = 0x001 +}; + +static const struct WindowTemplate gUnknown_846E3F8[] = { + { + .bg = 0, + .tilemapLeft = 0, + .tilemapTop = 0, + .width = 9, + .height = 2, + .paletteNum = 0x8, + .baseBlock = 0x3ed + }, { + .bg = 0, + .tilemapLeft = 0, + .tilemapTop = 3, + .width = 9, + .height = 2, + .paletteNum = 0x8, + .baseBlock = 0x3db + }, { + .bg = 0, + .tilemapLeft = 0, + .tilemapTop = 6, + .width = 9, + .height = 2, + .paletteNum = 0x8, + .baseBlock = 0x3c9 + }, { + .bg = 0, + .tilemapLeft = 21, + .tilemapTop = 3, + .width = 9, + .height = 2, + .paletteNum = 0x8, + .baseBlock = 0x3b7 + }, { + .bg = 0, + .tilemapLeft = 21, + .tilemapTop = 6, + .width = 9, + .height = 2, + .paletteNum = 0x8, + .baseBlock = 0x3a5 + }, DUMMY_WIN_TEMPLATE +}; + +static const struct WindowTemplate gUnknown_846E428[] = { + { + .bg = 0, + .tilemapLeft = 4, + .tilemapTop = 2, + .width = 22, + .height = 16, + .paletteNum = 0xF, + .baseBlock = 0x001 + }, { + .bg = 0, + .tilemapLeft = 4, + .tilemapTop = 2, + .width = 22, + .height = 16, + .paletteNum = 0xF, + .baseBlock = 0x001 + }, { + .bg = 0, + .tilemapLeft = 3, + .tilemapTop = 2, + .width = 24, + .height = 16, + .paletteNum = 0xF, + .baseBlock = 0x001 + }, DUMMY_WIN_TEMPLATE +}; + +static const u8 gUnknown_846E448[][4] = { + { 6, 8, 9, 11 }, + { 12, 14, 15, 16} +}; + +static const u32 sPressingSpeedConversionTable[] = { + // Decimal point is vertically aligned with the pixel + // directly between the >< below. + 50000000, // 50 + 25000000, // 25 + 12500000, // 12.5 + 6250000, // 6.25 + 3125000, // 3.125 + 1562500, // 1.5625 + 781250, // 0.78125 + 390625 // 0.390625 +}; + +static const u16 sBerryCrushCorePal[] = INCBIN_U16("graphics/link_games/unk_846E4D0.gbapal"); +static const u16 sBerryCrushImpactAndSparklesPal[] = INCBIN_U16("graphics/link_games/unk_846E7FC.gbapal"); +static const u16 sBerryCrushTImerPal[] = INCBIN_U16("graphics/link_games/unk_846ECC4.gbapal"); + +static const u32 sBerryCrushCoreTiles[] = INCBIN_U32("graphics/link_games/unk_846E4D0.4bpp.lz"); +static const u32 sBerryCrushImpactTiles[] = INCBIN_U32("graphics/link_games/unk_846E7FC.4bpp.lz"); +static const u32 sBerryCrushPowderSparklesTiles[] = INCBIN_U32("graphics/link_games/unk_846EB78.4bpp.lz"); +static const u32 sBerryCrushTimerTiles[] = INCBIN_U32("graphics/link_games/unk_846ECC4.4bpp.lz"); + +static const u32 gBerryCrushGrinderTopTilemap[] = INCBIN_U32("graphics/link_games/unk_846ED90.bin.lz"); +static const u32 gBerryCrushContainerCapTilemap[] = INCBIN_U32("graphics/link_games/unk_846EEC0.bin.lz"); +static const u32 gBerryCrushBackgroundTilemap[] = INCBIN_U32("graphics/link_games/unk_846F058.bin.lz"); + +static const u8 gUnknown_846F280[][5] = { + {1, 3}, + {0, 1, 3}, + {1, 3, 2, 4}, + {0, 1, 3, 2, 4} +}; + +static const struct BerryCrushPlayerSeatCoords gUnknown_846F294[] = { + {0, 0, 0, 0, -16, 0, 0}, + {1, 0, 3, -28, -4, -24, 16}, + {2, 0, 6, -16, 20, -8, 16}, + {3, 20, 3, 28, -4, 32, -8}, + {4, 20, 6, 16, 20, 16, -8} +}; + +static const s8 gUnknown_846F2D0[][2] = { + { 0, 0}, + {-1, 0}, + { 1, 1} +}; + +static const s8 gUnknown_846F2D6[][2] = { + { 0, 0}, + {-16, -4}, + { 16, -4}, + { -8, -2}, + { 8, -2}, + {-24, -8}, + { 24, -8}, + {-32, -12}, + { 32, -12}, + {-40, -16}, + { 40, -16} +}; + +static const u16 sPlayerBerrySpriteTags[] = { + 5, 6, 7, 8, 9 +}; + +static const struct CompressedSpriteSheet sSpriteSheets[] = { + {sBerryCrushCoreTiles, 0x0800, 1}, + {sBerryCrushImpactTiles, 0x0e00, 2}, + {sBerryCrushPowderSparklesTiles, 0x0700, 3}, + {sBerryCrushTimerTiles, 0x02c0, 4}, + {} +}; + +static const struct SpritePalette sSpritePals[] = { + {sBerryCrushCorePal, 1}, + {sBerryCrushImpactAndSparklesPal, 2}, + {sBerryCrushTImerPal, 4}, + {} +}; + +static const union AnimCmd gUnknown_846F340[] = { + ANIMCMD_FRAME(0x00, 0), + ANIMCMD_END +}; + +static const union AnimCmd gUnknown_846F348[] = { + ANIMCMD_FRAME(0x00, 4), + ANIMCMD_FRAME(0x10, 4), + ANIMCMD_FRAME(0x20, 4), + ANIMCMD_END +}; + +static const union AnimCmd gUnknown_846F358[] = { + ANIMCMD_FRAME(0x30, 2), + ANIMCMD_FRAME(0x40, 2), + ANIMCMD_FRAME(0x50, 2), + ANIMCMD_FRAME(0x60, 2), + ANIMCMD_END +}; + +static const union AnimCmd gUnknown_846F36C[] = { + ANIMCMD_FRAME(0x00, 2), + ANIMCMD_FRAME(0x04, 2), + ANIMCMD_FRAME(0x08, 2), + ANIMCMD_FRAME(0x0c, 2), + ANIMCMD_FRAME(0x10, 2), + ANIMCMD_FRAME(0x14, 2), + ANIMCMD_JUMP(0) +}; + +static const union AnimCmd gUnknown_846F388[] = { + ANIMCMD_FRAME(0x18, 4), + ANIMCMD_FRAME(0x1c, 4), + ANIMCMD_FRAME(0x20, 4), + ANIMCMD_FRAME(0x24, 4), + ANIMCMD_FRAME(0x28, 4), + ANIMCMD_FRAME(0x2c, 4), + ANIMCMD_FRAME(0x30, 4), + ANIMCMD_FRAME(0x34, 4), + ANIMCMD_JUMP(0) +}; + +static const union AnimCmd gUnknown_846F3AC[] = { + ANIMCMD_FRAME(0x14, 0), + ANIMCMD_END +}; + +static const union AnimCmd gUnknown_846F3B4[] = { + ANIMCMD_FRAME(0x00, 0), + ANIMCMD_END +}; + +static const union AffineAnimCmd gUnknown_846F3BC[] = { + AFFINEANIMCMD_FRAME(256, 256, 0, 0), + AFFINEANIMCMD_FRAME(0, 0, 2, 1), + AFFINEANIMCMD_JUMP(1) +}; + +static const union AffineAnimCmd gUnknown_846F3D4[] = { + AFFINEANIMCMD_FRAME(256, 256, 0, 0), + AFFINEANIMCMD_FRAME(0, 0, -2, 1), + AFFINEANIMCMD_JUMP(1) +}; + +static const union AnimCmd *const sAnimTable_BerryCrushCore[] = { + gUnknown_846F340 +}; + +static const union AnimCmd *const sAnimTable_BerryCrushImpact[] = { + gUnknown_846F348, + gUnknown_846F358 +}; + +static const union AnimCmd *const sAnimTable_BerryCrushPowderSparkles[] = { + gUnknown_846F36C, + gUnknown_846F388 +}; + +static const union AnimCmd *const sAnimTable_BerryCrushTimer[] = { + gUnknown_846F3AC +}; + +static const union AnimCmd *const gUnknown_846F404[] = { + gUnknown_846F3B4 +}; + +static const union AffineAnimCmd *const gUnknown_846F408[] = { + gUnknown_846F3BC, + gUnknown_846F3D4 +}; + + +static const struct SpriteTemplate sSpriteTemplate_BerryCrushCore = { + .tileTag = 1, + .paletteTag = 1, + .oam = &gOamData_AffineOff_ObjNormal_64x64, + .anims = sAnimTable_BerryCrushCore, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy +}; + +static const struct SpriteTemplate sSpriteTemplate_BerryCrushImpact = { + .tileTag = 2, + .paletteTag = 2, + .oam = &gOamData_AffineOff_ObjNormal_32x32, + .anims = sAnimTable_BerryCrushImpact, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCB_BerryCrushImpact +}; + +static const struct SpriteTemplate sSpriteTemplate_BerryCrushPowderSparkles = { + .tileTag = 3, + .paletteTag = 2, + .oam = &gOamData_AffineOff_ObjNormal_16x16, + .anims = sAnimTable_BerryCrushPowderSparkles, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy +}; + +static const struct SpriteTemplate sSpriteTemplate_BerryCrushTimer = { + .tileTag = 4, + .paletteTag = 4, + .oam = &gOamData_AffineOff_ObjNormal_8x16, + .anims = sAnimTable_BerryCrushTimer, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy +}; + +static const struct SpriteTemplate sSpriteTemplate_PlayerBerry = { + .tileTag = 5, + .paletteTag = 5, + .oam = &gOamData_AffineDouble_ObjNormal_32x32, + .anims = gUnknown_846F404, + .affineAnims = gUnknown_846F408, + .callback = SpriteCallbackDummy +}; + +static const struct DigitObjUtilTemplate sDigitObjTemplates[] = { + { + .strConvMode = 1, + .shape = SPRITE_SHAPE(8x16), + .size = SPRITE_SIZE(8x16), + .priority = 0, + .oamCount = 2, + .xDelta = 8, + .x = 156, + .y = 0, + .spriteSheet = {.compressed = &sSpriteSheets[3]}, + .spritePal = &sSpritePals[2], + }, { + .strConvMode = 0, + .shape = SPRITE_SHAPE(8x16), + .size = SPRITE_SIZE(8x16), + .priority = 0, + .oamCount = 2, + .xDelta = 8, + .x = 180, + .y = 0, + .spriteSheet = {.compressed = &sSpriteSheets[3]}, + .spritePal = &sSpritePals[2], + }, { + .strConvMode = 0, + .shape = SPRITE_SHAPE(8x16), + .size = SPRITE_SIZE(8x16), + .priority = 0, + .oamCount = 2, + .xDelta = 8, + .x = 204, + .y = 0, + .spriteSheet = {.compressed = &sSpriteSheets[3]}, + .spritePal = &sSpritePals[2], + } +}; + +static const u8 *const sBCRankingHeaders[] = { + gText_SpaceTimes, + gText_XDotY, + gText_StrVar1Berry, + gText_NeatnessRankings, + gText_CooperativeRankings, + gText_PressingPowerRankings +}; struct BerryCrushGame *GetBerryCrushGame(void) { @@ -34,7 +788,7 @@ u32 ExitBerryCrushWithCallback(MainCallback callback) if (callback == NULL) callback = sBerryCrushGamePtr->savedCallback; - DestroyTask(sBerryCrushGamePtr->taskId); + DestroyTask(sBerryCrushGamePtr->mainTask); FREE_AND_SET_NULL(sBerryCrushGamePtr); SetMainCallback2(callback); if (callback == CB2_ReturnToField) @@ -71,7 +825,7 @@ void StartBerryCrush(MainCallback callback) return; } - sBerryCrushGamePtr = AllocZeroed(sizeof(*sBerryCrushGamePtr)); + sBerryCrushGamePtr = AllocZeroed(sizeof(struct BerryCrushGame)); if (!sBerryCrushGamePtr) { SetMainCallback2(callback); @@ -91,28 +845,28 @@ void StartBerryCrush(MainCallback callback) BerryCrush_SetPaletteFadeParams(sBerryCrushGamePtr->commandParams, TRUE, 0xFFFFFFFF, 0, 16, 0, RGB_BLACK); BerryCrush_RunOrScheduleCommand(BCCMD_InitGfx, 1, sBerryCrushGamePtr->commandParams); SetMainCallback2(CB2_BerryCrush); - sBerryCrushGamePtr->taskId = CreateTask(Task_RunBerryCrushGame, 8); + sBerryCrushGamePtr->mainTask = CreateTask(Task_RunBerryCrushGame, 8); } static void CB2_ReturnToBerryCrushGameFromBerryPouch(void) { if (gSpecialVar_ItemId < FIRST_BERRY_INDEX || gSpecialVar_ItemId > LAST_BERRY_INDEX + 1) - gSpecialVar_ItemId = ITEM_CHERI_BERRY; + gSpecialVar_ItemId = FIRST_BERRY_INDEX; else RemoveBagItem(gSpecialVar_ItemId, 1); - sBerryCrushGamePtr->unk68.as_four_players.others[sBerryCrushGamePtr->localId].berryId = gSpecialVar_ItemId - FIRST_BERRY_INDEX; + sBerryCrushGamePtr->unk98[sBerryCrushGamePtr->localId].unkC = gSpecialVar_ItemId - FIRST_BERRY_INDEX; sBerryCrushGamePtr->nextCmd = BCCMD_BeginNormalPaletteFade; sBerryCrushGamePtr->afterPalFadeCmd = BCCMD_WaitForOthersToPickBerries; BerryCrush_SetPaletteFadeParams(sBerryCrushGamePtr->commandParams, FALSE, 0xFFFFFFFF, 0, 16, 0, RGB_BLACK); BerryCrush_RunOrScheduleCommand(BCCMD_InitGfx, 1, sBerryCrushGamePtr->commandParams); - sBerryCrushGamePtr->taskId = CreateTask(Task_RunBerryCrushGame, 8); + sBerryCrushGamePtr->mainTask = CreateTask(Task_RunBerryCrushGame, 8); SetMainCallback2(CB2_BerryCrush); } void CB2_BerryCrush_GoToBerryPouch(void) { - DestroyTask(sBerryCrushGamePtr->taskId); + DestroyTask(sBerryCrushGamePtr->mainTask); InitBerryPouch(BERRYPOUCH_FROMBERRYCRUSH, CB2_ReturnToBerryCrushGameFromBerryPouch, FALSE); } @@ -130,11 +884,10 @@ void BerryCrush_UpdateSav2Records(void) { u32 var0, var1; - // unk0A / (unk04 / 60) - var0 = sBerryCrushGamePtr->unk68.as_four_players.unk00.unk04; + var0 = sBerryCrushGamePtr->unk68.unk04; var0 <<= 8; var0 = MathUtil_Div32(var0, 60 << 8); - var1 = sBerryCrushGamePtr->unk68.as_four_players.unk00.unk0A; + var1 = sBerryCrushGamePtr->unk68.unk0A; var1 <<= 8; var1 = MathUtil_Div32(var1, var0) & 0xFFFF; sBerryCrushGamePtr->pressingSpeed = var1; @@ -170,7 +923,7 @@ void BerryCrush_UpdateSav2Records(void) break; } - sBerryCrushGamePtr->powder = sBerryCrushGamePtr->unk68.as_four_players.unk00.unk00; + sBerryCrushGamePtr->powder = sBerryCrushGamePtr->unk68.unk00; if (GiveBerryPowder(sBerryCrushGamePtr->powder)) return; @@ -206,13 +959,13 @@ void BerryCrush_InitPlayerNamesAndTextSpeed(struct BerryCrushGame *game) for (i = 0; i < game->playerCount; i++) { - StringCopy(BERRYCRUSH_PLAYER_NAME(game, i), gLinkPlayers[i].name); - game->unk68.as_five_players.players[i].unk14[PLAYER_NAME_LENGTH] = EOS; + StringCopy(game->unk98[i].unk0, gLinkPlayers[i].name); + game->unk98[i].unk0[PLAYER_NAME_LENGTH] = EOS; } for (; i < 5; i++) { - memset(BERRYCRUSH_PLAYER_NAME(game, i), 1, PLAYER_NAME_LENGTH); - game->unk68.as_five_players.players[i].unk14[PLAYER_NAME_LENGTH] = EOS; + memset(game->unk98[i].unk0, 1, PLAYER_NAME_LENGTH); + game->unk98[i].unk0[PLAYER_NAME_LENGTH] = EOS; } switch (gSaveBlock2Ptr->optionsTextSpeed) @@ -228,3 +981,2202 @@ void BerryCrush_InitPlayerNamesAndTextSpeed(struct BerryCrushGame *game) break; } } + +void BerryCrush_RunOrScheduleCommand(u16 command, u8 runMode, u8 *params) +{ + struct BerryCrushGame * game = GetBerryCrushGame(); + + if (command >= NELEMS(sBerryCrushCommands)) + command = 0; + switch (runMode) + { + case 0: + // Call now and set followup to game->nextCmd + if (command != 0) + sBerryCrushCommands[command](game, params); + if (game->nextCmd >= NELEMS(sBerryCrushCommands)) + game->nextCmd = 0; + game->cmdCallback = sBerryCrushCommands[game->nextCmd]; + break; + case 1: + // Schedule for next frame + game->cmdCallback = sBerryCrushCommands[command]; + break; + } +} + +static u32 BerryCrushCommand_BeginNormalPaletteFade(struct BerryCrushGame * game, u8 *params) +{ + // params points to packed values: + // bytes 0-3: selectedPals (bitfield) + // byte 4: delay + // byte 5: startY + // byte 6: stopY + // bytes 7-8: fade color + // byte 9: if TRUE, communicate on fade complete + + u16 color; + u32 selectedPals[2]; + + selectedPals[0] = (u32)params[0]; + selectedPals[1] = (u32)params[1]; + selectedPals[1] <<= 8; + + selectedPals[0] |= selectedPals[1]; + selectedPals[1] = (u32)params[2]; + selectedPals[1] <<= 16; + + selectedPals[0] |= selectedPals[1]; + selectedPals[1] = (u32)params[3]; + selectedPals[1] <<= 24; + + selectedPals[0] |= selectedPals[1]; + params[0] = params[9]; + + color = params[8]; + color <<= 8; + color |= params[7]; + + gPaletteFade.bufferTransferDisabled = FALSE; + BeginNormalPaletteFade(selectedPals[0], params[4], params[5], params[6], color); + UpdatePaletteFade(); + game->nextCmd = BCCMD_WaitPaletteFade; + return 0; +} + +static u32 BerryCrushCommand_WaitPaletteFade(struct BerryCrushGame * game, u8 *params) +{ + switch (game->cmdState) + { + case 0: + if (UpdatePaletteFade()) + return 0; + if(params[0] != 0) + ++game->cmdState; + else + game->cmdState = 3; + return 0; + case 1: + LinkRfu_SetRfuFuncToSend6600(); + ++game->cmdState; + return 0; + case 2: + if (IsLinkTaskFinished()) + { + ++game->cmdState; + return 0; + } + return 0; + case 3: + BerryCrush_RunOrScheduleCommand(game->afterPalFadeCmd, 1, NULL); + game->cmdState = 0; + return 0; + default: + ++game->cmdState; + return 0; + } +} + +static u32 BerryCrushCommand_PrintMessage(struct BerryCrushGame * game, u8 *params) +{ + u16 waitKeys; + + waitKeys = params[3]; + waitKeys <<= 8; + waitKeys |= params[2] << 0; + switch (game->cmdState) + { + case 0: + DrawDialogueFrame(0, FALSE); + if (params[1] & 2) + { + StringExpandPlaceholders(gStringVar4, sBerryCrushMessages[params[0]]); + AddTextPrinterParameterized2(0, 2, gStringVar4, game->textSpeed, 0, TEXT_COLOR_DARK_GREY, TEXT_COLOR_WHITE, TEXT_COLOR_LIGHT_GREY); + } + else + { + AddTextPrinterParameterized2(0, 2, sBerryCrushMessages[params[0]], game->textSpeed, NULL, TEXT_COLOR_DARK_GREY, TEXT_COLOR_WHITE, TEXT_COLOR_LIGHT_GREY); + } + CopyWindowToVram(0, COPYWIN_BOTH); + break; + case 1: + if (!IsTextPrinterActive(0)) + { + if (waitKeys == 0) + ++game->cmdState; + break; + } + return 0; + case 2: + if (!(waitKeys & gMain.newKeys)) + return 0; + break; + case 3: + if (params[1] & 1) + ClearDialogWindowAndFrame(0, TRUE); + BerryCrush_RunOrScheduleCommand(game->nextCmd, 1, NULL); + game->cmdState = params[4]; + return 0; + } + ++game->cmdState; + return 0; +} + +static u32 BerryCrushCommand_InitGfx(struct BerryCrushGame * game, UNUSED u8 *params) +{ + if (BerryCrush_InitBgs() != 0) + BerryCrush_RunOrScheduleCommand(game->nextCmd, 0, game->commandParams); + return 0; +} + +static u32 BerryCrushCommand_TeardownGfx(struct BerryCrushGame * game, UNUSED u8 *params) +{ + if (BerryCrush_TeardownBgs() != 0) + BerryCrush_RunOrScheduleCommand(game->nextCmd, 0, game->commandParams); + return 0; +} + +static u32 BerryCrushCommand_SignalReadyToBegin(struct BerryCrushGame * game, UNUSED u8 *params) +{ + switch (game->cmdState) + { + case 0: + LinkRfu_SetRfuFuncToSend6600(); + break; + case 1: + if (IsLinkTaskFinished()) + { + PlayNewMapMusic(MUS_GAME_CORNER); + BerryCrush_RunOrScheduleCommand(BCCMD_AskPickBerry, 1, NULL); + game->gameState = 3; + game->cmdState = 0; + } + return 0; + } + ++game->cmdState; + return 0; +} + +static u32 BerryCrushCommand_AskPickBerry(struct BerryCrushGame * game, u8 *params) +{ + switch (game->cmdState) + { + default: + ++game->cmdState; + break; + case 0: + sub_814D4D8(game); + BerryCrush_SetShowMessageParams(params, BCTEXT_AREYOUREADY, 1, 0, BCCMD_BeginNormalPaletteFade); + game->nextCmd = BCCMD_AskPickBerry; + BerryCrush_RunOrScheduleCommand(BCCMD_PrintMessage, 1, NULL); + break; + case 1: + game->nextCmd = BCCMD_GoToBerryPouch; + BerryCrush_RunOrScheduleCommand(BCCMD_TeardownGfx, 1, NULL); + game->cmdState = 2; + break; + } + return 0; +} + +static u32 BerryCrushCommand_GoToBerryPouch(struct BerryCrushGame * game, UNUSED u8 *params) +{ + game->cmdCallback = NULL; + SetMainCallback2(CB2_BerryCrush_GoToBerryPouch); + return 0; +} + +static u32 BerryCrushCommand_WaitForOthersToPickBerries(struct BerryCrushGame * game, u8 *params) +{ + u8 i; + + switch (game->cmdState) + { + case 0: + BerryCrush_SetShowMessageParams(params, BCTEXT_WAITFOROTHERS, 0, 0, BCCMD_BeginNormalPaletteFade); + game->nextCmd = BCCMD_WaitForOthersToPickBerries; + BerryCrush_RunOrScheduleCommand(BCCMD_PrintMessage, 1, NULL); + return 0; + case 1: + LinkRfu_SetRfuFuncToSend6600(); + break; + case 2: + if (!IsLinkTaskFinished()) + return 0; + memset(game->sendCmd, 0, sizeof(game->sendCmd)); + game->sendCmd[0] = game->unk98[game->localId].unkC; + SendBlock(0, game->sendCmd, 2); + break; + case 3: + if (!IsLinkTaskFinished()) + return 0; + game->unk10 = 0; + break; + case 4: + if (GetBlockReceivedStatus() != sReceivedPlayerBitmasks[game->playerCount - 2]) + return 0; + for (i = 0; i < game->playerCount; ++i) + { + game->unk98[i].unkC = gBlockRecvBuffer[i][0]; + if (game->unk98[i].unkC > 0xB0) + game->unk98[i].unkC = 0; + game->unk18 += gBerryCrushStats[game->unk98[i].unkC].unk0; + game->powder += gBerryCrushStats[game->unk98[i].unkC].powder; + } + game->unk10 = 0; + ResetBlockReceivedFlags(); + game->unk20 = MathUtil_Div32(game->unk18 << 8, 0x2000); + break; + case 5: + ClearDialogWindowAndFrame(0, TRUE); + BerryCrush_RunOrScheduleCommand(BCCMD_DropBerriesIntoCrusher, 1, NULL); + game->gameState = 4; + game->cmdState = 0; + return 0; + } + ++game->cmdState; + return 0; +} + +static u32 BerryCrushCommand_DropBerriesIntoCrusher(struct BerryCrushGame * game, UNUSED u8 *params) +{ + switch (game->cmdState) + { + case 0: + BerryCrush_CreateBerrySprites(game, &game->spritesManager); + LinkRfu_SetRfuFuncToSend6600(); + break; + case 1: + if (!IsLinkTaskFinished()) + return 0; + game->spritesManager.animBerryIdx = 0; + game->spritesManager.unk1 = 0; + game->spritesManager.unk2 = 0; + game->spritesManager.unk3 = 0; + break; + case 2: + game->spritesManager.berrySprites[game->spritesManager.animBerryIdx]->callback = SpriteCB_DropBerryIntoCrusher; + game->spritesManager.berrySprites[game->spritesManager.animBerryIdx]->affineAnimPaused = FALSE; + PlaySE(SE_BALL_THROW); + break; + case 3: + if (game->spritesManager.berrySprites[game->spritesManager.animBerryIdx]->callback == SpriteCB_DropBerryIntoCrusher) + return 0; + game->spritesManager.berrySprites[game->spritesManager.animBerryIdx] = NULL; + ++game->spritesManager.animBerryIdx; + LinkRfu_SetRfuFuncToSend6600(); + break; + case 4: + if (!IsLinkTaskFinished()) + return 0; + if (game->spritesManager.animBerryIdx < game->playerCount) + { + game->cmdState = 2; + return 0; + } + game->spritesManager.animBerryIdx = 0; + break; + case 5: + BerryCrushFreeBerrySpriteGfx(game, &game->spritesManager); + LinkRfu_SetRfuFuncToSend6600(); + break; + case 6: + if (!IsLinkTaskFinished()) + return 0; + PlaySE(SE_FALL); + BerryCrush_RunOrScheduleCommand(BCCMD_DropLid, 1, NULL); + game->gameState = 5; + game->cmdState = 0; + return 0; + } + ++game->cmdState; + return 0; +} + +static u32 BerryCrushCommand_DropLid(struct BerryCrushGame * game, UNUSED u8 *params) +{ + switch (game->cmdState) + { + case 0: + game->depth += 4; + if (game->depth < 0) + return 0; + game->depth = 0; + game->spritesManager.unk1 = 4; + game->spritesManager.animBerryIdx = 0; + game->spritesManager.unk2 = gUnknown_846E2F0[game->spritesManager.unk1][0]; + PlaySE(SE_M_STRENGTH); + break; + case 1: + game->vibration = gUnknown_846E2F0[game->spritesManager.unk1][game->spritesManager.animBerryIdx]; + SetGpuReg(REG_OFFSET_BG0VOFS, -game->vibration); + SetGpuReg(REG_OFFSET_BG2VOFS, -game->vibration); + SetGpuReg(REG_OFFSET_BG3VOFS, -game->vibration); + ++game->spritesManager.animBerryIdx; + if (game->spritesManager.animBerryIdx < game->spritesManager.unk2) + return 0; + if (game->spritesManager.unk1 == 0) + break; + --game->spritesManager.unk1; + game->spritesManager.unk2 = gUnknown_846E2F0[game->spritesManager.unk1][0]; + game->spritesManager.animBerryIdx = 0; + return 0; + case 2: + game->vibration = 0; + SetGpuReg(REG_OFFSET_BG0VOFS, 0); + SetGpuReg(REG_OFFSET_BG2VOFS, 0); + SetGpuReg(REG_OFFSET_BG3VOFS, 0); + LinkRfu_SetRfuFuncToSend6600(); + break; + case 3: + if (!IsLinkTaskFinished()) + return 0; + BerryCrush_RunOrScheduleCommand(BCCMD_Countdown, 1, NULL); + game->gameState = 6; + game->cmdState = 0; + return 0; + } + ++game->cmdState; + return 0; +} + +static u32 BerryCrushCommand_Countdown(struct BerryCrushGame * game, UNUSED u8 *params) +{ + switch (game-> cmdState) + { + case 0: + LinkRfu_SetRfuFuncToSend6600(); + break; + case 1: + if (!IsLinkTaskFinished()) + return 0; + StartMinigameCountdown(TAG_COUNTDOWN, TAG_COUNTDOWN, 120, 80, 0); + break; + case 2: + if (IsMinigameCountdownRunning()) + return 0; + LinkRfu_SetRfuFuncToSend6600(); + break; + case 3: + if (!IsLinkTaskFinished()) + return 0; + game->spritesManager.animBerryIdx = 0; + game->spritesManager.unk1 = 0; + game->spritesManager.unk2 = 0; + game->spritesManager.unk3 = 0; + game->unk10 = 0; + if (game->localId == 0) + BerryCrush_RunOrScheduleCommand(BCCMD_PlayGame_Master, 1, NULL); + else + BerryCrush_RunOrScheduleCommand(BCCMD_PlayGame_Slave, 1, NULL); + game->gameState = 7; + game->cmdState = 0; + return 0; + } + ++game->cmdState; + return 0; +} + +static void BerryCrush_ProcessGamePartnerInput(struct BerryCrushGame * game) +{ + u8 numPressedA = 0; + u16 r3; + u16 *curRecvCmd; + u8 i = 0; + s32 r2_ = 0; + s32 r0; + + for (i = 0; i < game->playerCount; ++i) + { + curRecvCmd = gRecvCmds[i]; + if ((curRecvCmd[0] & 0xFF00) == 0x2F00 + && curRecvCmd[1] == 2) + { + if ((u8)curRecvCmd[2] & 4) // pushedAButton + { + game->localState.unk02_3 |= gUnknown_846E2E0[i]; + game->unk98[i].unk1C = 1; + ++game->unk98[i].unk16; + ++numPressedA; + r3 = game->timer - game->unk98[i].unkE; + if (r3 >= game->unk98[i].unk12 - 1 && r3 <= game->unk98[i].unk12 + 1) + { + ++game->unk98[i].unk10; + game->unk98[i].unk12 = r3; + if (game->unk98[i].unk10 > game->unk98[i].unk14) + game->unk98[i].unk14 = game->unk98[i].unk10; + } + else + { + game->unk98[i].unk10 = 0; + game->unk98[i].unk12 = r3; + } + game->unk98[i].unkE = game->timer; + if (++game->unk98[i].unk1B > 2) + game->unk98[i].unk1B = 0; + } + else + { + game->unk98[i].unk1C = 0; + } + } + } + if (numPressedA > 1) + { + for (i = 0; i < game->playerCount; ++i) + { + if (game->unk98[i].unk1C != 0) + { + game->unk98[i].unk1C |= 2; + ++game->unk98[i].unk18; + } + } + } + if (numPressedA != 0) + { + game->unk2E += numPressedA; + numPressedA += gUnknown_846E2E8[numPressedA - 1]; + game->unk34 += numPressedA; + game->unk1A += numPressedA; + r0 = game->unk18; + r2_ = game->unk1A; + if (r0 - r2_ > 0) + { + r2_ <<= 8; + r2_ = MathUtil_Div32(r2_, game->unk20); + r2_ >>= 8; + game->unk24 = r2_; + } + else + { + game->unk24 = 32; + game->localState.unk02_0 = 1; + } + } +} + +static void BerryCrush_BuildLocalState(struct BerryCrushGame * game) +{ + u8 count = 0; + u16 r1 = 0; + u8 i = 0; + + for (i = 0; i < game->playerCount; ++i) + { + if (game->unk98[i].unk1C != 0) + { + ++count; + r1 = game->unk98[i].unk1B + 1; + if (game->unk98[i].unk1C & 2) + r1 |= 4; + r1 <<= 3 * i; + game->localState.unk08 |= r1; + } + } + game->localState.unk04 = game->unk24; + if (count == 0) + { + if (game->spritesManager.unk3 != 0) + ++game->spritesManager.animBerryIdx; + } + else if (game->spritesManager.unk3 != 0) + { + if (count != game->spritesManager.unk1) + { + game->spritesManager.unk1 = count - 1; + game->spritesManager.unk2 = gUnknown_846E314[count - 1][0]; + } + else + { + ++game->spritesManager.animBerryIdx; + } + } + else + { + game->spritesManager.animBerryIdx = 0; + game->spritesManager.unk1 = count - 1; + game->spritesManager.unk2 = gUnknown_846E314[count - 1][0]; + game->spritesManager.unk3 = 1; + } + + if (game->spritesManager.unk3 != 0) + { + if (game->spritesManager.animBerryIdx >= game->spritesManager.unk2) + { + game->spritesManager.animBerryIdx = 0; + game->spritesManager.unk1 = 0; + game->spritesManager.unk2 = 0; + game->spritesManager.unk3 = 0; + r1 = 0; + } + else + { + r1 = gUnknown_846E314[game->spritesManager.unk1][game->spritesManager.animBerryIdx + 1]; + } + game->localState.unk03 = r1; + } + else + { + game->localState.unk03 = 0; + } + game->localState.unk06 = game->unk26; +} + +static void BerryCrush_HandlePlayerInput(struct BerryCrushGame * game) +{ + if (JOY_NEW(A_BUTTON)) + game->localState.pushedAButton = TRUE; + if (JOY_HELD(A_BUTTON)) + { + if (game->unk98[game->localId].unk1A < game->timer) + ++game->unk98[game->localId].unk1A; + } + if (game->localId != 0 && !game->localState.pushedAButton) + return; + game->localState.unk00 = 2; + if (game->timer % 30 == 0) + { + if (game->unk2E > gUnknown_846E3C4[game->playerCount - 2]) + { + ++game->unk30; + game->unk25_4 = 1; + } + else + { + game->unk25_4 = 0; + } + game->unk2E = 0; + ++game->unk32; + } + if (game->timer % 15 == 0) + { + if (game->unk34 < gUnknown_846E3B4[game->playerCount - 2][0]) + game->unk25_5 = 0; + else if (game->unk34 < gUnknown_846E3B4[game->playerCount - 2][1]) + game->unk25_5 = 1; + else if (game->unk34 < gUnknown_846E3B4[game->playerCount - 2][2]) + game->unk34 = 2; // typo since game->unk34 will be reset? + else if (game->unk34 < gUnknown_846E3B4[game->playerCount - 2][3]) + game->unk34 = 3; // typo since game->unk34 will be reset? + else + game->unk25_5 = 4; + game->unk34 = 0; + } + else + { + ++game->unk10; + if (game->unk10 > 60) + { + if (game->unk10 > 70) + { + sub_80FBA44(); + game->unk10 = 0; + } + else if (game->localState.unk02_3 == 0) + { + sub_80FBA44(); + game->unk10 = 0; + } + } + + } + if (game->timer >= 36000) + game->localState.unk02_0 = 1; + game->localState.unk02_1 = game->unk25_4; + game->localState.unk0A = game->unk25_5; + memcpy(&game->sendCmd, &game->localState, sizeof(game->sendCmd)); + RfuPrepareSend0x2f00(game->sendCmd); +} + +static void BerryCrush_UpdateGameState(struct BerryCrushGame * game) +{ + u8 i = 0; + struct BerryCrushGame_4E * r4_ = NULL; + + for (i = 0; i < game->playerCount; ++i) + game->unk98[i].unk1C = 0; + if ((gRecvCmds[0][0] & 0xFF00) != 0x2F00 || gRecvCmds[0][1] != 2) + { + game->unk25_2 = 0; + return; + } + + memcpy(game->recvCmd, gRecvCmds[0], 14); + r4_ = (struct BerryCrushGame_4E *)&game->recvCmd; + game->depth = r4_->unk6; + game->vibration = r4_->unk5; + game->timer = r4_->unk8; + sub_814DC5C(game, &game->spritesManager); + if (r4_->unk4_0) + game->unk25_3 = 1; +} + +static u32 BerryCrushCommand_PlayGame_Master(struct BerryCrushGame * game, UNUSED u8 *params) +{ + memset(&game->localState, 0, sizeof(game->localState)); + memset(&game->recvCmd, 0, sizeof(game->recvCmd)); + BerryCrush_UpdateGameState(game); + SetGpuReg(REG_OFFSET_BG0VOFS, -game->vibration); + SetGpuReg(REG_OFFSET_BG2VOFS, -game->vibration); + SetGpuReg(REG_OFFSET_BG3VOFS, -game->vibration); + if (game->unk25_3) + { + if (game->timer >= 36000) + { + game->timer = 36000; + BerryCrush_RunOrScheduleCommand(BCCMD_HandleTimeUp, 1, NULL); + } + else + { + BerryCrush_RunOrScheduleCommand(BCCMD_FinishGame, 1, NULL); + } + game->unk10 = 0; + game->cmdState = 0; + return 0; + } + else + { + ++game->unk26; + BerryCrush_ProcessGamePartnerInput(game); + BerryCrush_BuildLocalState(game); + BerryCrush_HandlePlayerInput(game); + return 0; + } +} + +static u32 BerryCrushCommand_PlayGame_Slave(struct BerryCrushGame * game, UNUSED u8 *params) +{ + memset(&game->localState, 0, sizeof(game->localState)); + memset(&game->recvCmd, 0, sizeof(game->recvCmd)); + BerryCrush_UpdateGameState(game); + SetGpuReg(REG_OFFSET_BG0VOFS, -game->vibration); + SetGpuReg(REG_OFFSET_BG2VOFS, -game->vibration); + SetGpuReg(REG_OFFSET_BG3VOFS, -game->vibration); + if (game->unk25_3) + { + if (game->timer >= 36000) + { + game->timer = 36000; + BerryCrush_RunOrScheduleCommand(BCCMD_HandleTimeUp, 1, NULL); + } + else + { + BerryCrush_RunOrScheduleCommand(BCCMD_FinishGame, 1, NULL); + } + game->unk10 = 0; + game->cmdState = 0; + return 0; + } + else + { + BerryCrush_HandlePlayerInput(game); + return 0; + } +} + +static u32 BerryCrushCommand_FinishGame(struct BerryCrushGame * game, UNUSED u8 *params) +{ + switch (game->cmdState) + { + case 0: + game->gameState = 8; + PlaySE(SE_M_STRENGTH); + BlendPalettes(0xFFFFFFFF, 8, RGB(31, 31, 0)); + game->spritesManager.animBerryIdx = 2; + break; + case 1: + if (--game->spritesManager.animBerryIdx != 255) + return 0; + BlendPalettes(0xFFFFFFFF, 0, RGB(31, 31, 0)); + game->spritesManager.unk1 = 4; + game->spritesManager.animBerryIdx = 0; + game->spritesManager.unk2 = gUnknown_846E2F0[game->spritesManager.unk1][0]; + break; + case 2: + game->vibration = gUnknown_846E2F0[game->spritesManager.unk1][game->spritesManager.animBerryIdx]; + SetGpuReg(REG_OFFSET_BG0VOFS, -game->vibration); + SetGpuReg(REG_OFFSET_BG2VOFS, -game->vibration); + SetGpuReg(REG_OFFSET_BG3VOFS, -game->vibration); + if (++game->spritesManager.animBerryIdx < game->spritesManager.unk2) + return 0; + if (game->spritesManager.unk1 != 0) + { + --game->spritesManager.unk1; + game->spritesManager.unk2 = gUnknown_846E2F0[game->spritesManager.unk1][0]; + game->spritesManager.animBerryIdx = 0; + return 0; + } + break; + case 3: + game->vibration = 0; + SetGpuReg(REG_OFFSET_BG0VOFS, 0); + SetGpuReg(REG_OFFSET_BG2VOFS, 0); + SetGpuReg(REG_OFFSET_BG3VOFS, 0); + break; + case 4: + if (!sub_814DE50(game, &game->spritesManager)) + return 0; + LinkRfu_SetRfuFuncToSend6600(); + game->unk10 = 0; + break; + case 5: + if (!IsLinkTaskFinished()) + return 0; + BerryCrush_RunOrScheduleCommand(BCCMD_TabulateResults, 1, NULL); + game->unk10 = 0; + game->cmdState = 0; + return 0; + } + ++game->cmdState; + return 0; +} + +static u32 BerryCrushCommand_HandleTimeUp(struct BerryCrushGame * game, u8 *params) +{ + switch (game->cmdState) + { + case 0: + game->gameState = 9; + PlaySE(SE_FAILURE); + BlendPalettes(0xFFFFFFFF, 8, RGB(31, 0, 0)); + game->spritesManager.animBerryIdx = 4; + break; + case 1: + if (--game->spritesManager.animBerryIdx != 255) + return 0; + BlendPalettes(0xFFFFFFFF, 0, RGB(31, 0, 0)); + game->spritesManager.animBerryIdx = 0; + break; + case 2: + if (!sub_814DE50(game, &game->spritesManager)) + return 0; + LinkRfu_SetRfuFuncToSend6600(); + game->unk10 = 0; + SetGpuReg(REG_OFFSET_BG0VOFS, 0); + SetGpuReg(REG_OFFSET_BG2VOFS, 0); + SetGpuReg(REG_OFFSET_BG3VOFS, 0); + break; + case 3: + if (!IsLinkTaskFinished()) + return 0; + ConvertIntToDecimalStringN(gStringVar1, game->powder, STR_CONV_MODE_LEFT_ALIGN, 6); + BerryCrush_SetShowMessageParams(params, BCTEXT_TIMEUP, 1, 0, 0); + game->nextCmd = BCCMD_SaveTheGame; + BerryCrush_RunOrScheduleCommand(BCCMD_PrintMessage, 1, NULL); + game->unk10 = 0; + game->cmdState = 0; + return 0; + } + ++game->cmdState; + return 0; +} + +static u32 BerryCrushCommand_TabulateResults(struct BerryCrushGame * game, UNUSED u8 *params) +{ + u8 i, j, r3; + s32 r2; + s32 r4; + u16 r6; + + switch (game->cmdState) + { + case 0: + memset(game->sendCmd, 0, 2 * sizeof(u16)); + if (game->unk98[game->localId].unk1A > game->timer) + game->unk98[game->localId].unk1A = game->timer; + game->sendCmd[0] = game->unk98[game->localId].unk1A; + SendBlock(0, game->sendCmd, 2); + break; + case 1: + if (!IsLinkTaskFinished()) + return 0; + game->unk10 = 0; + break; + case 2: + if (GetBlockReceivedStatus() != sReceivedPlayerBitmasks[game->playerCount - 2]) + return 0; + for (i = 0; i < game->playerCount; ++i) + game->unk98[i].unk1A = gBlockRecvBuffer[i][0]; + game->unk10 = 0; + game->sendCmd[0] = 0; + ResetBlockReceivedFlags(); + if (game->localId == 0) + game->cmdState = 3; + else + game->cmdState = 6; + return 0; + case 3: + memset(&game->unk68, 0, sizeof(struct BerryCrushGame_68)); + game->unk68.unk04 = game->timer; + game->unk68.unk06 = game->unk18 / (game->timer / 60); + // (unk30 * 50 / unk32) + 50 + r2 = MathUtil_Mul32(game->unk30 << 8, 50 << 8); + r2 = MathUtil_Div32(r2, game->unk32 << 8) + (50 << 8); + r2 >>= 8; + game->unk68.unk08 = r2 & 0x7F; + // powder + playerCount * (r2 / 100) + r2 <<= 8; + r2 = MathUtil_Div32(r2, 100 << 8); + r4 = (game->powder * game->playerCount) << 8; + r4 = MathUtil_Mul32(r4, r2); + game->unk68.unk00 = r4 >> 8; + game->unk68.unk20[0][7] = Random() % 3; + for (i = 0; i < game->playerCount; ++i) + { + game->unk68.unk20[0][i] = i; + game->unk68.unk20[1][i] = i; + game->unk68.stats[0][i] = game->unk98[i].unk16; + game->unk68.unk0A += game->unk68.stats[0][i]; + switch (game->unk68.unk20[0][7]) + { + case 0: + if (game->unk98[i].unk16 != 0) + { + r2 = game->unk98[i].unk14; + r2 <<= 8; + r2 = MathUtil_Mul32(r2, 0x6400); + r4 = game->unk98[i].unk16; + r4 <<= 8; + r4 = MathUtil_Div32(r2, r4); + } + else + { + r4 = 0; + } + break; + case 1: + if (game->unk98[i].unk16 != 0) + { + r2 = game->unk98[i].unk18; + r2 <<= 8; + r2 = MathUtil_Mul32(r2, 0x6400); + r4 = game->unk98[i].unk16; + r4 <<= 8; + r4 = MathUtil_Div32(r2, r4); + } + else + { + r4 = 0; + } + break; + case 2: + if (game->unk98[i].unk16 == 0) + { + r4 = 0; + } + else if (game->unk98[i].unk1A >= game->timer) + { + r4 = 0x6400; + } + else + { + r2 = game->unk98[i].unk1A; + r2 <<= 8; + r2 = MathUtil_Mul32(r2, 0x6400); + r4 = game->timer; + r4 <<= 8; + r4 = MathUtil_Div32(r2, r4); + } + break; + } + r4 >>= 4; + game->unk68.stats[1][i] = r4; + } + break; + case 4: + for (i = 0; i < game->playerCount - 1; ++i) + { + for (j = game->playerCount - 1; j > i; --j) + { + if (game->unk68.stats[0][j - 1] < game->unk68.stats[0][j]) + { + r6 = game->unk68.stats[0][j]; + game->unk68.stats[0][j] = game->unk68.stats[0][j - 1]; + game->unk68.stats[0][j - 1] = r6; + r3 = game->unk68.unk20[0][j]; + game->unk68.unk20[0][j] = game->unk68.unk20[0][j - 1]; + game->unk68.unk20[0][j - 1] = r3; + } + if (game->unk68.stats[1][j - 1] < game->unk68.stats[1][j]) + { + r6 = game->unk68.stats[1][j]; + game->unk68.stats[1][j] = game->unk68.stats[1][j - 1]; + game->unk68.stats[1][j - 1] = r6; + r3 = game->unk68.unk20[1][j]; + game->unk68.unk20[1][j] = game->unk68.unk20[1][j - 1]; + game->unk68.unk20[1][j - 1] = r3; + } + } + } + SendBlock(0, &game->unk68, sizeof(struct BerryCrushGame_68)); + break; + case 5: + if (!IsLinkTaskFinished()) + return 0; + game->unk10 = 0; + break; + case 6: + if (GetBlockReceivedStatus() != 1) + return 0; + memset(&game->unk68, 0, sizeof(struct BerryCrushGame_68)); + memcpy(&game->unk68, gBlockRecvBuffer, sizeof(struct BerryCrushGame_68)); + ResetBlockReceivedFlags(); + game->unk10 = 0; + break; + case 7: + BerryCrush_UpdateSav2Records(); + BerryCrush_RunOrScheduleCommand(BCCMD_ShowResults, 1, NULL); + game->gameState = 11; + game->cmdState = 0; + game->unk24 = 0; + return 0; + } + ++game->cmdState; + return 0; +} + +static u32 BerryCrushCommand_ShowResults(struct BerryCrushGame * game, u8 *params) +{ + switch (game->cmdState) + { + case 0: + if (!sub_814E644(game, &game->spritesManager)) + return 0; + break; + case 1: + CopyBgTilemapBufferToVram(0); + game->spritesManager.animBerryIdx = 30; + break; + case 2: + if (game->spritesManager.animBerryIdx != 0) + { + --game->spritesManager.animBerryIdx; + return 0; + } + if (!JOY_NEW(A_BUTTON)) + return 0; + PlaySE(SE_SELECT); + sub_814E80C(game); + break; + case 3: + if (game->gameState <= 12) + { + ++game->gameState; + game->cmdState = 0; + return 0; + } + break; + case 4: + ConvertIntToDecimalStringN(gStringVar1, game->powder, STR_CONV_MODE_LEFT_ALIGN, 6); + ConvertIntToDecimalStringN(gStringVar2, GetBerryPowder(), STR_CONV_MODE_LEFT_ALIGN, 6); + BerryCrush_SetShowMessageParams(params, BCTEXT_GAINEDPOWDER, 3, 0, 0); + game->nextCmd = BCCMD_SaveTheGame; + BerryCrush_RunOrScheduleCommand(BCCMD_PrintMessage, 1, NULL); + game->cmdState = 0; + return 0; + } + ++game->cmdState; + return 0; +} + +static u32 BerryCrushCommand_SaveTheGame(struct BerryCrushGame * game, u8 *params) +{ + switch (game->cmdState) + { + case 0: + if (game->timer >= 36000) + BerryCrush_HideTimerSprites(&game->spritesManager); + BerryCrush_SetShowMessageParams(params, BCTEXT_COMMSTANDBY, 0, 0, BCCMD_BeginNormalPaletteFade); + game->nextCmd = BCCMD_SaveTheGame; + BerryCrush_RunOrScheduleCommand(BCCMD_PrintMessage, 1, NULL); + game->cmdState = 0; + return 0; + case 1: + LinkRfu_SetRfuFuncToSend6600(); + break; + case 2: + if (!IsLinkTaskFinished()) + return 0; + DrawDialogueFrame(0, FALSE); + AddTextPrinterParameterized2(0, 2, gText_SavingDontTurnOffThePower2, 0, NULL, 2, 1, 3); + CopyWindowToVram(0, COPYWIN_BOTH); + CreateTask(Task_SaveGame_UpdatedLinkRecords, 0); + break; + case 3: + if (FuncIsActiveTask(Task_SaveGame_UpdatedLinkRecords)) + return 0; + break; + case 4: + BerryCrush_RunOrScheduleCommand(BCCMD_AskPlayAgain, 1, NULL); + game->gameState = 15; + game->cmdState = 0; + return 0; + } + ++game->cmdState; + return 0; +} + +static u32 BerryCrushCommand_AskPlayAgain(struct BerryCrushGame * game, u8 *params) +{ + s8 r4 = 0; + + switch (game->cmdState) + { + case 0: + BerryCrush_SetShowMessageParams(params, BCTEXT_ASKPLAYAGAIN, 0, 0, BCCMD_BeginNormalPaletteFade); + game->nextCmd = BCCMD_AskPlayAgain; + BerryCrush_RunOrScheduleCommand(BCCMD_PrintMessage, 1, NULL); + game->cmdState = 0; // dunno what it's doing because it's already in case 0 + return 0; + case 1: + DisplayYesNoMenuDefaultYes(); + break; + case 2: + r4 = Menu_ProcessInputNoWrapClearOnChoose(); + if (r4 != -2) + { + memset(game->sendCmd, 0, sizeof(game->sendCmd)); + if (r4 == 0) + { + if (CheckHasAtLeastOneBerry()) + game->unk14 = 0; + else + game->unk14 = 3; + } + else + { + game->unk14 = 1; + } + ClearDialogWindowAndFrame(0, TRUE); + BerryCrush_SetShowMessageParams(params, BCTEXT_COMMSTANDBY, 0, 0, 0); + game->nextCmd = BCCMD_CommunicatePlayAgainResponses; + BerryCrush_RunOrScheduleCommand(BCCMD_PrintMessage, 1, NULL); + game->cmdState = 0; + } + return 0; + } + ++game->cmdState; + return 0; +} + +static u32 BerryCrushCommand_CommunicatePlayAgainResponses(struct BerryCrushGame * game, UNUSED u8 *params) +{ + u8 i = 0; + + switch (game->cmdState) + { + case 0: + LinkRfu_SetRfuFuncToSend6600(); + break; + case 1: + if (!IsLinkTaskFinished()) + return 0; + game->sendCmd[0] = game->unk14; + game->recvCmd[0] = 0; + SendBlock(0, game->sendCmd, sizeof(u16)); + break; + case 2: + if (!IsLinkTaskFinished()) + return 0; + game->unk10 = 0; + break; + case 3: + if (GetBlockReceivedStatus() != sReceivedPlayerBitmasks[game->playerCount - 2]) + return 0; + for (; i < game->playerCount; ++i) + game->recvCmd[0] += gBlockRecvBuffer[i][0]; + if (game->recvCmd[0] != 0) + BerryCrush_RunOrScheduleCommand(BCCMD_PlayAgainFailureMessage, 1, NULL); + else + BerryCrush_RunOrScheduleCommand(BCCMD_FadeOutToPlayAgain, 1, NULL); + ResetBlockReceivedFlags(); + game->sendCmd[0] = 0; + game->recvCmd[0] = 0; + game->unk10 = 0; + game->cmdState = 0; + return 0; + } + ++game->cmdState; + return 0; +} + +static u32 BerryCrushCommand_FadeOutToPlayAgain(struct BerryCrushGame * game, UNUSED u8 *params) +{ + switch (game->cmdState) + { + case 0: + BeginNormalPaletteFade(0xFFFFFFFF, 1, 0, 0x10, RGB_BLACK); + UpdatePaletteFade(); + break; + case 1: + if (UpdatePaletteFade()) + return 0; + break; + case 2: + ClearDialogWindowAndFrame(0, TRUE); + sub_814DA04(game); + BeginNormalPaletteFade(0xFFFFFFFF, 0, 0x10, 0, RGB_BLACK); + UpdatePaletteFade(); + break; + case 3: + if (UpdatePaletteFade()) + return 0; + BerryCrush_RunOrScheduleCommand(BCCMD_AskPickBerry, 1, NULL); + game->gameState = 3; + game->cmdState = 0; + return 0; + } + ++game->cmdState; + return 0; +} + +static u32 BerryCrushCommand_PlayAgainFailureMessage(struct BerryCrushGame * game, UNUSED u8 *params) +{ + switch (game->cmdState) + { + case 0: + DrawDialogueFrame(0, FALSE); + if (game->unk14 == 3) + AddTextPrinterParameterized2(0, 2, sBerryCrushMessages[BCTEXT_CANCEL_NOBERRIES], game->textSpeed, NULL, 2, 1, 3); + else + AddTextPrinterParameterized2(0, 2, sBerryCrushMessages[BCTEXT_CANCEL_DROPPEDOUT], game->textSpeed, NULL, 2, 1, 3); + CopyWindowToVram(0, COPYWIN_BOTH); + break; + case 1: + if (IsTextPrinterActive(0)) + return 0; + game->spritesManager.animBerryIdx = 120; + break; + case 2: + if (game->spritesManager.animBerryIdx != 0) + --game->spritesManager.animBerryIdx; + else + { + BerryCrush_RunOrScheduleCommand(BCCMD_GracefulExit, 1, NULL); + game->cmdState = 0; + } + return 0; + } + ++game->cmdState; + return 0; +} + +static u32 BerryCrushCommand_GracefulExit(struct BerryCrushGame * game, UNUSED u8 *params) +{ + switch (game->cmdState) + { + case 0: + LinkRfu_SetRfuFuncToSend6600(); + break; + case 1: + if (!IsLinkTaskFinished()) + return 0; + SetCloseLinkCallback(); + break; + case 2: + if (gReceivedRemoteLinkPlayers) + return 0; + game->nextCmd = BCCMD_Quit; + BerryCrush_RunOrScheduleCommand(BCCMD_TeardownGfx, 1, NULL); + game->cmdState = 2; // ??? + return 0; + } + ++game->cmdState; + return 0; +} + +static u32 BerryCrushCommand_Quit(UNUSED struct BerryCrushGame * game, UNUSED u8 *params) +{ + ExitBerryCrushWithCallback(NULL); + return 0; +} + +static void sub_814D4D8(struct BerryCrushGame * game) +{ + u8 r5 = 0; + + IncrementGameStat(GAME_STAT_BERRY_CRUSH_POINTS); + game->unkD = 0; + game->unk10 = 0; + game->gameState = 2; + game->unk14 = 0; + game->powder = 0; + game->unk18 = 0; + game->unk1A = 0; + game->unk20 = 0; + game->unk24 = 0; + game->unk25_0 = 0; + game->unk25_1 = 0; + game->unk25_2 = 0; + game->unk25_3 = FALSE; + game->unk25_4 = 0; + game->unk25_5 = 0; + game->unk26 = 0; + game->timer = 0; + game->unk2E = 0; + game->unk32 = -1; + game->unk30 = 0; + game->unk34 = 0; + for (; r5 < 5; ++r5) + { + game->unk98[r5].unkC = -1; + game->unk98[r5].unkE = 0; + game->unk98[r5].unk10 = 0; + game->unk98[r5].unk12 = 1; + game->unk98[r5].unk14 = 0; + game->unk98[r5].unk16 = 0; + game->unk98[r5].unk18 = 0; + game->unk98[r5].unk1A = 0; + game->unk98[r5].unk1B = 0; + game->unk98[r5].unk1C = 0; + } +} + +void BerryCrush_SetPaletteFadeParams(u8 *params, bool8 communicateAfter, u32 selectedPals, s8 delay, u8 startY, u8 targetY, u16 palette) +{ + params[0] = ((u8 *)&selectedPals)[0]; + params[1] = ((u8 *)&selectedPals)[1]; + params[2] = ((u8 *)&selectedPals)[2]; + params[3] = ((u8 *)&selectedPals)[3]; + params[4] = delay; + params[5] = startY; + params[6] = targetY; + params[7] = ((u8 *)&palette)[0]; + params[8] = ((u8 *)&palette)[1]; + params[9] = communicateAfter; +} + +void BerryCrush_SetShowMessageParams(u8 *params, u8 stringId, u8 flags, u16 waitKeys, u8 followupCmd) +{ + params[0] = stringId; + params[1] = flags; + params[2] = ((u8 *)&waitKeys)[0]; + params[3] = ((u8 *)&waitKeys)[1]; + params[4] = followupCmd; +} + +int BerryCrush_InitBgs(void) +{ + struct BerryCrushGame * game = GetBerryCrushGame(); + if (game == NULL) + return -1; + + switch (game->cmdState) + { + case 0: + SetVBlankCallback(NULL); + SetHBlankCallback(NULL); + SetGpuReg(REG_OFFSET_DISPCNT, 0); + ScanlineEffect_Stop(); + ResetTempTileDataBuffers(); + break; + case 1: + CpuFill16(0, (void *)OAM, OAM_SIZE); + gReservedSpritePaletteCount = 0; + DigitObjUtil_Init(3); + break; + case 2: + ResetPaletteFade(); + ResetSpriteData(); + FreeAllSpritePalettes(); + break; + case 3: + ResetBgsAndClearDma3BusyFlags(FALSE); + InitBgsFromTemplates(0, sBgTemplates, NELEMS(sBgTemplates)); + SetBgTilemapBuffer(1, game->spritesManager.bgBuffers[0]); + SetBgTilemapBuffer(2, game->spritesManager.bgBuffers[2]); + SetBgTilemapBuffer(3, game->spritesManager.bgBuffers[3]); + ChangeBgX(0, 0, 0); + ChangeBgY(0, 0, 0); + ChangeBgX(2, 0, 0); + ChangeBgY(2, 0, 0); + ChangeBgX(3, 0, 0); + ChangeBgY(3, 0, 0); + SetGpuReg(REG_OFFSET_BLDCNT, 0); + SetGpuReg(REG_OFFSET_BLDALPHA, 0); + break; + case 4: + FillBgTilemapBufferRect_Palette0(0, 0, 0, 0, 32, 32); + FillBgTilemapBufferRect_Palette0(1, 0, 0, 0, 32, 64); + FillBgTilemapBufferRect_Palette0(2, 0, 0, 0, 32, 32); + FillBgTilemapBufferRect_Palette0(3, 0, 0, 0, 32, 32); + break; + case 5: + CopyBgTilemapBufferToVram(0); + CopyBgTilemapBufferToVram(1); + CopyBgTilemapBufferToVram(2); + CopyBgTilemapBufferToVram(3); + DecompressAndCopyTileDataToVram(1, gUnknown_8EAFFC0, 0, 0, 0); + break; + case 6: + if (FreeTempTileDataBuffersIfPossible()) + return 0; + + InitStandardTextBoxWindows(); + ResetBg0(); + sub_814EB38(game); + sub_814EBB0(game); + gPaletteFade.bufferTransferDisabled = TRUE; + break; + case 7: + LoadPalette(gUnknown_8EAFEA0, 0, 0x180); + CopyToBgTilemapBuffer(1, gBerryCrushGrinderTopTilemap, 0, 0); + CopyToBgTilemapBuffer(2, gBerryCrushContainerCapTilemap, 0, 0); + CopyToBgTilemapBuffer(3, gBerryCrushBackgroundTilemap, 0, 0); + sub_814EC80(game); + CopyBgTilemapBufferToVram(1); + CopyBgTilemapBufferToVram(2); + CopyBgTilemapBufferToVram(3); + break; + case 8: + LoadWirelessStatusIndicatorSpriteGfx(); + CreateWirelessStatusIndicatorSprite(0, 0); + sub_814ECE0(game); + SetGpuReg(REG_OFFSET_BG1VOFS, -gSpriteCoordOffsetY); + ChangeBgX(1, 0, 0); + ChangeBgY(1, 0, 0); + break; + case 9: + gPaletteFade.bufferTransferDisabled = FALSE; + BlendPalettes(0xFFFFFFFF, 16, RGB_BLACK); + ShowBg(0); + ShowBg(1); + ShowBg(2); + ShowBg(3); + SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_OBJ_ON | DISPCNT_OBJ_1D_MAP); + BerryCrush_SetVBlankCallback(); + game->cmdState = 0; + return 1; + } + + game->cmdState++; + return 0; +} + +int BerryCrush_TeardownBgs(void) +{ + struct BerryCrushGame * var0 = GetBerryCrushGame(); + if (!var0) + return -1; + + switch (var0->cmdState) + { + case 0: + LinkRfu_SetRfuFuncToSend6600(); + break; + case 1: + if (!IsLinkTaskFinished()) + return 0; + // fall through. The original author forgot to use "break" here + // because this will call BeginNormalPaletteFade() twice. + case 2: + BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB_BLACK); + UpdatePaletteFade(); + break; + case 3: + if (UpdatePaletteFade()) + return 0; + break; + case 4: + FillBgTilemapBufferRect_Palette0(0, 0, 0, 0, 32, 32); + FillBgTilemapBufferRect_Palette0(1, 0, 0, 0, 32, 32); + FillBgTilemapBufferRect_Palette0(2, 0, 0, 0, 32, 32); + FillBgTilemapBufferRect_Palette0(3, 0, 0, 0, 32, 32); + CopyBgTilemapBufferToVram(0); + CopyBgTilemapBufferToVram(1); + CopyBgTilemapBufferToVram(2); + CopyBgTilemapBufferToVram(3); + break; + case 5: + FreeAllWindowBuffers(); + HideBg(0); + UnsetBgTilemapBuffer(0); + HideBg(1); + UnsetBgTilemapBuffer(1); + HideBg(2); + UnsetBgTilemapBuffer(2); + HideBg(3); + UnsetBgTilemapBuffer(3); + ClearGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_OBJ_ON | DISPCNT_OBJ_1D_MAP); + break; + case 6: + DestroyWirelessStatusIndicatorSprite(); + sub_814EF10(var0); + DigitObjUtil_Teardown(); + break; + case 7: + var0->cmdState = 0; + return 1; + } + + var0->cmdState++; + return 0; +} + +int sub_814D9CC(struct BerryCrushGame * game) +{ + gSpriteCoordOffsetY = game->depth + game->vibration; + SetGpuReg(REG_OFFSET_BG1VOFS, -gSpriteCoordOffsetY); + if (game->gameState == 7) + { + BerryCrush_PrintTimeOnSprites(&game->spritesManager, game->timer); + } + + return 0; +} + +void sub_814DA04(struct BerryCrushGame * game) +{ + game->depth = -104; + game->vibration = 0; + gSpriteCoordOffsetX = 0; + gSpriteCoordOffsetY = -104; +} + +void BerryCrush_CreateBerrySprites(struct BerryCrushGame * game, struct BerryCrushGame_138 * spritesManager) +{ + u8 i; + u8 spriteId; + s16 var0, var1; + s16 *data; + int var3; + s16 var5; + u32 var6; + + for (i = 0; i < game->playerCount; i++) + { + spriteId = AddItemIconObjectWithCustomObjectTemplate( + &sSpriteTemplate_PlayerBerry, + sPlayerBerrySpriteTags[i], + sPlayerBerrySpriteTags[i], + game->unk98[i].unkC + FIRST_BERRY_INDEX); + spritesManager->berrySprites[i] = &gSprites[spriteId]; + spritesManager->berrySprites[i]->oam.priority = 3; + spritesManager->berrySprites[i]->affineAnimPaused = TRUE; + spritesManager->berrySprites[i]->pos1.x = spritesManager->seatCoords[i]->unk8 + 120; + spritesManager->berrySprites[i]->pos1.y = -16; + data = spritesManager->berrySprites[i]->data; + var5 = 512; + data[1] = var5; + data[2] = 32; + data[7] = 112; + var0 = spritesManager->seatCoords[i]->unkA - spritesManager->seatCoords[i]->unk8; + var3 = var0; + if (var0 < 0) + var3 += 3; + + data[6] = var3 >> 2; + var0 *= 128; + var6 = var5 + 32; + var6 = var6 / 2; + var1 = MathUtil_Div16Shift(7, 0x3F80, var6); + data[0] = (u16)spritesManager->berrySprites[i]->pos1.x * 128; + data[3] = MathUtil_Div16Shift(7, var0, var1); + var1 = MathUtil_Mul16Shift(7, var1, 85); + data[4] = 0; + data[5] = MathUtil_Div16Shift(7, 0x3F80, var1); + data[7] |= 0x8000; + if (spritesManager->seatCoords[i]->unk8 < 0) + StartSpriteAffineAnim(spritesManager->berrySprites[i], 1); + } +} + +void SpriteCB_DropBerryIntoCrusher(struct Sprite * sprite) +{ + s16 *data = sprite->data; + + data[1] += data[2]; + sprite->pos2.y += data[1] >> 8; + if (data[7] & 0x8000) + { + sprite->data[0] += data[3]; + data[4] += data[5]; + sprite->pos2.x = Sin(data[4] >> 7, data[6]); + if ((data[7] & 0x8000) && (data[4] >> 7) > 126) + { + sprite->pos2.x = 0; + data[7] &= 0x7FFF; + } + } + + sprite->pos1.x = data[0] >> 7; + if (sprite->pos1.y + sprite->pos2.y >= (data[7] & 0x7FFF)) + { + sprite->callback = SpriteCallbackDummy; + FreeSpriteOamMatrix(sprite); + DestroySprite(sprite); + } +} + +void BerryCrushFreeBerrySpriteGfx(struct BerryCrushGame * arg0, UNUSED struct BerryCrushGame_138 * arg1) +{ + u8 i; + for (i = 0; i < arg0->playerCount; i++) + { + FreeSpritePaletteByTag(sPlayerBerrySpriteTags[i]); + FreeSpriteTilesByTag(sPlayerBerrySpriteTags[i]); + } +} + +void sub_814DC5C(struct BerryCrushGame * game, struct BerryCrushGame_138 * manager) +{ + u8 sp4; + struct BerryCrushGame_4E * var4E; + u8 i; + u16 var, var2; + + sp4 = 0; + var4E = (struct BerryCrushGame_4E *)&game->recvCmd; + for (i = 0; i < game->playerCount; i++) + { + var = var4E->unkA >> (i * 3); + var &= 7; + if (var) + { + sp4++; + if (var & 0x4) + StartSpriteAnim(manager->impactSprites[i], 1); + else + StartSpriteAnim(manager->impactSprites[i], 0); + + manager->impactSprites[i]->invisible = FALSE; + manager->impactSprites[i]->animPaused = FALSE; + manager->impactSprites[i]->pos2.x = gUnknown_846F2D0[(var % 4) - 1][0]; + manager->impactSprites[i]->pos2.y = gUnknown_846F2D0[(var % 4) - 1][1]; + } + } + + if (sp4 == 0) + { + game->unk25_2 = 0; + } + else + { + var = (u8)(game->timer % 3); + var2 = var; + for (i = 0; i < var4E->unkC * 2 + 3; i++) + { + if (manager->sparkleSprites[i]->invisible) + { + manager->sparkleSprites[i]->callback = sub_814F0D8; + manager->sparkleSprites[i]->pos1.x = gUnknown_846F2D6[i][0] + 120; + manager->sparkleSprites[i]->pos1.y = gUnknown_846F2D6[i][1] + 136 - (var * 4); + manager->sparkleSprites[i]->pos2.x = gUnknown_846F2D6[i][0] + (gUnknown_846F2D6[i][0] / (var2 * 4)); + manager->sparkleSprites[i]->pos2.y = gUnknown_846F2D6[i][1]; + if (var4E->unk4_1) + StartSpriteAnim(manager->sparkleSprites[i], 1); + else + StartSpriteAnim(manager->sparkleSprites[i], 0); + + var++; + if (var > 3) + var = 0; + } + } + + if (game->unk25_2) + { + game->unk25_2 = 0; + } + else + { + if (sp4 == 1) + PlaySE(SE_MUD_BALL); + else + PlaySE(SE_BREAKABLE_DOOR); + + game->unk25_2 = 1; + } + } +} + +bool32 sub_814DE50(struct BerryCrushGame * arg0, struct BerryCrushGame_138 * arg1) +{ + u8 i; + + for (i = 0; i < arg0->playerCount; i++) + { + if (!arg1->impactSprites[i]->invisible) + return FALSE; + } + + for (i = 0; i < 11; i++) + { + if (!arg1->sparkleSprites[i]->invisible) + return FALSE; + } + + if (arg0->vibration != 0) + arg0->vibration = 0; + + return TRUE; +} + +static void FramesToMinSec(struct BerryCrushGame_138 * manager, u16 frames) +{ + u8 i = 0; + u32 fractionalFrames = 0; + s16 r3 = 0; + + manager->minutes = frames / 3600; + manager->secondsInt = (frames % 3600) / 60; + r3 = MathUtil_Mul16((frames % 60) << 8, 4); + + for (i = 0; i < 8; i++) + { + if ((r3 >> (7 - i)) & 1) + fractionalFrames += sPressingSpeedConversionTable[i]; + } + + manager->secondsFrac = fractionalFrames / 1000000; +} + +static void PrintTextCentered(u8 windowId, u8 left, u8 colorId, const u8 *string) +{ + left = (left * 4) - (GetStringWidth(2, string, -1) / 2u); + AddTextPrinterParameterized3(windowId, 2, left, 0, sBerryCrushTextColorTable[colorId], 0, string); +} + +static void PrintBerryCrushResultWindow(struct BerryCrushGame * game, u8 command, u8 x, u8 y) +{ + u8 i = 0; + u8 linkPlayerId = 0; + u8 linkIdToPrint = 0; + u8 j; + s32 score; + u8 realX; + struct BerryCrushGame_68 * bcPlayers = &game->unk68; + s32 realX2; + + for (; i < game->playerCount; i++) + { + DynamicPlaceholderTextUtil_Reset(); + switch (command) + { + case 0: + // Number of presses + linkPlayerId = bcPlayers->unk20[command][i]; + if (i != 0 && bcPlayers->stats[command][i] != bcPlayers->stats[command][i - 1]) + linkIdToPrint = i; + ConvertIntToDecimalStringN(gStringVar1, bcPlayers->stats[command][i], STR_CONV_MODE_RIGHT_ALIGN, 4); + realX = x - GetStringWidth(2, sBCRankingHeaders[command], -1) - 4; + AddTextPrinterParameterized3(game->spritesManager.unk82, 2, realX, y + 14 * i, sBerryCrushTextColorTable[0], 0, sBCRankingHeaders[command]); + AddTextPrinterParameterized3(game->spritesManager.unk82, 2, realX - 24, y + 14 * i, sBerryCrushTextColorTable[0], 0, gStringVar1); + break; + case 1: + // Neatness + linkPlayerId = bcPlayers->unk20[command][i]; + if (i != 0 && bcPlayers->stats[command][i] != bcPlayers->stats[command][i - 1]) + linkIdToPrint = i; + ConvertIntToDecimalStringN(gStringVar1, bcPlayers->stats[command][i] >> 4, STR_CONV_MODE_RIGHT_ALIGN, 3); + score = 0; + realX = bcPlayers->stats[command][i] & 15; + for (j = 0; j < 4; j++) + { + if ((realX >> (3 - j)) & 1) + score += sPressingSpeedConversionTable[j]; + } + realX = score / 1000000u; + ConvertIntToDecimalStringN(gStringVar2, realX, STR_CONV_MODE_LEADING_ZEROS, 2); + StringExpandPlaceholders(gStringVar4, sBCRankingHeaders[command]); + realX2 = x - 4; + AddTextPrinterParameterized3(game->spritesManager.unk82, 2, realX2 - GetStringWidth(2, gStringVar4, 0), y + 14 * i, sBerryCrushTextColorTable[0], 0, gStringVar4); + break; + case 2: + // Berry names + linkPlayerId = i; + linkIdToPrint = i; + j = game->unk98[i].unkC; + if (j >= LAST_BERRY_INDEX - FIRST_BERRY_INDEX + 2) + j = 0; + StringCopy(gStringVar1, gBerries[j].name); + StringExpandPlaceholders(gStringVar4, sBCRankingHeaders[command]); + AddTextPrinterParameterized3(game->spritesManager.unk82, 2, x - GetStringWidth(2, gStringVar4, -1) - 4, y + 14 * i, sBerryCrushTextColorTable[0], 0, gStringVar4); + break; + } + if (linkPlayerId == game->localId) + StringCopy(gStringVar3, gText_1_ClrLtGryShdwBlk_Dynamic0); + else + StringCopy(gStringVar3, gText_1_Dynamic0); + gStringVar3[0] = linkIdToPrint + CHAR_1; + DynamicPlaceholderTextUtil_SetPlaceholderPtr(0, game->unk98[linkPlayerId].unk0); + DynamicPlaceholderTextUtil_ExpandPlaceholders(gStringVar4, gStringVar3); + AddTextPrinterParameterized3(game->spritesManager.unk82, 2, 4, y + 14 * i, sBerryCrushTextColorTable[0], 0, gStringVar4); + } +} + +static void sub_814E32C(struct BerryCrushGame * game) +{ + u8 i = 0; + u8 x = 0; + u32 score = 0; + struct BerryCrushGame_68 *players = &game->unk68; + u8 y = GetWindowAttribute(game->spritesManager.unk82, WINDOW_HEIGHT) * 8 - 42; + + FramesToMinSec(&game->spritesManager, players->unk04); + AddTextPrinterParameterized3(game->spritesManager.unk82, 2, 2, y, sBerryCrushTextColorTable[0], 0, gText_TimeColon); + + x = 190 - (u8)GetStringWidth(2, gText_SpaceSec, 0); + AddTextPrinterParameterized3(game->spritesManager.unk82, 2, x, y, sBerryCrushTextColorTable[0], 0, gText_SpaceSec); + + x -= 32; + ConvertIntToDecimalStringN(gStringVar1, game->spritesManager.secondsInt, STR_CONV_MODE_LEADING_ZEROS, 2); + ConvertIntToDecimalStringN(gStringVar2, game->spritesManager.secondsFrac, STR_CONV_MODE_LEADING_ZEROS, 2); + StringExpandPlaceholders(gStringVar4, gText_XDotY2); + AddTextPrinterParameterized3(game->spritesManager.unk82, 2, x, y, sBerryCrushTextColorTable[0], 0, gStringVar4); + + x -= (u8)GetStringWidth(2, gText_SpaceMin, 0) + 3; + AddTextPrinterParameterized3(game->spritesManager.unk82, 2, x, y, sBerryCrushTextColorTable[0], 0, gText_SpaceMin); + + x -= 9; + ConvertIntToDecimalStringN(gStringVar1, game->spritesManager.minutes, STR_CONV_MODE_LEADING_ZEROS, 1); + StringExpandPlaceholders(gStringVar4, gText_StrVar1); + AddTextPrinterParameterized3(game->spritesManager.unk82, 2, x, y, sBerryCrushTextColorTable[0], 0, gStringVar4); + + y += 14; + AddTextPrinterParameterized3(game->spritesManager.unk82, 2, 2, y, sBerryCrushTextColorTable[0], 0, gText_PressingSpeed); + + x = 190 - (u8)GetStringWidth(2, gText_TimesPerSec, 0); + AddTextPrinterParameterized3(game->spritesManager.unk82, 3, x, y, sBerryCrushTextColorTable[0], 0, gText_TimesPerSec); + + for (i = 0; i < 8; ++i) + if (((u8)game->pressingSpeed >> (7 - i)) & 1) + score += *(i + sPressingSpeedConversionTable); // It's accessed in a different way here for unknown reason + ConvertIntToDecimalStringN(gStringVar1, game->pressingSpeed >> 8, STR_CONV_MODE_RIGHT_ALIGN, 3); + ConvertIntToDecimalStringN(gStringVar2, score / 1000000, STR_CONV_MODE_LEADING_ZEROS, 2); + StringExpandPlaceholders(gStringVar4, gText_XDotY3); + x -= 38; + if (game->unk25_1) + AddTextPrinterParameterized3(game->spritesManager.unk82, 2, x, y, sBerryCrushTextColorTable[5], 0, gStringVar4); + else + AddTextPrinterParameterized3(game->spritesManager.unk82, 2, x, y, sBerryCrushTextColorTable[0], 0, gStringVar4); + + y += 14; + AddTextPrinterParameterized3(game->spritesManager.unk82, 2, 2, y, sBerryCrushTextColorTable[0], 0, gText_Silkiness); + + ConvertIntToDecimalStringN(gStringVar1, players->unk08, STR_CONV_MODE_RIGHT_ALIGN, 3); + StringExpandPlaceholders(gStringVar4, gText_Var1Percent); + x = 190 - (u8)GetStringWidth(2, gStringVar4, 0); + AddTextPrinterParameterized3(game->spritesManager.unk82, 2, x, y, sBerryCrushTextColorTable[0], 0, gStringVar4); +} + +bool32 sub_814E644(struct BerryCrushGame * game, struct BerryCrushGame_138 * spriteManager) +{ + u8 playerCountMinus2; + struct WindowTemplate template; + + switch (spriteManager->unk80) + { + case 0: + playerCountMinus2 = game->playerCount - 2; + BerryCrush_HideTimerSprites(spriteManager); + memcpy(&template, &gUnknown_846E428[game->gameState - 11], sizeof(struct WindowTemplate)); + if (game->gameState == 13) + template.height = gUnknown_846E448[1][playerCountMinus2]; + else + template.height = gUnknown_846E448[0][playerCountMinus2]; + spriteManager->unk82 = AddWindow(&template); + break; + case 1: + PutWindowTilemap(spriteManager->unk82); + FillWindowPixelBuffer(spriteManager->unk82, PIXEL_FILL(0)); + break; + case 2: + TextWindow_SetStdFrame0_WithPal(spriteManager->unk82, 0x21D, 0xD0); + DrawStdFrameWithCustomTileAndPalette(spriteManager->unk82, FALSE, 541, 13); + break; + case 3: + playerCountMinus2 = game->playerCount - 2; + switch (game->gameState) + { + case 11: + PrintTextCentered(spriteManager->unk82, 22, 3, gText_PressesRankings); + PrintBerryCrushResultWindow(game, 0, 0xB0, 8 * gUnknown_846E448[0][playerCountMinus2] - game->playerCount * 14); + spriteManager->unk80 = 5; + return FALSE; + case 12: + PrintTextCentered(spriteManager->unk82, 22, 4, sBCRankingHeaders[game->unk68.unk20[0][7] + 3]); + PrintBerryCrushResultWindow(game, 1, 0xB0, 8 * gUnknown_846E448[0][playerCountMinus2] - game->playerCount * 14); + spriteManager->unk80 = 5; + return FALSE; + case 13: + PrintTextCentered(spriteManager->unk82, 24, 3, gText_CrushingResults); + PrintBerryCrushResultWindow(game, 2, 0xC0, 0x10); + break; + } + break; + case 4: + sub_814E32C(game); + break; + case 5: + CopyWindowToVram(spriteManager->unk82, COPYWIN_BOTH); + spriteManager->unk80 = 0; + return TRUE; + } + ++spriteManager->unk80; + return FALSE; +} + +void sub_814E80C(struct BerryCrushGame * game) +{ + ClearStdWindowAndFrameToTransparent(game->spritesManager.unk82, 1); + RemoveWindow(game->spritesManager.unk82); + sub_814EBB0(game); +} + +static void Task_ShowBerryCrushRankings(u8 taskId) +{ + u8 i = 0, j, xPos, yPos; + u32 score = 0; + s16 *data = gTasks[taskId].data; + u8 *str; + + switch (data[0]) + { + case 0: + data[1] = AddWindow(&sWindowTemplate_BerryCrushRankings); + PutWindowTilemap(data[1]); + FillWindowPixelBuffer(data[1], PIXEL_FILL(0)); + TextWindow_SetStdFrame0_WithPal(data[1], 0x21D, 0xD0); + DrawStdFrameWithCustomTileAndPalette(data[1], 0, 0x21D, 0xD); + break; + case 1: + xPos = 96 - GetStringWidth(2, gText_BerryCrush2, -1) / 2u; + AddTextPrinterParameterized3( + data[1], + 2, + xPos, + 2, + sBerryCrushTextColorTable[3], + 0, + gText_BerryCrush2 + ); + xPos = 96 - GetStringWidth(2, gText_PressingSpeedRankings, -1) / 2u; + AddTextPrinterParameterized3( + data[1], + 2, + xPos, + 18, + sBerryCrushTextColorTable[3], + 0, + gText_PressingSpeedRankings + ); + yPos = 42; + for (i = 0; i < 4; ++i) + { + ConvertIntToDecimalStringN(gStringVar1, i + 2, STR_CONV_MODE_LEFT_ALIGN, 1); + StringExpandPlaceholders(gStringVar4, gText_Var1Players); + AddTextPrinterParameterized3( + data[1], + 2, + 4, + yPos, + sBerryCrushTextColorTable[0], + 0, + gStringVar4 + ); + for (j = 0; j < 8; ++j) + { + if (((data[i + 2] & 0xFF) >> (7 - j)) & 1) + score += sPressingSpeedConversionTable[j]; + } + ConvertIntToDecimalStringN(gStringVar1, (u16)data[i + 2] >> 8, STR_CONV_MODE_RIGHT_ALIGN, 3); + ConvertIntToDecimalStringN(gStringVar2, score / 1000000, STR_CONV_MODE_LEADING_ZEROS, 2); + str = StringExpandPlaceholders(gStringVar4, gText_XDotY3); + *str++ = CHAR_SPACE; + StringCopy(str, gText_TimesPerSec); + xPos = 192 - (u8)GetStringWidth(3, gStringVar4, 0); + AddTextPrinterParameterized3( + data[1], + 3, + xPos, + yPos, + sBerryCrushTextColorTable[0], + 0, + gStringVar4 + ); + yPos += 14; + score = 0; + } + CopyWindowToVram(data[1], COPYWIN_BOTH); + break; + case 2: + if (gMain.newKeys & (A_BUTTON | B_BUTTON)) + break; + else + return; + case 3: + ClearStdWindowAndFrameToTransparent(data[1], 1); + ClearWindowTilemap(data[1]); + RemoveWindow(data[1]); + DestroyTask(taskId); + EnableBothScriptContexts(); + ScriptContext2_Disable(); + data[0] = 0; + return; + } + ++data[0]; +} + +void ShowBerryCrushRankings(void) +{ + u8 taskId; + + ScriptContext2_Enable(); + taskId = CreateTask(Task_ShowBerryCrushRankings, 0); + gTasks[taskId].data[2] = gSaveBlock2Ptr->berryCrush.berryCrushResults[0]; + gTasks[taskId].data[3] = gSaveBlock2Ptr->berryCrush.berryCrushResults[1]; + gTasks[taskId].data[4] = gSaveBlock2Ptr->berryCrush.berryCrushResults[2]; + gTasks[taskId].data[5] = gSaveBlock2Ptr->berryCrush.berryCrushResults[3]; +} + +static void BerryCrush_PrintTimeOnSprites(struct BerryCrushGame_138 * manager, u16 frames) +{ + FramesToMinSec(manager, frames); + DigitObjUtil_PrintNumOn(0, manager->minutes); + DigitObjUtil_PrintNumOn(1, manager->secondsInt); + DigitObjUtil_PrintNumOn(2, manager->secondsFrac); +} + +void BerryCrush_HideTimerSprites(struct BerryCrushGame_138 * manager) +{ + manager->timerSprites[0]->invisible = TRUE; + manager->timerSprites[1]->invisible = TRUE; + DigitObjUtil_HideOrShow(2, 1); + DigitObjUtil_HideOrShow(1, 1); + DigitObjUtil_HideOrShow(0, 1); +} + +static void sub_814EB38(struct BerryCrushGame * game) +{ + u8 i; + + for (i = 0; i < game->playerCount; ++i) + { + game->spritesManager.seatCoords[i] = &gUnknown_846F294[gUnknown_846F280[game->playerCount - 2][i]]; + game->spritesManager.unk83[i] = AddWindow(&gUnknown_846E3F8[game->spritesManager.seatCoords[i]->unk0]); + PutWindowTilemap(game->spritesManager.unk83[i]); + FillWindowPixelBuffer(game->spritesManager.unk83[i], PIXEL_FILL(0)); + } +} + +static void sub_814EBB0(struct BerryCrushGame * game) +{ + u8 i; + + for (i = 0; i < game->playerCount; ++i) + { + PutWindowTilemap(game->spritesManager.unk83[i]); + if (i == game->localId) + { + AddTextPrinterParameterized4( + game->spritesManager.unk83[i], + 2, + 36 - GetStringWidth(2, game->unk98[i].unk0, 0) / 2u, + 1, + 0, + 0, + sBerryCrushTextColorTable[1], + 0, + game->unk98[i].unk0 + ); + } + else + { + AddTextPrinterParameterized4( + game->spritesManager.unk83[i], + 2, + 36 - GetStringWidth(2, game->unk98[i].unk0, 0) / 2u, + 1, + 0, + 0, + sBerryCrushTextColorTable[2], + 0, + game->unk98[i].unk0 + ); + } + CopyWindowToVram(game->spritesManager.unk83[i], COPYWIN_BOTH); + } + CopyBgTilemapBufferToVram(0); +} + +static void sub_814EC80(struct BerryCrushGame * game) +{ + u8 i = 0; + u8 *r4; + + LZ77UnCompWram(gUnknown_8EB0ADC, gDecompressionBuffer); + for (r4 = gDecompressionBuffer; i < game->playerCount; ++i) + { + CopyToBgTilemapBufferRect( + 3, + &r4[game->spritesManager.seatCoords[i]->unk0 * 40], + game->spritesManager.seatCoords[i]->unk1, + game->spritesManager.seatCoords[i]->unk2, + 10, + 2 + ); + } + CopyBgTilemapBufferToVram(3); +} + +static void sub_814ECE0(struct BerryCrushGame * game) +{ + u8 i = 0; + u8 spriteId; + + game->depth = -104; + game->vibration = 0; + gSpriteCoordOffsetX = 0; + gSpriteCoordOffsetY = -104; + for (; i < 4; ++i) + LoadCompressedSpriteSheet(&sSpriteSheets[i]); + LoadSpritePalettes(sSpritePals); + spriteId = CreateSprite(&sSpriteTemplate_BerryCrushCore, 120, 88, 5); + game->spritesManager.coreSprite = &gSprites[spriteId]; + game->spritesManager.coreSprite->oam.priority = 3; + game->spritesManager.coreSprite->coordOffsetEnabled = TRUE; + game->spritesManager.coreSprite->animPaused = TRUE; + for (i = 0; i < game->playerCount; ++i) + { + spriteId = CreateSprite( + &sSpriteTemplate_BerryCrushImpact, + game->spritesManager.seatCoords[i]->unk4 + 120, + game->spritesManager.seatCoords[i]->unk6 + 32, + 0 + ); + game->spritesManager.impactSprites[i] = &gSprites[spriteId]; + game->spritesManager.impactSprites[i]->oam.priority = 1; + game->spritesManager.impactSprites[i]->invisible = TRUE; + game->spritesManager.impactSprites[i]->coordOffsetEnabled = TRUE; + game->spritesManager.impactSprites[i]->animPaused = TRUE; + } + for (i = 0; i < NELEMS(game->spritesManager.sparkleSprites); ++i) + { + spriteId = CreateSprite( + &sSpriteTemplate_BerryCrushPowderSparkles, + gUnknown_846F2D6[i][0] + 120, + gUnknown_846F2D6[i][1] + 136, + 6 + ); + game->spritesManager.sparkleSprites[i] = &gSprites[spriteId]; + game->spritesManager.sparkleSprites[i]->oam.priority = 3; + game->spritesManager.sparkleSprites[i]->invisible = TRUE; + game->spritesManager.sparkleSprites[i]->animPaused = TRUE; + game->spritesManager.sparkleSprites[i]->data[0] = i; + } + for (i = 0; i < NELEMS(game->spritesManager.timerSprites); ++i) + { + spriteId = CreateSprite( + &sSpriteTemplate_BerryCrushTimer, + 24 * i + 176, + 8, + 0 + ); + game->spritesManager.timerSprites[i] = &gSprites[spriteId]; + game->spritesManager.timerSprites[i]->oam.priority = 0; + game->spritesManager.timerSprites[i]->invisible = FALSE; + game->spritesManager.timerSprites[i]->animPaused = FALSE; + } + DigitObjUtil_CreatePrinter(0, 0, &sDigitObjTemplates[0]); + DigitObjUtil_CreatePrinter(1, 0, &sDigitObjTemplates[1]); + DigitObjUtil_CreatePrinter(2, 0, &sDigitObjTemplates[2]); + if (game->gameState == 1) + BerryCrush_HideTimerSprites(&game->spritesManager); +} + +static void sub_814EF10(struct BerryCrushGame * r5) +{ + u8 r4 = 0; + + FreeSpriteTilesByTag(4); + FreeSpriteTilesByTag(3); + FreeSpriteTilesByTag(2); + FreeSpriteTilesByTag(1); + FreeSpritePaletteByTag(4); + FreeSpritePaletteByTag(2); + FreeSpritePaletteByTag(1); + for (; r4 < NELEMS(r5->spritesManager.timerSprites); ++r4) + DestroySprite(r5->spritesManager.timerSprites[r4]); + DigitObjUtil_DeletePrinter(2); + DigitObjUtil_DeletePrinter(1); + DigitObjUtil_DeletePrinter(0); + for (r4 = 0; r4 < NELEMS(r5->spritesManager.sparkleSprites); ++r4) + DestroySprite(r5->spritesManager.sparkleSprites[r4]); + for (r4 = 0; r4 < r5->playerCount; ++r4) + DestroySprite(r5->spritesManager.impactSprites[r4]); + if (r5->spritesManager.coreSprite->inUse) + DestroySprite(r5->spritesManager.coreSprite); +} + +static void SpriteCB_BerryCrushImpact(struct Sprite * sprite) +{ + if (sprite->animEnded) + { + sprite->invisible = TRUE; + sprite->animPaused = TRUE; + } +} + +static void sub_814EFFC(struct Sprite * sprite) +{ + u8 r1 = 0; + SpriteCallback r5 = SpriteCallbackDummy; + + for (; r1 < NELEMS(sprite->data); ++r1) + sprite->data[r1] = 0; + sprite->pos2.x = 0; + sprite->pos2.y = 0; + sprite->invisible = TRUE; + sprite->animPaused = TRUE; + sprite->callback = r5; +} + +static void sub_814F044(struct Sprite * sprite) +{ + s16 *r4 = sprite->data; + + r4[1] += r4[2]; + sprite->pos2.y += r4[1] >> 8; + if (r4[7] & 0x8000) + { + sprite->data[0] += r4[3]; + r4[4] += r4[5]; + sprite->pos2.x = Sin(r4[4] >> 7, r4[6]); + if (r4[7] & 0x8000 && r4[4] >> 7 > 126) + { + sprite->pos2.x = 0; + r4[7] &= 0x7FFF; + } + } + sprite->pos1.x = r4[0] >> 7; + if (sprite->pos1.y + sprite->pos2.y > (r4[7] & 0x7FFF)) + sprite->callback = sub_814EFFC; +} + +static void sub_814F0D8(struct Sprite * sprite) +{ + s16 *r7 = sprite->data; + s16 r4, r5; + s32 r2; + u32 r8 = 0; + + r2 = 640; + r7[1] = r2; + r7[2] = 32; + r7[7] = 168; + r4 = sprite->pos2.x * 128; + r5 = MathUtil_Div16Shift(7, (168 - sprite->pos1.y) << 7, (r2 + 32) >> 1); + sprite->data[0] = sprite->pos1.x << 7; + r7[3] = MathUtil_Div16Shift(7, r4, r5); + r2 = MathUtil_Mul16Shift(7, r5, 85); + r7[4] = r8; + r7[5] = MathUtil_Div16Shift(7, 0x3F80, r2); + r7[6] = sprite->pos2.x / 4; + r7[7] |= 0x8000; + sprite->pos2.y = r8; + sprite->pos2.x = r8; + sprite->callback = sub_814F044; + sprite->animPaused = FALSE; + sprite->invisible = FALSE; +} diff --git a/src/berry_crush_2.c b/src/berry_crush_2.c deleted file mode 100644 index fa9440888..000000000 --- a/src/berry_crush_2.c +++ /dev/null @@ -1,1441 +0,0 @@ -#include "global.h" -#include "gflib.h" -#include "berry.h" -#include "berry_crush.h" -#include "berry_powder.h" -#include "item.h" -#include "link.h" -#include "link_rfu.h" -#include "math_util.h" -#include "menu.h" -#include "minigame_countdown.h" -#include "new_menu_helpers.h" -#include "overworld.h" -#include "random.h" -#include "save.h" -#include "strings.h" -#include "constants/songs.h" - -static u32 BerryCrushCommand_BeginNormalPaletteFade(struct BerryCrushGame * game, u8 *params); -static u32 BerryCrushCommand_WaitPaletteFade(struct BerryCrushGame * game, u8 *params); -static u32 BerryCrushCommand_PrintMessage(struct BerryCrushGame * game, u8 *params); -static u32 BerryCrushCommand_InitGfx(struct BerryCrushGame * game, u8 *params); -static u32 BerryCrushCommand_TeardownGfx(struct BerryCrushGame * game, u8 *params); -static u32 BerryCrushCommand_SignalReadyToBegin(struct BerryCrushGame * game, u8 *params); -static u32 BerryCrushCommand_AskPickBerry(struct BerryCrushGame * game, u8 *params); -static u32 BerryCrushCommand_GoToBerryPouch(struct BerryCrushGame * game, u8 *params); -static u32 BerryCrushCommand_WaitForOthersToPickBerries(struct BerryCrushGame * game, u8 *params); -static u32 BerryCrushCommand_DropBerriesIntoCrusher(struct BerryCrushGame * game, u8 *params); -static u32 BerryCrushCommand_DropLid(struct BerryCrushGame * game, u8 *params); -static u32 BerryCrushCommand_Countdown(struct BerryCrushGame * game, u8 *params); -static u32 BerryCrushCommand_PlayGame_Master(struct BerryCrushGame * game, u8 *params); -static u32 BerryCrushCommand_PlayGame_Slave(struct BerryCrushGame * game, u8 *params); -static u32 BerryCrushCommand_FinishGame(struct BerryCrushGame * game, u8 *params); -static u32 BerryCrushCommand_HandleTimeUp(struct BerryCrushGame * game, u8 *params); -static u32 BerryCrushCommand_TabulateResults(struct BerryCrushGame * game, u8 *params); -static u32 BerryCrushCommand_ShowResults(struct BerryCrushGame * game, u8 *params); -static u32 BerryCrushCommand_SaveTheGame(struct BerryCrushGame * game, u8 *params); -static u32 BerryCrushCommand_AskPlayAgain(struct BerryCrushGame * game, u8 *params); -static u32 BerryCrushCommand_CommunicatePlayAgainResponses(struct BerryCrushGame * game, u8 *params); -static u32 BerryCrushCommand_FadeOutToPlayAgain(struct BerryCrushGame * game, u8 *params); -static u32 BerryCrushCommand_PlayAgainFailureMessage(struct BerryCrushGame * game, u8 *params); -static u32 BerryCrushCommand_GracefulExit(struct BerryCrushGame * game, u8 *params); -static u32 BerryCrushCommand_Quit(struct BerryCrushGame * game, u8 *params); -static void sub_814D4D8(struct BerryCrushGame * game); -static void BerryCrush_SetShowMessageParams(u8 *params, u8 stringId, u8 flags, u16 waitKeys, u8 followupCmd); - -static const u8 gUnknown_846E2E0[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80}; -static const u8 gUnknown_846E2E8[] = {0x00, 0x01, 0x02, 0x03, 0x05, 0x00, 0x00, 0x00}; - -static const s8 gUnknown_846E2F0[][7] = { - {0x04, 0x01, 0x00, 0xff, 0x00, 0x00, 0x00}, - {0x04, 0x02, 0x00, 0xff, 0x00, 0x00, 0x00}, - {0x04, 0x02, 0x00, 0xfe, 0x00, 0x00, 0x00}, - {0x06, 0x03, 0x01, 0xff, 0xfd, 0xff, 0x00}, - {0x06, 0x04, 0x01, 0xfe, 0xfc, 0xfe, 0x00}, -}; - -ALIGNED(4) const u8 gUnknown_846E314[][4] = { - {0x03, 0x02, 0x01, 0x00}, - {0x03, 0x03, 0x01, 0x00}, - {0x03, 0x03, 0x02, 0x00}, - {0x03, 0x04, 0x02, 0x00}, - {0x03, 0x05, 0x03, 0x00} -}; - -static const u8 *const sBerryCrushMessages[] = { - gText_BerryCrush_AreYouReady, - gText_BerryCrush_WaitForOthersToChooseBerry, - gText_BerryCrush_GainedXUnitsOfPowder, - gText_BerryCrush_RecordingGameResults, - gText_BerryCrush_WantToPlayAgain, - gText_BerryCrush_NoBerries, - gText_BerryCrush_MemberDroppedOut, - gText_BerryCrush_TimeUp, - gText_BerryCrush_CommunicationStandby -}; - -static u32 (*const sBerryCrushCommands[])(struct BerryCrushGame * berryCrushGame, u8 *params) = { - NULL, - BerryCrushCommand_BeginNormalPaletteFade, - BerryCrushCommand_WaitPaletteFade, - BerryCrushCommand_PrintMessage, - BerryCrushCommand_InitGfx, - BerryCrushCommand_TeardownGfx, - BerryCrushCommand_SignalReadyToBegin, - BerryCrushCommand_AskPickBerry, - BerryCrushCommand_GoToBerryPouch, - BerryCrushCommand_WaitForOthersToPickBerries, - BerryCrushCommand_DropBerriesIntoCrusher, - BerryCrushCommand_DropLid, - BerryCrushCommand_Countdown, - BerryCrushCommand_PlayGame_Master, - BerryCrushCommand_PlayGame_Slave, - BerryCrushCommand_FinishGame, - BerryCrushCommand_HandleTimeUp, - BerryCrushCommand_TabulateResults, - BerryCrushCommand_ShowResults, - BerryCrushCommand_SaveTheGame, - BerryCrushCommand_AskPlayAgain, - BerryCrushCommand_CommunicatePlayAgainResponses, - BerryCrushCommand_FadeOutToPlayAgain, - BerryCrushCommand_PlayAgainFailureMessage, - BerryCrushCommand_GracefulExit, - BerryCrushCommand_Quit -}; - -static const u8 gUnknown_846E3B4[][4] = { - {0x02, 0x04, 0x06, 0x07}, - {0x03, 0x05, 0x08, 0x0b}, - {0x03, 0x07, 0x0b, 0x0f}, - {0x04, 0x08, 0x0c, 0x11} -}; - -static const u8 gUnknown_846E3C4[] = {5, 7, 9, 12}; - -static const u8 sReceivedPlayerBitmasks[] = {0x03, 0x07, 0x0F, 0x1F}; - -void BerryCrush_RunOrScheduleCommand(u16 command, u8 runMode, u8 *params) -{ - struct BerryCrushGame * game = GetBerryCrushGame(); - - if (command >= NELEMS(sBerryCrushCommands)) - command = 0; - switch (runMode) - { - case 0: - // Call now and set followup to game->nextCmd - if (command != 0) - sBerryCrushCommands[command](game, params); - if (game->nextCmd >= NELEMS(sBerryCrushCommands)) - game->nextCmd = 0; - game->cmdCallback = sBerryCrushCommands[game->nextCmd]; - break; - case 1: - // Schedule for next frame - game->cmdCallback = sBerryCrushCommands[command]; - break; - } -} - -static u32 BerryCrushCommand_BeginNormalPaletteFade(struct BerryCrushGame * game, u8 *params) -{ - // params points to packed values: - // bytes 0-3: selectedPals (bitfield) - // byte 4: delay - // byte 5: startY - // byte 6: stopY - // bytes 7-8: fade color - // byte 9: if TRUE, communicate on fade complete - - u16 color; - u32 selectedPals[2]; - - selectedPals[0] = (u32)params[0]; - selectedPals[1] = (u32)params[1]; - selectedPals[1] <<= 8; - - selectedPals[0] |= selectedPals[1]; - selectedPals[1] = (u32)params[2]; - selectedPals[1] <<= 16; - - selectedPals[0] |= selectedPals[1]; - selectedPals[1] = (u32)params[3]; - selectedPals[1] <<= 24; - - selectedPals[0] |= selectedPals[1]; - params[0] = params[9]; - - color = params[8]; - color <<= 8; - color |= params[7]; - - gPaletteFade.bufferTransferDisabled = FALSE; - BeginNormalPaletteFade(selectedPals[0], params[4], params[5], params[6], color); - UpdatePaletteFade(); - game->nextCmd = BCCMD_WaitPaletteFade; - return 0; -} - -static u32 BerryCrushCommand_WaitPaletteFade(struct BerryCrushGame * game, u8 *params) -{ - switch (game->cmdState) - { - case 0: - if (UpdatePaletteFade()) - return 0; - if(params[0] != 0) - ++game->cmdState; - else - game->cmdState = 3; - return 0; - case 1: - LinkRfu_SetRfuFuncToSend6600(); - ++game->cmdState; - return 0; - case 2: - if (IsLinkTaskFinished()) - { - ++game->cmdState; - return 0; - } - return 0; - case 3: - BerryCrush_RunOrScheduleCommand(game->afterPalFadeCmd, 1, NULL); - game->cmdState = 0; - return 0; - default: - ++game->cmdState; - return 0; - } -} - -static u32 BerryCrushCommand_PrintMessage(struct BerryCrushGame * game, u8 *params) -{ - u16 waitKeys; - - waitKeys = params[3]; - waitKeys <<= 8; - waitKeys |= params[2] << 0; - switch (game->cmdState) - { - case 0: - DrawDialogueFrame(0, FALSE); - if (params[1] & 2) - { - StringExpandPlaceholders(gStringVar4, sBerryCrushMessages[params[0]]); - AddTextPrinterParameterized2(0, 2, gStringVar4, game->textSpeed, 0, TEXT_COLOR_DARK_GREY, TEXT_COLOR_WHITE, TEXT_COLOR_LIGHT_GREY); - } - else - { - AddTextPrinterParameterized2(0, 2, sBerryCrushMessages[params[0]], game->textSpeed, NULL, TEXT_COLOR_DARK_GREY, TEXT_COLOR_WHITE, TEXT_COLOR_LIGHT_GREY); - } - CopyWindowToVram(0, COPYWIN_BOTH); - break; - case 1: - if (!IsTextPrinterActive(0)) - { - if (waitKeys == 0) - ++game->cmdState; - break; - } - return 0; - case 2: - if (!(waitKeys & gMain.newKeys)) - return 0; - break; - case 3: - if (params[1] & 1) - ClearDialogWindowAndFrame(0, TRUE); - BerryCrush_RunOrScheduleCommand(game->nextCmd, 1, NULL); - game->cmdState = params[4]; - return 0; - } - ++game->cmdState; - return 0; -} - -static u32 BerryCrushCommand_InitGfx(struct BerryCrushGame * game, UNUSED u8 *params) -{ - if (BerryCrush_InitBgs() != 0) - BerryCrush_RunOrScheduleCommand(game->nextCmd, 0, game->commandParams); - return 0; -} - -static u32 BerryCrushCommand_TeardownGfx(struct BerryCrushGame * game, UNUSED u8 *params) -{ - if (BerryCrush_TeardownBgs() != 0) - BerryCrush_RunOrScheduleCommand(game->nextCmd, 0, game->commandParams); - return 0; -} - -static u32 BerryCrushCommand_SignalReadyToBegin(struct BerryCrushGame * game, UNUSED u8 *params) -{ - switch (game->cmdState) - { - case 0: - LinkRfu_SetRfuFuncToSend6600(); - break; - case 1: - if (IsLinkTaskFinished()) - { - PlayNewMapMusic(MUS_GAME_CORNER); - BerryCrush_RunOrScheduleCommand(BCCMD_AskPickBerry, 1, NULL); - game->gameState = 3; - game->cmdState = 0; - } - return 0; - } - ++game->cmdState; - return 0; -} - -static u32 BerryCrushCommand_AskPickBerry(struct BerryCrushGame * game, u8 *params) -{ - switch (game->cmdState) - { - default: - ++game->cmdState; - break; - case 0: - sub_814D4D8(game); - BerryCrush_SetShowMessageParams(params, BCTEXT_AREYOUREADY, 1, 0, BCCMD_BeginNormalPaletteFade); - game->nextCmd = BCCMD_AskPickBerry; - BerryCrush_RunOrScheduleCommand(BCCMD_PrintMessage, 1, NULL); - break; - case 1: - game->nextCmd = BCCMD_GoToBerryPouch; - BerryCrush_RunOrScheduleCommand(BCCMD_TeardownGfx, 1, NULL); - game->cmdState = 2; - break; - } - return 0; -} - -static u32 BerryCrushCommand_GoToBerryPouch(struct BerryCrushGame * game, UNUSED u8 *params) -{ - game->cmdCallback = NULL; - SetMainCallback2(CB2_BerryCrush_GoToBerryPouch); - return 0; -} - -static u32 BerryCrushCommand_WaitForOthersToPickBerries(struct BerryCrushGame * game, u8 *params) -{ - u8 i; - - switch (game->cmdState) - { - case 0: - BerryCrush_SetShowMessageParams(params, BCTEXT_WAITFOROTHERS, 0, 0, BCCMD_BeginNormalPaletteFade); - game->nextCmd = BCCMD_WaitForOthersToPickBerries; - BerryCrush_RunOrScheduleCommand(BCCMD_PrintMessage, 1, NULL); - return 0; - case 1: - LinkRfu_SetRfuFuncToSend6600(); - break; - case 2: - if (!IsLinkTaskFinished()) - return 0; - memset(game->sendCmd + 1, 0, sizeof(game->sendCmd) - 2); - game->sendCmd[1] = game->unk68.as_four_players.others[game->localId].berryId; - SendBlock(0, game->sendCmd + 1, 2); - break; - case 3: - if (!IsLinkTaskFinished()) - return 0; - game->unk10 = 0; - break; - case 4: - if (GetBlockReceivedStatus() != sReceivedPlayerBitmasks[game->playerCount - 2]) - return 0; - for (i = 0; i < game->playerCount; ++i) - { - game->unk68.as_four_players.others[i].berryId = gBlockRecvBuffer[i][0]; - if (game->unk68.as_four_players.others[i].berryId > 0xB0) - game->unk68.as_four_players.others[i].berryId = 0; - game->unk18 += gBerryCrushStats[game->unk68.as_four_players.others[i].berryId].unk0; - game->powder += gBerryCrushStats[game->unk68.as_four_players.others[i].berryId].powder; - } - game->unk10 = 0; - ResetBlockReceivedFlags(); - game->unk20 = MathUtil_Div32(game->unk18 << 8, 0x2000); - break; - case 5: - ClearDialogWindowAndFrame(0, TRUE); - BerryCrush_RunOrScheduleCommand(BCCMD_DropBerriesIntoCrusher, 1, NULL); - game->gameState = 4; - game->cmdState = 0; - return 0; - } - ++game->cmdState; - return 0; -} - -static u32 BerryCrushCommand_DropBerriesIntoCrusher(struct BerryCrushGame * game, UNUSED u8 *params) -{ - switch (game->cmdState) - { - case 0: - BerryCrush_CreateBerrySprites(game, &game->spritesManager); - LinkRfu_SetRfuFuncToSend6600(); - break; - case 1: - if (!IsLinkTaskFinished()) - return 0; - game->spritesManager.animBerryIdx = 0; - game->spritesManager.unk1 = 0; - game->spritesManager.unk2 = 0; - game->spritesManager.unk3 = 0; - break; - case 2: - game->spritesManager.berrySprites[game->spritesManager.animBerryIdx]->callback = SpriteCB_DropBerryIntoCrusher; - game->spritesManager.berrySprites[game->spritesManager.animBerryIdx]->affineAnimPaused = FALSE; - PlaySE(SE_BALL_THROW); - break; - case 3: - if (game->spritesManager.berrySprites[game->spritesManager.animBerryIdx]->callback == SpriteCB_DropBerryIntoCrusher) - return 0; - game->spritesManager.berrySprites[game->spritesManager.animBerryIdx] = NULL; - ++game->spritesManager.animBerryIdx; - LinkRfu_SetRfuFuncToSend6600(); - break; - case 4: - if (!IsLinkTaskFinished()) - return 0; - if (game->spritesManager.animBerryIdx < game->playerCount) - { - game->cmdState = 2; - return 0; - } - game->spritesManager.animBerryIdx = 0; - break; - case 5: - BerryCrushFreeBerrySpriteGfx(game, &game->spritesManager); - LinkRfu_SetRfuFuncToSend6600(); - break; - case 6: - if (!IsLinkTaskFinished()) - return 0; - PlaySE(SE_FALL); - BerryCrush_RunOrScheduleCommand(BCCMD_DropLid, 1, NULL); - game->gameState = 5; - game->cmdState = 0; - return 0; - } - ++game->cmdState; - return 0; -} - -static u32 BerryCrushCommand_DropLid(struct BerryCrushGame * game, UNUSED u8 *params) -{ - switch (game->cmdState) - { - case 0: - game->depth += 4; - if (game->depth < 0) - return 0; - game->depth = 0; - game->spritesManager.unk1 = 4; - game->spritesManager.animBerryIdx = 0; - game->spritesManager.unk2 = gUnknown_846E2F0[game->spritesManager.unk1][0]; - PlaySE(SE_M_STRENGTH); - break; - case 1: - game->vibration = gUnknown_846E2F0[game->spritesManager.unk1][game->spritesManager.animBerryIdx]; - SetGpuReg(REG_OFFSET_BG0VOFS, -game->vibration); - SetGpuReg(REG_OFFSET_BG2VOFS, -game->vibration); - SetGpuReg(REG_OFFSET_BG3VOFS, -game->vibration); - ++game->spritesManager.animBerryIdx; - if (game->spritesManager.animBerryIdx < game->spritesManager.unk2) - return 0; - if (game->spritesManager.unk1 == 0) - break; - --game->spritesManager.unk1; - game->spritesManager.unk2 = gUnknown_846E2F0[game->spritesManager.unk1][0]; - game->spritesManager.animBerryIdx = 0; - return 0; - case 2: - game->vibration = 0; - SetGpuReg(REG_OFFSET_BG0VOFS, 0); - SetGpuReg(REG_OFFSET_BG2VOFS, 0); - SetGpuReg(REG_OFFSET_BG3VOFS, 0); - LinkRfu_SetRfuFuncToSend6600(); - break; - case 3: - if (!IsLinkTaskFinished()) - return 0; - BerryCrush_RunOrScheduleCommand(BCCMD_Countdown, 1, NULL); - game->gameState = 6; - game->cmdState = 0; - return 0; - } - ++game->cmdState; - return 0; -} - -static u32 BerryCrushCommand_Countdown(struct BerryCrushGame * game, UNUSED u8 *params) -{ - switch (game-> cmdState) - { - case 0: - LinkRfu_SetRfuFuncToSend6600(); - break; - case 1: - if (!IsLinkTaskFinished()) - return 0; - StartMinigameCountdown(0x1000, 0x1000, 120, 80, 0); - break; - case 2: - if (IsMinigameCountdownRunning()) - return 0; - LinkRfu_SetRfuFuncToSend6600(); - break; - case 3: - if (!IsLinkTaskFinished()) - return 0; - game->spritesManager.animBerryIdx = 0; - game->spritesManager.unk1 = 0; - game->spritesManager.unk2 = 0; - game->spritesManager.unk3 = 0; - game->unk10 = 0; - if (game->localId == 0) - BerryCrush_RunOrScheduleCommand(BCCMD_PlayGame_Master, 1, NULL); - else - BerryCrush_RunOrScheduleCommand(BCCMD_PlayGame_Slave, 1, NULL); - game->gameState = 7; - game->cmdState = 0; - return 0; - } - ++game->cmdState; - return 0; -} - -static void BerryCrush_ProcessGamePartnerInput(struct BerryCrushGame * game) -{ - u8 numPressedA = 0; - u16 r3; - u16 *curRecvCmd; - u8 i = 0; - s32 r2_ = 0; - s32 r0; - - for (i = 0; i < game->playerCount; ++i) - { - curRecvCmd = gRecvCmds[i]; - if ((curRecvCmd[0] & 0xFF00) == 0x2F00 - && curRecvCmd[1] == 2) - { - if ((u8)curRecvCmd[2] & 4) // pushedAButton - { - game->localState.unk02_3 |= gUnknown_846E2E0[i]; - game->unk68.as_four_players.others[i].unk4.as_2d_bytes[1][5] = 1; - ++game->unk68.as_four_players.others[i].unk4.as_hwords[3]; - ++numPressedA; - r3 = game->timer - game->unk68.as_four_players.others[i].unk2; - if (r3 >= game->unk68.as_four_players.others[i].unk4.as_hwords[1] - 1 - && r3 <= game->unk68.as_four_players.others[i].unk4.as_hwords[1] + 1) - { - ++game->unk68.as_four_players.others[i].unk4.as_hwords[0]; - game->unk68.as_four_players.others[i].unk4.as_hwords[1] = r3; - if (game->unk68.as_four_players.others[i].unk4.as_hwords[0] > game->unk68.as_four_players.others[i].unk4.as_hwords[2]) - game->unk68.as_four_players.others[i].unk4.as_hwords[2] = game->unk68.as_four_players.others[i].unk4.as_hwords[0]; - } - else - { - game->unk68.as_four_players.others[i].unk4.as_hwords[0] = 0; - game->unk68.as_four_players.others[i].unk4.as_hwords[1] = r3; - } - game->unk68.as_four_players.others[i].unk2 = game->timer; - if (++game->unk68.as_four_players.others[i].unk4.as_2d_bytes[1][4] > 2) - game->unk68.as_four_players.others[i].unk4.as_2d_bytes[1][4] = 0; - } - else - { - game->unk68.as_four_players.others[i].unk4.as_2d_bytes[1][5] = 0; - } - } - } - if (numPressedA > 1) - { - for (i = 0; i < game->playerCount; ++i) - { - if (game->unk68.as_four_players.others[i].unk4.as_2d_bytes[1][5] != 0) - { - game->unk68.as_four_players.others[i].unk4.as_2d_bytes[1][5] |= 2; - ++game->unk68.as_four_players.others[i].unk4.as_hwords[4]; - } - } - } - if (numPressedA != 0) - { - game->unk2E += numPressedA; - numPressedA += gUnknown_846E2E8[numPressedA - 1]; - game->unk34 += numPressedA; - game->unk1A += numPressedA; - r0 = game->unk18; - r2_ = game->unk1A; - if (r0 - r2_ > 0) - { - r2_ <<= 8; - r2_ = MathUtil_Div32(r2_, game->unk20); - r2_ >>= 8; - game->unk24 = r2_; - } - else - { - game->unk24 = 32; - game->localState.unk02_0 = 1; - } - } -} - -static void BerryCrush_BuildLocalState(struct BerryCrushGame * game) -{ - u8 count = 0; - u16 r1 = 0; - u8 i = 0; - - for (i = 0; i < game->playerCount; ++i) - { - if (game->unk68.as_four_players.others[i].unk4.as_2d_bytes[1][5] != 0) - { - ++count; - r1 = game->unk68.as_four_players.others[i].unk4.as_2d_bytes[1][4] + 1; - if (game->unk68.as_four_players.others[i].unk4.as_2d_bytes[1][5] & 2) - r1 |= 4; - r1 <<= 3 * i; - game->localState.unk08 |= r1; - } - } - game->localState.unk04 = game->unk24; - if (count == 0) - { - if (game->spritesManager.unk3 != 0) - ++game->spritesManager.animBerryIdx; - else - goto SET_UNK5F_0; - } - else - { - if (game->spritesManager.unk3 != 0) - { - if (count != game->spritesManager.unk1) - { - game->spritesManager.unk1 = count - 1; - game->spritesManager.unk2 = gUnknown_846E314[count - 1][0]; - } - else - { - ++game->spritesManager.animBerryIdx; - } - } - else - { - game->spritesManager.animBerryIdx = 0; - game->spritesManager.unk1 = count - 1; - game->spritesManager.unk2 = gUnknown_846E314[count - 1][0]; - game->spritesManager.unk3 = 1; - } - } - if (game->spritesManager.unk3 != 0) - { - if (game->spritesManager.animBerryIdx >= game->spritesManager.unk2) - { - game->spritesManager.animBerryIdx = 0; - game->spritesManager.unk1 = 0; - game->spritesManager.unk2 = 0; - game->spritesManager.unk3 = 0; - r1 = 0; - } - else - { - r1 = gUnknown_846E314[game->spritesManager.unk1][game->spritesManager.animBerryIdx + 1]; - } - game->localState.unk03 = r1; - } - else - { - SET_UNK5F_0: - game->localState.unk03 = 0; - } - game->localState.unk06 = game->unk26; -} - -static void BerryCrush_HandlePlayerInput(struct BerryCrushGame * game) -{ - if (JOY_NEW(A_BUTTON)) - game->localState.pushedAButton = TRUE; - if (JOY_HELD(A_BUTTON)) - { - if (game->unk68.as_four_players.others[game->localId].unk4.as_hwords[5] < game->timer) - ++game->unk68.as_four_players.others[game->localId].unk4.as_hwords[5]; - } - if (game->localId != 0 && !game->localState.pushedAButton) - return; - game->localState.unk00 = 2; - if (game->timer % 30 == 0) - { - if (game->unk2E > gUnknown_846E3C4[game->playerCount - 2]) - { - ++game->unk30; - game->unk25_4 = 1; - } - else - { - game->unk25_4 = 0; - } - game->unk2E = 0; - ++game->unk32; - } - if (game->timer % 15 == 0) - { - if (game->unk34 < gUnknown_846E3B4[game->playerCount - 2][0]) - game->unk25_5 = 0; - else if (game->unk34 < gUnknown_846E3B4[game->playerCount - 2][1]) - game->unk25_5 = 1; - else if (game->unk34 < gUnknown_846E3B4[game->playerCount - 2][2]) - game->unk34 = 2; // typo since game->unk34 will be reset? - else if (game->unk34 < gUnknown_846E3B4[game->playerCount - 2][3]) - game->unk34 = 3; // typo since game->unk34 will be reset? - else - game->unk25_5 = 4; - game->unk34 = 0; - } - else - { - ++game->unk10; - if (game->unk10 > 60) - { - if (game->unk10 > 70) - { - sub_80FBA44(); - game->unk10 = 0; - } - else if (game->localState.unk02_3 == 0) - { - sub_80FBA44(); - game->unk10 = 0; - } - } - - } - if (game->timer >= 36000) - game->localState.unk02_0 = 1; - game->localState.unk02_1 = game->unk25_4; - game->localState.unk0A = game->unk25_5; - memcpy(&game->sendCmd[1], &game->localState, sizeof(game->sendCmd) - 2); - RfuPrepareSend0x2f00(game->sendCmd + 1); -} - -static void BerryCrush_UpdateGameState(struct BerryCrushGame * game) -{ - struct BerryCrushGame_4E * r4_; -#ifndef NONMATCHING - register u32 i asm("r4"); - register u32 iPlusPlus asm("r0"); - - for (i = 0; i < game->playerCount; i = (u8)iPlusPlus) - { - game->unk68.as_four_players.others[i].unk4.as_2d_bytes[1][5] = 0; - iPlusPlus = i + 1; - } -#else - u8 i; - - for (i = 0; i < game->playerCount; ++i) - game->unk68.as_four_players.others[i].unk4.as_2d_bytes[1][5] = 0; -#endif - if ((gRecvCmds[0][0] & 0xFF00) != 0x2F00 - || gRecvCmds[0][1] != 2) - { - game->unk25_2 = 0; - } - else - { - r4_ = (struct BerryCrushGame_4E *)&game->recvCmd; - memcpy(r4_, gRecvCmds, sizeof(struct BerryCrushGame_4E)); - game->depth = r4_->data.unk04; - game->vibration = r4_->data.unk03; - game->timer = r4_->data.unk06; - sub_814DC5C(game, &game->spritesManager); - if (r4_->data.unk02_0) - game->unk25_3 = 1; - } -} - -static u32 BerryCrushCommand_PlayGame_Master(struct BerryCrushGame * game, UNUSED u8 *params) -{ - memset(&game->localState, 0, sizeof(game->localState)); - memset(&game->recvCmd, 0, sizeof(game->recvCmd)); - BerryCrush_UpdateGameState(game); - SetGpuReg(REG_OFFSET_BG0VOFS, -game->vibration); - SetGpuReg(REG_OFFSET_BG2VOFS, -game->vibration); - SetGpuReg(REG_OFFSET_BG3VOFS, -game->vibration); - if (game->unk25_3) - { - if (game->timer >= 36000) - { - game->timer = 36000; - BerryCrush_RunOrScheduleCommand(BCCMD_HandleTimeUp, 1, NULL); - } - else - { - BerryCrush_RunOrScheduleCommand(BCCMD_FinishGame, 1, NULL); - } - game->unk10 = 0; - game->cmdState = 0; - return 0; - } - else - { - ++game->unk26; - BerryCrush_ProcessGamePartnerInput(game); - BerryCrush_BuildLocalState(game); - BerryCrush_HandlePlayerInput(game); - return 0; - } -} - -static u32 BerryCrushCommand_PlayGame_Slave(struct BerryCrushGame * game, UNUSED u8 *params) -{ - memset(&game->localState, 0, sizeof(game->localState)); - memset(&game->recvCmd, 0, sizeof(game->recvCmd)); - BerryCrush_UpdateGameState(game); - SetGpuReg(REG_OFFSET_BG0VOFS, -game->vibration); - SetGpuReg(REG_OFFSET_BG2VOFS, -game->vibration); - SetGpuReg(REG_OFFSET_BG3VOFS, -game->vibration); - if (game->unk25_3) - { - if (game->timer >= 36000) - { - game->timer = 36000; - BerryCrush_RunOrScheduleCommand(BCCMD_HandleTimeUp, 1, NULL); - } - else - { - BerryCrush_RunOrScheduleCommand(BCCMD_FinishGame, 1, NULL); - } - game->unk10 = 0; - game->cmdState = 0; - return 0; - } - else - { - BerryCrush_HandlePlayerInput(game); - return 0; - } -} - -static u32 BerryCrushCommand_FinishGame(struct BerryCrushGame * game, UNUSED u8 *params) -{ - switch (game->cmdState) - { - case 0: - game->gameState = 8; - PlaySE(SE_M_STRENGTH); - BlendPalettes(0xFFFFFFFF, 8, RGB(31, 31, 0)); - game->spritesManager.animBerryIdx = 2; - break; - case 1: - if (--game->spritesManager.animBerryIdx != 255) - return 0; - BlendPalettes(0xFFFFFFFF, 0, RGB(31, 31, 0)); - game->spritesManager.unk1 = 4; - game->spritesManager.animBerryIdx = 0; - game->spritesManager.unk2 = gUnknown_846E2F0[game->spritesManager.unk1][0]; - break; - case 2: - game->vibration = gUnknown_846E2F0[game->spritesManager.unk1][game->spritesManager.animBerryIdx]; - SetGpuReg(REG_OFFSET_BG0VOFS, -game->vibration); - SetGpuReg(REG_OFFSET_BG2VOFS, -game->vibration); - SetGpuReg(REG_OFFSET_BG3VOFS, -game->vibration); - if (++game->spritesManager.animBerryIdx < game->spritesManager.unk2) - return 0; - if (game->spritesManager.unk1 != 0) - { - --game->spritesManager.unk1; - game->spritesManager.unk2 = gUnknown_846E2F0[game->spritesManager.unk1][0]; - game->spritesManager.animBerryIdx = 0; - return 0; - } - break; - case 3: - game->vibration = 0; - SetGpuReg(REG_OFFSET_BG0VOFS, 0); - SetGpuReg(REG_OFFSET_BG2VOFS, 0); - SetGpuReg(REG_OFFSET_BG3VOFS, 0); - break; - case 4: - if (!sub_814DE50(game, &game->spritesManager)) - return 0; - LinkRfu_SetRfuFuncToSend6600(); - game->unk10 = 0; - break; - case 5: - if (!IsLinkTaskFinished()) - return 0; - BerryCrush_RunOrScheduleCommand(BCCMD_TabulateResults, 1, NULL); - game->unk10 = 0; - game->cmdState = 0; - return 0; - } - ++game->cmdState; - return 0; -} - -static u32 BerryCrushCommand_HandleTimeUp(struct BerryCrushGame * game, u8 *params) -{ - switch (game->cmdState) - { - case 0: - game->gameState = 9; - PlaySE(SE_FAILURE); - BlendPalettes(0xFFFFFFFF, 8, RGB(31, 0, 0)); - game->spritesManager.animBerryIdx = 4; - break; - case 1: - if (--game->spritesManager.animBerryIdx != 255) - return 0; - BlendPalettes(0xFFFFFFFF, 0, RGB(31, 0, 0)); - game->spritesManager.animBerryIdx = 0; - break; - case 2: - if (!sub_814DE50(game, &game->spritesManager)) - return 0; - LinkRfu_SetRfuFuncToSend6600(); - game->unk10 = 0; - SetGpuReg(REG_OFFSET_BG0VOFS, 0); - SetGpuReg(REG_OFFSET_BG2VOFS, 0); - SetGpuReg(REG_OFFSET_BG3VOFS, 0); - break; - case 3: - if (!IsLinkTaskFinished()) - return 0; - ConvertIntToDecimalStringN(gStringVar1, game->powder, STR_CONV_MODE_LEFT_ALIGN, 6); - BerryCrush_SetShowMessageParams(params, BCTEXT_TIMEUP, 1, 0, 0); - game->nextCmd = BCCMD_SaveTheGame; - BerryCrush_RunOrScheduleCommand(BCCMD_PrintMessage, 1, NULL); - game->unk10 = 0; - game->cmdState = 0; - return 0; - } - ++game->cmdState; - return 0; -} - -static u32 BerryCrushCommand_TabulateResults(struct BerryCrushGame * game, UNUSED u8 *params) -{ - u8 i, j; - s32 r2; - s32 r4; - u8 r6; // ??? - - switch (game->cmdState) - { - case 0: - memset(game->sendCmd + 1, 0, 2 * sizeof(u16)); - if (game->unk68.as_four_players.others[game->localId].unk4.as_hwords[5] > game->timer) - game->unk68.as_four_players.others[game->localId].unk4.as_hwords[5] = game->timer; - game->sendCmd[1] = game->unk68.as_four_players.others[game->localId].unk4.as_hwords[5]; - SendBlock(0, game->sendCmd + 1, 2); - break; - case 1: - if (!IsLinkTaskFinished()) - return 0; - game->unk10 = 0; - break; - case 2: - if (GetBlockReceivedStatus() != sReceivedPlayerBitmasks[game->playerCount - 2]) - return 0; - for (i = 0; i < game->playerCount; ++i) - game->unk68.as_four_players.others[i].unk4.as_hwords[5] = gBlockRecvBuffer[i][0]; - game->unk10 = 0; - game->sendCmd[1] = 0; - ResetBlockReceivedFlags(); - if (game->localId == 0) - game->cmdState = 3; - else - game->cmdState = 6; - return 0; - case 3: - memset( - &game->unk68, - 0, - sizeof(struct BerryCrushGame_68_x_SubStruct) - ); - game->unk68.as_four_players.unk00.unk04 = game->timer; - game->unk68.as_four_players.unk00.unk06 = game->unk18 / (game->timer / 60); - // (unk30 * 50 / unk32) + 50 - r2 = MathUtil_Mul32(game->unk30 << 8, 50 << 8); - r2 = MathUtil_Div32(r2, game->unk32 << 8) + (50 << 8); - r2 >>= 8; - game->unk68.as_four_players.unk00.unk08 = r2 & 0x7F; - // powder + playerCount * (r2 / 100) - r2 <<= 8; - r2 = MathUtil_Div32(r2, 100 << 8); - r4 = (game->powder * game->playerCount) << 8; - r4 = MathUtil_Mul32(r4, r2); - game->unk68.as_four_players.unk00.unk00 = r4 >> 8; - game->unk68.as_five_players.players[0].unk4.as_2d_bytes[0][7] = Random() % 3; - for (r6 = 0, i = 0; i < game->playerCount; ++i) - { - game->unk68.as_five_players.players[0].unk4.as_2d_bytes[0][i] = i; - game->unk68.as_five_players.players[0].unk4.as_2d_bytes[1][i] = i; - game->unk68.as_four_players.unk00.stats[0][i] = game->unk68.as_four_players.others[i].unk4.as_hwords[3]; - game->unk68.as_four_players.unk00.unk0A += game->unk68.as_four_players.unk00.stats[0][i]; - switch (game->unk68.as_five_players.players[0].unk4.as_2d_bytes[0][7]) - { - case 0: - if (game->unk68.as_four_players.others[i].unk4.as_hwords[3] != 0) - { - r2 = game->unk68.as_four_players.others[i].unk4.as_hwords[2]; - r2 <<= 8; - r2 = MathUtil_Mul32(r2, 0x6400); - r4 = game->unk68.as_four_players.others[i].unk4.as_hwords[3]; - r4 <<= 8; - r4 = MathUtil_Div32(r2, r4); - } - else - { - r4 = 0; - } - break; - case 1: - if (game->unk68.as_four_players.others[i].unk4.as_hwords[3] != 0) - { - r2 = game->unk68.as_four_players.others[i].unk4.as_hwords[4]; - r2 <<= 8; - r2 = MathUtil_Mul32(r2, 0x6400); - r4 = game->unk68.as_four_players.others[i].unk4.as_hwords[3]; - r4 <<= 8; - r4 = MathUtil_Div32(r2, r4); - } - else - { - r4 = 0; - } - break; - case 2: - if (game->unk68.as_four_players.others[i].unk4.as_hwords[3] == 0) - { - r4 = 0; - } - else if (game->unk68.as_four_players.others[i].unk4.as_hwords[5] >= game->timer) - { - r4 = 0x6400; - } - else - { - r2 = game->unk68.as_four_players.others[i].unk4.as_hwords[5]; - r2 <<= 8; - r2 = MathUtil_Mul32(r2, 0x6400); - r4 = game->timer; - r4 <<= 8; - r4 = MathUtil_Div32(r2, r4); - } - break; - } - r4 >>= 4; - game->unk68.as_four_players.unk00.stats[1][i] = r4; - } - break; - case 4: - for (r6 = 0, i = 0; i < game->playerCount - 1; ++i) - { - for (j = game->playerCount - 1; j > i; --j) - { - u16 r0; - u8 r3; - u16 *numPresses_p = game->unk68.as_four_players.unk00.stats[0]; - u8 *sp04 = game->unk68.as_five_players.players[0].unk4.as_2d_bytes[0]; - u8 *r10 = game->unk68.as_five_players.players[0].unk4.as_2d_bytes[1]; - u16 *r9 = game->unk68.as_four_players.unk00.stats[1]; - s32 r12 = j - 1; - u16 *p1 = numPresses_p + r12; // these have to be here - u16 *p2 = numPresses_p + j; // to swap operands. macro? - - if (*p1 < *p2) - { - r0 = numPresses_p[j]; - numPresses_p[j] = numPresses_p[r12]; - numPresses_p[r12] = r0; - r3 = sp04[j]; - sp04[j] = sp04[r12]; - sp04[r12] = r3; - } - p1 = r9 + r12; - p2 = r9 + j; - if (*p1 < *p2) - { - r0 = r9[j]; - r9[j] = r9[r12]; - r9[r12] = r0; - r3 = r10[j]; - r10[j] = r10[r12]; - r10[r12] = r3; - } - } - } - SendBlock( - 0, - &game->unk68, - sizeof(struct BerryCrushGame_68_x_SubStruct) - ); - break; - case 5: - if (!IsLinkTaskFinished()) - return 0; - game->unk10 = 0; - break; - case 6: - if (GetBlockReceivedStatus() != 1) - return 0; - memset( - &game->unk68, - 0, - sizeof(struct BerryCrushGame_68_x_SubStruct) - ); - memcpy( - &game->unk68, - gBlockRecvBuffer, - sizeof(struct BerryCrushGame_68_x_SubStruct) - ); - ResetBlockReceivedFlags(); - game->unk10 = 0; - break; - case 7: - BerryCrush_UpdateSav2Records(); - BerryCrush_RunOrScheduleCommand(BCCMD_ShowResults, 1, NULL); - game->gameState = 11; - game->cmdState = 0; - game->unk24 = 0; - return 0; - } - ++game->cmdState; - return 0; -} - -static u32 BerryCrushCommand_ShowResults(struct BerryCrushGame * game, u8 *params) -{ - switch (game->cmdState) - { - case 0: - if (!sub_814E644(game, &game->spritesManager)) - return 0; - break; - case 1: - CopyBgTilemapBufferToVram(0); - game->spritesManager.animBerryIdx = 30; - break; - case 2: - if (game->spritesManager.animBerryIdx != 0) - { - --game->spritesManager.animBerryIdx; - return 0; - } - if (!JOY_NEW(A_BUTTON)) - return 0; - PlaySE(SE_SELECT); - sub_814E80C(game); - break; - case 3: - if (game->gameState <= 12) - { - ++game->gameState; - game->cmdState = 0; - return 0; - } - break; - case 4: - ConvertIntToDecimalStringN(gStringVar1, game->powder, STR_CONV_MODE_LEFT_ALIGN, 6); - ConvertIntToDecimalStringN(gStringVar2, GetBerryPowder(), STR_CONV_MODE_LEFT_ALIGN, 6); - BerryCrush_SetShowMessageParams(params, BCTEXT_GAINEDPOWDER, 3, 0, 0); - game->nextCmd = BCCMD_SaveTheGame; - BerryCrush_RunOrScheduleCommand(BCCMD_PrintMessage, 1, NULL); - game->cmdState = 0; - return 0; - } - ++game->cmdState; - return 0; -} - -static u32 BerryCrushCommand_SaveTheGame(struct BerryCrushGame * game, u8 *params) -{ - switch (game->cmdState) - { - case 0: - if (game->timer >= 36000) - BerryCrush_HideTimerSprites(&game->spritesManager); - BerryCrush_SetShowMessageParams(params, BCTEXT_COMMSTANDBY, 0, 0, BCCMD_BeginNormalPaletteFade); - game->nextCmd = BCCMD_SaveTheGame; - BerryCrush_RunOrScheduleCommand(BCCMD_PrintMessage, 1, NULL); - game->cmdState = 0; - return 0; - case 1: - LinkRfu_SetRfuFuncToSend6600(); - break; - case 2: - if (!IsLinkTaskFinished()) - return 0; - DrawDialogueFrame(0, FALSE); - AddTextPrinterParameterized2(0, 2, gText_SavingDontTurnOffThePower2, 0, NULL, 2, 1, 3); - CopyWindowToVram(0, COPYWIN_BOTH); - CreateTask(Task_SaveGame_UpdatedLinkRecords, 0); - break; - case 3: - if (FuncIsActiveTask(Task_SaveGame_UpdatedLinkRecords)) - return 0; - break; - case 4: - BerryCrush_RunOrScheduleCommand(BCCMD_AskPlayAgain, 1, NULL); - game->gameState = 15; - game->cmdState = 0; - return 0; - } - ++game->cmdState; - return 0; -} - -static u32 BerryCrushCommand_AskPlayAgain(struct BerryCrushGame * game, u8 *params) -{ - s32 r4; -#ifndef NONMATCHING - register s32 r0 asm("r0"); -#else - s32 r0; -#endif - - switch (game->cmdState) - { - case 0: - BerryCrush_SetShowMessageParams(params, BCTEXT_ASKPLAYAGAIN, 0, 0, BCCMD_BeginNormalPaletteFade); - game->nextCmd = BCCMD_AskPlayAgain; - BerryCrush_RunOrScheduleCommand(BCCMD_PrintMessage, 1, NULL); - r0 = 0; - game->cmdState = r0; // dunno what it's doing because it's already in case 0 - return 0; - case 1: - DisplayYesNoMenuDefaultYes(); - break; - case 2: - if ((r4 = Menu_ProcessInputNoWrapClearOnChoose()) != -2) - { - memset(game->sendCmd + 1, 0, sizeof(game->sendCmd) - 2); - if (r4 == 0) - { - if (CheckHasAtLeastOneBerry()) - game->unk14 = 0; - else - game->unk14 = 3; - } - else - { - game->unk14 = 1; - } - ClearDialogWindowAndFrame(0, TRUE); - BerryCrush_SetShowMessageParams(params, BCTEXT_COMMSTANDBY, 0, 0, 0); - game->nextCmd = BCCMD_CommunicatePlayAgainResponses; - BerryCrush_RunOrScheduleCommand(BCCMD_PrintMessage, 1, NULL); - game->cmdState = 0; - } - return 0; - } - ++game->cmdState; - return 0; -} - -static u32 BerryCrushCommand_CommunicatePlayAgainResponses(struct BerryCrushGame * game, UNUSED u8 *params) -{ - u8 i = 0; - - switch (game->cmdState) - { - case 0: - LinkRfu_SetRfuFuncToSend6600(); - break; - case 1: - if (!IsLinkTaskFinished()) - return 0; - game->sendCmd[1] = game->unk14; - game->recvCmd[0] = 0; - SendBlock(0, game->sendCmd + 1, sizeof(u16)); - break; - case 2: - if (!IsLinkTaskFinished()) - return 0; - game->unk10 = 0; - break; - case 3: - if (GetBlockReceivedStatus() != sReceivedPlayerBitmasks[game->playerCount - 2]) - return 0; - for (; i < game->playerCount; ++i) - game->recvCmd[0] += gBlockRecvBuffer[i][0]; - if (game->recvCmd[0] != 0) - BerryCrush_RunOrScheduleCommand(BCCMD_PlayAgainFailureMessage, 1, NULL); - else - BerryCrush_RunOrScheduleCommand(BCCMD_FadeOutToPlayAgain, 1, NULL); - ResetBlockReceivedFlags(); - game->sendCmd[1] = 0; - game->recvCmd[0] = 0; - game->unk10 = 0; - game->cmdState = 0; - return 0; - } - ++game->cmdState; - return 0; -} - -static u32 BerryCrushCommand_FadeOutToPlayAgain(struct BerryCrushGame * game, UNUSED u8 *params) -{ - switch (game->cmdState) - { - case 0: - BeginNormalPaletteFade(0xFFFFFFFF, 1, 0, 0x10, RGB_BLACK); - UpdatePaletteFade(); - break; - case 1: - if (UpdatePaletteFade()) - return 0; - break; - case 2: - ClearDialogWindowAndFrame(0, TRUE); - sub_814DA04(game); - BeginNormalPaletteFade(0xFFFFFFFF, 0, 0x10, 0, RGB_BLACK); - UpdatePaletteFade(); - break; - case 3: - if (UpdatePaletteFade()) - return 0; - BerryCrush_RunOrScheduleCommand(BCCMD_AskPickBerry, 1, NULL); - game->gameState = 3; - game->cmdState = 0; - return 0; - } - ++game->cmdState; - return 0; -} - -static u32 BerryCrushCommand_PlayAgainFailureMessage(struct BerryCrushGame * game, UNUSED u8 *params) -{ - switch (game->cmdState) - { - case 0: - DrawDialogueFrame(0, FALSE); - if (game->unk14 == 3) - AddTextPrinterParameterized2(0, 2, sBerryCrushMessages[BCTEXT_CANCEL_NOBERRIES], game->textSpeed, NULL, 2, 1, 3); - else - AddTextPrinterParameterized2(0, 2, sBerryCrushMessages[BCTEXT_CANCEL_DROPPEDOUT], game->textSpeed, NULL, 2, 1, 3); - CopyWindowToVram(0, COPYWIN_BOTH); - break; - case 1: - if (IsTextPrinterActive(0)) - return 0; - game->spritesManager.animBerryIdx = 120; - break; - case 2: - if (game->spritesManager.animBerryIdx != 0) - --game->spritesManager.animBerryIdx; - else - { - BerryCrush_RunOrScheduleCommand(BCCMD_GracefulExit, 1, NULL); - game->cmdState = 0; - } - return 0; - } - ++game->cmdState; - return 0; -} - -static u32 BerryCrushCommand_GracefulExit(struct BerryCrushGame * game, UNUSED u8 *params) -{ - switch (game->cmdState) - { - case 0: - LinkRfu_SetRfuFuncToSend6600(); - break; - case 1: - if (!IsLinkTaskFinished()) - return 0; - SetCloseLinkCallback(); - break; - case 2: - if (gReceivedRemoteLinkPlayers) - return 0; - game->nextCmd = BCCMD_Quit; - BerryCrush_RunOrScheduleCommand(BCCMD_TeardownGfx, 1, NULL); - game->cmdState = 2; // ??? - return 0; - } - ++game->cmdState; - return 0; -} - -static u32 BerryCrushCommand_Quit(UNUSED struct BerryCrushGame * game, UNUSED u8 *params) -{ - ExitBerryCrushWithCallback(NULL); - return 0; -} - -static void sub_814D4D8(struct BerryCrushGame * game) -{ - u8 r5 = 0; - - IncrementGameStat(GAME_STAT_BERRY_CRUSH_POINTS); - game->unkD = 0; - game->unk10 = 0; - game->gameState = 2; - game->unk14 = 0; - game->powder = 0; - game->unk18 = 0; - game->unk1A = 0; - game->unk20 = 0; - game->unk24 = 0; - game->unk25_0 = 0; - game->unk25_1 = 0; - game->unk25_2 = 0; - game->unk25_3 = FALSE; - game->unk25_4 = 0; - game->unk25_5 = 0; - game->unk26 = 0; - game->timer = 0; - game->unk2E = 0; - game->unk32 = -1; - game->unk30 = 0; - game->unk34 = 0; - for (; r5 < 5; ++r5) // why is it 5 instead of 4? fillerBC isn't sufficient for one player - { - game->unk68.as_four_players.others[r5].berryId = -1; - game->unk68.as_four_players.others[r5].unk2 = 0; - game->unk68.as_four_players.others[r5].unk4.as_hwords[0] = 0; - game->unk68.as_four_players.others[r5].unk4.as_hwords[1] = 1; - game->unk68.as_four_players.others[r5].unk4.as_hwords[2] = 0; - game->unk68.as_four_players.others[r5].unk4.as_hwords[3] = 0; - game->unk68.as_four_players.others[r5].unk4.as_hwords[4] = 0; - game->unk68.as_four_players.others[r5].unk4.as_hwords[5] = 0; - game->unk68.as_four_players.others[r5].unk4.as_2d_bytes[1][4] = 0; - game->unk68.as_four_players.others[r5].unk4.as_2d_bytes[1][5] = 0; - } -} - -void BerryCrush_SetPaletteFadeParams(u8 *params, bool8 communicateAfter, u32 selectedPals, s8 delay, u8 startY, u8 targetY, u16 palette) -{ - params[0] = ((u8 *)&selectedPals)[0]; - params[1] = ((u8 *)&selectedPals)[1]; - params[2] = ((u8 *)&selectedPals)[2]; - params[3] = ((u8 *)&selectedPals)[3]; - params[4] = delay; - params[5] = startY; - params[6] = targetY; - params[7] = ((u8 *)&palette)[0]; - params[8] = ((u8 *)&palette)[1]; - params[9] = communicateAfter; -} - -void BerryCrush_SetShowMessageParams(u8 *params, u8 stringId, u8 flags, u16 waitKeys, u8 followupCmd) -{ - params[0] = stringId; - params[1] = flags; - params[2] = ((u8 *)&waitKeys)[0]; - params[3] = ((u8 *)&waitKeys)[1]; - params[4] = followupCmd; -} diff --git a/src/berry_crush_3.c b/src/berry_crush_3.c deleted file mode 100644 index 8272a2297..000000000 --- a/src/berry_crush_3.c +++ /dev/null @@ -1,1390 +0,0 @@ -#include "global.h" -#include "gflib.h" -#include "battle_anim.h" -#include "berry.h" -#include "berry_crush.h" -#include "decompress.h" -#include "digit_obj_util.h" -#include "dynamic_placeholder_text_util.h" -#include "graphics.h" -#include "item_menu_icons.h" -#include "link.h" -#include "link_rfu.h" -#include "math_util.h" -#include "menu.h" -#include "new_menu_helpers.h" -#include "scanline_effect.h" -#include "script.h" -#include "strings.h" -#include "text_window.h" -#include "trig.h" -#include "constants/items.h" -#include "constants/songs.h" - -static void FramesToMinSec(struct BerryCrushGame_138 * arg0, u16 arg1); -static void PrintTextCentered(u8 windowId, u8 left, u8 colorId, const u8 *string); -static void PrintBerryCrushResultWindow(struct BerryCrushGame * sp0C, u8 sp10, u8 sp14, u8 r3); -static void sub_814E32C(struct BerryCrushGame * r8); -static void Task_ShowBerryCrushRankings(u8 r4); -static void BerryCrush_PrintTimeOnSprites(struct BerryCrushGame_138 * r4, u16 r1); -static void sub_814EB38(struct BerryCrushGame * r5); -static void sub_814EBB0(struct BerryCrushGame * r6); -static void sub_814EC80(struct BerryCrushGame * r6); -static void sub_814ECE0(struct BerryCrushGame * r6); -static void sub_814EF10(struct BerryCrushGame * r5); -static void SpriteCB_BerryCrushImpact(struct Sprite * sprite); -static void sub_814EFFC(struct Sprite * sprite); -static void sub_814F044(struct Sprite * sprite); -static void sub_814F0D8(struct Sprite * sprite); - -static const struct BgTemplate sBgTemplates[] = { - { - .bg = 0, - .charBaseIndex = 2, - .mapBaseIndex = 15, - .screenSize = 0, - .paletteMode = 0, - .priority = 0, - .baseTile = 0x0000 - }, { - .bg = 1, - .charBaseIndex = 0, - .mapBaseIndex = 13, - .screenSize = 2, - .paletteMode = 0, - .priority = 1, - .baseTile = 0x0000 - }, { - .bg = 2, - .charBaseIndex = 0, - .mapBaseIndex = 12, - .screenSize = 0, - .paletteMode = 0, - .priority = 2, - .baseTile = 0x0000 - }, { - .bg = 3, - .charBaseIndex = 0, - .mapBaseIndex = 11, - .screenSize = 0, - .paletteMode = 0, - .priority = 3, - .baseTile = 0x0000 - } -}; - -static const u8 sBerryCrushTextColorTable[][3] = { - { - TEXT_COLOR_WHITE, - TEXT_COLOR_DARK_GREY, - TEXT_COLOR_LIGHT_GREY - }, { - TEXT_COLOR_TRANSPARENT, - TEXT_COLOR_WHITE, - TEXT_COLOR_DARK_GREY - }, { - TEXT_COLOR_TRANSPARENT, - TEXT_COLOR_LIGHT_GREY, - TEXT_COLOR_RED - }, { - TEXT_COLOR_WHITE, - TEXT_COLOR_BLUE, - TEXT_COLOR_LIGHT_BLUE - }, { - TEXT_COLOR_WHITE, - TEXT_COLOR_GREEN, - TEXT_COLOR_LIGHT_GREEN - }, { - TEXT_COLOR_WHITE, - TEXT_COLOR_RED, - TEXT_COLOR_LIGHT_RED - } -}; - -static const struct WindowTemplate sWindowTemplate_BerryCrushRankings = { - .bg = 0, - .tilemapLeft = 3, - .tilemapTop = 4, - .width = 24, - .height = 13, - .paletteNum = 0xF, - .baseBlock = 0x001 -}; - -static const struct WindowTemplate gUnknown_846E3F8[] = { - { - .bg = 0, - .tilemapLeft = 0, - .tilemapTop = 0, - .width = 9, - .height = 2, - .paletteNum = 0x8, - .baseBlock = 0x3ed - }, { - .bg = 0, - .tilemapLeft = 0, - .tilemapTop = 3, - .width = 9, - .height = 2, - .paletteNum = 0x8, - .baseBlock = 0x3db - }, { - .bg = 0, - .tilemapLeft = 0, - .tilemapTop = 6, - .width = 9, - .height = 2, - .paletteNum = 0x8, - .baseBlock = 0x3c9 - }, { - .bg = 0, - .tilemapLeft = 21, - .tilemapTop = 3, - .width = 9, - .height = 2, - .paletteNum = 0x8, - .baseBlock = 0x3b7 - }, { - .bg = 0, - .tilemapLeft = 21, - .tilemapTop = 6, - .width = 9, - .height = 2, - .paletteNum = 0x8, - .baseBlock = 0x3a5 - }, DUMMY_WIN_TEMPLATE -}; - -static const struct WindowTemplate gUnknown_846E428[] = { - { - .bg = 0, - .tilemapLeft = 4, - .tilemapTop = 2, - .width = 22, - .height = 16, - .paletteNum = 0xF, - .baseBlock = 0x001 - }, { - .bg = 0, - .tilemapLeft = 4, - .tilemapTop = 2, - .width = 22, - .height = 16, - .paletteNum = 0xF, - .baseBlock = 0x001 - }, { - .bg = 0, - .tilemapLeft = 3, - .tilemapTop = 2, - .width = 24, - .height = 16, - .paletteNum = 0xF, - .baseBlock = 0x001 - }, DUMMY_WIN_TEMPLATE -}; - -static const u8 gUnknown_846E448[][4] = { - { 6, 8, 9, 11 }, - { 12, 14, 15, 16} -}; - -static const u32 sPressingSpeedConversionTable[] = { - // Decimal point is vertically aligned with the pixel - // directly between the >< below. - 50000000, // 50 - 25000000, // 25 - 12500000, // 12.5 - 6250000, // 6.25 - 3125000, // 3.125 - 1562500, // 1.5625 - 781250, // 0.78125 - 390625 // 0.390625 -}; - -static const u16 sBerryCrushCorePal[] = INCBIN_U16("graphics/link_games/unk_846E4D0.gbapal"); -static const u16 sBerryCrushImpactAndSparklesPal[] = INCBIN_U16("graphics/link_games/unk_846E7FC.gbapal"); -static const u16 sBerryCrushTImerPal[] = INCBIN_U16("graphics/link_games/unk_846ECC4.gbapal"); - -static const u32 sBerryCrushCoreTiles[] = INCBIN_U32("graphics/link_games/unk_846E4D0.4bpp.lz"); -static const u32 sBerryCrushImpactTiles[] = INCBIN_U32("graphics/link_games/unk_846E7FC.4bpp.lz"); -static const u32 sBerryCrushPowderSparklesTiles[] = INCBIN_U32("graphics/link_games/unk_846EB78.4bpp.lz"); -static const u32 sBerryCrushTimerTiles[] = INCBIN_U32("graphics/link_games/unk_846ECC4.4bpp.lz"); - -static const u32 gBerryCrushGrinderTopTilemap[] = INCBIN_U32("graphics/link_games/unk_846ED90.bin.lz"); -static const u32 gBerryCrushContainerCapTilemap[] = INCBIN_U32("graphics/link_games/unk_846EEC0.bin.lz"); -static const u32 gBerryCrushBackgroundTilemap[] = INCBIN_U32("graphics/link_games/unk_846F058.bin.lz"); - -static const u8 gUnknown_846F280[][5] = { - {1, 3}, - {0, 1, 3}, - {1, 3, 2, 4}, - {0, 1, 3, 2, 4} -}; - -static const struct BerryCrushPlayerSeatCoords gUnknown_846F294[] = { - {0, 0, 0, 0, -16, 0, 0}, - {1, 0, 3, -28, -4, -24, 16}, - {2, 0, 6, -16, 20, -8, 16}, - {3, 20, 3, 28, -4, 32, -8}, - {4, 20, 6, 16, 20, 16, -8} -}; - -static const s8 gUnknown_846F2D0[][2] = { - { 0, 0}, - {-1, 0}, - { 1, 1} -}; - -static const s8 gUnknown_846F2D6[][2] = { - { 0, 0}, - {-16, -4}, - { 16, -4}, - { -8, -2}, - { 8, -2}, - {-24, -8}, - { 24, -8}, - {-32, -12}, - { 32, -12}, - {-40, -16}, - { 40, -16} -}; - -static const u16 sPlayerBerrySpriteTags[] = { - 5, 6, 7, 8, 9 -}; - -static const struct CompressedSpriteSheet sSpriteSheets[] = { - {sBerryCrushCoreTiles, 0x0800, 1}, - {sBerryCrushImpactTiles, 0x0e00, 2}, - {sBerryCrushPowderSparklesTiles, 0x0700, 3}, - {sBerryCrushTimerTiles, 0x02c0, 4}, - {} -}; - -static const struct SpritePalette sSpritePals[] = { - {sBerryCrushCorePal, 1}, - {sBerryCrushImpactAndSparklesPal, 2}, - {sBerryCrushTImerPal, 4}, - {} -}; - -static const union AnimCmd gUnknown_846F340[] = { - ANIMCMD_FRAME(0x00, 0), - ANIMCMD_END -}; - -static const union AnimCmd gUnknown_846F348[] = { - ANIMCMD_FRAME(0x00, 4), - ANIMCMD_FRAME(0x10, 4), - ANIMCMD_FRAME(0x20, 4), - ANIMCMD_END -}; - -static const union AnimCmd gUnknown_846F358[] = { - ANIMCMD_FRAME(0x30, 2), - ANIMCMD_FRAME(0x40, 2), - ANIMCMD_FRAME(0x50, 2), - ANIMCMD_FRAME(0x60, 2), - ANIMCMD_END -}; - -static const union AnimCmd gUnknown_846F36C[] = { - ANIMCMD_FRAME(0x00, 2), - ANIMCMD_FRAME(0x04, 2), - ANIMCMD_FRAME(0x08, 2), - ANIMCMD_FRAME(0x0c, 2), - ANIMCMD_FRAME(0x10, 2), - ANIMCMD_FRAME(0x14, 2), - ANIMCMD_JUMP(0) -}; - -static const union AnimCmd gUnknown_846F388[] = { - ANIMCMD_FRAME(0x18, 4), - ANIMCMD_FRAME(0x1c, 4), - ANIMCMD_FRAME(0x20, 4), - ANIMCMD_FRAME(0x24, 4), - ANIMCMD_FRAME(0x28, 4), - ANIMCMD_FRAME(0x2c, 4), - ANIMCMD_FRAME(0x30, 4), - ANIMCMD_FRAME(0x34, 4), - ANIMCMD_JUMP(0) -}; - -static const union AnimCmd gUnknown_846F3AC[] = { - ANIMCMD_FRAME(0x14, 0), - ANIMCMD_END -}; - -static const union AnimCmd gUnknown_846F3B4[] = { - ANIMCMD_FRAME(0x00, 0), - ANIMCMD_END -}; - -static const union AffineAnimCmd gUnknown_846F3BC[] = { - AFFINEANIMCMD_FRAME(256, 256, 0, 0), - AFFINEANIMCMD_FRAME(0, 0, 2, 1), - AFFINEANIMCMD_JUMP(1) -}; - -static const union AffineAnimCmd gUnknown_846F3D4[] = { - AFFINEANIMCMD_FRAME(256, 256, 0, 0), - AFFINEANIMCMD_FRAME(0, 0, -2, 1), - AFFINEANIMCMD_JUMP(1) -}; - -static const union AnimCmd *const sAnimTable_BerryCrushCore[] = { - gUnknown_846F340 -}; - -static const union AnimCmd *const sAnimTable_BerryCrushImpact[] = { - gUnknown_846F348, - gUnknown_846F358 -}; - -static const union AnimCmd *const sAnimTable_BerryCrushPowderSparkles[] = { - gUnknown_846F36C, - gUnknown_846F388 -}; - -static const union AnimCmd *const sAnimTable_BerryCrushTimer[] = { - gUnknown_846F3AC -}; - -static const union AnimCmd *const gUnknown_846F404[] = { - gUnknown_846F3B4 -}; - -static const union AffineAnimCmd *const gUnknown_846F408[] = { - gUnknown_846F3BC, - gUnknown_846F3D4 -}; - - -static const struct SpriteTemplate sSpriteTemplate_BerryCrushCore = { - .tileTag = 1, - .paletteTag = 1, - .oam = &gOamData_AffineOff_ObjNormal_64x64, - .anims = sAnimTable_BerryCrushCore, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCallbackDummy -}; - -static const struct SpriteTemplate sSpriteTemplate_BerryCrushImpact = { - .tileTag = 2, - .paletteTag = 2, - .oam = &gOamData_AffineOff_ObjNormal_32x32, - .anims = sAnimTable_BerryCrushImpact, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCB_BerryCrushImpact -}; - -static const struct SpriteTemplate sSpriteTemplate_BerryCrushPowderSparkles = { - .tileTag = 3, - .paletteTag = 2, - .oam = &gOamData_AffineOff_ObjNormal_16x16, - .anims = sAnimTable_BerryCrushPowderSparkles, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCallbackDummy -}; - -static const struct SpriteTemplate sSpriteTemplate_BerryCrushTimer = { - .tileTag = 4, - .paletteTag = 4, - .oam = &gOamData_AffineOff_ObjNormal_8x16, - .anims = sAnimTable_BerryCrushTimer, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCallbackDummy -}; - -static const struct SpriteTemplate sSpriteTemplate_PlayerBerry = { - .tileTag = 5, - .paletteTag = 5, - .oam = &gOamData_AffineDouble_ObjNormal_32x32, - .anims = gUnknown_846F404, - .affineAnims = gUnknown_846F408, - .callback = SpriteCallbackDummy -}; - -static const struct DigitObjUtilTemplate sDigitObjTemplates[] = { - { - .strConvMode = 1, - .shape = SPRITE_SHAPE(8x16), - .size = SPRITE_SIZE(8x16), - .priority = 0, - .oamCount = 2, - .xDelta = 8, - .x = 156, - .y = 0, - .spriteSheet = {.compressed = &sSpriteSheets[3]}, - .spritePal = &sSpritePals[2], - }, { - .strConvMode = 0, - .shape = SPRITE_SHAPE(8x16), - .size = SPRITE_SIZE(8x16), - .priority = 0, - .oamCount = 2, - .xDelta = 8, - .x = 180, - .y = 0, - .spriteSheet = {.compressed = &sSpriteSheets[3]}, - .spritePal = &sSpritePals[2], - }, { - .strConvMode = 0, - .shape = SPRITE_SHAPE(8x16), - .size = SPRITE_SIZE(8x16), - .priority = 0, - .oamCount = 2, - .xDelta = 8, - .x = 204, - .y = 0, - .spriteSheet = {.compressed = &sSpriteSheets[3]}, - .spritePal = &sSpritePals[2], - } -}; - -static const u8 *const sBCRankingHeaders[] = { - gText_SpaceTimes, - gText_XDotY, - gText_StrVar1Berry, - gText_NeatnessRankings, - gText_CooperativeRankings, - gText_PressingPowerRankings -}; - -int BerryCrush_InitBgs(void) -{ - struct BerryCrushGame * game = GetBerryCrushGame(); - if (game == NULL) - return -1; - - switch (game->cmdState) - { - case 0: - SetVBlankCallback(NULL); - SetHBlankCallback(NULL); - SetGpuReg(REG_OFFSET_DISPCNT, 0); - ScanlineEffect_Stop(); - ResetTempTileDataBuffers(); - break; - case 1: - CpuFill16(0, (void *)OAM, OAM_SIZE); - gReservedSpritePaletteCount = 0; - DigitObjUtil_Init(3); - break; - case 2: - ResetPaletteFade(); - ResetSpriteData(); - FreeAllSpritePalettes(); - break; - case 3: - ResetBgsAndClearDma3BusyFlags(FALSE); - InitBgsFromTemplates(0, sBgTemplates, NELEMS(sBgTemplates)); - SetBgTilemapBuffer(1, game->bg1Buffer); - SetBgTilemapBuffer(2, game->bg2Buffer); - SetBgTilemapBuffer(3, game->bg3Buffer); - ChangeBgX(0, 0, 0); - ChangeBgY(0, 0, 0); - ChangeBgX(2, 0, 0); - ChangeBgY(2, 0, 0); - ChangeBgX(3, 0, 0); - ChangeBgY(3, 0, 0); - SetGpuReg(REG_OFFSET_BLDCNT, 0); - SetGpuReg(REG_OFFSET_BLDALPHA, 0); - break; - case 4: - FillBgTilemapBufferRect_Palette0(0, 0, 0, 0, 32, 32); - FillBgTilemapBufferRect_Palette0(1, 0, 0, 0, 32, 64); - FillBgTilemapBufferRect_Palette0(2, 0, 0, 0, 32, 32); - FillBgTilemapBufferRect_Palette0(3, 0, 0, 0, 32, 32); - break; - case 5: - CopyBgTilemapBufferToVram(0); - CopyBgTilemapBufferToVram(1); - CopyBgTilemapBufferToVram(2); - CopyBgTilemapBufferToVram(3); - DecompressAndCopyTileDataToVram(1, gUnknown_8EAFFC0, 0, 0, 0); - break; - case 6: - if (FreeTempTileDataBuffersIfPossible()) - return 0; - - InitStandardTextBoxWindows(); - ResetBg0(); - sub_814EB38(game); - sub_814EBB0(game); - gPaletteFade.bufferTransferDisabled = TRUE; - break; - case 7: - LoadPalette(gUnknown_8EAFEA0, 0, 0x180); - CopyToBgTilemapBuffer(1, gBerryCrushGrinderTopTilemap, 0, 0); - CopyToBgTilemapBuffer(2, gBerryCrushContainerCapTilemap, 0, 0); - CopyToBgTilemapBuffer(3, gBerryCrushBackgroundTilemap, 0, 0); - sub_814EC80(game); - CopyBgTilemapBufferToVram(1); - CopyBgTilemapBufferToVram(2); - CopyBgTilemapBufferToVram(3); - break; - case 8: - LoadWirelessStatusIndicatorSpriteGfx(); - CreateWirelessStatusIndicatorSprite(0, 0); - sub_814ECE0(game); - SetGpuReg(REG_OFFSET_BG1VOFS, -gSpriteCoordOffsetY); - ChangeBgX(1, 0, 0); - ChangeBgY(1, 0, 0); - break; - case 9: - gPaletteFade.bufferTransferDisabled = FALSE; - BlendPalettes(0xFFFFFFFF, 16, RGB_BLACK); - ShowBg(0); - ShowBg(1); - ShowBg(2); - ShowBg(3); - SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_OBJ_ON | DISPCNT_OBJ_1D_MAP); - BerryCrush_SetVBlankCallback(); - game->cmdState = 0; - return 1; - } - - game->cmdState++; - return 0; -} - -int BerryCrush_TeardownBgs(void) -{ - struct BerryCrushGame * var0 = GetBerryCrushGame(); - if (!var0) - return -1; - - switch (var0->cmdState) - { - case 0: - LinkRfu_SetRfuFuncToSend6600(); - break; - case 1: - if (!IsLinkTaskFinished()) - return 0; - // fall through. The original author forgot to use "break" here - // because this will call BeginNormalPaletteFade() twice. - case 2: - BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB_BLACK); - UpdatePaletteFade(); - break; - case 3: - if (UpdatePaletteFade()) - return 0; - break; - case 4: - FillBgTilemapBufferRect_Palette0(0, 0, 0, 0, 32, 32); - FillBgTilemapBufferRect_Palette0(1, 0, 0, 0, 32, 32); - FillBgTilemapBufferRect_Palette0(2, 0, 0, 0, 32, 32); - FillBgTilemapBufferRect_Palette0(3, 0, 0, 0, 32, 32); - CopyBgTilemapBufferToVram(0); - CopyBgTilemapBufferToVram(1); - CopyBgTilemapBufferToVram(2); - CopyBgTilemapBufferToVram(3); - break; - case 5: - FreeAllWindowBuffers(); - HideBg(0); - UnsetBgTilemapBuffer(0); - HideBg(1); - UnsetBgTilemapBuffer(1); - HideBg(2); - UnsetBgTilemapBuffer(2); - HideBg(3); - UnsetBgTilemapBuffer(3); - ClearGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_OBJ_ON | DISPCNT_OBJ_1D_MAP); - break; - case 6: - DestroyWirelessStatusIndicatorSprite(); - sub_814EF10(var0); - DigitObjUtil_Teardown(); - break; - case 7: - var0->cmdState = 0; - return 1; - } - - var0->cmdState++; - return 0; -} - -int sub_814D9CC(struct BerryCrushGame * game) -{ - gSpriteCoordOffsetY = game->depth + game->vibration; - SetGpuReg(REG_OFFSET_BG1VOFS, -gSpriteCoordOffsetY); - if (game->gameState == 7) - { - BerryCrush_PrintTimeOnSprites(&game->spritesManager, game->timer); - } - - return 0; -} - -void sub_814DA04(struct BerryCrushGame * game) -{ - game->depth = -104; - game->vibration = 0; - gSpriteCoordOffsetX = 0; - gSpriteCoordOffsetY = -104; -} - -void BerryCrush_CreateBerrySprites(struct BerryCrushGame * game, struct BerryCrushGame_138 * spritesManager) -{ - u8 i; - u8 spriteId; - s16 var0, var1; - s16 *data; - int var3; - s16 var5; - u32 var6; - - for (i = 0; i < game->playerCount; i++) - { - spriteId = AddItemIconObjectWithCustomObjectTemplate( - &sSpriteTemplate_PlayerBerry, - sPlayerBerrySpriteTags[i], - sPlayerBerrySpriteTags[i], - game->unk68.as_four_players.others[i].berryId + FIRST_BERRY_INDEX); - spritesManager->berrySprites[i] = &gSprites[spriteId]; - spritesManager->berrySprites[i]->oam.priority = 3; - spritesManager->berrySprites[i]->affineAnimPaused = TRUE; - spritesManager->berrySprites[i]->pos1.x = spritesManager->seatCoords[i]->unk8 + 120; - spritesManager->berrySprites[i]->pos1.y = -16; - data = spritesManager->berrySprites[i]->data; - var5 = 512; - data[1] = var5; - data[2] = 32; - data[7] = 112; - var0 = spritesManager->seatCoords[i]->unkA - spritesManager->seatCoords[i]->unk8; - var3 = var0; - if (var0 < 0) - var3 += 3; - - data[6] = var3 >> 2; - var0 *= 128; - var6 = var5 + 32; - var6 = var6 / 2; - var1 = MathUtil_Div16Shift(7, 0x3F80, var6); - data[0] = (u16)spritesManager->berrySprites[i]->pos1.x * 128; - data[3] = MathUtil_Div16Shift(7, var0, var1); - var1 = MathUtil_Mul16Shift(7, var1, 85); - data[4] = 0; - data[5] = MathUtil_Div16Shift(7, 0x3F80, var1); - data[7] |= 0x8000; - if (spritesManager->seatCoords[i]->unk8 < 0) - StartSpriteAffineAnim(spritesManager->berrySprites[i], 1); - } -} - -void SpriteCB_DropBerryIntoCrusher(struct Sprite * sprite) -{ - s16 *data = sprite->data; - - data[1] += data[2]; - sprite->pos2.y += data[1] >> 8; - if (data[7] & 0x8000) - { - sprite->data[0] += data[3]; - data[4] += data[5]; - sprite->pos2.x = Sin(data[4] >> 7, data[6]); - if ((data[7] & 0x8000) && (data[4] >> 7) > 126) - { - sprite->pos2.x = 0; - data[7] &= 0x7FFF; - } - } - - sprite->pos1.x = data[0] >> 7; - if (sprite->pos1.y + sprite->pos2.y >= (data[7] & 0x7FFF)) - { - sprite->callback = SpriteCallbackDummy; - FreeSpriteOamMatrix(sprite); - DestroySprite(sprite); - } -} - -void BerryCrushFreeBerrySpriteGfx(struct BerryCrushGame * arg0, UNUSED struct BerryCrushGame_138 * arg1) -{ - u8 i; - for (i = 0; i < arg0->playerCount; i++) - { - FreeSpritePaletteByTag(sPlayerBerrySpriteTags[i]); - FreeSpriteTilesByTag(sPlayerBerrySpriteTags[i]); - } -} - -void sub_814DC5C(struct BerryCrushGame * game, struct BerryCrushGame_138 * manager) -{ - u8 sp4; - struct BerryCrushGame_4E * var4E; - u8 i; - u16 var, var2; - - sp4 = 0; - var4E = (struct BerryCrushGame_4E *)&game->recvCmd; - for (i = 0; i < game->playerCount; i++) - { - var = var4E->data.unk08 >> (i * 3); - var &= 7; - if (var) - { - sp4++; - if (var & 0x4) - StartSpriteAnim(manager->impactSprites[i], 1); - else - StartSpriteAnim(manager->impactSprites[i], 0); - - manager->impactSprites[i]->invisible = FALSE; - manager->impactSprites[i]->animPaused = FALSE; - manager->impactSprites[i]->pos2.x = gUnknown_846F2D0[(var % 4) - 1][0]; - manager->impactSprites[i]->pos2.y = gUnknown_846F2D0[(var % 4) - 1][1]; - } - } - - if (sp4 == 0) - { - game->unk25_2 = 0; - } - else - { - var = (u8)(game->timer % 3); - var2 = var; - for (i = 0; i < var4E->data.unk0A * 2 + 3; i++) - { - if (manager->sparkleSprites[i]->invisible) - { - manager->sparkleSprites[i]->callback = sub_814F0D8; - manager->sparkleSprites[i]->pos1.x = gUnknown_846F2D6[i][0] + 120; - manager->sparkleSprites[i]->pos1.y = gUnknown_846F2D6[i][1] + 136 - (var * 4); - manager->sparkleSprites[i]->pos2.x = gUnknown_846F2D6[i][0] + (gUnknown_846F2D6[i][0] / (var2 * 4)); - manager->sparkleSprites[i]->pos2.y = gUnknown_846F2D6[i][1]; - if (var4E->data.unk02_1) - StartSpriteAnim(manager->sparkleSprites[i], 1); - else - StartSpriteAnim(manager->sparkleSprites[i], 0); - - var++; - if (var > 3) - var = 0; - } - } - - if (game->unk25_2) - { - game->unk25_2 = 0; - } - else - { - if (sp4 == 1) - PlaySE(SE_MUD_BALL); - else - PlaySE(SE_BREAKABLE_DOOR); - - game->unk25_2 = 1; - } - } -} - -bool32 sub_814DE50(struct BerryCrushGame * arg0, struct BerryCrushGame_138 * arg1) -{ - u8 i; - - for (i = 0; i < arg0->playerCount; i++) - { - if (!arg1->impactSprites[i]->invisible) - return FALSE; - } - - for (i = 0; i < 11; i++) - { - if (!arg1->sparkleSprites[i]->invisible) - return FALSE; - } - - if (arg0->vibration != 0) - arg0->vibration = 0; - - return TRUE; -} - -static void FramesToMinSec(struct BerryCrushGame_138 * manager, u16 frames) -{ - u8 i = 0; - u32 fractionalFrames = 0; - s16 r3 = 0; - - manager->minutes = frames / 3600; - manager->secondsInt = (frames % 3600) / 60; - r3 = MathUtil_Mul16((frames % 60) << 8, 4); - - for (i = 0; i < 8; i++) - { - if ((r3 >> (7 - i)) & 1) - fractionalFrames += sPressingSpeedConversionTable[i]; - } - - manager->secondsFrac = fractionalFrames / 1000000; -} - -static void PrintTextCentered(u8 windowId, u8 left, u8 colorId, const u8 *string) -{ - left = (left * 4) - (GetStringWidth(2, string, -1) / 2u); - AddTextPrinterParameterized3(windowId, 2, left, 0, sBerryCrushTextColorTable[colorId], 0, string); -} - -static void PrintBerryCrushResultWindow(struct BerryCrushGame * game, u8 command, u8 x, u8 y) -{ - u8 i = 0; - u8 linkPlayerId = 0; - u8 linkIdToPrint = 0; - u8 j; - s32 score; - u8 realX; - union BerryCrushGame_68 * bcPlayers = &game->unk68; - s32 realX2; - - for (; i < game->playerCount; i++) - { - DynamicPlaceholderTextUtil_Reset(); - switch (command) - { - case 0: - // Number of presses - linkPlayerId = bcPlayers->as_five_players.players[0].unk4.as_2d_bytes[command][i]; - if (i != 0 && bcPlayers->as_four_players.unk00.stats[command][i] != bcPlayers->as_four_players.unk00.stats[command][i - 1]) - { - linkIdToPrint = i; - } - ConvertIntToDecimalStringN(gStringVar1, bcPlayers->as_four_players.unk00.stats[command][i], STR_CONV_MODE_RIGHT_ALIGN, 4); - realX = x - GetStringWidth(2, sBCRankingHeaders[command], -1) - 4; - AddTextPrinterParameterized3(game->spritesManager.unk82, 2, realX, y + 14 * i, sBerryCrushTextColorTable[0], 0, sBCRankingHeaders[command]); - AddTextPrinterParameterized3(game->spritesManager.unk82, 2, realX - 24, y + 14 * i, sBerryCrushTextColorTable[0], 0, gStringVar1); - break; - case 1: - // Neatness - linkPlayerId = bcPlayers->as_five_players.players[0].unk4.as_2d_bytes[command][i]; - if (i != 0 && bcPlayers->as_four_players.unk00.stats[command][i] != bcPlayers->as_four_players.unk00.stats[command][i - 1]) - { - linkIdToPrint = i; - } - ConvertIntToDecimalStringN(gStringVar1, bcPlayers->as_four_players.unk00.stats[command][i] >> 4, STR_CONV_MODE_RIGHT_ALIGN, 3); - score = 0; - realX = bcPlayers->as_four_players.unk00.stats[command][i] & 15; - for (j = 0; j < 4; j++) - { - if ((realX >> (3 - j)) & 1) - score += sPressingSpeedConversionTable[j]; - } - realX = score / 1000000u; - ConvertIntToDecimalStringN(gStringVar2, realX, STR_CONV_MODE_LEADING_ZEROS, 2); - StringExpandPlaceholders(gStringVar4, sBCRankingHeaders[command]); - realX2 = x - 4; - AddTextPrinterParameterized3(game->spritesManager.unk82, 2, realX2 - GetStringWidth(2, gStringVar4, 0), y + 14 * i, sBerryCrushTextColorTable[0], 0, gStringVar4); - break; - case 2: - // Berry names - linkPlayerId = i; - linkIdToPrint = i; - j = game->unk68.as_five_players.players[i].unk14[12]; - if (j >= LAST_BERRY_INDEX - FIRST_BERRY_INDEX + 2) - j = 0; - StringCopy(gStringVar1, gBerries[j].name); - StringExpandPlaceholders(gStringVar4, sBCRankingHeaders[command]); - AddTextPrinterParameterized3(game->spritesManager.unk82, 2, x - GetStringWidth(2, gStringVar4, -1) - 4, y + 14 * i, sBerryCrushTextColorTable[0], 0, gStringVar4); - break; - } - if (linkPlayerId == game->localId) - StringCopy(gStringVar3, gText_1_ClrLtGryShdwBlk_Dynamic0); - else - StringCopy(gStringVar3, gText_1_Dynamic0); - gStringVar3[0] = linkIdToPrint + CHAR_1; - DynamicPlaceholderTextUtil_SetPlaceholderPtr(0, BERRYCRUSH_PLAYER_NAME(game, linkPlayerId)); - DynamicPlaceholderTextUtil_ExpandPlaceholders(gStringVar4, gStringVar3); - AddTextPrinterParameterized3(game->spritesManager.unk82, 2, 4, y + 14 * i, sBerryCrushTextColorTable[0], 0, gStringVar4); - } -} - -static void sub_814E32C(struct BerryCrushGame * game) -{ - u8 i = 0; - u8 x = 0; - u32 score = 0; - union BerryCrushGame_68 *players = &game->unk68; - u8 y = GetWindowAttribute(game->spritesManager.unk82, WINDOW_HEIGHT) * 8 - 42; - - FramesToMinSec(&game->spritesManager, players->as_four_players.unk00.unk04); - AddTextPrinterParameterized3(game->spritesManager.unk82, 2, 2, y, sBerryCrushTextColorTable[0], 0, gText_TimeColon); - - x = 190 - (u8)GetStringWidth(2, gText_SpaceSec, 0); - AddTextPrinterParameterized3(game->spritesManager.unk82, 2, x, y, sBerryCrushTextColorTable[0], 0, gText_SpaceSec); - - x -= 32; - ConvertIntToDecimalStringN(gStringVar1, game->spritesManager.secondsInt, STR_CONV_MODE_LEADING_ZEROS, 2); - ConvertIntToDecimalStringN(gStringVar2, game->spritesManager.secondsFrac, STR_CONV_MODE_LEADING_ZEROS, 2); - StringExpandPlaceholders(gStringVar4, gText_XDotY2); - AddTextPrinterParameterized3(game->spritesManager.unk82, 2, x, y, sBerryCrushTextColorTable[0], 0, gStringVar4); - - x -= (u8)GetStringWidth(2, gText_SpaceMin, 0) + 3; - AddTextPrinterParameterized3(game->spritesManager.unk82, 2, x, y, sBerryCrushTextColorTable[0], 0, gText_SpaceMin); - - x -= 9; - ConvertIntToDecimalStringN(gStringVar1, game->spritesManager.minutes, STR_CONV_MODE_LEADING_ZEROS, 1); - StringExpandPlaceholders(gStringVar4, gText_StrVar1); - AddTextPrinterParameterized3(game->spritesManager.unk82, 2, x, y, sBerryCrushTextColorTable[0], 0, gStringVar4); - - y += 14; - AddTextPrinterParameterized3(game->spritesManager.unk82, 2, 2, y, sBerryCrushTextColorTable[0], 0, gText_PressingSpeed); - - x = 190 - (u8)GetStringWidth(2, gText_TimesPerSec, 0); - AddTextPrinterParameterized3(game->spritesManager.unk82, 3, x, y, sBerryCrushTextColorTable[0], 0, gText_TimesPerSec); - - for (i = 0; i < 8; ++i) - if (((u8)game->pressingSpeed >> (7 - i)) & 1) - score += *(i + sPressingSpeedConversionTable); // It's accessed in a different way here for unknown reason - ConvertIntToDecimalStringN(gStringVar1, game->pressingSpeed >> 8, STR_CONV_MODE_RIGHT_ALIGN, 3); - ConvertIntToDecimalStringN(gStringVar2, score / 1000000, STR_CONV_MODE_LEADING_ZEROS, 2); - StringExpandPlaceholders(gStringVar4, gText_XDotY3); - x -= 38; - if (game->unk25_1) - AddTextPrinterParameterized3(game->spritesManager.unk82, 2, x, y, sBerryCrushTextColorTable[5], 0, gStringVar4); - else - AddTextPrinterParameterized3(game->spritesManager.unk82, 2, x, y, sBerryCrushTextColorTable[0], 0, gStringVar4); - - y += 14; - AddTextPrinterParameterized3(game->spritesManager.unk82, 2, 2, y, sBerryCrushTextColorTable[0], 0, gText_Silkiness); - - ConvertIntToDecimalStringN(gStringVar1, players->as_four_players.unk00.unk08, STR_CONV_MODE_RIGHT_ALIGN, 3); - StringExpandPlaceholders(gStringVar4, gText_Var1Percent); - x = 190 - (u8)GetStringWidth(2, gStringVar4, 0); - AddTextPrinterParameterized3(game->spritesManager.unk82, 2, x, y, sBerryCrushTextColorTable[0], 0, gStringVar4); -} - -bool32 sub_814E644(struct BerryCrushGame * game, struct BerryCrushGame_138 * spriteManager) -{ - u8 playerCountMinus2; - struct WindowTemplate template; - - switch (spriteManager->unk80) - { - case 0: - playerCountMinus2 = game->playerCount - 2; - BerryCrush_HideTimerSprites(spriteManager); - memcpy(&template, &gUnknown_846E428[game->gameState - 11], sizeof(struct WindowTemplate)); - if (game->gameState == 13) - template.height = gUnknown_846E448[1][playerCountMinus2]; - else - template.height = gUnknown_846E448[0][playerCountMinus2]; - spriteManager->unk82 = AddWindow(&template); - break; - case 1: - PutWindowTilemap(spriteManager->unk82); - FillWindowPixelBuffer(spriteManager->unk82, PIXEL_FILL(0)); - break; - case 2: - TextWindow_SetStdFrame0_WithPal(spriteManager->unk82, 0x21D, 0xD0); - DrawStdFrameWithCustomTileAndPalette(spriteManager->unk82, FALSE, 541, 13); - break; - case 3: - playerCountMinus2 = game->playerCount - 2; - switch (game->gameState) - { - case 11: - PrintTextCentered(spriteManager->unk82, 22, 3, gText_PressesRankings); - PrintBerryCrushResultWindow(game, 0, 0xB0, 8 * gUnknown_846E448[0][playerCountMinus2] - game->playerCount * 14); - spriteManager->unk80 = 5; - return FALSE; - case 12: - PrintTextCentered(spriteManager->unk82, 22, 4, sBCRankingHeaders[game->unk68.as_five_players.players[0].unk4.as_2d_bytes[0][7] + 3]); - PrintBerryCrushResultWindow(game, 1, 0xB0, 8 * gUnknown_846E448[0][playerCountMinus2] - game->playerCount * 14); - spriteManager->unk80 = 5; - return FALSE; - case 13: - PrintTextCentered(spriteManager->unk82, 24, 3, gText_CrushingResults); - PrintBerryCrushResultWindow(game, 2, 0xC0, 0x10); - break; - } - break; - case 4: - sub_814E32C(game); - break; - case 5: - CopyWindowToVram(spriteManager->unk82, COPYWIN_BOTH); - spriteManager->unk80 = 0; - return TRUE; - } - ++spriteManager->unk80; - return FALSE; -} - -void sub_814E80C(struct BerryCrushGame * game) -{ - ClearStdWindowAndFrameToTransparent(game->spritesManager.unk82, 1); - RemoveWindow(game->spritesManager.unk82); - sub_814EBB0(game); -} - -static void Task_ShowBerryCrushRankings(u8 taskId) -{ - u8 i = 0, j, xPos, yPos; - u32 score = 0; - s16 *data = gTasks[taskId].data; - u8 *str; - - switch (data[0]) - { - case 0: - data[1] = AddWindow(&sWindowTemplate_BerryCrushRankings); - PutWindowTilemap(data[1]); - FillWindowPixelBuffer(data[1], PIXEL_FILL(0)); - TextWindow_SetStdFrame0_WithPal(data[1], 0x21D, 0xD0); - DrawStdFrameWithCustomTileAndPalette(data[1], 0, 0x21D, 0xD); - break; - case 1: - xPos = 96 - GetStringWidth(2, gText_BerryCrush2, -1) / 2u; - AddTextPrinterParameterized3( - data[1], - 2, - xPos, - 2, - sBerryCrushTextColorTable[3], - 0, - gText_BerryCrush2 - ); - xPos = 96 - GetStringWidth(2, gText_PressingSpeedRankings, -1) / 2u; - AddTextPrinterParameterized3( - data[1], - 2, - xPos, - 18, - sBerryCrushTextColorTable[3], - 0, - gText_PressingSpeedRankings - ); - yPos = 42; - for (i = 0; i < 4; ++i) - { - ConvertIntToDecimalStringN(gStringVar1, i + 2, STR_CONV_MODE_LEFT_ALIGN, 1); - StringExpandPlaceholders(gStringVar4, gText_Var1Players); - AddTextPrinterParameterized3( - data[1], - 2, - 4, - yPos, - sBerryCrushTextColorTable[0], - 0, - gStringVar4 - ); - for (j = 0; j < 8; ++j) - { - if (((data[i + 2] & 0xFF) >> (7 - j)) & 1) - score += sPressingSpeedConversionTable[j]; - } - ConvertIntToDecimalStringN(gStringVar1, (u16)data[i + 2] >> 8, STR_CONV_MODE_RIGHT_ALIGN, 3); - ConvertIntToDecimalStringN(gStringVar2, score / 1000000, STR_CONV_MODE_LEADING_ZEROS, 2); - str = StringExpandPlaceholders(gStringVar4, gText_XDotY3); - *str++ = CHAR_SPACE; - StringCopy(str, gText_TimesPerSec); - xPos = 192 - (u8)GetStringWidth(3, gStringVar4, 0); - AddTextPrinterParameterized3( - data[1], - 3, - xPos, - yPos, - sBerryCrushTextColorTable[0], - 0, - gStringVar4 - ); - yPos += 14; - score = 0; - } - CopyWindowToVram(data[1], COPYWIN_BOTH); - break; - case 2: - if (gMain.newKeys & (A_BUTTON | B_BUTTON)) - break; - else - return; - case 3: - ClearStdWindowAndFrameToTransparent(data[1], 1); - ClearWindowTilemap(data[1]); - RemoveWindow(data[1]); - DestroyTask(taskId); - EnableBothScriptContexts(); - ScriptContext2_Disable(); - data[0] = 0; - return; - } - ++data[0]; -} - -void ShowBerryCrushRankings(void) -{ - u8 taskId; - - ScriptContext2_Enable(); - taskId = CreateTask(Task_ShowBerryCrushRankings, 0); - gTasks[taskId].data[2] = gSaveBlock2Ptr->berryCrush.berryCrushResults[0]; - gTasks[taskId].data[3] = gSaveBlock2Ptr->berryCrush.berryCrushResults[1]; - gTasks[taskId].data[4] = gSaveBlock2Ptr->berryCrush.berryCrushResults[2]; - gTasks[taskId].data[5] = gSaveBlock2Ptr->berryCrush.berryCrushResults[3]; -} - -static void BerryCrush_PrintTimeOnSprites(struct BerryCrushGame_138 * manager, u16 frames) -{ - FramesToMinSec(manager, frames); - DigitObjUtil_PrintNumOn(0, manager->minutes); - DigitObjUtil_PrintNumOn(1, manager->secondsInt); - DigitObjUtil_PrintNumOn(2, manager->secondsFrac); -} - -void BerryCrush_HideTimerSprites(struct BerryCrushGame_138 * manager) -{ - manager->timerSprites[0]->invisible = TRUE; - manager->timerSprites[1]->invisible = TRUE; - DigitObjUtil_HideOrShow(2, 1); - DigitObjUtil_HideOrShow(1, 1); - DigitObjUtil_HideOrShow(0, 1); -} - -static void sub_814EB38(struct BerryCrushGame * game) -{ - u8 i; - - for (i = 0; i < game->playerCount; ++i) - { - game->spritesManager.seatCoords[i] = &gUnknown_846F294[gUnknown_846F280[game->playerCount - 2][i]]; - game->spritesManager.unk83[i] = AddWindow(&gUnknown_846E3F8[game->spritesManager.seatCoords[i]->unk0]); - PutWindowTilemap(game->spritesManager.unk83[i]); - FillWindowPixelBuffer(game->spritesManager.unk83[i], PIXEL_FILL(0)); - } -} - -static void sub_814EBB0(struct BerryCrushGame * game) -{ - u8 i; - - for (i = 0; i < game->playerCount; ++i) - { - PutWindowTilemap(game->spritesManager.unk83[i]); - if (i == game->localId) - { - AddTextPrinterParameterized4( - game->spritesManager.unk83[i], - 2, - 36 - GetStringWidth(2, BERRYCRUSH_PLAYER_NAME(game, i), 0) / 2u, - 1, - 0, - 0, - sBerryCrushTextColorTable[1], - 0, - BERRYCRUSH_PLAYER_NAME(game, i) - ); - } - else - { - AddTextPrinterParameterized4( - game->spritesManager.unk83[i], - 2, - 36 - GetStringWidth(2, BERRYCRUSH_PLAYER_NAME(game, i), 0) / 2u, - 1, - 0, - 0, - sBerryCrushTextColorTable[2], - 0, - BERRYCRUSH_PLAYER_NAME(game, i) - ); - } - CopyWindowToVram(game->spritesManager.unk83[i], COPYWIN_BOTH); - } - CopyBgTilemapBufferToVram(0); -} - -static void sub_814EC80(struct BerryCrushGame * game) -{ - u8 i = 0; - const u32 *r0 = gUnknown_8EB0ADC; -#ifndef NONMATCHING // r4, r5, r6 register roulette - register u8 *r4 asm("r4") = gDecompressionBuffer; - register u32 r0_ asm("r0"); -#else - u8 *r4 = gDecompressionBuffer; - u32 r0_; -#endif - - LZ77UnCompWram(r0, r4); - for (; i < game->playerCount; ++i) - { - r0_ = game->spritesManager.seatCoords[i]->unk0; - CopyToBgTilemapBufferRect( - 3, - &r4[r0_ * 40], - game->spritesManager.seatCoords[i]->unk1, - game->spritesManager.seatCoords[i]->unk2, - 10, - 2 - ); - } - CopyBgTilemapBufferToVram(3); -} - -static void sub_814ECE0(struct BerryCrushGame * game) -{ - u8 i = 0; - u8 spriteId; - - game->depth = -104; - game->vibration = 0; - gSpriteCoordOffsetX = 0; - gSpriteCoordOffsetY = -104; - for (; i < 4; ++i) - LoadCompressedSpriteSheet(&sSpriteSheets[i]); - LoadSpritePalettes(sSpritePals); - spriteId = CreateSprite(&sSpriteTemplate_BerryCrushCore, 120, 88, 5); - game->spritesManager.coreSprite = &gSprites[spriteId]; - game->spritesManager.coreSprite->oam.priority = 3; - game->spritesManager.coreSprite->coordOffsetEnabled = TRUE; - game->spritesManager.coreSprite->animPaused = TRUE; - for (i = 0; i < game->playerCount; ++i) - { - spriteId = CreateSprite( - &sSpriteTemplate_BerryCrushImpact, - game->spritesManager.seatCoords[i]->unk4 + 120, - game->spritesManager.seatCoords[i]->unk6 + 32, - 0 - ); - game->spritesManager.impactSprites[i] = &gSprites[spriteId]; - game->spritesManager.impactSprites[i]->oam.priority = 1; - game->spritesManager.impactSprites[i]->invisible = TRUE; - game->spritesManager.impactSprites[i]->coordOffsetEnabled = TRUE; - game->spritesManager.impactSprites[i]->animPaused = TRUE; - } - for (i = 0; i < NELEMS(game->spritesManager.sparkleSprites); ++i) - { - spriteId = CreateSprite( - &sSpriteTemplate_BerryCrushPowderSparkles, - gUnknown_846F2D6[i][0] + 120, - gUnknown_846F2D6[i][1] + 136, - 6 - ); - game->spritesManager.sparkleSprites[i] = &gSprites[spriteId]; - game->spritesManager.sparkleSprites[i]->oam.priority = 3; - game->spritesManager.sparkleSprites[i]->invisible = TRUE; - game->spritesManager.sparkleSprites[i]->animPaused = TRUE; - game->spritesManager.sparkleSprites[i]->data[0] = i; - } - for (i = 0; i < NELEMS(game->spritesManager.timerSprites); ++i) - { - spriteId = CreateSprite( - &sSpriteTemplate_BerryCrushTimer, - 24 * i + 176, - 8, - 0 - ); - game->spritesManager.timerSprites[i] = &gSprites[spriteId]; - game->spritesManager.timerSprites[i]->oam.priority = 0; - game->spritesManager.timerSprites[i]->invisible = FALSE; - game->spritesManager.timerSprites[i]->animPaused = FALSE; - } - DigitObjUtil_CreatePrinter(0, 0, &sDigitObjTemplates[0]); - DigitObjUtil_CreatePrinter(1, 0, &sDigitObjTemplates[1]); - DigitObjUtil_CreatePrinter(2, 0, &sDigitObjTemplates[2]); - if (game->gameState == 1) - BerryCrush_HideTimerSprites(&game->spritesManager); -} - -static void sub_814EF10(struct BerryCrushGame * r5) -{ - u8 r4 = 0; - - FreeSpriteTilesByTag(4); - FreeSpriteTilesByTag(3); - FreeSpriteTilesByTag(2); - FreeSpriteTilesByTag(1); - FreeSpritePaletteByTag(4); - FreeSpritePaletteByTag(2); - FreeSpritePaletteByTag(1); - for (; r4 < NELEMS(r5->spritesManager.timerSprites); ++r4) - DestroySprite(r5->spritesManager.timerSprites[r4]); - DigitObjUtil_DeletePrinter(2); - DigitObjUtil_DeletePrinter(1); - DigitObjUtil_DeletePrinter(0); - for (r4 = 0; r4 < NELEMS(r5->spritesManager.sparkleSprites); ++r4) - DestroySprite(r5->spritesManager.sparkleSprites[r4]); - for (r4 = 0; r4 < r5->playerCount; ++r4) - DestroySprite(r5->spritesManager.impactSprites[r4]); - if (r5->spritesManager.coreSprite->inUse) - DestroySprite(r5->spritesManager.coreSprite); -} - -static void SpriteCB_BerryCrushImpact(struct Sprite * sprite) -{ - if (sprite->animEnded) - { - sprite->invisible = TRUE; - sprite->animPaused = TRUE; - } -} - -static void sub_814EFFC(struct Sprite * sprite) -{ - u8 r1 = 0; - SpriteCallback r5 = SpriteCallbackDummy; - - for (; r1 < NELEMS(sprite->data); ++r1) - sprite->data[r1] = 0; - sprite->pos2.x = 0; - sprite->pos2.y = 0; - sprite->invisible = TRUE; - sprite->animPaused = TRUE; - sprite->callback = r5; -} - -static void sub_814F044(struct Sprite * sprite) -{ - s16 *r4 = sprite->data; - - r4[1] += r4[2]; - sprite->pos2.y += r4[1] >> 8; - if (r4[7] & 0x8000) - { - sprite->data[0] += r4[3]; - r4[4] += r4[5]; - sprite->pos2.x = Sin(r4[4] >> 7, r4[6]); - if (r4[7] & 0x8000 && r4[4] >> 7 > 126) - { - sprite->pos2.x = 0; - r4[7] &= 0x7FFF; - } - } - sprite->pos1.x = r4[0] >> 7; - if (sprite->pos1.y + sprite->pos2.y > (r4[7] & 0x7FFF)) - sprite->callback = sub_814EFFC; -} - -static void sub_814F0D8(struct Sprite * sprite) -{ - s16 *r7 = sprite->data; - s16 r4, r5; - s32 r2; - u32 r8 = 0; - - r2 = 640; - r7[1] = r2; - r7[2] = 32; - r7[7] = 168; - r4 = sprite->pos2.x * 128; - r5 = MathUtil_Div16Shift(7, (168 - sprite->pos1.y) << 7, (r2 + 32) >> 1); - sprite->data[0] = sprite->pos1.x << 7; - r7[3] = MathUtil_Div16Shift(7, r4, r5); - r2 = MathUtil_Mul16Shift(7, r5, 85); - r7[4] = r8; - r7[5] = MathUtil_Div16Shift(7, 0x3F80, r2); - r7[6] = sprite->pos2.x / 4; - r7[7] |= 0x8000; - sprite->pos2.y = r8; - sprite->pos2.x = r8; - sprite->callback = sub_814F044; - sprite->animPaused = FALSE; - sprite->invisible = FALSE; -} diff --git a/src/clear_save_data_screen.c b/src/clear_save_data_screen.c index fe28c1ec7..b2f106594 100644 --- a/src/clear_save_data_screen.c +++ b/src/clear_save_data_screen.c @@ -186,24 +186,8 @@ static void CB2_Sub_SaveClearScreen_Init(void) static void SaveClearScreen_GpuInit(void) { DmaClearLarge16(3, (void *)VRAM, VRAM_SIZE, 0x1000); - -#ifndef NONMATCHING - asm("":::"ip"); -#endif - - do - { - void * dest = (void *)OAM; - size_t size = OAM_SIZE; - DmaClear32(3, dest, size); - } while (0); - - do - { - void * dest = (void *)PLTT; - size_t size = PLTT_SIZE; - DmaClear16(3, dest, size); - } while (0); + DmaClear32(3, (void *)OAM, OAM_SIZE); + DmaClear16(3, (void *)PLTT, PLTT_SIZE); SetGpuReg(REG_OFFSET_DISPCNT, 0); SetGpuReg(REG_OFFSET_BLDY, 0); diff --git a/src/credits.c b/src/credits.c index ba57947c8..5bf2eae7f 100644 --- a/src/credits.c +++ b/src/credits.c @@ -16,14 +16,8 @@ #if defined(FIRERED) #define TITLE_TEXT gString_PokemonFireRed_Staff -asm(".set TITLE_TEXT, gString_PokemonFireRed_Staff"); #elif defined(LEAFGREEN) #define TITLE_TEXT gString_PokemonLeafGreen_Staff -asm(".set TITLE_TEXT, gString_PokemonLeafGreen_Staff"); -#endif - -#if !defined(NONMATCHING) && MODERN -#define static #endif enum CreditsSceneIdx @@ -807,7 +801,6 @@ static bool32 DoOverworldMapScrollScene(UNUSED u8 unused) } } -#ifdef NONMATCHING static s32 RollCredits(void) { u16 win0v[8]; @@ -840,45 +833,40 @@ static s32 RollCredits(void) { win0v[0]--; win0v[1]++; - SetGpuReg(REG_OFFSET_WIN0V, win0v[1] + (win0v[0] << 8)); + SetGpuReg(REG_OFFSET_WIN0V, (win0v[0] << 8) + win0v[1]); } return 0; case CREDITSSCENE_LOAD_PLAYER_SPRITE_AT_INDIGO: - if (sCreditsMgr->timer == 0) - { - LoadPlayerOrRivalSprite(0); - sCreditsMgr->timer = 100; - sCreditsMgr->mainseqno = CREDITSSCENE_PRINT_TITLE_STAFF; - } - else + if (sCreditsMgr->timer) { sCreditsMgr->timer--; + return 0; } + LoadPlayerOrRivalSprite(0); + sCreditsMgr->timer = 100; + sCreditsMgr->mainseqno = CREDITSSCENE_PRINT_TITLE_STAFF; return 0; case CREDITSSCENE_PRINT_TITLE_STAFF: - if (sCreditsMgr->timer == 0) - { - sCreditsMgr->timer = 360; - AddTextPrinterParameterized4(sCreditsMgr->windowId, 1, 0x08, 0x29, 1, 2, sTextColor_Header, 0, TITLE_TEXT); - sCreditsMgr->mainseqno = CREDITSSCENE_WAIT_TITLE_STAFF; - } - else + if (sCreditsMgr->timer) { sCreditsMgr->timer--; + return 0; + } + sCreditsMgr->timer = 360; + AddTextPrinterParameterized4(sCreditsMgr->windowId, 1, 0x08, 0x29, 1, 2, sTextColor_Header, 0, TITLE_TEXT); + sCreditsMgr->mainseqno = CREDITSSCENE_WAIT_TITLE_STAFF; return 0; case CREDITSSCENE_WAIT_TITLE_STAFF: - if (sCreditsMgr->timer != 0) + if (sCreditsMgr->timer) { sCreditsMgr->timer--; + return 0; } - else - { - DestroyCreditsWindow(); - sCreditsMgr->mainseqno = CREDITSSCENE_EXEC_CMD; - sCreditsMgr->timer = 0; - sCreditsMgr->scrcmdidx = 0; - } + DestroyCreditsWindow(); + sCreditsMgr->mainseqno = CREDITSSCENE_EXEC_CMD; + sCreditsMgr->timer = 0; + sCreditsMgr->scrcmdidx = 0; return 0; case CREDITSSCENE_EXEC_CMD: if (sCreditsMgr->timer != 0) @@ -886,53 +874,49 @@ static s32 RollCredits(void) sCreditsMgr->timer--; return sCreditsMgr->canSpeedThrough; } - else + switch (sCreditsScript[sCreditsMgr->scrcmdidx].cmd) { - switch (sCreditsScript[sCreditsMgr->scrcmdidx].cmd) - { - case CREDITSSCRCMD_PRINT: - BeginNormalPaletteFade(0x00008000, 0, 0, 16, RGB_BLACK); - sCreditsMgr->mainseqno = CREDITSSCENE_PRINT_ADDPRINTER1; - FillWindowPixelBuffer(sCreditsMgr->windowId, PIXEL_FILL(0)); - return sCreditsMgr->canSpeedThrough; - case CREDITSSCRCMD_MAPNEXT: - sCreditsMgr->mainseqno = CREDITSSCENE_MAPNEXT_DESTROYWINDOW; - sCreditsMgr->whichMon = sCreditsScript[sCreditsMgr->scrcmdidx].param; - FadeSelectedPals(1, 0, 0x3FFFFFFF); - break; - case CREDITSSCRCMD_MAP: - sCreditsMgr->mainseqno = CREDITSSCENE_MAP_LOADMAP_CREATESPRITES; - sCreditsMgr->whichMon = sCreditsScript[sCreditsMgr->scrcmdidx].param; - break; - case CREDITSSCRCMD_MON: - sCreditsMgr->mainseqno = CREDITSSCENE_MON_DESTROY_ASSETS; - sCreditsMgr->whichMon = sCreditsScript[sCreditsMgr->scrcmdidx].param; - FadeScreen(FADE_TO_BLACK, 0); - break; - case CREDITSSCRCMD_THEENDGFX: - sCreditsMgr->mainseqno = CREDITSSCENE_THEEND_DESTROY_ASSETS; - sCreditsMgr->whichMon = sCreditsScript[sCreditsMgr->scrcmdidx].param; - BeginNormalPaletteFade(0xFFFFFFFF, 4, 0, 16, RGB_BLACK); - break; - case CREDITSSCRCMD_WAITBUTTON: - sCreditsMgr->mainseqno = CREDITSSCENE_WAITBUTTON; - break; - } - sCreditsMgr->timer = sCreditsScript[sCreditsMgr->scrcmdidx].duration; - sCreditsMgr->scrcmdidx++; - return 0; + case CREDITSSCRCMD_PRINT: + BeginNormalPaletteFade(0x00008000, 0, 0, 16, RGB_BLACK); + sCreditsMgr->mainseqno = CREDITSSCENE_PRINT_ADDPRINTER1; + FillWindowPixelBuffer(sCreditsMgr->windowId, PIXEL_FILL(0)); + return sCreditsMgr->canSpeedThrough; + case CREDITSSCRCMD_MAPNEXT: + sCreditsMgr->mainseqno = CREDITSSCENE_MAPNEXT_DESTROYWINDOW; + sCreditsMgr->whichMon = sCreditsScript[sCreditsMgr->scrcmdidx].param; + FadeSelectedPals(1, 0, 0x3FFFFFFF); + break; + case CREDITSSCRCMD_MAP: + sCreditsMgr->mainseqno = CREDITSSCENE_MAP_LOADMAP_CREATESPRITES; + sCreditsMgr->whichMon = sCreditsScript[sCreditsMgr->scrcmdidx].param; + break; + case CREDITSSCRCMD_MON: + sCreditsMgr->mainseqno = CREDITSSCENE_MON_DESTROY_ASSETS; + sCreditsMgr->whichMon = sCreditsScript[sCreditsMgr->scrcmdidx].param; + FadeScreen(FADE_TO_BLACK, 0); + break; + case CREDITSSCRCMD_THEENDGFX: + sCreditsMgr->mainseqno = CREDITSSCENE_THEEND_DESTROY_ASSETS; + sCreditsMgr->whichMon = sCreditsScript[sCreditsMgr->scrcmdidx].param; + BeginNormalPaletteFade(0xFFFFFFFF, 4, 0, 16, RGB_BLACK); + break; + case CREDITSSCRCMD_WAITBUTTON: + sCreditsMgr->mainseqno = CREDITSSCENE_WAITBUTTON; + break; } + sCreditsMgr->timer = sCreditsScript[sCreditsMgr->scrcmdidx].duration; + sCreditsMgr->scrcmdidx++; + return 0; case CREDITSSCENE_PRINT_ADDPRINTER1: - if (!gPaletteFade.active) - { - win0v[0] = sCreditsTexts[sCreditsScript[sCreditsMgr->scrcmdidx].param].unk_8; // unused - AddTextPrinterParameterized4(sCreditsMgr->windowId, 1, 2, 6, 0, 0, sTextColor_Header, -1, sCreditsTexts[sCreditsScript[sCreditsMgr->scrcmdidx].param].unk_0); - sCreditsMgr->mainseqno = CREDITSSCENE_PRINT_ADDPRINTER2; - } + if (gPaletteFade.active) + return sCreditsMgr->canSpeedThrough; + win0v[0] = sCreditsTexts[sCreditsScript[sCreditsMgr->scrcmdidx].param].unk_8; // unused + AddTextPrinterParameterized4(sCreditsMgr->windowId, 1, 2, 6, 0, 0, sTextColor_Header, -1, sCreditsTexts[sCreditsScript[sCreditsMgr->scrcmdidx].param].unk_0); + sCreditsMgr->mainseqno = CREDITSSCENE_PRINT_ADDPRINTER2; return sCreditsMgr->canSpeedThrough; case CREDITSSCENE_PRINT_ADDPRINTER2: win0v[0] = sCreditsTexts[sCreditsScript[sCreditsMgr->scrcmdidx].param].unk_8; - AddTextPrinterParameterized4(sCreditsMgr->windowId, 2, 8, 6, 0, 0, sTextColor_Header, -1, sCreditsTexts[sCreditsScript[sCreditsMgr->scrcmdidx].param].unk_4); + AddTextPrinterParameterized4(sCreditsMgr->windowId, 2, 8, 6, 0, 0, sTextColor_Regular, -1, sCreditsTexts[sCreditsScript[sCreditsMgr->scrcmdidx].param].unk_4); sCreditsMgr->mainseqno = CREDITSSCENE_PRINT_DELAY; return sCreditsMgr->canSpeedThrough; case CREDITSSCENE_PRINT_DELAY: @@ -1021,14 +1005,17 @@ static s32 RollCredits(void) { BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB_WHITE); sCreditsMgr->mainseqno = CREDITSSCENE_TERMINATE; + return 0; + } + if (sCreditsMgr->timer) + { + sCreditsMgr->timer--; } - else if (sCreditsMgr->timer == 0) + else { sCreditsMgr->mainseqno = CREDITSSCENE_TERMINATE; BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB_WHITE); } - else - sCreditsMgr->timer--; return 0; case CREDITSSCENE_TERMINATE: if (!gPaletteFade.active) @@ -1037,714 +1024,6 @@ static s32 RollCredits(void) } return 2; } -#else -NAKED -static s32 RollCredits(void) -{ - asm_unified("\tpush {r4-r7,lr}\n" - "\tsub sp, 0x24\n" - "\tldr r1, _080F3BEC @ =sCreditsMgr\n" - "\tldr r0, [r1]\n" - "\tldrb r0, [r0]\n" - "\tadds r7, r1, 0\n" - "\tcmp r0, 0x12\n" - "\tbls _080F3BE2\n" - "\tb _080F4180_default_return2\n" - "_080F3BE2:\n" - "\tlsls r0, 2\n" - "\tldr r1, _080F3BF0 @ =_080F3BF4\n" - "\tadds r0, r1\n" - "\tldr r0, [r0]\n" - "\tmov pc, r0\n" - "\t.align 2, 0\n" - "_080F3BEC: .4byte sCreditsMgr\n" - "_080F3BF0: .4byte _080F3BF4\n" - "\t.align 2, 0\n" - "_080F3BF4:\n" - "\t.4byte _080F3C40_case00\n" - "\t.4byte _080F3C64_case01\n" - "\t.4byte _080F3C98_case02\n" - "\t.4byte _080F3CEE_case03\n" - "\t.4byte _080F3D0A_case04\n" - "\t.4byte _080F3D48_case05\n" - "\t.4byte _080F3D6A_case06\n" - "\t.4byte _080F3EB4_case07\n" - "\t.4byte _080F3F24_case08\n" - "\t.4byte _080F3F84_case09\n" - "\t.4byte _080F3FC4_case0A\n" - "\t.4byte _080F3FF0_case0B\n" - "\t.4byte _080F400A_case0C\n" - "\t.4byte _080F4084_case0D\n" - "\t.4byte _080F40B8_case0E\n" - "\t.4byte _080F40D0_case0F\n" - "\t.4byte _080F4100_case10\n" - "\t.4byte _080F4118_case11\n" - "\t.4byte _080F4170_case12\n" - "_080F3C40_case00:\n" - "\tbl SwitchWin1OffWin0On\n" - "\tmovs r0, 0x40\n" - "\tmovs r1, 0xF0\n" - "\tbl SetGpuReg\n" - "\tldr r1, _080F3C5C @ =0x00004f51\n" - "\tmovs r0, 0x44\n" - "\tbl SetGpuReg\n" - "\tldr r0, _080F3C60 @ =sCreditsMgr\n" - "\tldr r1, [r0]\n" - "\tmovs r0, 0x1\n" - "\tb _080F413C_setfield0_return0\n" - "\t.align 2, 0\n" - "_080F3C5C: .4byte 0x00004f51\n" - "_080F3C60: .4byte sCreditsMgr\n" - "_080F3C64_case01:\n" - "\tbl InitBgDarkenEffect\n" - "\tbl CreateCreditsWindow\n" - "\tmovs r0, 0xF0\n" - "\tbl Menu_LoadStdPalAt\n" - "\tldr r0, _080F3C8C @ =gPlttBufferUnfaded\n" - "\tmovs r2, 0xFF\n" - "\tlsls r2, 1\n" - "\tadds r0, r2\n" - "\tmovs r1, 0\n" - "\tstrh r1, [r0]\n" - "\tldr r0, _080F3C90 @ =gPlttBufferFaded\n" - "\tadds r0, r2\n" - "\tstrh r1, [r0]\n" - "\tldr r0, _080F3C94 @ =sCreditsMgr\n" - "\tldr r1, [r0]\n" - "\tmovs r0, 0x2\n" - "\tb _080F413C_setfield0_return0\n" - "\t.align 2, 0\n" - "_080F3C8C: .4byte gPlttBufferUnfaded\n" - "_080F3C90: .4byte gPlttBufferFaded\n" - "_080F3C94: .4byte sCreditsMgr\n" - "_080F3C98_case02:\n" - "\tmovs r0, 0x44\n" - "\tbl GetGpuReg\n" - "\tadd r1, sp, 0x14\n" - "\tlsls r0, 16\n" - "\tlsrs r0, 24\n" - "\tstrh r0, [r1]\n" - "\tmovs r0, 0x44\n" - "\tbl GetGpuReg\n" - "\tadd r2, sp, 0x14\n" - "\tmovs r1, 0xFF\n" - "\tands r1, r0\n" - "\tstrh r1, [r2, 0x2]\n" - "\tadds r0, r2, 0\n" - "\tldrh r0, [r0]\n" - "\tcmp r0, 0x24\n" - "\tbne _080F3CCC\n" - "\tldr r0, _080F3CC8 @ =sCreditsMgr\n" - "\tldr r1, [r0]\n" - "\tmovs r0, 0\n" - "\tstrh r0, [r1, 0x4]\n" - "\tmovs r0, 0x3\n" - "\tb _080F413C_setfield0_return0\n" - "\t.align 2, 0\n" - "_080F3CC8: .4byte sCreditsMgr\n" - "_080F3CCC:\n" - "\tadd r1, sp, 0x14\n" - "\tsubs r0, 0x1\n" - "\tstrh r0, [r1]\n" - "\tadds r2, r1, 0\n" - "\tadds r0, r1, 0\n" - "\tldrh r1, [r0, 0x2]\n" - "\tadds r1, 0x1\n" - "\tstrh r1, [r2, 0x2]\n" - "\tldrh r0, [r0]\n" - "\tlsls r0, 8\n" - "\tadds r1, r0\n" - "\tlsls r1, 16\n" - "\tlsrs r1, 16\n" - "\tmovs r0, 0x44\n" - "\tbl SetGpuReg\n" - "\tb _080F3D06_return0\n" - "_080F3CEE_case03:\n" - "\tldr r1, [r7]\n" - "\tldrh r0, [r1, 0x4]\n" - "\tcmp r0, 0\n" - "\tbne _080F3D52_decfield4_return0\n" - "\tmovs r0, 0\n" - "\tbl LoadPlayerOrRivalSprite\n" - "\tldr r0, [r7]\n" - "\tmovs r1, 0x64\n" - "\tstrh r1, [r0, 0x4]\n" - "\tmovs r1, 0x4\n" - "\tstrb r1, [r0]\n" - "_080F3D06_return0:\n" - "\tmovs r0, 0\n" - "\tb _080F4182_return\n" - "_080F3D0A_case04:\n" - "\tldr r1, [r7]\n" - "\tldrh r0, [r1, 0x4]\n" - "\tadds r2, r0, 0\n" - "\tcmp r2, 0\n" - "\tbne _080F3D52_decfield4_return0\n" - "\tmovs r0, 0xB4\n" - "\tlsls r0, 1\n" - "\tstrh r0, [r1, 0x4]\n" - "\tldrb r0, [r1, 0xA]\n" - "\tmovs r1, 0x1\n" - "\tstr r1, [sp]\n" - "\tmovs r1, 0x2\n" - "\tstr r1, [sp, 0x4]\n" - "\tldr r1, _080F3D40 @ =sTextColor_Header\n" - "\tstr r1, [sp, 0x8]\n" - "\tstr r2, [sp, 0xC]\n" - "\tldr r1, _080F3D44 @ =TITLE_TEXT\n" - "\tstr r1, [sp, 0x10]\n" - "\tmovs r1, 0x1\n" - "\tmovs r2, 0x8\n" - "\tmovs r3, 0x29\n" - "\tbl AddTextPrinterParameterized4\n" - "\tldr r1, [r7]\n" - "\tmovs r0, 0x5\n" - "\tb _080F413C_setfield0_return0\n" - "\t.align 2, 0\n" - "_080F3D40: .4byte sTextColor_Header\n" - "_080F3D44: .4byte TITLE_TEXT\n" - "_080F3D48_case05:\n" - "\tldr r1, [r7]\n" - "\tldrh r0, [r1, 0x4]\n" - "\tadds r4, r0, 0\n" - "\tcmp r4, 0\n" - "\tbeq _080F3D58\n" - "_080F3D52_decfield4_return0:\n" - "\tsubs r0, 0x1\n" - "\tstrh r0, [r1, 0x4]\n" - "\tb _080F3D06_return0\n" - "_080F3D58:\n" - "\tbl DestroyCreditsWindow\n" - "\tldr r0, [r7]\n" - "\tmovs r1, 0x6\n" - "\tstrb r1, [r0]\n" - "\tldr r0, [r7]\n" - "\tstrh r4, [r0, 0x4]\n" - "\tstrh r4, [r0, 0x6]\n" - "\tb _080F3D06_return0\n" - "_080F3D6A_case06:\n" - "\tldr r2, [r7]\n" - "\tldrh r0, [r2, 0x4]\n" - "\tcmp r0, 0\n" - "\tbeq _080F3D7A\n" - "\tsubs r0, 0x1\n" - "\tstrh r0, [r2, 0x4]\n" - "\tldrb r0, [r2, 0x8]\n" - "\tb _080F4182_return\n" - "_080F3D7A:\n" - "\tldr r1, _080F3D94 @ =sCreditsScript\n" - "\tldrh r0, [r2, 0x6]\n" - "\tlsls r0, 2\n" - "\tadds r0, r1\n" - "\tldrb r0, [r0]\n" - "\tcmp r0, 0x5\n" - "\tbls _080F3D8A\n" - "\tb _080F3E94\n" - "_080F3D8A:\n" - "\tlsls r0, 2\n" - "\tldr r1, _080F3D98 @ =_080F3D9C\n" - "\tadds r0, r1\n" - "\tldr r0, [r0]\n" - "\tmov pc, r0\n" - "\t.align 2, 0\n" - "_080F3D94: .4byte sCreditsScript\n" - "_080F3D98: .4byte _080F3D9C\n" - "\t.align 2, 0\n" - "_080F3D9C:\n" - "\t.4byte _080F3DB4\n" - "\t.4byte _080F3DE0\n" - "\t.4byte _080F3E10\n" - "\t.4byte _080F3E30\n" - "\t.4byte _080F3E58\n" - "\t.4byte _080F3E8C\n" - "_080F3DB4:\n" - "\tmovs r0, 0x80\n" - "\tlsls r0, 8\n" - "\tmovs r1, 0\n" - "\tstr r1, [sp]\n" - "\tmovs r2, 0\n" - "\tmovs r3, 0x10\n" - "\tbl BeginNormalPaletteFade\n" - "\tldr r4, _080F3DDC @ =sCreditsMgr\n" - "\tldr r1, [r4]\n" - "\tmovs r0, 0x7\n" - "\tstrb r0, [r1]\n" - "\tldr r0, [r4]\n" - "\tldrb r0, [r0, 0xA]\n" - "\tmovs r1, 0\n" - "\tbl FillWindowPixelBuffer\n" - "\tldr r0, [r4]\n" - "\tldrb r0, [r0, 0x8]\n" - "\tb _080F4182_return\n" - "\t.align 2, 0\n" - "_080F3DDC: .4byte sCreditsMgr\n" - "_080F3DE0:\n" - "\tldr r2, _080F3E04 @ =sCreditsMgr\n" - "\tldr r1, [r2]\n" - "\tmovs r0, 0xA\n" - "\tstrb r0, [r1]\n" - "\tldr r2, [r2]\n" - "\tldr r1, _080F3E08 @ =sCreditsScript\n" - "\tldrh r0, [r2, 0x6]\n" - "\tlsls r0, 2\n" - "\tadds r0, r1\n" - "\tldrb r0, [r0, 0x1]\n" - "\tstrb r0, [r2, 0x9]\n" - "\tldr r2, _080F3E0C @ =0x3fffffff\n" - "\tmovs r0, 0x1\n" - "\tmovs r1, 0\n" - "\tbl FadeSelectedPals\n" - "\tb _080F3E94\n" - "\t.align 2, 0\n" - "_080F3E04: .4byte sCreditsMgr\n" - "_080F3E08: .4byte sCreditsScript\n" - "_080F3E0C: .4byte 0x3fffffff\n" - "_080F3E10:\n" - "\tldr r2, _080F3E28 @ =sCreditsMgr\n" - "\tldr r1, [r2]\n" - "\tmovs r0, 0xC\n" - "\tstrb r0, [r1]\n" - "\tldr r2, [r2]\n" - "\tldr r1, _080F3E2C @ =sCreditsScript\n" - "\tldrh r0, [r2, 0x6]\n" - "\tlsls r0, 2\n" - "\tadds r0, r1\n" - "\tldrb r0, [r0, 0x1]\n" - "\tstrb r0, [r2, 0x9]\n" - "\tb _080F3E94\n" - "\t.align 2, 0\n" - "_080F3E28: .4byte sCreditsMgr\n" - "_080F3E2C: .4byte sCreditsScript\n" - "_080F3E30:\n" - "\tldr r2, _080F3E50 @ =sCreditsMgr\n" - "\tldr r1, [r2]\n" - "\tmovs r0, 0xD\n" - "\tstrb r0, [r1]\n" - "\tldr r2, [r2]\n" - "\tldr r1, _080F3E54 @ =sCreditsScript\n" - "\tldrh r0, [r2, 0x6]\n" - "\tlsls r0, 2\n" - "\tadds r0, r1\n" - "\tldrb r0, [r0, 0x1]\n" - "\tstrb r0, [r2, 0x9]\n" - "\tmovs r0, 0x1\n" - "\tmovs r1, 0\n" - "\tbl FadeScreen\n" - "\tb _080F3E94\n" - "\t.align 2, 0\n" - "_080F3E50: .4byte sCreditsMgr\n" - "_080F3E54: .4byte sCreditsScript\n" - "_080F3E58:\n" - "\tldr r2, _080F3E84 @ =sCreditsMgr\n" - "\tldr r1, [r2]\n" - "\tmovs r3, 0\n" - "\tmovs r0, 0xF\n" - "\tstrb r0, [r1]\n" - "\tldr r2, [r2]\n" - "\tldr r1, _080F3E88 @ =sCreditsScript\n" - "\tldrh r0, [r2, 0x6]\n" - "\tlsls r0, 2\n" - "\tadds r0, r1\n" - "\tldrb r0, [r0, 0x1]\n" - "\tstrb r0, [r2, 0x9]\n" - "\tmovs r0, 0x1\n" - "\tnegs r0, r0\n" - "\tstr r3, [sp]\n" - "\tmovs r1, 0x4\n" - "\tmovs r2, 0\n" - "\tmovs r3, 0x10\n" - "\tbl BeginNormalPaletteFade\n" - "\tb _080F3E94\n" - "\t.align 2, 0\n" - "_080F3E84: .4byte sCreditsMgr\n" - "_080F3E88: .4byte sCreditsScript\n" - "_080F3E8C:\n" - "\tldr r0, _080F3EAC @ =sCreditsMgr\n" - "\tldr r1, [r0]\n" - "\tmovs r0, 0x11\n" - "\tstrb r0, [r1]\n" - "_080F3E94:\n" - "\tldr r0, _080F3EAC @ =sCreditsMgr\n" - "\tldr r1, [r0]\n" - "\tldr r2, _080F3EB0 @ =sCreditsScript\n" - "\tldrh r0, [r1, 0x6]\n" - "\tlsls r0, 2\n" - "\tadds r0, r2\n" - "\tldrh r0, [r0, 0x2]\n" - "\tstrh r0, [r1, 0x4]\n" - "\tldrh r0, [r1, 0x6]\n" - "\tadds r0, 0x1\n" - "\tstrh r0, [r1, 0x6]\n" - "\tb _080F3D06_return0\n" - "\t.align 2, 0\n" - "_080F3EAC: .4byte sCreditsMgr\n" - "_080F3EB0: .4byte sCreditsScript\n" - "_080F3EB4_case07:\n" - "\tldr r0, _080F3F14 @ =gPaletteFade\n" - "\tldrb r1, [r0, 0x7]\n" - "\tmovs r0, 0x80\n" - "\tands r0, r1\n" - "\tlsls r0, 24\n" - "\tlsrs r6, r0, 24\n" - "\tcmp r6, 0\n" - "\tbne _080F3FBA_returnfield8\n" - "\tadd r3, sp, 0x14\n" - "\tldr r5, _080F3F18 @ =sCreditsTexts\n" - "\tldr r4, _080F3F1C @ =sCreditsScript\n" - "\tldr r2, [r7]\n" - "\tldrh r0, [r2, 0x6]\n" - "\tlsls r0, 2\n" - "\tadds r0, r4\n" - "\tldrb r1, [r0, 0x1]\n" - "\tlsls r0, r1, 1\n" - "\tadds r0, r1\n" - "\tlsls r0, 2\n" - "\tadds r0, r5\n" - "\tldrb r0, [r0, 0x8]\n" - "\tstrh r0, [r3]\n" - "\tldrb r0, [r2, 0xA]\n" - "\tstr r6, [sp]\n" - "\tstr r6, [sp, 0x4]\n" - "\tldr r1, _080F3F20 @ =sTextColor_Header\n" - "\tstr r1, [sp, 0x8]\n" - "\tmovs r1, 0x1\n" - "\tnegs r1, r1\n" - "\tstr r1, [sp, 0xC]\n" - "\tldrh r1, [r2, 0x6]\n" - "\tlsls r1, 2\n" - "\tadds r1, r4\n" - "\tldrb r2, [r1, 0x1]\n" - "\tlsls r1, r2, 1\n" - "\tadds r1, r2\n" - "\tlsls r1, 2\n" - "\tadds r1, r5\n" - "\tldr r1, [r1]\n" - "\tstr r1, [sp, 0x10]\n" - "\tmovs r1, 0x1\n" - "\tmovs r2, 0x2\n" - "\tmovs r3, 0x6\n" - "\tbl AddTextPrinterParameterized4\n" - "\tldr r1, [r7]\n" - "\tmovs r0, 0x8\n" - "\tb _080F3FB8_setfield0_returnfield8\n" - "\t.align 2, 0\n" - "_080F3F14: .4byte gPaletteFade\n" - "_080F3F18: .4byte sCreditsTexts\n" - "_080F3F1C: .4byte sCreditsScript\n" - "_080F3F20: .4byte sTextColor_Header\n" - "_080F3F24_case08:\n" - "\tadd r4, sp, 0x14\n" - "\tldr r3, _080F3F78 @ =sCreditsTexts\n" - "\tldr r5, _080F3F7C @ =sCreditsScript\n" - "\tldr r2, [r7]\n" - "\tldrh r0, [r2, 0x6]\n" - "\tlsls r0, 2\n" - "\tadds r0, r5\n" - "\tldrb r1, [r0, 0x1]\n" - "\tlsls r0, r1, 1\n" - "\tadds r0, r1\n" - "\tlsls r0, 2\n" - "\tadds r0, r3\n" - "\tldrb r0, [r0, 0x8]\n" - "\tmovs r1, 0\n" - "\tstrh r0, [r4]\n" - "\tldrb r0, [r2, 0xA]\n" - "\tstr r1, [sp]\n" - "\tstr r1, [sp, 0x4]\n" - "\tldr r1, _080F3F80 @ =sTextColor_Regular\n" - "\tstr r1, [sp, 0x8]\n" - "\tmovs r1, 0x1\n" - "\tnegs r1, r1\n" - "\tstr r1, [sp, 0xC]\n" - "\tldrh r1, [r2, 0x6]\n" - "\tlsls r1, 2\n" - "\tadds r1, r5\n" - "\tldrb r2, [r1, 0x1]\n" - "\tlsls r1, r2, 1\n" - "\tadds r1, r2\n" - "\tlsls r1, 2\n" - "\tadds r3, 0x4\n" - "\tadds r1, r3\n" - "\tldr r1, [r1]\n" - "\tstr r1, [sp, 0x10]\n" - "\tmovs r1, 0x2\n" - "\tmovs r2, 0x8\n" - "\tmovs r3, 0x6\n" - "\tbl AddTextPrinterParameterized4\n" - "\tldr r1, [r7]\n" - "\tmovs r0, 0x9\n" - "\tb _080F3FB8_setfield0_returnfield8\n" - "\t.align 2, 0\n" - "_080F3F78: .4byte sCreditsTexts\n" - "_080F3F7C: .4byte sCreditsScript\n" - "_080F3F80: .4byte sTextColor_Regular\n" - "_080F3F84_case09:\n" - "\tldr r0, [r7]\n" - "\tldrb r0, [r0, 0xA]\n" - "\tmovs r1, 0x2\n" - "\tbl CopyWindowToVram\n" - "\tldr r1, [r7]\n" - "\tldr r2, _080F3FC0 @ =sCreditsScript\n" - "\tldrh r0, [r1, 0x6]\n" - "\tlsls r0, 2\n" - "\tadds r0, r2\n" - "\tldrh r0, [r0, 0x2]\n" - "\tmovs r2, 0\n" - "\tstrh r0, [r1, 0x4]\n" - "\tldrh r0, [r1, 0x6]\n" - "\tadds r0, 0x1\n" - "\tstrh r0, [r1, 0x6]\n" - "\tmovs r0, 0x80\n" - "\tlsls r0, 8\n" - "\tstr r2, [sp]\n" - "\tmovs r1, 0\n" - "\tmovs r2, 0x10\n" - "\tmovs r3, 0\n" - "\tbl BeginNormalPaletteFade\n" - "\tldr r1, [r7]\n" - "\tmovs r0, 0x6\n" - "_080F3FB8_setfield0_returnfield8:\n" - "\tstrb r0, [r1]\n" - "_080F3FBA_returnfield8:\n" - "\tldr r0, [r7]\n" - "\tldrb r0, [r0, 0x8]\n" - "\tb _080F4182_return\n" - "\t.align 2, 0\n" - "_080F3FC0: .4byte sCreditsScript\n" - "_080F3FC4_case0A:\n" - "\tldr r0, _080F3FE8 @ =gPaletteFade\n" - "\tldrb r1, [r0, 0x7]\n" - "\tmovs r0, 0x80\n" - "\tands r0, r1\n" - "\tlsls r0, 24\n" - "\tlsrs r4, r0, 24\n" - "\tcmp r4, 0\n" - "\tbeq _080F3FD6\n" - "\tb _080F3D06_return0\n" - "_080F3FD6:\n" - "\tbl DestroyCreditsWindow\n" - "\tldr r1, _080F3FEC @ =sCreditsMgr\n" - "\tldr r0, [r1]\n" - "\tstrb r4, [r0, 0x1]\n" - "\tldr r1, [r1]\n" - "\tmovs r0, 0xB\n" - "\tb _080F413C_setfield0_return0\n" - "\t.align 2, 0\n" - "_080F3FE8: .4byte gPaletteFade\n" - "_080F3FEC: .4byte sCreditsMgr\n" - "_080F3FF0_case0B:\n" - "\tldr r0, [r7]\n" - "\tldrb r0, [r0, 0x9]\n" - "\tbl DoOverworldMapScrollScene\n" - "\tcmp r0, 0\n" - "\tbne _080F3FFE\n" - "\tb _080F3D06_return0\n" - "_080F3FFE:\n" - "\tldr r1, [r7]\n" - "\tmovs r0, 0x1\n" - "\tstrb r0, [r1, 0x8]\n" - "\tldr r1, [r7]\n" - "\tmovs r0, 0x6\n" - "\tb _080F413C_setfield0_return0\n" - "_080F400A_case0C:\n" - "\tldr r0, _080F4050 @ =gPaletteFade\n" - "\tldrb r1, [r0, 0x7]\n" - "\tmovs r0, 0x80\n" - "\tands r0, r1\n" - "\tlsls r0, 24\n" - "\tlsrs r4, r0, 24\n" - "\tcmp r4, 0\n" - "\tbeq _080F401C\n" - "\tb _080F3D06_return0\n" - "_080F401C:\n" - "\tbl DestroyCreditsWindow\n" - "\tldr r1, _080F4054 @ =sCreditsMgr\n" - "\tldr r0, [r1]\n" - "\tstrb r4, [r0, 0x1]\n" - "\tadds r4, r1, 0\n" - "_080F4028:\n" - "\tldr r0, [r4]\n" - "\tldrb r0, [r0, 0x9]\n" - "\tbl DoOverworldMapScrollScene\n" - "\tcmp r0, 0\n" - "\tbeq _080F4028\n" - "\tldr r0, _080F4054 @ =sCreditsMgr\n" - "\tldr r0, [r0]\n" - "\tldrb r0, [r0, 0x9]\n" - "\tcmp r0, 0x6\n" - "\tbeq _080F4058\n" - "\tcmp r0, 0x6\n" - "\tble _080F404A\n" - "\tcmp r0, 0x9\n" - "\tbeq _080F405E\n" - "\tcmp r0, 0xC\n" - "\tbeq _080F4064\n" - "_080F404A:\n" - "\tadd r1, sp, 0x14\n" - "\tmovs r0, 0x1\n" - "\tb _080F4068\n" - "\t.align 2, 0\n" - "_080F4050: .4byte gPaletteFade\n" - "_080F4054: .4byte sCreditsMgr\n" - "_080F4058:\n" - "\tadd r1, sp, 0x14\n" - "\tmovs r0, 0x2\n" - "\tb _080F4068\n" - "_080F405E:\n" - "\tadd r1, sp, 0x14\n" - "\tmovs r0, 0x3\n" - "\tb _080F4068\n" - "_080F4064:\n" - "\tadd r1, sp, 0x14\n" - "\tmovs r0, 0x4\n" - "_080F4068:\n" - "\tstrh r0, [r1]\n" - "\tadd r0, sp, 0x14\n" - "\tldrb r0, [r0]\n" - "\tbl LoadPlayerOrRivalSprite\n" - "\tldr r2, _080F4080 @ =sCreditsMgr\n" - "\tldr r1, [r2]\n" - "\tmovs r0, 0x1\n" - "\tstrb r0, [r1, 0x8]\n" - "\tldr r1, [r2]\n" - "\tmovs r0, 0x6\n" - "\tb _080F413C_setfield0_return0\n" - "\t.align 2, 0\n" - "_080F4080: .4byte sCreditsMgr\n" - "_080F4084_case0D:\n" - "\tldr r0, _080F40B0 @ =gPaletteFade\n" - "\tldrb r1, [r0, 0x7]\n" - "\tmovs r0, 0x80\n" - "\tands r0, r1\n" - "\tlsls r0, 24\n" - "\tlsrs r4, r0, 24\n" - "\tcmp r4, 0\n" - "\tbeq _080F4096\n" - "\tb _080F3D06_return0\n" - "_080F4096:\n" - "\tbl DestroyPlayerOrRivalSprite\n" - "\tbl DestroyCreditsWindow\n" - "\tldr r1, _080F40B4 @ =sCreditsMgr\n" - "\tldr r0, [r1]\n" - "\tstrb r4, [r0, 0x1]\n" - "\tldr r0, [r1]\n" - "\tstrb r4, [r0, 0x8]\n" - "\tldr r1, [r1]\n" - "\tmovs r0, 0xE\n" - "\tb _080F413C_setfield0_return0\n" - "\t.align 2, 0\n" - "_080F40B0: .4byte gPaletteFade\n" - "_080F40B4: .4byte sCreditsMgr\n" - "_080F40B8_case0E:\n" - "\tbl DoCreditsMonScene\n" - "\tcmp r0, 0\n" - "\tbne _080F40C2\n" - "\tb _080F3D06_return0\n" - "_080F40C2:\n" - "\tldr r0, _080F40CC @ =sCreditsMgr\n" - "\tldr r1, [r0]\n" - "\tmovs r0, 0x6\n" - "\tb _080F413C_setfield0_return0\n" - "\t.align 2, 0\n" - "_080F40CC: .4byte sCreditsMgr\n" - "_080F40D0_case0F:\n" - "\tldr r0, _080F40F8 @ =gPaletteFade\n" - "\tldrb r1, [r0, 0x7]\n" - "\tmovs r0, 0x80\n" - "\tands r0, r1\n" - "\tlsls r0, 24\n" - "\tlsrs r4, r0, 24\n" - "\tcmp r4, 0\n" - "\tbeq _080F40E2\n" - "\tb _080F3D06_return0\n" - "_080F40E2:\n" - "\tbl DestroyCreditsWindow\n" - "\tldr r1, _080F40FC @ =sCreditsMgr\n" - "\tldr r0, [r1]\n" - "\tstrb r4, [r0, 0x1]\n" - "\tldr r0, [r1]\n" - "\tstrb r4, [r0, 0x8]\n" - "\tldr r1, [r1]\n" - "\tmovs r0, 0x10\n" - "\tb _080F413C_setfield0_return0\n" - "\t.align 2, 0\n" - "_080F40F8: .4byte gPaletteFade\n" - "_080F40FC: .4byte sCreditsMgr\n" - "_080F4100_case10:\n" - "\tbl DoCopyrightOrTheEndGfxScene\n" - "\tcmp r0, 0\n" - "\tbne _080F410A\n" - "\tb _080F3D06_return0\n" - "_080F410A:\n" - "\tldr r0, _080F4114 @ =sCreditsMgr\n" - "\tldr r1, [r0]\n" - "\tmovs r0, 0x6\n" - "\tb _080F413C_setfield0_return0\n" - "\t.align 2, 0\n" - "_080F4114: .4byte sCreditsMgr\n" - "_080F4118_case11:\n" - "\tldr r0, _080F4140 @ =gMain\n" - "\tldrh r1, [r0, 0x2E]\n" - "\tmovs r0, 0x1\n" - "\tands r0, r1\n" - "\tcmp r0, 0\n" - "\tbeq _080F414C\n" - "\tmovs r0, 0x1\n" - "\tnegs r0, r0\n" - "\tldr r1, _080F4144 @ =0x00007fff\n" - "\tstr r1, [sp]\n" - "\tmovs r1, 0\n" - "\tmovs r2, 0\n" - "\tmovs r3, 0x10\n" - "\tbl BeginNormalPaletteFade\n" - "\tldr r0, _080F4148 @ =sCreditsMgr\n" - "\tldr r1, [r0]\n" - "\tmovs r0, 0x12\n" - "_080F413C_setfield0_return0:\n" - "\tstrb r0, [r1]\n" - "\tb _080F3D06_return0\n" - "\t.align 2, 0\n" - "_080F4140: .4byte gMain\n" - "_080F4144: .4byte 0x00007fff\n" - "_080F4148: .4byte sCreditsMgr\n" - "_080F414C:\n" - "\tldr r1, [r7]\n" - "\tldrh r0, [r1, 0x4]\n" - "\tcmp r0, 0\n" - "\tbeq _080F4156\n" - "\tb _080F3D52_decfield4_return0\n" - "_080F4156:\n" - "\tmovs r0, 0x12\n" - "\tstrb r0, [r1]\n" - "\tsubs r0, 0x13\n" - "\tldr r1, _080F416C @ =0x00007fff\n" - "\tstr r1, [sp]\n" - "\tmovs r1, 0\n" - "\tmovs r2, 0\n" - "\tmovs r3, 0x10\n" - "\tbl BeginNormalPaletteFade\n" - "\tb _080F3D06_return0\n" - "\t.align 2, 0\n" - "_080F416C: .4byte 0x00007fff\n" - "_080F4170_case12:\n" - "\tldr r0, _080F418C @ =gPaletteFade\n" - "\tldrb r1, [r0, 0x7]\n" - "\tmovs r0, 0x80\n" - "\tands r0, r1\n" - "\tcmp r0, 0\n" - "\tbne _080F4180_default_return2\n" - "\tbl DestroyCreditsWindow\n" - "_080F4180_default_return2:\n" - "\tmovs r0, 0x2\n" - "_080F4182_return:\n" - "\tadd sp, 0x24\n" - "\tpop {r4-r7}\n" - "\tpop {r1}\n" - "\tbx r1\n" - "\t.align 2, 0\n" - "_080F418C: .4byte gPaletteFade"); -} -#endif //NONMATCHING static void VBlankCB(void) { diff --git a/src/dodrio_berry_picking_2.c b/src/dodrio_berry_picking_2.c index df6b3ff4b..ff44a70de 100644 --- a/src/dodrio_berry_picking_2.c +++ b/src/dodrio_berry_picking_2.c @@ -675,7 +675,7 @@ static void sub_81543C4(u8 spriteId) #define sKeepPosX data[1] #else #define sKeepPosX data[10] -#endif // NONMATCHING +#endif // BUGFIX static void sub_81543E8(struct Sprite * sprite) { diff --git a/src/electric.c b/src/electric.c index b1bc32c50..9c957f097 100644 --- a/src/electric.c +++ b/src/electric.c @@ -552,7 +552,7 @@ static void sub_80ADD4C(struct Sprite *sprite) gOamMatrices[matrixNum].b = sineVal; gOamMatrices[matrixNum].c = -sineVal; sprite->data[0] = gBattleAnimArgs[3]; - sprite->callback = sub_80B1D3C; + sprite->callback = DestroyAnimSpriteAfterTimer; } static void AnimZapCannonSpark(struct Sprite *sprite) diff --git a/src/event_object_movement.c b/src/event_object_movement.c index 271d60bf5..1f9b47691 100644 --- a/src/event_object_movement.c +++ b/src/event_object_movement.c @@ -20,10 +20,6 @@ #define NUM_FIELD_MAP_OBJECT_TEMPLATES 0x51 -#if !defined(NONMATCHING) && MODERN -#define static -#endif - static void MoveCoordsInDirection(u32, s16 *, s16 *, s16, s16); static bool8 ObjectEventExecSingleMovementAction(struct ObjectEvent *, struct Sprite *); static u8 GetCollisionInDirection(struct ObjectEvent *, u8); @@ -1326,45 +1322,54 @@ static u8 GetObjectEventIdByLocalId(u8 localId) return OBJECT_EVENTS_COUNT; } -#ifdef NONMATCHING static u8 InitObjectEventStateFromTemplate(struct ObjectEventTemplate *template, u8 mapNum, u8 mapGroup) { struct ObjectEvent *objectEvent; - struct ObjectEventTemplate *template2 = template; + const struct MapHeader *mapHeader; u8 objectEventId; + u8 var0; + u8 elevation; s16 x; s16 y; - s16 var; s16 x2; s16 y2; - s16 elevation2; + s16 x3; + s16 y3; - if(template->inConnection == 0xFF) - { - var = 1; - mapNum = template2->trainerType; - mapGroup = template2->trainerRange_berryTreeId & 0xFF; - elevation2 = template2->elevation; - x = template2->x; - y = template2->y; - x2 = template2->x; - y2 = template2->y; - template = &Overworld_GetMapHeaderByGroupAndId(mapGroup, mapNum)->events->objectEvents[elevation2 - 1]; + var0 = 0; + elevation = 0; + x2 = 0; + y2 = 0; + x3 = 0; + y3 = 0; + + if (template->inConnection == 0xFF) + { + var0 = 1; + elevation = template->elevation; + mapNum = template->trainerType; + mapGroup = template->trainerRange_berryTreeId & 0xFF; + x2 = template->x; + y2 = template->y; + x3 = template->x; + y3 = template->y; + mapHeader = Overworld_GetMapHeaderByGroupAndId(mapGroup, mapNum); + template = &(mapHeader->events->objectEvents[elevation - 1]); } if (GetAvailableObjectEventId(template->localId, mapNum, mapGroup, &objectEventId) - && !sub_805E238(template, var, x2, y2)) + || !sub_805E238(template, var0, x3, y3)) return OBJECT_EVENTS_COUNT; objectEvent = &gObjectEvents[objectEventId]; ClearObjectEvent(objectEvent); - if (var) + if (var0) { - x = x2 * 0x10000 + 0x7000; - y = y2 * 0x10000 + 0x7000; + x = x2 + 7; + y = y2 + 7; } else { - x = x2 + 7; - y = y2 + 7; + x = template->x + 7; + y = template->y + 7; } objectEvent->active = TRUE; objectEvent->triggerGroundEffectsOnMove = TRUE; @@ -1372,7 +1377,6 @@ static u8 InitObjectEventStateFromTemplate(struct ObjectEventTemplate *template, objectEvent->movementType = template->movementType; objectEvent->localId = template->localId; objectEvent->mapNum = mapNum; - // objectEvent++; objectEvent--; is a trick used in pokeruby and pokeemerald here objectEvent->mapGroup = mapGroup; objectEvent->initialCoords.x = x; objectEvent->initialCoords.y = y; @@ -1382,258 +1386,27 @@ static u8 InitObjectEventStateFromTemplate(struct ObjectEventTemplate *template, objectEvent->previousCoords.y = y; objectEvent->currentElevation = template->elevation; objectEvent->previousElevation = template->elevation; - objectEvent->range.as_nybbles.x = template->movementRangeX; - objectEvent->range.as_nybbles.y = template->movementRangeY; + objectEvent->rangeX = template->movementRangeX; + objectEvent->rangeY = template->movementRangeY; objectEvent->trainerType = template->trainerType; objectEvent->trainerRange_berryTreeId = template->trainerRange_berryTreeId; + objectEvent->mapNum = mapNum; // oops (yes this is required for matching) objectEvent->previousMovementDirection = gInitialMovementTypeFacingDirections[template->movementType]; SetObjectEventDirection(objectEvent, objectEvent->previousMovementDirection); SetObjectEventDynamicGraphicsId(objectEvent); -/*#ifndef NONMATCHING - asm("":::"r5", "r6"); is a trick used in pokeruby and pokeemerald here -#endif*/ if (gRangedMovementTypes[objectEvent->movementType]) { - if (objectEvent->range.as_nybbles.x == 0) + if (objectEvent->rangeX == 0) { - objectEvent->range.as_nybbles.x++; + objectEvent->rangeX++; } - if (objectEvent->range.as_nybbles.y == 0) + if (objectEvent->rangeY == 0) { - objectEvent->range.as_nybbles.y++; + objectEvent->rangeY++; } } return objectEventId; } -#else -NAKED -static u8 InitObjectEventStateFromTemplate(struct ObjectEventTemplate *template, u8 mapNum, u8 mapGroup) -{ - asm_unified("\n\ - push {r4-r7,lr}\n\ - mov r7, r10\n\ - mov r6, r9\n\ - mov r5, r8\n\ - push {r5-r7}\n\ - sub sp, 0xC\n\ - adds r5, r0, 0\n\ - lsls r1, 24\n\ - lsrs r7, r1, 24\n\ - lsls r2, 24\n\ - lsrs r6, r2, 24\n\ - movs r0, 0\n\ - mov r10, r0\n\ - mov r8, r0\n\ - mov r9, r0\n\ - movs r1, 0\n\ - str r1, [sp, 0x4]\n\ - str r0, [sp, 0x8]\n\ - ldrb r0, [r5, 0x2]\n\ - cmp r0, 0xFF\n\ - bne _0805E0DA\n\ - movs r1, 0x1\n\ - mov r10, r1\n\ - ldrb r4, [r5, 0x8]\n\ - ldrb r7, [r5, 0xC]\n\ - ldrb r6, [r5, 0xE]\n\ - ldrh r0, [r5, 0x4]\n\ - mov r8, r0\n\ - ldrh r5, [r5, 0x6]\n\ - mov r9, r5\n\ - mov r1, r8\n\ - str r1, [sp, 0x4]\n\ - mov r0, r9\n\ - str r0, [sp, 0x8]\n\ - adds r0, r6, 0\n\ - adds r1, r7, 0\n\ - bl Overworld_GetMapHeaderByGroupAndId\n\ - ldr r1, [r0, 0x4]\n\ - lsls r0, r4, 1\n\ - adds r0, r4\n\ - lsls r0, 3\n\ - subs r0, 0x18\n\ - ldr r1, [r1, 0x4]\n\ - adds r5, r1, r0\n\ - _0805E0DA:\n\ - ldrb r0, [r5]\n\ - adds r1, r7, 0\n\ - adds r2, r6, 0\n\ - mov r3, sp\n\ - bl GetAvailableObjectEventId\n\ - lsls r0, 24\n\ - cmp r0, 0\n\ - bne _0805E106\n\ - ldr r1, [sp, 0x4]\n\ - lsls r2, r1, 16\n\ - asrs r2, 16\n\ - ldr r0, [sp, 0x8]\n\ - lsls r3, r0, 16\n\ - asrs r3, 16\n\ - adds r0, r5, 0\n\ - mov r1, r10\n\ - bl sub_805E238\n\ - lsls r0, 24\n\ - cmp r0, 0\n\ - bne _0805E10A\n\ - _0805E106:\n\ - movs r0, 0x10\n\ - b _0805E220\n\ - _0805E10A:\n\ - mov r0, sp\n\ - ldrb r1, [r0]\n\ - lsls r0, r1, 3\n\ - adds r0, r1\n\ - lsls r0, 2\n\ - ldr r1, _0805E13C @ =gObjectEvents\n\ - adds r4, r0, r1\n\ - adds r0, r4, 0\n\ - bl ClearObjectEvent\n\ - mov r1, r10\n\ - cmp r1, 0\n\ - beq _0805E140\n\ - mov r1, r8\n\ - lsls r0, r1, 16\n\ - movs r1, 0xE0\n\ - lsls r1, 11\n\ - adds r0, r1\n\ - lsrs r3, r0, 16\n\ - mov r1, r9\n\ - lsls r0, r1, 16\n\ - movs r1, 0xE0\n\ - lsls r1, 11\n\ - adds r0, r1\n\ - b _0805E14E\n\ - .align 2, 0\n\ - _0805E13C: .4byte gObjectEvents\n\ - _0805E140:\n\ - ldrh r0, [r5, 0x4]\n\ - adds r0, 0x7\n\ - lsls r0, 16\n\ - lsrs r3, r0, 16\n\ - ldrh r0, [r5, 0x6]\n\ - adds r0, 0x7\n\ - lsls r0, 16\n\ - _0805E14E:\n\ - lsrs r2, r0, 16\n\ - ldrb r0, [r4]\n\ - movs r1, 0x1\n\ - orrs r0, r1\n\ - movs r1, 0x4\n\ - orrs r0, r1\n\ - strb r0, [r4]\n\ - ldrb r0, [r5, 0x1]\n\ - strb r0, [r4, 0x5]\n\ - ldrb r0, [r5, 0x9]\n\ - strb r0, [r4, 0x6]\n\ - ldrb r0, [r5]\n\ - strb r0, [r4, 0x8]\n\ - strb r7, [r4, 0x9]\n\ - strb r6, [r4, 0xA]\n\ - strh r3, [r4, 0xC]\n\ - strh r2, [r4, 0xE]\n\ - strh r3, [r4, 0x10]\n\ - strh r2, [r4, 0x12]\n\ - strh r3, [r4, 0x14]\n\ - strh r2, [r4, 0x16]\n\ - ldrb r0, [r5, 0x8]\n\ - movs r6, 0xF\n\ - adds r1, r6, 0\n\ - ands r1, r0\n\ - ldrb r2, [r4, 0xB]\n\ - movs r0, 0x10\n\ - negs r0, r0\n\ - mov r8, r0\n\ - ands r0, r2\n\ - orrs r0, r1\n\ - strb r0, [r4, 0xB]\n\ - ldrb r1, [r5, 0x8]\n\ - lsls r1, 4\n\ - ands r0, r6\n\ - orrs r0, r1\n\ - strb r0, [r4, 0xB]\n\ - ldrb r1, [r5, 0xA]\n\ - lsls r1, 28\n\ - movs r0, 0xF\n\ - mov r9, r0\n\ - lsrs r1, 28\n\ - ldrb r2, [r4, 0x19]\n\ - mov r0, r8\n\ - ands r0, r2\n\ - orrs r0, r1\n\ - strb r0, [r4, 0x19]\n\ - ldrb r1, [r5, 0xA]\n\ - lsrs r1, 4\n\ - lsls r1, 4\n\ - ands r0, r6\n\ - orrs r0, r1\n\ - strb r0, [r4, 0x19]\n\ - ldrh r0, [r5, 0xC]\n\ - strb r0, [r4, 0x7]\n\ - ldrh r0, [r5, 0xE]\n\ - strb r0, [r4, 0x1D]\n\ - ldr r1, _0805E230 @ =gInitialMovementTypeFacingDirections\n\ - ldrb r0, [r5, 0x9]\n\ - adds r0, r1\n\ - ldrb r1, [r0]\n\ - adds r0, r4, 0\n\ - adds r0, 0x20\n\ - strb r1, [r0]\n\ - ldrb r1, [r0]\n\ - adds r0, r4, 0\n\ - bl SetObjectEventDirection\n\ - adds r0, r4, 0\n\ - bl SetObjectEventDynamicGraphicsId\n\ - ldr r1, _0805E234 @ =gRangedMovementTypes\n\ - ldrb r0, [r4, 0x6]\n\ - adds r0, r1\n\ - ldrb r0, [r0]\n\ - cmp r0, 0\n\ - beq _0805E21C\n\ - ldrb r2, [r4, 0x19]\n\ - adds r0, r6, 0\n\ - ands r0, r2\n\ - cmp r0, 0\n\ - bne _0805E204\n\ - lsls r0, r2, 28\n\ - lsrs r0, 28\n\ - adds r0, 0x1\n\ - mov r1, r9\n\ - ands r0, r1\n\ - mov r1, r8\n\ - ands r1, r2\n\ - orrs r1, r0\n\ - strb r1, [r4, 0x19]\n\ - _0805E204:\n\ - ldrb r2, [r4, 0x19]\n\ - movs r0, 0xF0\n\ - ands r0, r2\n\ - cmp r0, 0\n\ - bne _0805E21C\n\ - lsrs r1, r2, 4\n\ - adds r1, 0x1\n\ - lsls r1, 4\n\ - adds r0, r6, 0\n\ - ands r0, r2\n\ - orrs r0, r1\n\ - strb r0, [r4, 0x19]\n\ - _0805E21C:\n\ - mov r0, sp\n\ - ldrb r0, [r0]\n\ - _0805E220:\n\ - add sp, 0xC\n\ - pop {r3-r5}\n\ - mov r8, r3\n\ - mov r9, r4\n\ - mov r10, r5\n\ - pop {r4-r7}\n\ - pop {r1}\n\ - bx r1\n\ - .align 2, 0\n\ - _0805E230: .4byte gInitialMovementTypeFacingDirections\n\ - _0805E234: .4byte gRangedMovementTypes\n\ - "); -} -#endif static bool8 sub_805E238(struct ObjectEventTemplate *template, u8 var, s16 x, s16 y) { @@ -2163,9 +1936,7 @@ static void sub_805EE3C(u8 objectEventId, s16 x, s16 y) #undef i objectEvent = &gObjectEvents[objectEventId]; - #ifndef NONMATCHING - asm("":::"r5"); - #endif + objectEvent++;objectEvent--; // fakematch subspriteTables = NULL; graphicsInfo = GetObjectEventGraphicsInfo(objectEvent->graphicsId); spriteFrameImage.size = graphicsInfo->size; @@ -5140,19 +4911,19 @@ static bool8 IsCoordOutsideObjectEventMovementRange(struct ObjectEvent *objectEv s16 top; s16 bottom; - if (objectEvent->range.as_nybbles.x != 0) + if (objectEvent->rangeX != 0) { - left = objectEvent->initialCoords.x - objectEvent->range.as_nybbles.x; - right = objectEvent->initialCoords.x + objectEvent->range.as_nybbles.x; + left = objectEvent->initialCoords.x - objectEvent->rangeX; + right = objectEvent->initialCoords.x + objectEvent->rangeX; if (left > x || right < x) { return TRUE; } } - if (objectEvent->range.as_nybbles.y != 0) + if (objectEvent->rangeY != 0) { - top = objectEvent->initialCoords.y - objectEvent->range.as_nybbles.y; - bottom = objectEvent->initialCoords.y + objectEvent->range.as_nybbles.y; + top = objectEvent->initialCoords.y - objectEvent->rangeY; + bottom = objectEvent->initialCoords.y + objectEvent->rangeY; if (top > y || bottom < y) { return TRUE; diff --git a/src/fldeff_cut.c b/src/fldeff_cut.c index eed361b49..2286f49ed 100644 --- a/src/fldeff_cut.c +++ b/src/fldeff_cut.c @@ -19,6 +19,7 @@ #include "constants/metatile_labels.h" #define CUT_GRASS_SPRITE_COUNT 8 +#define CUT_SIDE 3 static EWRAM_DATA u8 *sCutGrassSpriteArrayPtr = NULL; static EWRAM_DATA bool8 sScheduleOpenDottedHole = FALSE; @@ -133,25 +134,18 @@ bool8 SetUpFieldMove_Cut(void) gPostMenuFieldCallback = FieldCallback_CutTree; return TRUE; } + else { - // FIXME: this fakematch - #ifndef NONMATCHING - register s32 neg1 asm("r8"); - #else - s32 neg1; - #endif - struct MapPosition *pos; PlayerGetDestCoords(&gPlayerFacingPosition.x, &gPlayerFacingPosition.y); - - for (i = 0, pos = &gPlayerFacingPosition, neg1 = 0xFFFF; i < 3; i++) + + for (i = 0; i < CUT_SIDE; i++) { - - y = i + neg1 + pos->y; - for (j = 0; j < 3; j++) + y = gPlayerFacingPosition.y - 1 + i; + for (j = 0; j < CUT_SIDE; j++) { - x = j + neg1 + pos->x; - if (MapGridGetZCoordAt(x, y) == pos->height) + x = gPlayerFacingPosition.x - 1 + j; + if (MapGridGetZCoordAt(x, y) == gPlayerFacingPosition.height) { if (MetatileAtCoordsIsGrassTile(x, y) == TRUE) { @@ -207,26 +201,20 @@ bool8 FldEff_CutGrass(void) { u8 i, j; s16 x, y; - // FIXME: this fakematch - #ifndef NONMATCHING - register s32 neg1 asm("r9"); - #else - s32 neg1; - #endif - struct MapPosition *pos; + u8 pos; i = 0; PlaySE(SE_M_CUT); + pos = gFieldEffectArguments[1] - 1; PlayerGetDestCoords(&gPlayerFacingPosition.x, &gPlayerFacingPosition.y); - for (i = 0, pos = &gPlayerFacingPosition, neg1 = 0xFFFF; i < 3; i++) + for (i = 0; i < CUT_SIDE; i++) { - - y = i + neg1 + pos->y; - for (j = 0; j < 3; j++) + y = gPlayerFacingPosition.y - 1 + i; + for (j = 0; j < CUT_SIDE; j++) { - x = j + neg1 + pos->x; - if (MapGridGetZCoordAt(x, y) == pos->height) + x = gPlayerFacingPosition.x - 1 + j; + if (MapGridGetZCoordAt(x, y) == gPlayerFacingPosition.height) { if (MetatileAtCoordsIsGrassTile(x, y) == TRUE) { diff --git a/src/flying.c b/src/flying.c index 18cfa4e39..c68fda99f 100644 --- a/src/flying.c +++ b/src/flying.c @@ -26,7 +26,7 @@ static void sub_80B198C(u8 taskId); static void sub_80B1A9C(struct Sprite *sprite); static void sub_80B1BF8(struct Sprite *sprite); static void sub_80B1CC0(struct Sprite *sprite); -static void sub_80B1F94(struct Sprite *sprite); +static void AnimFallingFeather_Step(struct Sprite *sprite); static void sub_80B268C(struct Sprite *sprite); static void sub_80B2820(struct Sprite *sprite); static void sub_80B2A50(struct Sprite *sprite); @@ -532,7 +532,7 @@ static void sub_80B1CC0(struct Sprite *sprite) } } -void sub_80B1D3C(struct Sprite *sprite) +void DestroyAnimSpriteAfterTimer(struct Sprite *sprite) { if (sprite->data[0]-- <= 0) { @@ -631,15 +631,14 @@ static void AnimFallingFeather(struct Sprite *sprite) gOamMatrices[matrixNum].b = sinVal; gOamMatrices[matrixNum].c = -sinVal; } - sprite->callback = sub_80B1F94; + sprite->callback = AnimFallingFeather_Step; } -static void sub_80B1F94(struct Sprite *sprite) +static void AnimFallingFeather_Step(struct Sprite *sprite) { u8 matrixNum, sinIndex; s16 sinVal = 0; struct FeatherDanceData *data = (struct FeatherDanceData *)sprite->data; - if (data->unk0_0a) { if (data->unk1-- % 256 == 0) @@ -653,13 +652,13 @@ static void sub_80B1F94(struct Sprite *sprite) switch (data->unk2 / 64) { case 0: - if (data->unk0_1 << 24 >> 24 == 1) // the shifts have to be here + if ((u8)data->unk0_1 == 1) //casts to u8 here are necessary for matching { data->unk0_0d = 1; data->unk0_0a = 1; data->unk1 = 0; } - else if (data->unk0_1 << 24 >> 24 == 3) + else if ((u8)data->unk0_1 == 3) { data->unk0_0b ^= 1; data->unk0_0a = 1; @@ -706,13 +705,13 @@ static void sub_80B1F94(struct Sprite *sprite) data->unk0_1 = 0; break; case 1: - if (data->unk0_1 << 24 >> 24 == 0) + if ((u8)data->unk0_1 == 0) { data->unk0_0d = 1; data->unk0_0a = 1; data->unk1 = 0; } - else if (data->unk0_1 << 24 >> 24 == 2) + else if ((u8)data->unk0_1 == 2) { data->unk0_0a = 1; data->unk1 = 0; @@ -757,13 +756,13 @@ static void sub_80B1F94(struct Sprite *sprite) data->unk0_1 = 1; break; case 2: - if (data->unk0_1 << 24 >> 24 == 3) + if ((u8)data->unk0_1 == 3) { data->unk0_0d = 1; data->unk0_0a = 1; data->unk1 = 0; } - else if (data->unk0_1 << 24 >> 24 == 1) + else if ((u8)data->unk0_1 == 1) { data->unk0_0a = 1; data->unk1 = 0; @@ -808,11 +807,11 @@ static void sub_80B1F94(struct Sprite *sprite) data->unk0_1 = 2; break; case 3: - if (data->unk0_1 << 24 >> 24 == 2) + if ((u8)data->unk0_1 == 2) { data->unk0_0d = 1; } - else if (data->unk0_1 << 24 >> 24 == 0) + else if ((u8)data->unk0_1 == 0) { data->unk0_0b ^= 1; data->unk0_0a = 1; @@ -858,26 +857,28 @@ static void sub_80B1F94(struct Sprite *sprite) data->unk0_1 = 3; break; } - #ifndef NONMATCHING - asm("":::"r8"); - #endif - sprite->pos2.x = (data->unkC[data->unk0_0b] * gSineTable[data->unk2]) >> 8; + + sprite->pos2.x = ((s32)data->unkC[data->unk0_0b] * gSineTable[data->unk2]) >> 8; matrixNum = sprite->oam.matrixNum; + sinIndex = (-sprite->pos2.x >> 1) + data->unkA; sinVal = gSineTable[sinIndex]; + gOamMatrices[matrixNum].a = gOamMatrices[matrixNum].d = gSineTable[sinIndex + 64]; gOamMatrices[matrixNum].b = sinVal; gOamMatrices[matrixNum].c = -sinVal; + data->unk8 += data->unk6; sprite->pos1.y = data->unk8 >> 8; if (data->unk4 & 0x8000) data->unk2 = (data->unk2 - (data->unk4 & 0x7FFF)) & 0xFF; else data->unk2 = (data->unk2 + (data->unk4 & 0x7FFF)) & 0xFF; + if (sprite->pos1.y + sprite->pos2.y >= data->unkE_1) { sprite->data[0] = 0; - sprite->callback = sub_80B1D3C; + sprite->callback = DestroyAnimSpriteAfterTimer; } } } @@ -983,7 +984,7 @@ static void sub_80B268C(struct Sprite *sprite) x = (((u16 *)&fData)[7] << 1); y = (((u16 *)tData)[7] & 1); ((u16 *)tData)[7] = y | x; - sprite->callback = sub_80B1F94; + sprite->callback = AnimFallingFeather_Step; } static void AnimWhirlwindLine(struct Sprite *sprite) diff --git a/src/menu2.c b/src/menu2.c index b7b3adeb9..fdf482fe8 100644 --- a/src/menu2.c +++ b/src/menu2.c @@ -507,8 +507,8 @@ static void sub_812E768(const struct Bitmap *src, struct Bitmap *dst, u16 srcX, { s32 loopSrcY, loopDstY, loopSrcX, loopDstX, xEnd, yEnd, multiplierSrcY, multiplierDstY; u16 toOrr; - const u8 *pixelsSrc; - u16 *pixelsDst; + u8 *pixelsSrc; + u8 *pixelsDst; if (dst->width - dstX < width) xEnd = dst->width - dstX + srcX; @@ -525,51 +525,49 @@ static void sub_812E768(const struct Bitmap *src, struct Bitmap *dst, u16 srcX, { for (loopSrcX = srcX, loopDstX = dstX; loopSrcX < xEnd; loopSrcX++, loopDstX++) { - #ifndef NONMATCHING - asm("":::"r4"); - #endif - pixelsSrc = src->pixels + ((loopSrcX >> 1) & 3) + ((loopSrcX >> 3) << 5) + (((loopSrcY >> 3) * multiplierSrcY) << 5) + ((u32)(loopSrcY << 0x1d) >> 0x1B); - pixelsDst = (u16 *)(dst->pixels + ((loopDstX >> 1) & 3) + ((loopDstX >> 3) << 5) + ((( loopDstY >> 3) * multiplierDstY) << 5) + ((u32)( loopDstY << 0x1d) >> 0x1B)); + pixelsSrc = (u8 *)(src->pixels + ((loopSrcX >> 1) & 3) + ((loopSrcX >> 3) << 5) + (((loopSrcY >> 3) * multiplierSrcY) << 5) + ((u32)(loopSrcY << 0x1d) >> 0x1B)); + pixelsDst = (u8 *)(dst->pixels + ((loopDstX >> 1) & 3) + ((loopDstX >> 3) << 5) + ((( loopDstY >> 3) * multiplierDstY) << 5) + ((u32)( loopDstY << 0x1d) >> 0x1B)); - if ((uintptr_t)pixelsDst & 0x1) + if ((u32)pixelsDst & 0x1) { - pixelsDst = (void *)pixelsDst - 1; + pixelsDst--; if (loopDstX & 0x1) { - toOrr = *pixelsDst & 0x0fff; + toOrr = *(vu16 *)pixelsDst & 0x0fff; if (loopSrcX & 0x1) - *pixelsDst = toOrr | ((*pixelsSrc & 0xf0) << 8); + toOrr |= ((*pixelsSrc & 0xf0) << 8); else - *pixelsDst = toOrr | ((*pixelsSrc & 0x0f) << 12); + toOrr |= ((*pixelsSrc & 0x0f) << 12); } else { - toOrr = *pixelsDst & 0xf0ff; + toOrr = *(vu16 *)pixelsDst & 0xf0ff; if (loopSrcX & 0x1) - *pixelsDst = toOrr | ((*pixelsSrc & 0xf0) << 4); + toOrr |= ((*pixelsSrc & 0xf0) << 4); else - *pixelsDst = toOrr | ((*pixelsSrc & 0x0f) << 8); + toOrr |= ((*pixelsSrc & 0x0f) << 8); } } else { if (loopDstX & 1) { - toOrr = *pixelsDst & 0xff0f; + toOrr = *(vu16 *)pixelsDst & 0xff0f; if (loopSrcX & 1) - *pixelsDst = toOrr | ((*pixelsSrc & 0xf0) << 0); + toOrr |= ((*pixelsSrc & 0xf0) << 0); else - *pixelsDst = toOrr | ((*pixelsSrc & 0x0f) << 4); + toOrr |= ((*pixelsSrc & 0x0f) << 4); } else { - toOrr = *pixelsDst & 0xfff0; + toOrr = *(vu16 *)pixelsDst & 0xfff0; if (loopSrcX & 1) - *pixelsDst = toOrr | ((*pixelsSrc & 0xf0) >> 4); + toOrr |= ((*pixelsSrc & 0xf0) >> 4); else - *pixelsDst = toOrr | ((*pixelsSrc & 0x0f) >> 0); + toOrr |= ((*pixelsSrc & 0x0f) >> 0); } } + *(vu16 *)pixelsDst = toOrr; } } } diff --git a/src/mystery_gift_menu.c b/src/mystery_gift_menu.c index cfc05fe46..2c455b57a 100644 --- a/src/mystery_gift_menu.c +++ b/src/mystery_gift_menu.c @@ -1123,7 +1123,7 @@ void task_add_00_mystery_gift(void) void task00_mystery_gift(u8 taskId) { struct MysteryGiftTaskData * data = (void *)gTasks[taskId].data; - u32 sp0; + u32 sp0, flag; const u8 * r1; switch (data->state) @@ -1291,7 +1291,8 @@ void task00_mystery_gift(u8 taskId) } break; case 9: - switch ((u32)mevent_message_print_and_prompt_yes_no(&data->textState, &data->curPromptWindowId, FALSE, mevent_client_get_buffer())) + flag = mevent_message_print_and_prompt_yes_no(&data->textState, &data->curPromptWindowId, FALSE, mevent_client_get_buffer()); + switch (flag) { case 0: mevent_client_set_param(0); @@ -1318,7 +1319,8 @@ void task00_mystery_gift(u8 taskId) } break; case 11: - switch ((u32)mevent_message_print_and_prompt_yes_no(&data->textState, &data->curPromptWindowId, FALSE, gText_ThrowAwayWonderCard)) + flag = mevent_message_print_and_prompt_yes_no(&data->textState, &data->curPromptWindowId, FALSE, gText_ThrowAwayWonderCard); + switch (flag) { case 0: if (CheckReceivedGiftFromWonderCard() == TRUE) @@ -1345,7 +1347,8 @@ void task00_mystery_gift(u8 taskId) } break; case 12: - switch ((u32)mevent_message_print_and_prompt_yes_no(&data->textState, &data->curPromptWindowId, FALSE, gText_HaventReceivedCardsGift)) + flag = mevent_message_print_and_prompt_yes_no(&data->textState, &data->curPromptWindowId, FALSE, gText_HaventReceivedCardsGift); + switch (flag) { case 0: mevent_client_set_param(0); @@ -1382,12 +1385,6 @@ void task00_mystery_gift(u8 taskId) } break; case 15: - { - #ifndef NONMATCHING - register bool32 flag asm("r1"); - #else - bool32 flag; - #endif r1 = mevent_message(&sp0, data->IsCardOrNews, data->source, data->prevPromptWindowId); if (r1 == NULL) { @@ -1425,7 +1422,6 @@ void task00_mystery_gift(u8 taskId) } } break; - } case 16: if (MG_PrintTextOnWindow1AndWaitButton(&data->textState, gText_CommunicationError)) { diff --git a/src/normal.c b/src/normal.c index 99ee0e922..422b413c6 100644 --- a/src/normal.c +++ b/src/normal.c @@ -850,7 +850,7 @@ static void AnimHitSplatPersistent(struct Sprite *sprite) InitSpritePosToAnimTarget(sprite, TRUE); sprite->data[0] = gBattleAnimArgs[4]; sprite->callback = RunStoredCallbackWhenAffineAnimEnds; - StoreSpriteCallbackInData6(sprite, sub_80B1D3C); + StoreSpriteCallbackInData6(sprite, DestroyAnimSpriteAfterTimer); } static void AnimHitSplatHandleInvert(struct Sprite *sprite) diff --git a/src/overworld.c b/src/overworld.c index 7bdd0ddb4..e3e8fb885 100644 --- a/src/overworld.c +++ b/src/overworld.c @@ -194,7 +194,7 @@ static void CreateConfirmLeaveTradeRoomPrompt(void); static void InitLinkRoomStartMenuScript(void); static void InitMenuBasedScript(const u8 *script); static void sub_80581DC(const u8 *script); -static void sub_8058230(void); +static void RunTerminateLinkScript(void); static void SpawnLinkPlayerObjectEvent(u8 i, s16 x, s16 y, u8 gender); static void InitLinkPlayerObjectEventPos(struct ObjectEvent *objEvent, s16 x, s16 y); static u8 GetSpriteForLinkedPlayer(u8 linkPlayerId); @@ -2673,7 +2673,7 @@ static void HandleLinkPlayerKeyInput(u32 playerId, u16 key, struct TradeRoomPlay if (trainer->isLocalPlayer) { SetKeyInterceptCallback(KeyInterCB_DeferToEventScript); - sub_8058230(); + RunTerminateLinkScript(); } return; } @@ -3170,7 +3170,7 @@ static void InitMenuBasedScript(const u8 *script) ScriptContext2_Enable(); } -static void sub_8058230(void) +static void RunTerminateLinkScript(void) { ScriptContext1_SetupScript(TradeCenter_TerminateLink); ScriptContext2_Enable(); @@ -3260,7 +3260,14 @@ static void ZeroObjectEvent(struct ObjectEvent *objEvent) memset(objEvent, 0, sizeof(struct ObjectEvent)); } -static void SpawnLinkPlayerObjectEvent(u8 linkPlayerId, s16 x, s16 y, u8 a4) +// Note: Emerald reuses the direction and range variables during Link mode +// as special gender and direction values. The types and placement +// conflict with the usual Event Object struct, thus the definitions. +#define linkGender(obj) obj->singleMovementActive +// not even one can reference *byte* aligned bitfield members... +#define linkDirection(obj) ((u8*)obj)[offsetof(typeof(*obj), fieldEffectSpriteId) - 1] // -> rangeX + +static void SpawnLinkPlayerObjectEvent(u8 linkPlayerId, s16 x, s16 y, u8 gender) { u8 objEventId = GetFirstInactiveObjectEventId(); struct LinkPlayerObjectEvent *linkPlayerObjEvent = &gLinkPlayerObjectEvents[linkPlayerId]; @@ -3275,8 +3282,8 @@ static void SpawnLinkPlayerObjectEvent(u8 linkPlayerId, s16 x, s16 y, u8 a4) linkPlayerObjEvent->movementMode = MOVEMENT_MODE_FREE; objEvent->active = TRUE; - objEvent->singleMovementActive = a4; - objEvent->range.as_byte = 2; + linkGender(objEvent) = gender; + linkDirection(objEvent) = DIR_NORTH; objEvent->spriteId = MAX_SPRITES; InitLinkPlayerObjectEventPos(objEvent, x, y); @@ -3293,17 +3300,17 @@ static void InitLinkPlayerObjectEventPos(struct ObjectEvent *objEvent, s16 x, s1 ObjectEventUpdateZCoord(objEvent); } -static void SetLinkPlayerObjectRange(u8 linkPlayerId, u8 range) +static void SetLinkPlayerObjectRange(u8 linkPlayerId, u8 dir) { if (gLinkPlayerObjectEvents[linkPlayerId].active) { u8 objEventId = gLinkPlayerObjectEvents[linkPlayerId].objEventId; struct ObjectEvent *objEvent = &gObjectEvents[objEventId]; - objEvent->range.as_byte = range; + linkDirection(objEvent) = dir; } } -static void DestroyLinkPlayerOBject(u8 linkPlayerId) +static void DestroyLinkPlayerObject(u8 linkPlayerId) { struct LinkPlayerObjectEvent *linkPlayerObjEvent = &gLinkPlayerObjectEvents[linkPlayerId]; u8 objEventId = linkPlayerObjEvent->objEventId; @@ -3334,7 +3341,7 @@ static u8 GetLinkPlayerFacingDirection(u8 linkPlayerId) { u8 objEventId = gLinkPlayerObjectEvents[linkPlayerId].objEventId; struct ObjectEvent *objEvent = &gObjectEvents[objEventId]; - return objEvent->range.as_byte; + return linkDirection(objEvent); } static u8 GetLinkPlayerElevation(u8 linkPlayerId) @@ -3393,35 +3400,35 @@ static void SetPlayerFacingDirection(u8 linkPlayerId, u8 facing) } } -static u8 MovementEventModeCB_Normal(struct LinkPlayerObjectEvent *linkPlayerObjEvent, struct ObjectEvent *objEvent, u8 a3) +static u8 MovementEventModeCB_Normal(struct LinkPlayerObjectEvent *linkPlayerObjEvent, struct ObjectEvent *objEvent, u8 dir) { - return sLinkPlayerFacingHandlers[a3](linkPlayerObjEvent, objEvent, a3); + return sLinkPlayerFacingHandlers[dir](linkPlayerObjEvent, objEvent, dir); } -static u8 MovementEventModeCB_Ignored(struct LinkPlayerObjectEvent *linkPlayerObjEvent, struct ObjectEvent *objEvent, u8 a3) +static u8 MovementEventModeCB_Ignored(struct LinkPlayerObjectEvent *linkPlayerObjEvent, struct ObjectEvent *objEvent, u8 dir) { return FACING_UP; } // Duplicate Function -static u8 MovementEventModeCB_Normal_2(struct LinkPlayerObjectEvent *linkPlayerObjEvent, struct ObjectEvent *objEvent, u8 a3) +static u8 MovementEventModeCB_Normal_2(struct LinkPlayerObjectEvent *linkPlayerObjEvent, struct ObjectEvent *objEvent, u8 dir) { - return sLinkPlayerFacingHandlers[a3](linkPlayerObjEvent, objEvent, a3); + return sLinkPlayerFacingHandlers[dir](linkPlayerObjEvent, objEvent, dir); } -static bool8 FacingHandler_DoNothing(struct LinkPlayerObjectEvent *linkPlayerObjEvent, struct ObjectEvent *objEvent, u8 a3) +static bool8 FacingHandler_DoNothing(struct LinkPlayerObjectEvent *linkPlayerObjEvent, struct ObjectEvent *objEvent, u8 dir) { return FALSE; } -static bool8 FacingHandler_DpadMovement(struct LinkPlayerObjectEvent *linkPlayerObjEvent, struct ObjectEvent *objEvent, u8 a3) +static bool8 FacingHandler_DpadMovement(struct LinkPlayerObjectEvent *linkPlayerObjEvent, struct ObjectEvent *objEvent, u8 dir) { s16 x, y; - objEvent->range.as_byte = FlipVerticalAndClearForced(a3, objEvent->range.as_byte); - ObjectEventMoveDestCoords(objEvent, objEvent->range.as_byte, &x, &y); + linkDirection(objEvent) = FlipVerticalAndClearForced(dir, linkDirection(objEvent)); + ObjectEventMoveDestCoords(objEvent, linkDirection(objEvent), &x, &y); - if (LinkPlayerDetectCollision(linkPlayerObjEvent->objEventId, objEvent->range.as_byte, x, y)) + if (LinkPlayerDetectCollision(linkPlayerObjEvent->objEventId, linkDirection(objEvent), x, y)) { return FALSE; } @@ -3434,9 +3441,9 @@ static bool8 FacingHandler_DpadMovement(struct LinkPlayerObjectEvent *linkPlayer } } -static bool8 FacingHandler_ForcedFacingChange(struct LinkPlayerObjectEvent *linkPlayerObjEvent, struct ObjectEvent *objEvent, u8 a3) +static bool8 FacingHandler_ForcedFacingChange(struct LinkPlayerObjectEvent *linkPlayerObjEvent, struct ObjectEvent *objEvent, u8 dir) { - objEvent->range.as_byte = FlipVerticalAndClearForced(a3, objEvent->range.as_byte); + linkDirection(objEvent) = FlipVerticalAndClearForced(dir, linkDirection(objEvent)); return FALSE; } @@ -3450,7 +3457,7 @@ static void MovementStatusHandler_TryAdvanceScript(struct LinkPlayerObjectEvent { objEvent->directionSequenceIndex--; linkPlayerObjEvent->movementMode = MOVEMENT_MODE_FROZEN; - MoveCoords(objEvent->range.as_byte, &objEvent->initialCoords.x, &objEvent->initialCoords.y); + MoveCoords(linkDirection(objEvent), &objEvent->initialCoords.x, &objEvent->initialCoords.y); if (!objEvent->directionSequenceIndex) { ShiftStillObjectEventCoords(objEvent); @@ -3510,12 +3517,12 @@ static void CreateLinkPlayerSprite(u8 linkPlayerId, u8 gameVersion) if (gameVersion == VERSION_FIRE_RED || gameVersion == VERSION_LEAF_GREEN) { objEvent->spriteId = AddPseudoObjectEvent( - GetRivalAvatarGraphicsIdByStateIdAndGender(PLAYER_AVATAR_STATE_NORMAL, objEvent->singleMovementActive), + GetRivalAvatarGraphicsIdByStateIdAndGender(PLAYER_AVATAR_STATE_NORMAL, linkGender(objEvent)), SpriteCB_LinkPlayer, 0, 0, 0); } else { - objEvent->spriteId = AddPseudoObjectEvent(GetRSAvatarGraphicsIdByGender(objEvent->singleMovementActive), SpriteCB_LinkPlayer, 0, 0, 0); + objEvent->spriteId = AddPseudoObjectEvent(GetRSAvatarGraphicsIdByGender(linkGender(objEvent)), SpriteCB_LinkPlayer, 0, 0, 0); } sprite = &gSprites[objEvent->spriteId]; @@ -3535,9 +3542,9 @@ static void SpriteCB_LinkPlayer(struct Sprite *sprite) sprite->oam.priority = ZCoordToPriority(objEvent->previousElevation); if (!linkPlayerObjEvent->movementMode != MOVEMENT_MODE_FREE) - StartSpriteAnim(sprite, GetFaceDirectionAnimNum(objEvent->range.as_byte)); + StartSpriteAnim(sprite, GetFaceDirectionAnimNum(linkDirection(objEvent))); else - StartSpriteAnimIfDifferent(sprite, GetMoveDirectionAnimNum(objEvent->range.as_byte)); + StartSpriteAnimIfDifferent(sprite, GetMoveDirectionAnimNum(linkDirection(objEvent))); UpdateObjectEventSpriteVisibility(sprite, 0); if (objEvent->triggerGroundEffectsOnMove) diff --git a/src/pokemon_special_anim_scene.c b/src/pokemon_special_anim_scene.c index b3f005c87..e7201ef52 100644 --- a/src/pokemon_special_anim_scene.c +++ b/src/pokemon_special_anim_scene.c @@ -1038,14 +1038,8 @@ void PSA_UseItem_CleanUpForCancel(void) static void InitItemIconSpriteState(struct PokemonSpecialAnimScene * scene, struct Sprite * sprite, u8 closeness) { - u16 species; + u16 species, x, y; u32 personality; - #ifndef NONMATCHING - register int x asm("r4"); // FIXME - #else - int x; - #endif - u8 y; if (closeness == 3) { sprite->pos1.x = 120; @@ -1060,22 +1054,33 @@ static void InitItemIconSpriteState(struct PokemonSpecialAnimScene * scene, stru sprite->pos1.y += 4; species = PSA_GetMonSpecies(); personality = PSA_GetMonPersonality(); - if (PSA_GetAnimType() == 4) - { - x = Menu2_GetMonSpriteAnchorCoord(species, personality, 0); - y = Menu2_GetMonSpriteAnchorCoord(species, personality, 1); - } - else + switch (PSA_GetAnimType()) { - x = Menu2_GetMonSpriteAnchorCoord(species, personality, 3); - y = Menu2_GetMonSpriteAnchorCoord(species, personality, 4); + case 4: + { + x = Menu2_GetMonSpriteAnchorCoord(species, personality, 0); + y = Menu2_GetMonSpriteAnchorCoord(species, personality, 1); + if (x == 0xFF) + x = 0; + if (y == 0xFF) + y = 0; + sprite->data[6] = x; + sprite->data[7] = y; + break; + } + default: + { + x = Menu2_GetMonSpriteAnchorCoord(species, personality, 3); + y = Menu2_GetMonSpriteAnchorCoord(species, personality, 4); + if (x == 0xFF) + x = 0; + if (y == 0xFF) + y = 0; + sprite->data[6] = x; + sprite->data[7] = y; + break; + } } - if (x == 0xFF) - x = 0; - if (y == 0xFF) - y = 0; - sprite->data[6] = x; - sprite->data[7] = y; ItemSpriteZoom_UpdateYPos(sprite, closeness); } @@ -1254,23 +1259,14 @@ static void StopMakingOutwardSpiralDots(void) static void Task_UseItem_OutwardSpiralDots(u8 taskId) { s16 *data = gTasks[taskId].data; - struct Sprite * sprite; - int x; - #ifndef NONMATCHING - register int y asm("r10"); // FIXME - #else - int y; - #endif - int x2; - int y2; - int ampl; - u8 spriteId; + switch (tState) { case 0: if (tTimer == 0) { - sprite = PSA_GetSceneWork()->itemIconSprite; + u32 spriteId, x, y, x2, y2, ampl; + struct Sprite * sprite = PSA_GetSceneWork()->itemIconSprite; x = sprite->pos1.x + sprite->pos2.x; y = sprite->pos1.y + sprite->pos2.y; ampl = (PSAScene_RandomFromTask(taskId) % 21) + 70; diff --git a/src/quest_log_events.c b/src/quest_log_events.c index 72b8ddfd7..84a14f5e8 100644 --- a/src/quest_log_events.c +++ b/src/quest_log_events.c @@ -582,18 +582,16 @@ void sub_8113ABC(const u16 *a0) bool8 sub_8113AE8(const u16 *a0) { -#ifndef NONMATCHING - register const u16 *r0 asm("r0") = a0; -#else const u16 *r0 = a0; -#endif - if (r0 == NULL || r0[1] > sQuestLogCursor) + if (a0 == NULL) // checks must be separate to match + return FALSE; + if (r0[1] > sQuestLogCursor) return FALSE; - sQuestLogEventTextBufferCBs[a0[0] & 0xFFF](a0); - gUnknown_203B044.id = a0[0]; - gUnknown_203B044.unk_1 = (a0[0] & 0xF000) >> 12; + sQuestLogEventTextBufferCBs[(r0[0] & 0xFFF)](a0); + gUnknown_203B044.id = r0[0]; + gUnknown_203B044.unk_1 = (r0[0] & 0xF000) >> 12; if (gUnknown_203B044.unk_1 != 0) gUnknown_203B044.unk_2 = 1; return TRUE; diff --git a/src/quest_log_objects.c b/src/quest_log_objects.c index fa3bbcce5..47d328405 100644 --- a/src/quest_log_objects.c +++ b/src/quest_log_objects.c @@ -93,8 +93,8 @@ void SetSav1ObjectEventsFromQuestLog(const struct QuestLog * questLog, const str { gObjectEvents[i].initialCoords.x = templates[j].x + 7; gObjectEvents[i].initialCoords.y = templates[j].y + 7; - gObjectEvents[i].range.as_nybbles.x = templates[j].movementRangeX; - gObjectEvents[i].range.as_nybbles.y = templates[j].movementRangeY; + gObjectEvents[i].rangeX = templates[j].movementRangeX; + gObjectEvents[i].rangeY = templates[j].movementRangeY; } } diff --git a/src/trainer_see.c b/src/trainer_see.c index f393c4bbd..644b87c37 100644 --- a/src/trainer_see.c +++ b/src/trainer_see.c @@ -219,15 +219,15 @@ static u8 CheckPathBetweenTrainerAndPlayer(struct ObjectEvent *trainerObj, u8 ap } // preserve mapobj_unk_19 before clearing. - unk19_temp = trainerObj->range.as_nybbles.x; - unk19b_temp = trainerObj->range.as_nybbles.y; - trainerObj->range.as_nybbles.x = 0; - trainerObj->range.as_nybbles.y = 0; + unk19_temp = trainerObj->rangeX; + unk19b_temp = trainerObj->rangeY; + trainerObj->rangeX = 0; + trainerObj->rangeY = 0; collision = GetCollisionAtCoords(trainerObj, x, y, direction); - trainerObj->range.as_nybbles.x = unk19_temp; - trainerObj->range.as_nybbles.y = unk19b_temp; + trainerObj->rangeX = unk19_temp; + trainerObj->rangeY = unk19b_temp; if (collision == 4) return approachDistance; diff --git a/src/vs_seeker.c b/src/vs_seeker.c index 24e2b8c2f..af8bda8be 100644 --- a/src/vs_seeker.c +++ b/src/vs_seeker.c @@ -651,6 +651,9 @@ void VsSeekerResetObjectMovementAfterChargeComplete(void) bool8 UpdateVsSeekerStepCounter(void) { + u8 x; + x = 0; + if (CheckBagHasItem(ITEM_VS_SEEKER, 1) == TRUE) { if ((gSaveBlock1Ptr->trainerRematchStepCounter & 0xFF) < 100) @@ -659,19 +662,12 @@ bool8 UpdateVsSeekerStepCounter(void) if (FlagGet(FLAG_SYS_VS_SEEKER_CHARGING) == TRUE) { - u8 x = (gSaveBlock1Ptr->trainerRematchStepCounter >> 8) & 0xFF; - u32 r4 = 0xFF; - - if (x < 100) + if (((gSaveBlock1Ptr->trainerRematchStepCounter >> 8) & 0xFF) < 100) { - x++; - #ifndef NONMATCHING // fool the compiler that r4 has been changed - asm("":"=r"(r4)); - #endif + x = (((gSaveBlock1Ptr->trainerRematchStepCounter >> 8) & 0xFF) + 1); gSaveBlock1Ptr->trainerRematchStepCounter = (gSaveBlock1Ptr->trainerRematchStepCounter & 0xFF) | (x << 8); } - x = (gSaveBlock1Ptr->trainerRematchStepCounter >> 8) & r4; - if (x == 100) + if (((gSaveBlock1Ptr->trainerRematchStepCounter >> 8) & 0xFF) == 100) { FlagClear(FLAG_SYS_VS_SEEKER_CHARGING); VsSeekerResetChargingStepCounter(); @@ -860,16 +856,15 @@ static u8 CanUseVsSeeker(void) static u8 GetVsSeekerResponseInArea(const VsSeekerData * a0) { u16 r8 = 0; + u16 rval = 0; + u8 r7; u8 sp0 = 0; + u8 r0 = 0; s32 vsSeekerIdx; u8 *r2; -#ifndef NONMATCHING - register u32 r3 asm("r3"); - register s32 r0_ asm("r0"); - asm("":::"r10", "r8", "r6", "r4"); -#endif + vsSeekerIdx = 0; - for (vsSeekerIdx = 0; sVsSeeker->trainerInfo[vsSeekerIdx].localId != 0xFF; vsSeekerIdx++) + while (sVsSeeker->trainerInfo[vsSeekerIdx].localId != 0xFF) { if (IsTrainerVisibleOnScreen(&sVsSeeker->trainerInfo[vsSeekerIdx]) == 1) { @@ -877,59 +872,42 @@ static u8 GetVsSeekerResponseInArea(const VsSeekerData * a0) if (!HasTrainerBeenFought(r8)) { StartTrainerObjectMovementScript(&sVsSeeker->trainerInfo[vsSeekerIdx], sMovementScript_TrainerUnfought); - sVsSeeker->trainerInfo[vsSeekerIdx].trainerIdx += 0; sVsSeeker->trainerHasNotYetBeenFought = 1; + vsSeekerIdx++; + continue; + } + r7 = GetNextAvailableRematchTrainer(a0, r8, &sp0); + if (r7 == 0) + { + StartTrainerObjectMovementScript(&sVsSeeker->trainerInfo[vsSeekerIdx], sMovementScript_TrainerNoRematch); + sVsSeeker->trainerDoesNotWantRematch = 1; } else { - u8 r7 = GetNextAvailableRematchTrainer(a0, r8, &sp0); - if (r7 == 0) + rval = Random() % 100; + r0 = GetCurVsSeekerResponse(vsSeekerIdx, r8); + if (r0 == 2) + rval = 100; + else if (r0 == 1) + rval = 0; + if (rval < 30) { StartTrainerObjectMovementScript(&sVsSeeker->trainerInfo[vsSeekerIdx], sMovementScript_TrainerNoRematch); - #ifdef NONMATCHING sVsSeeker->trainerDoesNotWantRematch = 1; - #else - r2 = (u8 *)sVsSeeker; - r3 = 0x431; - asm("":::"r1"); - r2 = &r2[r3]; - *(r2) |= 2; - #endif } else { - u16 rval = Random() % 100; - u8 r0 = GetCurVsSeekerResponse(vsSeekerIdx, r8); - if (r0 == 2) - rval = 100; - else if (r0 == 1) - rval = 0; - if (rval < 30) - { - StartTrainerObjectMovementScript(&sVsSeeker->trainerInfo[vsSeekerIdx], sMovementScript_TrainerNoRematch); - #ifdef NONMATCHING - sVsSeeker->trainerDoesNotWantRematch = 1; - #else - r2 = (u8 *)sVsSeeker; - r0_ = 0x431; - asm("":::"r1"); - r2 = &r2[r0_]; - *(r2) |= 2; - #endif - } - else - { - gSaveBlock1Ptr->trainerRematches[sVsSeeker->trainerInfo[vsSeekerIdx].localId] = r7; - ShiftStillObjectEventCoords(&gObjectEvents[sVsSeeker->trainerInfo[vsSeekerIdx].objectEventId]); - StartTrainerObjectMovementScript(&sVsSeeker->trainerInfo[vsSeekerIdx], sMovementScript_TrainerRematch); - sVsSeeker->trainerIdxArray[sVsSeeker->numRematchableTrainers] = r8; - sVsSeeker->runningBehaviourEtcArray[sVsSeeker->numRematchableTrainers] = GetRunningBehaviorFromGraphicsId(sVsSeeker->trainerInfo[vsSeekerIdx].graphicsId); - sVsSeeker->numRematchableTrainers++; - sVsSeeker->trainerWantsRematch = 1; - } + gSaveBlock1Ptr->trainerRematches[sVsSeeker->trainerInfo[vsSeekerIdx].localId] = r7; + ShiftStillObjectEventCoords(&gObjectEvents[sVsSeeker->trainerInfo[vsSeekerIdx].objectEventId]); + StartTrainerObjectMovementScript(&sVsSeeker->trainerInfo[vsSeekerIdx], sMovementScript_TrainerRematch); + sVsSeeker->trainerIdxArray[sVsSeeker->numRematchableTrainers] = r8; + sVsSeeker->runningBehaviourEtcArray[sVsSeeker->numRematchableTrainers] = GetRunningBehaviorFromGraphicsId(sVsSeeker->trainerInfo[vsSeekerIdx].graphicsId); + sVsSeeker->numRematchableTrainers++; + sVsSeeker->trainerWantsRematch = 1; } } } + vsSeekerIdx++; } if (sVsSeeker->trainerWantsRematch) |