#include "global.h" #include "gflib.h" #include "berry_crush.h" #include "berry_pouch.h" #include "berry_powder.h" #include "item.h" #include "item_menu.h" #include "link.h" #include "link_rfu.h" #include "math_util.h" #include "overworld.h" #include "task.h" #include "constants/songs.h" #include "constants/items.h" static EWRAM_DATA struct BerryCrushGame *sBerryCrushGamePtr = NULL; static void BerryCrush_InitPlayerNamesAndTextSpeed(struct BerryCrushGame *game); static void CB2_ReturnToBerryCrushGameFromBerryPouch(void); static void VBlankCB_BerryCrush(void); static void CB2_BerryCrush(void); static void Task_RunBerryCrushGame(u8 taskId); struct BerryCrushGame *GetBerryCrushGame(void) { return sBerryCrushGamePtr; } u32 ExitBerryCrushWithCallback(MainCallback callback) { if (sBerryCrushGamePtr == NULL) return 2; if (callback == NULL) callback = sBerryCrushGamePtr->savedCallback; DestroyTask(sBerryCrushGamePtr->taskId); FREE_AND_SET_NULL(sBerryCrushGamePtr); SetMainCallback2(callback); if (callback == CB2_ReturnToField) { PlayNewMapMusic(MUS_POKECEN); SetMainCallback1(CB1_Overworld); } return 0; } void StartBerryCrush(MainCallback callback) { u8 playerCount = 0; u8 multiplayerId; if (!gReceivedRemoteLinkPlayers || gWirelessCommType == 0) { SetMainCallback2(callback); Rfu.linkman_param[0] = 0; Rfu.linkman_param[1] = 0; Rfu.errorState = 1; return; } playerCount = GetLinkPlayerCount(); multiplayerId = GetMultiplayerId(); if (playerCount < 2 || multiplayerId >= playerCount) { SetMainCallback2(callback); Rfu.linkman_param[0] = 0; Rfu.linkman_param[1] = 0; Rfu.errorState = 1; return; } sBerryCrushGamePtr = AllocZeroed(sizeof(*sBerryCrushGamePtr)); if (!sBerryCrushGamePtr) { SetMainCallback2(callback); Rfu.linkman_param[0] = 0; Rfu.linkman_param[1] = 0; Rfu.errorState = 1; return; } sBerryCrushGamePtr->savedCallback = callback; sBerryCrushGamePtr->localId = multiplayerId; sBerryCrushGamePtr->playerCount = playerCount; BerryCrush_InitPlayerNamesAndTextSpeed(sBerryCrushGamePtr); sBerryCrushGamePtr->gameState = 1; sBerryCrushGamePtr->nextCmd = BCCMD_BeginNormalPaletteFade; sBerryCrushGamePtr->afterPalFadeCmd = BCCMD_SignalReadyToBegin; 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); } static void CB2_ReturnToBerryCrushGameFromBerryPouch(void) { if (gSpecialVar_ItemId < FIRST_BERRY_INDEX || gSpecialVar_ItemId > LAST_BERRY_INDEX + 1) gSpecialVar_ItemId = ITEM_CHERI_BERRY; else RemoveBagItem(gSpecialVar_ItemId, 1); sBerryCrushGamePtr->unk68.as_four_players.others[sBerryCrushGamePtr->localId].berryId = 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); SetMainCallback2(CB2_BerryCrush); } void CB2_BerryCrush_GoToBerryPouch(void) { DestroyTask(sBerryCrushGamePtr->taskId); InitBerryPouch(BERRYPOUCH_FROMBERRYCRUSH, CB2_ReturnToBerryCrushGameFromBerryPouch, FALSE); } void BerryCrush_SetVBlankCallback(void) { SetVBlankCallback(VBlankCB_BerryCrush); } void BerryCrush_UnsetVBlankCallback(void) { SetVBlankCallback(NULL); } void BerryCrush_UpdateSav2Records(void) { u32 var0, var1; // unk0A / (unk04 / 60) var0 = sBerryCrushGamePtr->unk68.as_four_players.unk00.unk04; var0 <<= 8; var0 = MathUtil_Div32(var0, 60 << 8); var1 = sBerryCrushGamePtr->unk68.as_four_players.unk00.unk0A; var1 <<= 8; var1 = MathUtil_Div32(var1, var0) & 0xFFFF; sBerryCrushGamePtr->pressingSpeed = var1; switch (sBerryCrushGamePtr->playerCount) { case 2: if (sBerryCrushGamePtr->pressingSpeed > gSaveBlock2Ptr->berryCrush.berryCrushResults[0]) { sBerryCrushGamePtr->unk25_1 = 1; gSaveBlock2Ptr->berryCrush.berryCrushResults[0] = sBerryCrushGamePtr->pressingSpeed; } break; case 3: if (sBerryCrushGamePtr->pressingSpeed > gSaveBlock2Ptr->berryCrush.berryCrushResults[1]) { sBerryCrushGamePtr->unk25_1 = 1; gSaveBlock2Ptr->berryCrush.berryCrushResults[1] = sBerryCrushGamePtr->pressingSpeed; } break; case 4: if (sBerryCrushGamePtr->pressingSpeed > gSaveBlock2Ptr->berryCrush.berryCrushResults[2]) { sBerryCrushGamePtr->unk25_1 = 1; gSaveBlock2Ptr->berryCrush.berryCrushResults[2] = sBerryCrushGamePtr->pressingSpeed; } break; case 5: if (sBerryCrushGamePtr->pressingSpeed > gSaveBlock2Ptr->berryCrush.berryCrushResults[3]) { sBerryCrushGamePtr->unk25_1 = 1; gSaveBlock2Ptr->berryCrush.berryCrushResults[3] = sBerryCrushGamePtr->pressingSpeed; } break; } sBerryCrushGamePtr->powder = sBerryCrushGamePtr->unk68.as_four_players.unk00.unk00; if (GiveBerryPowder(sBerryCrushGamePtr->powder)) return; sBerryCrushGamePtr->unk25_0 = 1; } static void VBlankCB_BerryCrush(void) { TransferPlttBuffer(); LoadOam(); ProcessSpriteCopyRequests(); } static void CB2_BerryCrush(void) { RunTasks(); RunTextPrinters(); AnimateSprites(); BuildOamBuffer(); } static void Task_RunBerryCrushGame(u8 taskId) { if (sBerryCrushGamePtr->cmdCallback != NULL) sBerryCrushGamePtr->cmdCallback(sBerryCrushGamePtr, sBerryCrushGamePtr->commandParams); sub_814D9CC(sBerryCrushGamePtr); } void BerryCrush_InitPlayerNamesAndTextSpeed(struct BerryCrushGame *game) { u8 i; 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; } 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; } switch (gSaveBlock2Ptr->optionsTextSpeed) { case OPTIONS_TEXT_SPEED_SLOW: game->textSpeed = 8; break; case OPTIONS_TEXT_SPEED_MID: game->textSpeed = 4; break; case OPTIONS_TEXT_SPEED_FAST: game->textSpeed = 1; break; } }