diff --git a/data/scripts/berry_blender.inc b/data/scripts/berry_blender.inc index d98add74d..7ad8e9e3a 100644 --- a/data/scripts/berry_blender.inc +++ b/data/scripts/berry_blender.inc @@ -6,6 +6,8 @@ .set LOCALID_EXPERT_M, 16 .set LOCALID_GIRL, 17 +.set NUM_OPPONENTS, VAR_0x8009 + BerryBlender_Text_WantToMakePokeblocks: @ 8292DEE .string "Oh? Did you want to make some {POKEBLOCK}S\n" .string "with this old-timer?$" @@ -243,7 +245,7 @@ BerryBlender_Text_DontHaveAnyBerriesNoneToSpare: @ 8293BB4 BerryBlender_EventScript_BerryBlender1:: @ 8293C3E lockall goto_if_unset FLAG_HIDE_LILYCOVE_CONTEST_HALL_BLEND_MASTER, BerryBlender_EventScript_BlendMasterPresent - setvar VAR_0x8009, 1 + setvar NUM_OPPONENTS, 1 applymovement LOCALID_EXPERT_M, BerryBlender_Movement_BlendLeaderWalkInPlace waitmovement 0 msgbox BerryBlender_Text_WantToMakePokeblocks, MSGBOX_YESNO @@ -307,9 +309,8 @@ BerryBlender_EventScript_TryUseBerryBlender1: @ 8293CEE goto BerryBlender_EventScript_UseBerryBlender1 end -@ VAR_0x8009 here is the Blender number. 1 is top right, 2 is bottom right, 3 is bottom left BerryBlender_EventScript_DoBerryBlending: @ 8293D2C - copyvar VAR_0x8004, VAR_0x8009 + copyvar VAR_0x8004, NUM_OPPONENTS fadescreen FADE_TO_BLACK special DoBerryBlending waitstate @@ -328,7 +329,7 @@ BerryBlender_EventScript_Blender1NoCase: @ 8293D43 BerryBlender_EventScript_BerryBlender2:: @ 8293D4D lockall - setvar VAR_0x8009, 2 + setvar NUM_OPPONENTS, 2 applymovement LOCALID_TWIN, Common_Movement_FaceOriginalDirection applymovement LOCALID_MAN, BerryBlender_Movement_BlendLeaderWalkInPlace waitmovement 0 @@ -393,7 +394,7 @@ BerryBlender_EventScript_Blender2NoCase: @ 8293E14 BerryBlender_EventScript_BerryBlender3:: @ 8293E1E lockall setvar VAR_0x8008, LOCALID_POKEFAN_F - setvar VAR_0x8009, 3 + setvar NUM_OPPONENTS, 3 applymovement LOCALID_BOY, Common_Movement_FaceOriginalDirection applymovement LOCALID_GIRL, Common_Movement_FaceOriginalDirection applymovement VAR_0x8008, BerryBlender_Movement_BlendLeaderWalkInPlace @@ -458,7 +459,7 @@ BerryBlender_EventScript_Blender3NoCase: @ 8293EF1 BerryBlender_EventScript_BlendMasterPresent: @ 8293EFB lockall - setvar VAR_0x8009, 1 + setvar NUM_OPPONENTS, 1 msgbox BerryBlender_Text_SeeMyMasteryInAction, MSGBOX_YESNO compare VAR_RESULT, YES goto_if_eq BerryBlender_EventScript_TryBlendWithBlendMaster @@ -636,7 +637,7 @@ BerryBlender_EventScript_FourPlayerLink: @ 8294139 end BerryBlender_EventScript_DoLinkBerryBlending: @ 8294147 - setvar VAR_0x8004, 0 + setvar VAR_0x8004, 0 @ number of opponents, 0 indicates Link fadescreen FADE_TO_BLACK removeobject 240 @ Unclear where these local IDs come from, removeobject 239 @ but presumably they'd be the 4 link players diff --git a/graphics/berry_blender/marubatsu.png b/graphics/berry_blender/score_symbols.png similarity index 100% rename from graphics/berry_blender/marubatsu.png rename to graphics/berry_blender/score_symbols.png diff --git a/graphics/unknown/unknown_339514.pal b/graphics/berry_blender/unused.pal similarity index 100% rename from graphics/unknown/unknown_339514.pal rename to graphics/berry_blender/unused.pal diff --git a/include/berry_blender.h b/include/berry_blender.h index e8f7bb83d..66d839389 100644 --- a/include/berry_blender.h +++ b/include/berry_blender.h @@ -1,6 +1,16 @@ #ifndef GUARD_BERRY_BLENDER_H #define GUARD_BERRY_BLENDER_H +// Indices into gSendCmd / gRecvCmds +#define BLENDER_COMM_INPUT_STATE 0 +#define BLENDER_COMM_RESP 1 +#define BLENDER_COMM_SCORE 2 +#define BLENDER_COMM_STOP_TYPE 2 // re-used +#define BLENDER_COMM_PLAYER_ID 3 +#define BLENDER_COMM_UNUSED 4 +#define BLENDER_COMM_PROGRESS_BAR 5 +#define BLENDER_COMM_ARROW_POS 6 + extern u8 gInGameOpponentsNo; void DoBerryBlending(void); diff --git a/include/global.h b/include/global.h index 7de8d1eb3..08988eac7 100644 --- a/include/global.h +++ b/include/global.h @@ -102,6 +102,7 @@ #define TEST_BUTTON(field, button) ({(field) & (button);}) #define JOY_NEW(button) TEST_BUTTON(gMain.newKeys, button) #define JOY_HELD(button) TEST_BUTTON(gMain.heldKeys, button) +#define JOY_HELD_RAW(button) TEST_BUTTON(gMain.heldKeysRaw, button) #define JOY_REPEAT(button) TEST_BUTTON(gMain.newAndRepeatedKeys, button) #define S16TOPOSFLOAT(val) \ diff --git a/include/global.tv.h b/include/global.tv.h index b211052e0..8e1a898b6 100644 --- a/include/global.tv.h +++ b/include/global.tv.h @@ -32,7 +32,7 @@ typedef union // size = 0x24 /*0x01*/ bool8 active; /*0x02*/ u16 species; /*0x04*/ u16 words[6]; - /*0x10*/ u8 playerName[8]; + /*0x10*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; /*0x18*/ u8 language; } fanclubLetter; @@ -42,7 +42,7 @@ typedef union // size = 0x24 /*0x01*/ bool8 active; /*0x02*/ u16 var02; /*0x04*/ u16 words[6]; - /*0x10*/ u8 playerName[8]; + /*0x10*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; /*0x18*/ u8 language; } recentHappenings; @@ -53,11 +53,11 @@ typedef union // size = 0x24 /*0x02*/ u16 species; /*0x04*/ u8 friendshipHighNybble:4; /*0x04*/ u8 questionAsked:4; - /*0x05*/ u8 playerName[8]; + /*0x05*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; /*0x0D*/ u8 language; /*0x0E*/ u8 pokemonNameLanguage; /*0x0F*/ u8 filler_0F[1]; - /*0x10*/ u8 nickname[8]; + /*0x10*/ u8 nickname[PLAYER_NAME_LENGTH + 1]; /*0x18*/ u16 words18[2]; /*0x1C*/ u16 words[4]; } fanclubOpinions; @@ -78,7 +78,7 @@ typedef union // size = 0x24 /*0x00*/ u8 kind; /*0x01*/ bool8 active; /*0x02*/ u16 species; - /*0x04*/ u8 pokemonName[11]; + /*0x04*/ u8 pokemonName[POKEMON_NAME_LENGTH + 1]; /*0x0F*/ u8 trainerName[11]; /*0x1A*/ u8 random; /*0x1B*/ u8 random2; @@ -93,12 +93,12 @@ typedef union // size = 0x24 /*0x01*/ bool8 active; /*0x02*/ u16 species; /*0x04*/ u16 words[2]; - /*0x08*/ u8 pokemonNickname[11]; + /*0x08*/ u8 pokemonNickname[POKEMON_NAME_LENGTH + 1]; /*0x13*/ u8 contestCategory:3; /*0x13*/ u8 contestRank:2; /*0x13*/ u8 contestResult:2; /*0x14*/ u16 move; - /*0x16*/ u8 playerName[8]; + /*0x16*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; /*0x1E*/ u8 language; /*0x1F*/ u8 pokemonNameLanguage; } bravoTrainer; @@ -107,7 +107,7 @@ typedef union // size = 0x24 struct { /*0x00*/ u8 kind; /*0x01*/ bool8 active; - /*0x02*/ u8 trainerName[8]; + /*0x02*/ u8 trainerName[PLAYER_NAME_LENGTH + 1]; /*0x0A*/ u16 species; /*0x0C*/ u8 pokemonName[8]; /*0x14*/ u16 defeatedSpecies; @@ -125,14 +125,14 @@ typedef union // size = 0x24 /*0x00*/ u8 kind; /*0x01*/ bool8 active; /*0x02*/ u16 losingSpecies; - /*0x04*/ u8 losingTrainerName[8]; + /*0x04*/ u8 losingTrainerName[PLAYER_NAME_LENGTH + 1]; /*0x0C*/ u8 loserAppealFlag; /*0x0D*/ u8 round1Placing; /*0x0e*/ u8 round2Placing; /*0x0f*/ u8 winnerAppealFlag; /*0x10*/ u16 move; /*0x12*/ u16 winningSpecies; - /*0x14*/ u8 winningTrainerName[8]; + /*0x14*/ u8 winningTrainerName[PLAYER_NAME_LENGTH + 1]; /*0x1C*/ u8 category; /*0x1D*/ u8 winningTrainerLanguage; /*0x1E*/ u8 losingTrainerLanguage; @@ -144,9 +144,9 @@ typedef union // size = 0x24 /*0x01*/ bool8 active; /*0x02*/ u8 sheen; /*0x03*/ u8 flavor:3; - /*0x03*/ u8 unk_03_3:2; - /*0x04*/ u8 worstBlenderName[8]; - /*0x0C*/ u8 playerName[8]; + /*0x03*/ u8 color:2; + /*0x04*/ u8 worstBlenderName[PLAYER_NAME_LENGTH + 1]; + /*0x0C*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; /*0x14*/ u8 language; /*0x15*/ u8 worstBlenderLanguage; } threeCheers; @@ -156,8 +156,8 @@ typedef union // size = 0x24 /*0x00*/ u8 kind; /*0x01*/ bool8 active; /*0x02*/ u16 speciesOpponent; - /*0x04*/ u8 playerName[8]; - /*0x0C*/ u8 linkOpponentName[8]; + /*0x04*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; + /*0x0C*/ u8 linkOpponentName[PLAYER_NAME_LENGTH + 1]; /*0x14*/ u16 move; /*0x16*/ u16 speciesPlayer; /*0x18*/ u8 battleType; @@ -169,10 +169,10 @@ typedef union // size = 0x24 struct { /*0x00*/ u8 kind; /*0x01*/ bool8 active; - /*0x02*/ u8 playerName[8]; + /*0x02*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; /*0x0a*/ u8 idLo; /*0x0b*/ u8 idHi; - /*0x0c*/ u8 idolName[8]; + /*0x0c*/ u8 idolName[PLAYER_NAME_LENGTH + 1]; /*0x14*/ u16 words[1]; /*0x16*/ u8 score; /*0x17*/ u8 language; @@ -183,9 +183,9 @@ typedef union // size = 0x24 struct { /*0x00*/ u8 kind; /*0x01*/ bool8 active; - /*0x02*/ u8 playerName[8]; + /*0x02*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; /*0x0a*/ u8 contestCategory; - /*0x0b*/ u8 nickname[11]; + /*0x0b*/ u8 nickname[POKEMON_NAME_LENGTH + 1]; /*0x16*/ u8 pokeblockState; /*0x17*/ u8 language; /*0x18*/ u8 pokemonNameLanguage; @@ -198,11 +198,11 @@ typedef union // size = 0x24 /*0x01*/ bool8 active; /*0x02*/ u8 language; /*0x03*/ u8 language2; - /*0x04*/ u8 nickname[11]; + /*0x04*/ u8 nickname[POKEMON_NAME_LENGTH + 1]; /*0x0F*/ u8 ball; /*0x10*/ u16 species; /*0x12*/ u8 nBallsUsed; - /*0x13*/ u8 playerName[8]; + /*0x13*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; } pokemonToday; // TVSHOW_SMART_SHOPPER @@ -215,7 +215,7 @@ typedef union // size = 0x24 /*0x06*/ u16 itemIds[3]; /*0x0C*/ u16 itemAmounts[3]; /*0x12*/ u8 shopLocation; - /*0x13*/ u8 playerName[8]; + /*0x13*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; } smartshopperShow; // TVSHOW_POKEMON_TODAY_FAILED @@ -229,7 +229,7 @@ typedef union // size = 0x24 /*0x10*/ u8 nBallsUsed; /*0x11*/ u8 outcome; /*0x12*/ u8 location; - /*0x13*/ u8 playerName[8]; + /*0x13*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; } pokemonTodayFailed; // TVSHOW_FISHING_ADVICE @@ -241,7 +241,7 @@ typedef union // size = 0x24 /*0x04*/ u16 species; /*0x06*/ u8 language; /*0x07*/ u8 pad07[12]; - /*0x13*/ u8 playerName[8]; + /*0x13*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; } pokemonAngler; // TVSHOW_WORLD_OF_MASTERS @@ -255,7 +255,7 @@ typedef union // size = 0x24 /*0x0a*/ u8 location; /*0x0b*/ u8 language; /*0x0c*/ u8 pad0c[7]; - /*0x13*/ u8 playerName[8]; + /*0x13*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; } worldOfMasters; // TVSHOW_TODAYS_RIVAL_TRAINER @@ -271,7 +271,7 @@ typedef union // size = 0x24 /*0x0a*/ u16 mapLayoutId; /*0x0c*/ u8 language; /*0x0d*/ u8 filler_0d[6]; - /*0x13*/ u8 playerName[8]; + /*0x13*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; } rivalTrainer; // TVSHOW_TREND_WATCHER @@ -283,7 +283,7 @@ typedef union // size = 0x24 /*0x08*/ u8 gender; /*0x09*/ u8 language; /*0x0a*/ u8 filler_0a[9]; - /*0x13*/ u8 playerName[8]; + /*0x13*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; } trendWatcher; // TVSHOW_TREASURE_INVESTIGATORS @@ -295,7 +295,7 @@ typedef union // size = 0x24 /*0x05*/ u8 language; /*0x06*/ u16 mapLayoutId; /*0x08*/ u8 filler_08[11]; - /*0x13*/ u8 playerName[8]; + /*0x13*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; } treasureInvestigators; // TVSHOW_FIND_THAT_GAMER @@ -308,7 +308,7 @@ typedef union // size = 0x24 /*0x06*/ u8 filler_06[2]; /*0x08*/ u8 language; /*0x09*/ u8 filler_09[10]; - /*0x13*/ u8 playerName[8]; + /*0x13*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; } findThatGamer; // TVSHOW_BREAKING_NEWS @@ -324,7 +324,7 @@ typedef union // size = 0x24 /*0x0c*/ u16 lastUsedMove; /*0x0e*/ u8 language; /*0x0f*/ u8 filler_0f[4]; - /*0x13*/ u8 playerName[8]; + /*0x13*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; } breakingNews; // TVSHOW_SECRET_BASE_VISIT @@ -338,7 +338,7 @@ typedef union // size = 0x24 /*0x0a*/ u16 move; /*0x0c*/ u8 language; /*0x0d*/ u8 filler_0d[6]; - /*0x13*/ u8 playerName[8]; + /*0x13*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; } secretBaseVisit; // TVSHOW_LOTTO_WINNER @@ -349,7 +349,7 @@ typedef union // size = 0x24 /*0x04*/ u8 whichPrize; /*0x05*/ u8 language; /*0x06*/ u8 filler_06[13]; - /*0x13*/ u8 playerName[8]; + /*0x13*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; } lottoWinner; // TVSHOW_BATTLE_SEMINAR @@ -364,7 +364,7 @@ typedef union // size = 0x24 /*0x10*/ u8 nOtherMoves; /*0x11*/ u8 language; /*0x12*/ u8 filler_12[1]; - /*0x13*/ u8 playerName[8]; + /*0x13*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; } battleSeminar; // TVSHOW_TRAINER_FAN_CLUB @@ -375,7 +375,7 @@ typedef union // size = 0x24 /*0x04*/ u16 words[2]; /*0x08*/ u8 language; /*0x09*/ u8 filler_09[10]; - /*0x13*/ u8 playerName[8]; + /*0x13*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; } trainerFanClub; // TVSHOW_CUTIES @@ -384,11 +384,11 @@ typedef union // size = 0x24 /*0x01*/ bool8 active; /*0x02*/ u8 nRibbons; /*0x03*/ u8 selectedRibbon; - /*0x04*/ u8 nickname[11]; + /*0x04*/ u8 nickname[POKEMON_NAME_LENGTH + 1]; /*0x0f*/ u8 language; /*0x10*/ u8 pokemonNameLanguage; /*0x11*/ u8 filler_12[2]; - /*0x13*/ u8 playerName[8]; + /*0x13*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; } cuties; // TVSHOW_FRONTIER @@ -403,7 +403,7 @@ typedef union // size = 0x24 /*0x0c*/ u8 language; /*0x0d*/ u8 facility; /*0x0e*/ u8 filler_0e[5]; - /*0x13*/ u8 playerName[8]; + /*0x13*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; } frontier; // TVSHOW_NUMBER_ONE @@ -414,7 +414,7 @@ typedef union // size = 0x24 /*0x04*/ u8 actionIdx; /*0x05*/ u8 language; /*0x06*/ u8 filler_06[13]; - /*0x13*/ u8 playerName[8]; + /*0x13*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; } numberOne; // TVSHOW_SECRET_BASE_SECRETS @@ -422,11 +422,11 @@ typedef union // size = 0x24 /*0x00*/ u8 kind; /*0x01*/ bool8 active; /*0x02*/ u16 stepsInBase; - /*0x04*/ u8 baseOwnersName[8]; + /*0x04*/ u8 baseOwnersName[PLAYER_NAME_LENGTH + 1]; /*0x0c*/ u32 flags; /*0x10*/ u16 item; /*0x12*/ u8 savedState; - /*0x13*/ u8 playerName[8]; + /*0x13*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; /*0x1b*/ u8 language; /*0x1c*/ u8 baseOwnersNameLanguage; } secretBaseSecrets; @@ -439,7 +439,7 @@ typedef union // size = 0x24 /*0x03*/ u8 nPkblkUsed; /*0x04*/ u8 language; /*0x05*/ u8 filler_05[14]; - /*0x13*/ u8 playerName[8]; + /*0x13*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; } safariFanClub; // Mass Outbreak diff --git a/include/graphics.h b/include/graphics.h index 4c98bee47..d9189622a 100644 --- a/include/graphics.h +++ b/include/graphics.h @@ -4812,16 +4812,16 @@ extern const u16 gUsePokeblockGraph_Pal[]; extern const u16 gUsePokeblockNatureWin_Pal[]; // Berry blender -extern const u32 gBerryBlenderArrowTiles[]; -extern const u32 gBerryBlenderStartTiles[]; -extern const u32 gBerryBlenderMarubatsuTiles[]; -extern const u32 gBerryBlenderParticlesTiles[]; -extern const u32 gBerryBlenderCountdownNumbersTiles[]; +extern const u32 gBerryBlenderPlayerArrow_Gfx[]; +extern const u32 gBerryBlenderStart_Gfx[]; +extern const u32 gBerryBlenderScoreSymbols_Gfx[]; +extern const u32 gBerryBlenderParticles_Gfx[]; +extern const u32 gBerryBlenderCountdownNumbers_Gfx[]; extern const u16 gBerryBlenderMiscPalette[]; extern const u16 gBerryBlenderArrowPalette[]; -extern const u32 sBlenderCenterGfx[]; -extern const u32 gUnknown_08D91DB8[]; -extern const u32 gUnknown_08D927EC[]; +extern const u32 gBerryBlenderCenter_Gfx[]; +extern const u32 gBerryBlenderOuter_Gfx[]; +extern const u32 gBerryBlenderOuter_Tilemap[]; // Slot Machine extern const u32 gSlotMachineDigitalDisplay_Gfx[]; diff --git a/include/item_menu.h b/include/item_menu.h index edfb986f7..a99272b0c 100644 --- a/include/item_menu.h +++ b/include/item_menu.h @@ -93,7 +93,7 @@ void CB2_GoToSellMenu(void); void GoToBagMenu(u8 bagMenuType, u8 pocketId, void ( *postExitMenuMainCallback2)()); void DoWallyTutorialBagMenu(void); void ResetBagScrollPositions(void); -void ChooseBerrySetCallback(void (*callback)(void)); +void ChooseBerryForMachine(void (*exitCallback)(void)); void CB2_ChooseBerry(void); void Task_FadeAndCloseBagMenu(u8 taskId); void BagMenu_YesNo(u8, u8, const struct YesNoFuncTable*); diff --git a/include/item_menu_icons.h b/include/item_menu_icons.h index 75e9100d2..e061149fc 100644 --- a/include/item_menu_icons.h +++ b/include/item_menu_icons.h @@ -19,7 +19,7 @@ void sub_80D4FC8(u8 arg0); void sub_80D4FEC(u8 arg0); u8 CreateBerryTagSprite(u8 id, s16 x, s16 y); void FreeBerryTagSpritePalette(void); -u8 LoadSpinningBerryPicGfx(u8 berryId, u8 x, u8 y, bool8 startAffine); +u8 CreateSpinningBerrySprite(u8 berryId, u8 x, u8 y, bool8 startAffine); u8 CreateBerryFlavorCircleSprite(s16 x); #define TAG_BAG_GFX 100 diff --git a/include/link.h b/include/link.h index de10bb8dc..086bf787b 100644 --- a/include/link.h +++ b/include/link.h @@ -48,52 +48,60 @@ #define EXTRACT_LINK_ERRORS(status) \ (((status) & LINK_STAT_ERRORS) >> LINK_STAT_ERRORS_SHIFT) -#define LINKCMD_SEND_LINK_TYPE 0x2222 -#define LINKCMD_READY_EXIT_STANDBY 0x2FFE -#define LINKCMD_SEND_HELD_KEYS 0x4444 -#define LINKCMD_0x5555 0x5555 -#define LINKCMD_0x5566 0x5566 -#define LINKCMD_READY_CLOSE_LINK 0x5FFF -#define LINKCMD_0x6666 0x6666 -#define LINKCMD_0x7777 0x7777 -#define LINKCMD_CONT_BLOCK 0x8888 -#define LINKCMD_0xAAAA 0xAAAA -#define LINKCMD_0xAAAB 0xAAAB -#define LINKCMD_READY_TO_TRADE 0xAABB -#define LINKCMD_READY_FINISH_TRADE 0xABCD -#define LINKCMD_INIT_BLOCK 0xBBBB -#define LINKCMD_READY_CANCEL_TRADE 0xBBCC -#define LINKCMD_SEND_HELD_KEYS_2 0xCAFE -#define LINKCMD_SEND_BLOCK_REQ 0xCCCC -#define LINKCMD_START_TRADE 0xCCDD -#define LINKCMD_CONFIRM_FINISH_TRADE 0xDCBA -#define LINKCMD_SET_MONS_TO_TRADE 0xDDDD -#define LINKCMD_0xDDEE 0xDDEE -#define LINKCMD_REQUEST_CANCEL 0xEEAA -#define LINKCMD_CANCEL_TRADE 0xEEBB -#define LINKCMD_0xEECC 0xEECC +#define LINKCMD_BLENDER_STOP 0x1111 +#define LINKCMD_SEND_LINK_TYPE 0x2222 +#define LINKCMD_BLENDER_SCORE_MISS 0x2345 +#define LINKCMD_READY_EXIT_STANDBY 0x2FFE +#define LINKCMD_SEND_PACKET 0x2FFF +#define LINKCMD_BLENDER_SEND_KEYS 0x4444 +#define LINKCMD_BLENDER_SCORE_BEST 0x4523 +#define LINKCMD_BLENDER_SCORE_GOOD 0x5432 +#define LINKCMD_0x5555 0x5555 +#define LINKCMD_0x5566 0x5566 +#define LINKCMD_READY_CLOSE_LINK 0x5FFF +#define LINKCMD_0x6666 0x6666 +#define LINKCMD_0x7777 0x7777 +#define LINKCMD_BLENDER_PLAY_AGAIN 0x7779 +#define LINKCMD_0x7FFF 0x7FFF +#define LINKCMD_CONT_BLOCK 0x8888 +#define LINKCMD_BLENDER_NO_BERRIES 0x9999 +#define LINKCMD_BLENDER_NO_PBLOCK_SPACE 0xAAAA +#define LINKCMD_0xAAAB 0xAAAB +#define LINKCMD_READY_TO_TRADE 0xAABB +#define LINKCMD_READY_FINISH_TRADE 0xABCD +#define LINKCMD_INIT_BLOCK 0xBBBB +#define LINKCMD_READY_CANCEL_TRADE 0xBBCC +#define LINKCMD_SEND_HELD_KEYS 0xCAFE +#define LINKCMD_SEND_BLOCK_REQ 0xCCCC +#define LINKCMD_START_TRADE 0xCCDD +#define LINKCMD_CONFIRM_FINISH_TRADE 0xDCBA +#define LINKCMD_SET_MONS_TO_TRADE 0xDDDD +#define LINKCMD_0xDDEE 0xDDEE +#define LINKCMD_REQUEST_CANCEL 0xEEAA +#define LINKCMD_CANCEL_TRADE 0xEEBB +#define LINKCMD_0xEECC 0xEECC -#define LINKTYPE_TRADE 0x1111 -#define LINKTYPE_TRADE_CONNECTING 0x1122 -#define LINKTYPE_TRADE_SETUP 0x1133 -#define LINKTYPE_TRADE_DISCONNECTED 0x1144 -#define LINKTYPE_BATTLE 0x2211 -#define LINKTYPE_0x2222 0x2222 // unused battle? -#define LINKTYPE_SINGLE_BATTLE 0x2233 -#define LINKTYPE_DOUBLE_BATTLE 0x2244 -#define LINKTYPE_MULTI_BATTLE 0x2255 -#define LINKTYPE_BATTLE_TOWER_50 0x2266 -#define LINKTYPE_BATTLE_TOWER_OPEN 0x2277 -#define LINKTYPE_BATTLE_TOWER 0x2288 -#define LINKTYPE_RECORD_MIX_BEFORE 0x3311 -#define LINKTYPE_RECORD_MIX_AFTER 0x3322 -#define LINKTYPE_BERRY_BLENDER_SETUP 0x4411 -#define LINKTYPE_BERRY_BLENDER 0x4422 -#define LINKTYPE_MYSTERY_EVENT 0x5501 -#define LINKTYPE_0x5502 0x5502 // unused? -#define LINKTYPE_EREADER 0x5503 -#define LINKTYPE_CONTEST_GMODE 0x6601 -#define LINKTYPE_CONTEST_EMODE 0x6602 +#define LINKTYPE_TRADE 0x1111 +#define LINKTYPE_TRADE_CONNECTING 0x1122 +#define LINKTYPE_TRADE_SETUP 0x1133 +#define LINKTYPE_TRADE_DISCONNECTED 0x1144 +#define LINKTYPE_BATTLE 0x2211 +#define LINKTYPE_0x2222 0x2222 // unused battle? +#define LINKTYPE_SINGLE_BATTLE 0x2233 +#define LINKTYPE_DOUBLE_BATTLE 0x2244 +#define LINKTYPE_MULTI_BATTLE 0x2255 +#define LINKTYPE_BATTLE_TOWER_50 0x2266 +#define LINKTYPE_BATTLE_TOWER_OPEN 0x2277 +#define LINKTYPE_BATTLE_TOWER 0x2288 +#define LINKTYPE_RECORD_MIX_BEFORE 0x3311 +#define LINKTYPE_RECORD_MIX_AFTER 0x3322 +#define LINKTYPE_BERRY_BLENDER_SETUP 0x4411 +#define LINKTYPE_BERRY_BLENDER 0x4422 +#define LINKTYPE_MYSTERY_EVENT 0x5501 +#define LINKTYPE_0x5502 0x5502 // unused? +#define LINKTYPE_EREADER 0x5503 +#define LINKTYPE_CONTEST_GMODE 0x6601 +#define LINKTYPE_CONTEST_EMODE 0x6602 struct LinkStatus { @@ -230,7 +238,7 @@ extern u16 gSendCmd[CMD_LENGTH]; extern struct LinkPlayer gLinkPlayers[5]; extern u16 word_3002910[]; extern bool8 gReceivedRemoteLinkPlayers; -extern u32 gUnknown_020223C0; +extern u32 gBerryBlenderKeySendAttempts; extern bool8 gLinkVSyncDisabled; extern u32 gLinkStatus; @@ -280,7 +288,7 @@ u8 IsLinkMaster(void); void SetCloseLinkCallback(void); bool8 HandleLinkConnection(void); void SetLinkDebugValues(u32 seed, u32 flags); -void sub_800A418(void); +void SetBerryBlenderLinkCallback(void); void SetSuppressLinkErrorMessage(bool8 flag); void sub_800B524(struct LinkPlayer *linkPlayer); u8 GetSioMultiSI(void); diff --git a/include/link_rfu.h b/include/link_rfu.h index 4d00039eb..9476da6b7 100644 --- a/include/link_rfu.h +++ b/include/link_rfu.h @@ -5,18 +5,18 @@ #include "link.h" #include "AgbRfu_LinkManager.h" -#define RFU_COMMAND_0x4400 0x4400 -#define RFU_COMMAND_0x8800 0x8800 -#define RFU_COMMAND_0x8900 0x8900 -#define RFU_COMMAND_SEND_BLOCK_REQ 0xA100 -#define RFU_COMMAND_0x7700 0x7700 -#define RFU_COMMAND_0x7800 0x7800 -#define RFU_COMMAND_READY_EXIT_STANDBY 0x6600 -#define RFU_COMMAND_READY_CLOSE_LINK 0x5F00 -#define RFU_COMMAND_0x2F00 0x2F00 -#define RFU_COMMAND_0xBE00 0xBE00 -#define RFU_COMMAND_0xEE00 0xEE00 -#define RFU_COMMAND_0xED00 0xED00 +#define RFUCMD_SEND_PACKET 0x2F00 +#define RFUCMD_BLENDER_SEND_KEYS 0x4400 +#define RFUCMD_READY_CLOSE_LINK 0x5F00 +#define RFUCMD_READY_EXIT_STANDBY 0x6600 +#define RFUCMD_0x7700 0x7700 +#define RFUCMD_0x7800 0x7800 +#define RFUCMD_0x8800 0x8800 +#define RFUCMD_0x8900 0x8900 +#define RFUCMD_SEND_BLOCK_REQ 0xA100 +#define RFUCMD_SEND_HELD_KEYS 0xBE00 +#define RFUCMD_0xED00 0xED00 +#define RFUCMD_0xEE00 0xEE00 #define RFU_SERIAL_7F7D 0x7F7D @@ -29,6 +29,8 @@ #define BACKUP_QUEUE_NUM_SLOTS 2 #define BACKUP_QUEUE_SLOT_LENGTH 14 +#define RFU_PACKET_SIZE 6 + #define RFU_STATUS_OK 0 #define RFU_STATUS_FATAL_ERROR 1 #define RFU_STATUS_CONNECTION_ERROR 2 @@ -140,7 +142,7 @@ struct GFRfuManager /* 0x0ef */ bool8 isShuttingDown; /* 0x0f0 */ u8 linkLossRecoveryState; /* 0x0f1 */ u8 status; - /* 0x0f2 */ u16 unk_f2[6]; + /* 0x0f2 */ u16 packet[RFU_PACKET_SIZE]; /* 0x0fe */ u16 resendExitStandbyTimer; /* 0x100 */ u16 unk_100; /* 0x102 */ u8 unk_102; @@ -197,7 +199,7 @@ void Rfu_SetBlockReceivedFlag(u8 who); void Rfu_ResetBlockReceivedFlag(u8 who); bool32 IsSendingKeysToRfu(void); void StartSendingKeysToRfu(void); -void sub_800F850(void); +void Rfu_SetBerryBlenderLinkCallback(void); u8 Rfu_GetBlockReceivedStatus(void); bool32 Rfu_InitBlockSend(const u8 *src, size_t size); void ClearLinkRfuCallback(void); @@ -250,7 +252,7 @@ void SetTradeBoardRegisteredMonInfo(u32 type, u32 species, u32 level); void InitializeRfuLinkManager_EnterUnionRoom(void); void sub_8012188(const u8 *name, struct GFtgtGname *structPtr, u8 a2); bool32 IsUnionRoomListenTaskActive(void); -void sub_800FE50(void *a0); +void Rfu_SendPacket(void *data); bool32 PlayerHasMetTrainerBefore(u16 id, u8 *name); void sub_8011DE0(u32 arg0); u8 sub_801100C(s32 a0); diff --git a/include/pokeblock.h b/include/pokeblock.h index 0d413a810..c82e99d8f 100644 --- a/include/pokeblock.h +++ b/include/pokeblock.h @@ -9,12 +9,21 @@ enum { - PBLOCK_CLR_BLACK, + PBLOCK_CLR_NONE, PBLOCK_CLR_RED, PBLOCK_CLR_BLUE, PBLOCK_CLR_PINK, PBLOCK_CLR_GREEN, - PBLOCK_CLR_YELLOW + PBLOCK_CLR_YELLOW, + PBLOCK_CLR_PURPLE, + PBLOCK_CLR_INDIGO, + PBLOCK_CLR_BROWN, + PBLOCK_CLR_LITE_BLUE, + PBLOCK_CLR_OLIVE, + PBLOCK_CLR_GRAY, + PBLOCK_CLR_BLACK, + PBLOCK_CLR_WHITE, + PBLOCK_CLR_GOLD, }; enum diff --git a/include/strings.h b/include/strings.h index 1f2920140..7018f9e0d 100644 --- a/include/strings.h +++ b/include/strings.h @@ -2983,4 +2983,9 @@ extern const u8 gText_Smartness[]; extern const u8 gText_Cuteness[]; extern const u8 gText_Beauty3[]; +// Berry Blender +extern const u8 gText_SavingDontTurnOff2[]; +extern const u8 gText_BlenderMaxSpeedRecord[]; +extern const u8 gText_234Players[]; + #endif // GUARD_STRINGS_H diff --git a/src/berry_blender.c b/src/berry_blender.c index 399a9e7b8..2cdb841ee 100644 --- a/src/berry_blender.c +++ b/src/berry_blender.c @@ -1,5 +1,4 @@ #include "global.h" -#include "constants/game_stat.h" #include "overworld.h" #include "berry_blender.h" #include "bg.h" @@ -7,7 +6,6 @@ #include "task.h" #include "sprite.h" #include "sound.h" -#include "constants/songs.h" #include "m4a.h" #include "bg.h" #include "palette.h" @@ -19,10 +17,10 @@ #include "event_data.h" #include "main.h" #include "link.h" +#include "link_rfu.h" #include "item_menu_icons.h" #include "berry.h" #include "item.h" -#include "constants/items.h" #include "string_util.h" #include "international_string_util.h" #include "random.h" @@ -35,43 +33,97 @@ #include "graphics.h" #include "new_game.h" #include "save.h" -#include "link.h" +#include "strings.h" #include "constants/berry.h" +#include "constants/game_stat.h" +#include "constants/items.h" #include "constants/rgb.h" +#include "constants/songs.h" -#define BLENDER_SCORE_BEST 0 -#define BLENDER_SCORE_GOOD 1 -#define BLENDER_SCORE_MISS 2 +enum { + SCORE_BEST, + SCORE_GOOD, + SCORE_MISS, + NUM_SCORE_TYPES, +}; -#define BLENDER_MAX_PLAYERS 4 -#define BLENDER_SCORES_NO 3 +// Redundant with the above. Reversed +enum { + PROXIMITY_MISS, + PROXIMITY_GOOD, + PROXIMITY_BEST, +}; -enum -{ - PLAY_AGAIN_OK, - DONT_PLAY_AGAIN, +enum { + SCOREANIM_GOOD, + SCOREANIM_MISS, + SCOREANIM_BEST_FLASH, + SCOREANIM_BEST_STATIC, +}; + +enum { + PLAY_AGAIN_YES, + PLAY_AGAIN_NO, CANT_PLAY_NO_BERRIES, CANT_PLAY_NO_PKBLCK_SPACE }; +enum { + BLENDER_MISTER, + BLENDER_LADDIE, + BLENDER_LASSIE, + BLENDER_MASTER, + BLENDER_DUDE, + BLENDER_MISS +}; + +#define BLENDER_MAX_PLAYERS MAX_LINK_PLAYERS + +#define NO_PLAYER 0xFF + +#define MAX_PROGRESS_BAR 1000 + +#define MAX_ARROW_POS 0x10000 // By virtue of being u16 +#define MIN_ARROW_SPEED 0x80 +#define ARROW_FALL_ROTATION 0x5800 // The amount the arrow spins as it falls in at the start + +// Tile offsets +#define PROGRESS_BAR_FILLED_TOP 0x80E9 +#define PROGRESS_BAR_FILLED_BOTTOM 0x80F9 +#define PROGRESS_BAR_EMPTY_TOP 0x80E1 +#define PROGRESS_BAR_EMPTY_BOTTOM 0x80F1 +#define RPM_DIGIT 0x8072 + +// Tile and palette tags +#define GFXTAG_COUNTDOWN_NUMBERS 12345 +#define GFXTAG_START 12346 +#define GFXTAG_PARTICLES 23456 +#define GFXTAG_PLAYER_ARROW 46545 +#define GFXTAG_SCORE_SYMBOLS 48888 + +#define PALTAG_PLAYER_ARROW 12312 +#define PALTAG_MISC 46546 + +// Last berry that an NPC can put in +#define NUM_NPC_BERRIES ITEM_TO_BERRY(ITEM_ASPEAR_BERRY) + struct BlenderBerry { u16 itemId; u8 name[BERRY_NAME_LENGTH + 1]; - u8 flavors[FLAVOR_COUNT]; - u8 smoothness; + u8 flavors[FLAVOR_COUNT + 1]; // 5 flavors, + 1 for feel }; struct TimeAndRPM { u32 time; - u16 max_RPM; + u16 maxRPM; }; struct BlenderGameBlock { struct TimeAndRPM timeRPM; - u16 scores[BLENDER_MAX_PLAYERS][BLENDER_SCORES_NO]; + u16 scores[BLENDER_MAX_PLAYERS][NUM_SCORE_TYPES]; }; struct TvBlenderStruct @@ -82,138 +134,122 @@ struct TvBlenderStruct u8 pokeblockSheen; }; -struct BerryBlenderData +struct BerryBlender { u8 mainState; u8 loadGfxState; - u8 unused_02[0x42]; - u16 field_44; - u8 scoreIconIds[BLENDER_SCORES_NO]; + u8 unused0[66]; + u16 unk0; // never read + u8 scoreIconIds[NUM_SCORE_TYPES]; u16 arrowPos; - s16 field_4C; - u16 max_RPM; - u8 syncArrowSpriteIds[BLENDER_MAX_PLAYERS]; - u8 syncArrowSprite2Ids[BLENDER_MAX_PLAYERS]; - u8 unused_57[0xB]; + s16 speed; + u16 maxRPM; + u8 playerArrowSpriteIds[BLENDER_MAX_PLAYERS]; + u8 playerArrowSpriteIds2[BLENDER_MAX_PLAYERS]; + u8 unused1[11]; u8 gameEndState; - u16 field_64[BLENDER_MAX_PLAYERS]; - u16 field_6C; - u16 field_6E; + u16 playerContinueResponses[BLENDER_MAX_PLAYERS]; + u16 canceledPlayerCmd; + u16 canceledPlayerId; u16 playAgainState; - u8 field_72; + u8 slowdownTimer; u16 chosenItemId[BLENDER_MAX_PLAYERS]; - u8 playersNo; - u8 unused_7D[0x10]; - u16 field_8E[BLENDER_MAX_PLAYERS]; - u16 field_96[BLENDER_MAX_PLAYERS]; + u8 numPlayers; + u8 unused2[16]; + u16 arrowIdToPlayerId[BLENDER_MAX_PLAYERS]; + u16 playerIdToArrowId[BLENDER_MAX_PLAYERS]; u8 yesNoAnswer; u8 stringVar[100]; u32 gameFrameTime; s32 framesToWait; - u32 field_10C; - u8 unused_110[4]; - u8 field_114; - u16 field_116; - u16 field_118; - u16 field_11A; + u32 unk1; // never read + u8 unused3[4]; + u8 playerToThrowBerry; + u16 progressBarValue; + u16 maxProgressBarValue; + u16 centerScale; s16 bg_X; s16 bg_Y; - u8 field_120[3]; - u8 field_123; - u16 scores[BLENDER_MAX_PLAYERS][BLENDER_SCORES_NO]; + u8 opponentTaskIds[BLENDER_MAX_PLAYERS - 1]; + u8 perfectOpponents; // for debugging, NPCs will always hit Best + u16 scores[BLENDER_MAX_PLAYERS][NUM_SCORE_TYPES]; u8 playerPlaces[BLENDER_MAX_PLAYERS]; struct BgAffineSrcData bgAffineSrc; - u16 field_154; + u16 savedMusic; struct BlenderBerry blendedBerries[BLENDER_MAX_PLAYERS]; struct TimeAndRPM smallBlock; - u32 field_1A0; - u8 field_1A4; + u32 linkPlayAgainState; + u8 ownRanking; struct TvBlenderStruct tvBlender; - u8 tilemapBuffers[2][0x800]; + u8 tilemapBuffers[2][BG_SCREEN_SIZE]; s16 textState; void *tilesBuffer; struct BlenderGameBlock gameBlock; }; -extern struct MusicPlayerInfo gMPlayInfo_SE2; -extern struct MusicPlayerInfo gMPlayInfo_BGM; +static void SetBgPos(void); +static void Task_HandleOpponent1(u8); +static void Task_HandleOpponent2(u8); +static void Task_HandleOpponent3(u8); +static void Task_HandleBerryMaster(u8); +static void Task_PlayPokeblockFanfare(u8); +static void SpriteCB_PlayerArrow(struct Sprite *); +static void SpriteCB_ScoreSymbol(struct Sprite *); +static void SpriteCB_CountdownNumber(struct Sprite *); +static void SpriteCB_Start(struct Sprite *); +static void SpriteCB_ScoreSymbolBest(struct Sprite *); +static void InitLocalPlayers(u8); +static void CB2_LoadBerryBlender(void); +static void UpdateBlenderCenter(void); +static bool32 Blender_PrintText(s16 *, const u8 *, s32 ); +static void StartBlender(void); +static void CB2_StartBlenderLink(void); +static void CB2_StartBlenderLocal(void); +static void Blender_DummiedOutFunc(s16, s16); +static void CB2_PlayBlender(void); +static void DrawBlenderCenter(struct BgAffineSrcData *); +static bool8 UpdateBlenderLandScreenShake(void); +static void SetPlayerIdMaps(void); +static void PrintPlayerNames(void); +static void InitBlenderBgs(void); +static void SetPlayerBerryData(u8, u16); +static void Blender_AddTextPrinter(u8, const u8 *, u8, u8, s32, s32); +static void ResetLinkCmds(void); +static void CreateParticleSprites(void); +static void ShakeBgCoordForHit(s16*, u16); +static void TryUpdateProgressBar(u16, u16); +static void UpdateRPM(u16); +static void RestoreBgCoords(void); +static void ProcessLinkPlayerCmds(void); +static void CB2_EndBlenderGame(void); +static bool8 PrintBlendingRanking(void); +static bool8 PrintBlendingResults(void); +static void CB2_CheckPlayAgainLocal(void); +static void CB2_CheckPlayAgainLink(void); +static void UpdateProgressBar(u16, u16); +static void PrintMadePokeblockString(struct Pokeblock *, u8 *); +static bool32 TryAddContestLinkTvShow(struct Pokeblock *, struct TvBlenderStruct *); -// text -extern const u8 gText_SavingDontTurnOff2[]; -extern const u8 gText_Space[]; -extern const u8 gText_BlenderMaxSpeedRecord[]; -extern const u8 gText_234Players[]; +EWRAM_DATA static struct BerryBlender *sBerryBlender = NULL; +EWRAM_DATA static s32 sDebug_PokeblockFactorFlavors[FLAVOR_COUNT] = {0}; +EWRAM_DATA static s32 sDebug_PokeblockFactorFlavorsAfterRPM[FLAVOR_COUNT] = {0}; +EWRAM_DATA static u32 sDebug_PokeblockFactorRPM = 0; -// this file's functions -static void BerryBlender_SetBackgroundsPos(void); -static void sub_8080EA4(u8 taskId); -static void sub_8080FD0(u8 taskId); -static void sub_80810F8(u8 taskId); -static void sub_8081224(u8 taskId); -static void sub_8083F3C(u8 taskId); -static void sub_80833F8(struct Sprite *sprite); -static void sub_8082F68(struct Sprite *sprite); -static void sub_8083010(struct Sprite *sprite); -static void sub_80830C0(struct Sprite *sprite); -static void sub_8082F9C(struct Sprite *sprite); -static void Blender_SetPlayerNamesLocal(u8 opponentsNum); -static void sub_807FAC8(void); -static void sub_8082D28(void); -static bool32 Blender_PrintText(s16 *textState, const u8 *string, s32 textSpeed); -static void sub_807FFA4(void); -static void sub_8080018(void); -static void sub_80808D4(void); -static void Blender_DummiedOutFunc(s16 a0, s16 a1); -static void sub_8081898(void); -static void sub_8082CB4(struct BgAffineSrcData *bgAffineSrc); -static bool8 sub_8083380(void); -static void sub_808074C(void); -static void Blender_PrintPlayerNames(void); -static void sub_8080588(void); -static void Blender_SetParticipantBerryData(u8 participantId, u16 itemId); -static void Blender_AddTextPrinter(u8 windowId, const u8 *string, u8 x, u8 y, s32 speed, s32 caseId); -static void sub_8080DF8(void); -static void sub_8082E84(void); -static void sub_80832BC(s16* a0, u16 a1); -static void sub_8083140(u16 a0, u16 a2); -static void sub_8083230(u16 a0); -static void sub_808330C(void); -static void sub_8082AD4(void); -static void CB2_HandleBlenderEndGame(void); -static bool8 Blender_PrintBlendingRanking(void); -static bool8 Blender_PrintBlendingResults(void); -static void CB2_HandlePlayerPlayAgainChoice(void); -static void CB2_HandlePlayerLinkPlayAgainChoice(void); -static void sub_8083170(u16 a0, u16 a1); -static void Blender_PrintMadePokeblockString(struct Pokeblock *pokeblock, u8 *dst); -static bool32 TryAddContestLinkTvShow(struct Pokeblock *pokeblock, struct TvBlenderStruct *a1); +static s16 sPokeblockFlavors[FLAVOR_COUNT + 1]; // + 1 for feel +static s16 sPokeblockPresentFlavors[FLAVOR_COUNT + 1]; +static s16 sDebug_MaxRPMStage; +static s16 sDebug_GameTimeStage; -// EWRAM -EWRAM_DATA static struct BerryBlenderData *sBerryBlenderData = NULL; -EWRAM_DATA static s32 sUnknown_020322A8[5] = {0}; -EWRAM_DATA static s32 sUnknown_020322BC[5] = {0}; -EWRAM_DATA static u32 sUnknown_020322D0 = 0; - -// IWRAM bss -static s16 sUnknown_03000DE8[8]; -static s16 sUnknown_03000DF8[6]; -static s16 sUnknown_03000E04; -static s16 sUnknown_03000E06; - -// IWRAM common u8 gInGameOpponentsNo; -// rom +static const u16 sBlenderCenter_Pal[] = INCBIN_U16("graphics/berry_blender/center.gbapal"); +static const u8 sBlenderCenter_Tilemap[] = INCBIN_U8("graphics/berry_blender/center_map.bin"); +static const u16 sBlenderOuter_Pal[] = INCBIN_U16("graphics/berry_blender/outer.gbapal"); -static const u16 sBlenderCenterPal[] = INCBIN_U16("graphics/berry_blender/center.gbapal"); -static const u8 sBlenderCenterMap[] = INCBIN_U8("graphics/berry_blender/center_map.bin"); -static const u16 sBlenderOuterPal[] = INCBIN_U16("graphics/berry_blender/outer.gbapal"); +static const u16 sUnused_Pal[] = INCBIN_U16("graphics/berry_blender/unused.gbapal"); +static const u16 sEmpty_Pal[16 * 14] = {0}; -// unreferenced pals? -static const u16 sUnknownPal_0[] = INCBIN_U16("graphics/unknown/unknown_339514.gbapal"); -static const u16 sUnknownArray_1[224] = {0}; - -// unused text? +// unused text static const u8 sUnusedText_YesNo[] = _("YES\nNO"); static const u8 sUnusedText_2[] = _("▶"); static const u8 sUnusedText_Space[] = _(" "); @@ -232,22 +268,12 @@ static const u8 sText_Miss[] = _("MISS"); static const u8* const sBlenderOpponentsNames[] = { - sText_Mister, - sText_Laddie, - sText_Lassie, - sText_Master, - sText_Dude, - sText_Miss -}; - -enum -{ - BLENDER_MISTER, - BLENDER_LADDIE, - BLENDER_LASSIE, - BLENDER_MASTER, - BLENDER_DUDE, - BLENDER_MISS + [BLENDER_MISTER] = sText_Mister, + [BLENDER_LADDIE] = sText_Laddie, + [BLENDER_LASSIE] = sText_Lassie, + [BLENDER_MASTER] = sText_Master, + [BLENDER_DUDE] = sText_Dude, + [BLENDER_MISS] = sText_Miss }; static const u8 sText_PressAToStart[] = _("Press the A Button to start."); @@ -274,7 +300,7 @@ static const u8 sText_TheLevelIs[] = _("The level is "); static const u8 sText_TheFeelIs[] = _(", and the feel is "); static const u8 sText_Dot2[] = _("."); -static const struct BgTemplate sBerryBlenderBgTemplates[3] = +static const struct BgTemplate sBgTemplates[3] = { { .bg = 0, @@ -305,7 +331,7 @@ static const struct BgTemplate sBerryBlenderBgTemplates[3] = } }; -static const struct WindowTemplate sBerryBlender_WindowTemplates[] = +static const struct WindowTemplate sWindowTemplates[] = { { .bg = 0, @@ -364,7 +390,7 @@ static const struct WindowTemplate sBerryBlender_WindowTemplates[] = DUMMY_WIN_TEMPLATE }; -static const struct WindowTemplate sBlender_YesNoWindowTemplate = +static const struct WindowTemplate sYesNoWindowTemplate_ContinuePlaying = { .bg = 0, .tilemapLeft = 21, @@ -375,31 +401,58 @@ static const struct WindowTemplate sBlender_YesNoWindowTemplate = .baseBlock = 0xCC }; -static const s8 sUnknown_083399C0[][2] = +static const s8 sPlayerArrowQuadrant[BLENDER_MAX_PLAYERS][2] = { - {-1, -1}, {1, -1}, {-1, 1}, {1, 1} + {-1, -1}, + { 1, -1}, + {-1, 1}, + { 1, 1} }; -static const u8 sBlenderSyncArrowsPos[BLENDER_MAX_PLAYERS][2] = +static const u8 sPlayerArrowPos[BLENDER_MAX_PLAYERS][2] = { - {72, 32}, {168, 32}, {72, 128}, {168, 128} + { 72, 32}, + {168, 32}, + { 72, 128}, + {168, 128} }; -static const u8 sUnknown_083399D0[3][4] = +static const u8 sPlayerIdMap[BLENDER_MAX_PLAYERS - 1][BLENDER_MAX_PLAYERS] = { - {-1, 0, 1, -1}, {-1, 0, 1, 2}, {0, 1, 2, 3} + {NO_PLAYER, 0, 1, NO_PLAYER}, // 2 Players + {NO_PLAYER, 0, 1, 2}, // 3 Players + { 0, 1, 2, 3} // 4 Players }; -static const u16 sUnknown_083399DC[] = {0, 0xC000, 0x4000, 0x8000}; -static const u8 sUnknown_083399E4[] = {1, 1, 0}; -static const u8 sUnknown_083399E7[] = {32, 224, 96, 160, 0}; -static const TaskFunc sUnknown_083399EC[] = +// Blender arrow positions: +// +// 0x0000 (limit 0x10000) +// . . +// . . +// 0x4000 . . 0xC000 +// . . +// . . +// . . +// 0x8000 +// +static const u16 sArrowStartPos[] = { + 0, + MAX_ARROW_POS / 4 * 3, // 0xC000 + MAX_ARROW_POS / 4, // 0x4000 + MAX_ARROW_POS / 4 * 2 // 0x8000 +}; +static const u8 sArrowStartPosIds[BLENDER_MAX_PLAYERS - 1] = {1, 1, 0}; +static const u8 sArrowHitRangeStart[BLENDER_MAX_PLAYERS] = {32, 224, 96, 160}; + +static const TaskFunc sLocalOpponentTasks[] = { - sub_8080EA4, sub_8080FD0, sub_80810F8 + Task_HandleOpponent1, + Task_HandleOpponent2, + Task_HandleOpponent3 }; -static const struct OamData sOamData_8216314 = +static const struct OamData sOam_PlayerArrow = { .y = 0, .affineMode = ST_OAM_AFFINE_OFF, @@ -416,40 +469,40 @@ static const struct OamData sOamData_8216314 = .affineParam = 0, }; -static const union AnimCmd sSpriteAnim_821631C[] = +static const union AnimCmd sAnim_PlayerArrow_TopLeft[] = { - ANIMCMD_FRAME(16, 5, 1, 1), + ANIMCMD_FRAME(16, 5, .vFlip = TRUE, .hFlip = TRUE), ANIMCMD_END }; -static const union AnimCmd sSpriteAnim_8216324[] = +static const union AnimCmd sAnim_PlayerArrow_TopRight[] = { ANIMCMD_FRAME(16, 5, .vFlip = TRUE), ANIMCMD_END }; -static const union AnimCmd sSpriteAnim_821632C[] = +static const union AnimCmd sAnim_PlayerArrow_BottomLeft[] = { ANIMCMD_FRAME(16, 5, .hFlip = TRUE), ANIMCMD_END }; -static const union AnimCmd sSpriteAnim_8216334[] = +static const union AnimCmd sAnim_PlayerArrow_BottomRight[] = { ANIMCMD_FRAME(16, 5, 0, 0), ANIMCMD_END }; -static const union AnimCmd sSpriteAnim_821633C[] = +static const union AnimCmd sAnim_PlayerArrow_TopLeft_Flash[] = { - ANIMCMD_FRAME(48, 2, 1, 1), - ANIMCMD_FRAME(32, 5, 1, 1), - ANIMCMD_FRAME(48, 3, 1, 1), - ANIMCMD_FRAME(16, 5, 1, 1), + ANIMCMD_FRAME(48, 2, .vFlip = TRUE, .hFlip = TRUE), + ANIMCMD_FRAME(32, 5, .vFlip = TRUE, .hFlip = TRUE), + ANIMCMD_FRAME(48, 3, .vFlip = TRUE, .hFlip = TRUE), + ANIMCMD_FRAME(16, 5, .vFlip = TRUE, .hFlip = TRUE), ANIMCMD_END }; -static const union AnimCmd sSpriteAnim_8216350[] = +static const union AnimCmd sAnim_PlayerArrow_TopRight_Flash[] = { ANIMCMD_FRAME(48, 2, .vFlip = TRUE), ANIMCMD_FRAME(32, 5, .vFlip = TRUE), @@ -458,7 +511,7 @@ static const union AnimCmd sSpriteAnim_8216350[] = ANIMCMD_END }; -static const union AnimCmd sSpriteAnim_8216364[] = +static const union AnimCmd sAnim_PlayerArrow_BottomLeft_Flash[] = { ANIMCMD_FRAME(48, 2, .hFlip = TRUE), ANIMCMD_FRAME(32, 5, .hFlip = TRUE), @@ -467,7 +520,7 @@ static const union AnimCmd sSpriteAnim_8216364[] = ANIMCMD_END }; -static const union AnimCmd sSpriteAnim_8216378[] = +static const union AnimCmd sAnim_PlayerArrow_BottomRight_Flash[] = { ANIMCMD_FRAME(48, 2, 0, 0), ANIMCMD_FRAME(32, 5, 0, 0), @@ -476,73 +529,73 @@ static const union AnimCmd sSpriteAnim_8216378[] = ANIMCMD_END }; -static const union AnimCmd sSpriteAnim_821638C[] = +static const union AnimCmd sAnim_PlayerArrow_TopLeft_Off[] = { - ANIMCMD_FRAME(0, 5, 1, 1), + ANIMCMD_FRAME(0, 5, .vFlip = TRUE, .hFlip = TRUE), ANIMCMD_END }; -static const union AnimCmd sSpriteAnim_8216394[] = +static const union AnimCmd sAnim_PlayerArrow_TopRight_Off[] = { ANIMCMD_FRAME(0, 5, .vFlip = TRUE), ANIMCMD_END }; -static const union AnimCmd sSpriteAnim_821639C[] = +static const union AnimCmd sAnim_PlayerArrow_BottomLeft_Off[] = { ANIMCMD_FRAME(0, 5, .hFlip = TRUE), ANIMCMD_END }; -static const union AnimCmd sSpriteAnim_82163A4[] = +static const union AnimCmd sAnim_PlayerArrow_BottomRight_Off[] = { ANIMCMD_FRAME(0, 5, 0, 0), ANIMCMD_END }; -static const union AnimCmd *const sSpriteAnimTable_82163AC[] = +static const union AnimCmd *const sAnims_PlayerArrow[] = { - sSpriteAnim_821631C, - sSpriteAnim_8216324, - sSpriteAnim_821632C, - sSpriteAnim_8216334, - sSpriteAnim_821633C, - sSpriteAnim_8216350, - sSpriteAnim_8216364, - sSpriteAnim_8216378, - sSpriteAnim_821638C, - sSpriteAnim_8216394, - sSpriteAnim_821639C, - sSpriteAnim_82163A4 + sAnim_PlayerArrow_TopLeft, + sAnim_PlayerArrow_TopRight, + sAnim_PlayerArrow_BottomLeft, + sAnim_PlayerArrow_BottomRight, + sAnim_PlayerArrow_TopLeft_Flash, + sAnim_PlayerArrow_TopRight_Flash, + sAnim_PlayerArrow_BottomLeft_Flash, + sAnim_PlayerArrow_BottomRight_Flash, + sAnim_PlayerArrow_TopLeft_Off, + sAnim_PlayerArrow_TopRight_Off, + sAnim_PlayerArrow_BottomLeft_Off, + sAnim_PlayerArrow_BottomRight_Off }; -static const struct SpriteSheet sSpriteSheet_BlenderArrow = +static const struct SpriteSheet sSpriteSheet_PlayerArrow = { - gBerryBlenderArrowTiles, 0x800, 46545 + gBerryBlenderPlayerArrow_Gfx, 0x800, GFXTAG_PLAYER_ARROW }; static const struct SpritePalette sSpritePal_BlenderMisc = { - gBerryBlenderMiscPalette, 46546 + gBerryBlenderMiscPalette, PALTAG_MISC }; -static const struct SpritePalette sSpritePal_BlenderArrow = +static const struct SpritePalette sSpritePal_PlayerArrow = { - gBerryBlenderArrowPalette, 12312 + gBerryBlenderArrowPalette, PALTAG_PLAYER_ARROW }; -static const struct SpriteTemplate sBlenderSyncArrow_SpriteTemplate = +static const struct SpriteTemplate sSpriteTemplate_PlayerArrow = { - .tileTag = 46545, - .paletteTag = 12312, - .oam = &sOamData_8216314, - .anims = sSpriteAnimTable_82163AC, + .tileTag = GFXTAG_PLAYER_ARROW, + .paletteTag = PALTAG_PLAYER_ARROW, + .oam = &sOam_PlayerArrow, + .anims = sAnims_PlayerArrow, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_80833F8 + .callback = SpriteCB_PlayerArrow }; -static const struct OamData sOamData_821640C = +static const struct OamData sOam_ScoreSymbols = { .y = 0, .affineMode = ST_OAM_AFFINE_OFF, @@ -559,19 +612,19 @@ static const struct OamData sOamData_821640C = .affineParam = 0, }; -static const union AnimCmd sSpriteAnim_8216414[] = +static const union AnimCmd sAnim_ScoreSymbols_Good[] = { ANIMCMD_FRAME(0, 20), ANIMCMD_END }; -static const union AnimCmd sSpriteAnim_821641C[] = +static const union AnimCmd sAnim_ScoreSymbols_Miss[] = { ANIMCMD_FRAME(4, 20, 1, 0), ANIMCMD_END }; -static const union AnimCmd sSpriteAnim_8216424[] = +static const union AnimCmd sAnim_ScoreSymbols_BestFlash[] = { ANIMCMD_FRAME(8, 4), ANIMCMD_FRAME(12, 4), @@ -581,37 +634,37 @@ static const union AnimCmd sSpriteAnim_8216424[] = ANIMCMD_END }; -static const union AnimCmd sSpriteAnim_821643C[] = +static const union AnimCmd sAnim_ScoreSymbols_BestStatic[] = { ANIMCMD_FRAME(8, 4), ANIMCMD_END }; -static const union AnimCmd *const sSpriteAnimTable_8216444[] = +static const union AnimCmd *const sAnims_ScoreSymbols[] = { - sSpriteAnim_8216414, - sSpriteAnim_821641C, - sSpriteAnim_8216424, - sSpriteAnim_821643C, + [SCOREANIM_GOOD] = sAnim_ScoreSymbols_Good, + [SCOREANIM_MISS] = sAnim_ScoreSymbols_Miss, + [SCOREANIM_BEST_FLASH] = sAnim_ScoreSymbols_BestFlash, + [SCOREANIM_BEST_STATIC] = sAnim_ScoreSymbols_BestStatic, }; -static const struct SpriteSheet sUnknown_08339B38 = +static const struct SpriteSheet sSpriteSheet_ScoreSymbols = { - gBerryBlenderMarubatsuTiles, 0x200, 48888 + gBerryBlenderScoreSymbols_Gfx, 0x200, GFXTAG_SCORE_SYMBOLS }; -static const struct SpriteTemplate sUnknown_08339B40 = +static const struct SpriteTemplate sSpriteTemplate_ScoreSymbols = { - .tileTag = 48888, - .paletteTag = 46546, - .oam = &sOamData_821640C, - .anims = sSpriteAnimTable_8216444, + .tileTag = GFXTAG_SCORE_SYMBOLS, + .paletteTag = PALTAG_MISC, + .oam = &sOam_ScoreSymbols, + .anims = sAnims_ScoreSymbols, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_8082F68 + .callback = SpriteCB_ScoreSymbol }; -static const struct OamData sOamData_8216474 = +static const struct OamData sOam_Particles = { .y = 0, .affineMode = ST_OAM_AFFINE_OFF, @@ -628,7 +681,7 @@ static const struct OamData sOamData_8216474 = .affineParam = 0, }; -static const union AnimCmd sSpriteAnim_821647C[] = +static const union AnimCmd sAnim_SparkleCrossToX[] = { ANIMCMD_FRAME(0, 3), ANIMCMD_FRAME(1, 4), @@ -638,7 +691,7 @@ static const union AnimCmd sSpriteAnim_821647C[] = ANIMCMD_END }; -static const union AnimCmd sSpriteAnim_8216494[] = +static const union AnimCmd sAnim_SparkleXToCross[] = { ANIMCMD_FRAME(0, 3), ANIMCMD_FRAME(2, 4), @@ -648,7 +701,7 @@ static const union AnimCmd sSpriteAnim_8216494[] = ANIMCMD_END }; -static const union AnimCmd sSpriteAnim_82164AC[] = +static const union AnimCmd sAnim_SparkleFull[] = { ANIMCMD_FRAME(0, 2), ANIMCMD_FRAME(1, 2), @@ -661,44 +714,44 @@ static const union AnimCmd sSpriteAnim_82164AC[] = ANIMCMD_END }; -static const union AnimCmd sSpriteAnim_82164D0[] = +static const union AnimCmd sAnim_GreenArrow[] = { ANIMCMD_FRAME(5, 5, 1, 1), ANIMCMD_END }; -static const union AnimCmd sSpriteAnim_82164D8[] = +static const union AnimCmd sAnim_GreenDot[] = { ANIMCMD_FRAME(6, 5, 1, 1), ANIMCMD_END }; -static const union AnimCmd *const sSpriteAnimTable_82164E0[] = +static const union AnimCmd *const sAnims_Particles[] = { - sSpriteAnim_821647C, - sSpriteAnim_8216494, - sSpriteAnim_82164AC, - sSpriteAnim_82164D0, - sSpriteAnim_82164D8, + sAnim_SparkleCrossToX, // Only this effect is ever used, rest go unused + sAnim_SparkleXToCross, + sAnim_SparkleFull, + sAnim_GreenArrow, + sAnim_GreenDot, }; -static const struct SpriteSheet sUnknown_08339BD8 = +static const struct SpriteSheet sSpriteSheet_Particles = { - gBerryBlenderParticlesTiles, 0xE0, 23456 + gBerryBlenderParticles_Gfx, 0xE0, GFXTAG_PARTICLES }; -static const struct SpriteTemplate sUnknown_08339BE0 = +static const struct SpriteTemplate sSpriteTemplate_Particles = { - .tileTag = 23456, - .paletteTag = 46546, - .oam = &sOamData_8216474, - .anims = sSpriteAnimTable_82164E0, + .tileTag = GFXTAG_PARTICLES, + .paletteTag = PALTAG_MISC, + .oam = &sOam_Particles, + .anims = sAnims_Particles, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = SpriteCallbackDummy }; -static const struct OamData sOamData_8216514 = +static const struct OamData sOam_CountdownNumbers = { .y = 0, .affineMode = ST_OAM_AFFINE_OFF, @@ -715,48 +768,48 @@ static const struct OamData sOamData_8216514 = .affineParam = 0, }; -static const union AnimCmd sSpriteAnim_821651C[] = +static const union AnimCmd sAnim_CountdownNumbers_3[] = { ANIMCMD_FRAME(32, 30), ANIMCMD_END }; -static const union AnimCmd sSpriteAnim_8216524[] = +static const union AnimCmd sAnim_CountdownNumbers_2[] = { ANIMCMD_FRAME(16, 30), ANIMCMD_END }; -static const union AnimCmd sSpriteAnim_821652C[] = +static const union AnimCmd sAnim_CountdownNumbers_1[] = { ANIMCMD_FRAME(0, 30), ANIMCMD_END }; -static const union AnimCmd *const sSpriteAnimTable_8216534[] = +static const union AnimCmd *const sAnims_CountdownNumbers[] = { - sSpriteAnim_821651C, - sSpriteAnim_8216524, - sSpriteAnim_821652C, + sAnim_CountdownNumbers_3, + sAnim_CountdownNumbers_2, + sAnim_CountdownNumbers_1, }; -static const struct SpriteSheet sUnknown_08339C24 = +static const struct SpriteSheet sSpriteSheet_CountdownNumbers = { - gBerryBlenderCountdownNumbersTiles, 0x600, 12345 + gBerryBlenderCountdownNumbers_Gfx, 0x600, GFXTAG_COUNTDOWN_NUMBERS }; -static const struct SpriteTemplate sUnknown_08339C2C = +static const struct SpriteTemplate sSpriteTemplate_CountdownNumbers = { - .tileTag = 12345, - .paletteTag = 46546, - .oam = &sOamData_8216514, - .anims = sSpriteAnimTable_8216534, + .tileTag = GFXTAG_COUNTDOWN_NUMBERS, + .paletteTag = PALTAG_MISC, + .oam = &sOam_CountdownNumbers, + .anims = sAnims_CountdownNumbers, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_8083010 + .callback = SpriteCB_CountdownNumber }; -static const struct OamData sOamData_8216560 = +static const struct OamData sOam_Start = { .y = 0, .affineMode = ST_OAM_AFFINE_OFF, @@ -773,34 +826,36 @@ static const struct OamData sOamData_8216560 = .affineParam = 0, }; -static const union AnimCmd sSpriteAnim_8216568[] = +static const union AnimCmd sAnim_Start[] = { ANIMCMD_FRAME(0, 30), ANIMCMD_END }; -static const union AnimCmd *const sSpriteAnimTable_8216570[] = +static const union AnimCmd *const sAnims_Start[] = { - sSpriteAnim_8216568, + sAnim_Start, }; -static const struct SpriteSheet sUnknown_08339C58 = +static const struct SpriteSheet sSpriteSheet_Start = { - gBerryBlenderStartTiles, 0x400, 12346 + gBerryBlenderStart_Gfx, 0x400, GFXTAG_START }; -static const struct SpriteTemplate sUnknown_08339C60 = +static const struct SpriteTemplate sSpriteTemplate_Start = { - .tileTag = 12346, - .paletteTag = 46546, - .oam = &sOamData_8216560, - .anims = sSpriteAnimTable_8216570, + .tileTag = GFXTAG_START, + .paletteTag = PALTAG_MISC, + .oam = &sOam_Start, + .anims = sAnims_Start, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_80830C0 + .callback = SpriteCB_Start }; -static const s16 sUnknown_08339C78[][5] = +// Data for throwing the berries in at the start +// x, y, bounce speed, x speed, y speed +static const s16 sBerrySpriteData[][5] = { {-10, 20, 10, 2, 1}, {250, 20, 10, -2, 1}, @@ -808,18 +863,54 @@ static const s16 sUnknown_08339C78[][5] = {250, 140, 10, -2, -1}, }; -static const u8 sOpponentBerrySets[][3] = +// There are only 5 different berries the NPCs will ever use +// Each of these sets represents 3 berries chosen to be used by the NPCs +// If the player's berry is one of the 5 possible berries, a set is chosen that excludes it +static const u8 sOpponentBerrySets[NUM_NPC_BERRIES * 2][3] = { - {4, 3, 2}, {0, 4, 3}, {1, 0, 4}, {2, 1, 0}, {3, 2, 1}, {0, 2, 3}, {1, 3, 4}, {2, 4, 0}, {3, 0, 1}, {4, 1, 2}, + // These sets are used if the player chose one of the 5 NPC berries + {ITEM_TO_BERRY(ITEM_ASPEAR_BERRY) - 1, ITEM_TO_BERRY(ITEM_RAWST_BERRY) - 1, ITEM_TO_BERRY(ITEM_PECHA_BERRY) - 1}, // player chose Cheri Berry + {ITEM_TO_BERRY(ITEM_CHERI_BERRY) - 1, ITEM_TO_BERRY(ITEM_ASPEAR_BERRY) - 1, ITEM_TO_BERRY(ITEM_RAWST_BERRY) - 1}, // player chose Chesto Berry + {ITEM_TO_BERRY(ITEM_CHESTO_BERRY) - 1, ITEM_TO_BERRY(ITEM_CHERI_BERRY) - 1, ITEM_TO_BERRY(ITEM_ASPEAR_BERRY) - 1}, // player chose Pecha Berry + {ITEM_TO_BERRY(ITEM_PECHA_BERRY) - 1, ITEM_TO_BERRY(ITEM_CHESTO_BERRY) - 1, ITEM_TO_BERRY(ITEM_CHERI_BERRY) - 1}, // player chose Rawst Berry + {ITEM_TO_BERRY(ITEM_RAWST_BERRY) - 1, ITEM_TO_BERRY(ITEM_PECHA_BERRY) - 1, ITEM_TO_BERRY(ITEM_CHESTO_BERRY) - 1}, // player chose Aspear Berry + + // These sets are used if the player chose a different berry (set is selected by player's berry % 5) + {ITEM_TO_BERRY(ITEM_CHERI_BERRY) - 1, ITEM_TO_BERRY(ITEM_PECHA_BERRY) - 1, ITEM_TO_BERRY(ITEM_RAWST_BERRY) - 1}, // player chose Leppa, Figy, ... + {ITEM_TO_BERRY(ITEM_CHESTO_BERRY) - 1, ITEM_TO_BERRY(ITEM_RAWST_BERRY) - 1, ITEM_TO_BERRY(ITEM_ASPEAR_BERRY) - 1}, // player chose Oran, Wiki, ... + {ITEM_TO_BERRY(ITEM_PECHA_BERRY) - 1, ITEM_TO_BERRY(ITEM_ASPEAR_BERRY) - 1, ITEM_TO_BERRY(ITEM_CHERI_BERRY) - 1}, // player chose Persim, Mago, ... + {ITEM_TO_BERRY(ITEM_RAWST_BERRY) - 1, ITEM_TO_BERRY(ITEM_CHERI_BERRY) - 1, ITEM_TO_BERRY(ITEM_CHESTO_BERRY) - 1}, // player chose Lum, Aguav, ... + {ITEM_TO_BERRY(ITEM_ASPEAR_BERRY) - 1, ITEM_TO_BERRY(ITEM_CHESTO_BERRY) - 1, ITEM_TO_BERRY(ITEM_PECHA_BERRY) - 1}, // player chose Sitrus, Iapapa, ... }; -static const u8 sSpecialOpponentBerrySets[] = {30, 31, 32, 33, 34}; +// Berry master's berries follow the same rules as above, but instead of explicitly listing +// the alternate sets if the player chooses one of these berries, it implicitly uses these berries - 5, i.e. Tamato - Nomel +static const u8 sBerryMasterBerries[] = { + ITEM_TO_BERRY(ITEM_SPELON_BERRY) - 1, + ITEM_TO_BERRY(ITEM_PAMTRE_BERRY) - 1, + ITEM_TO_BERRY(ITEM_WATMEL_BERRY) - 1, + ITEM_TO_BERRY(ITEM_DURIN_BERRY) - 1, + ITEM_TO_BERRY(ITEM_BELUE_BERRY) - 1 +}; -static const u8 sUnknown_08339CC3[] = {1, 1, 2, 3, 4}; +// "0 players" is link +static const u8 sNumPlayersToSpeedDivisor[] = {1, 1, 2, 3, 4}; -static const u8 sUnknown_08339CC8[] = {0x1C, 0x16, 0x13, 0x1A, 0x19, 0x0E, 0x0D, 0x0B, 0x07, 0x15}; +// Black pokeblocks will use one of these random combinations of flavors +static const u8 sBlackPokeblockFlavorFlags[] = { + (1 << FLAVOR_SOUR) | (1 << FLAVOR_BITTER) | (1 << FLAVOR_SWEET), + (1 << FLAVOR_SOUR) | (1 << FLAVOR_SWEET) | (1 << FLAVOR_DRY), + (1 << FLAVOR_SOUR) | (1 << FLAVOR_DRY) | (1 << FLAVOR_SPICY), + (1 << FLAVOR_SOUR) | (1 << FLAVOR_BITTER) | (1 << FLAVOR_DRY), + (1 << FLAVOR_SOUR) | (1 << FLAVOR_BITTER) | (1 << FLAVOR_SPICY), + (1 << FLAVOR_BITTER) | (1 << FLAVOR_SWEET) | (1 << FLAVOR_DRY), + (1 << FLAVOR_BITTER) | (1 << FLAVOR_SWEET) | (1 << FLAVOR_SPICY), + (1 << FLAVOR_BITTER) | (1 << FLAVOR_DRY) | (1 << FLAVOR_SPICY), + (1 << FLAVOR_SWEET) | (1 << FLAVOR_DRY) | (1 << FLAVOR_SPICY), + (1 << FLAVOR_SOUR) | (1 << FLAVOR_SWEET) | (1 << FLAVOR_SPICY), +}; -static const u8 sUnknown_08339CD2[] = +static const u8 sUnused[] = { 0xfe, 0x02, 0x02, 0xce, 0xd0, 0x37, 0x44, 0x07, 0x1f, 0x0c, 0x10, 0x00, 0xff, 0xfe, 0x91, 0x72, 0xce, 0xd0, 0x37, 0x44, 0x07, 0x1f, @@ -840,20 +931,18 @@ static const struct WindowTemplate sBlenderRecordWindowTemplate = .baseBlock = 8 }; -// code - -static void Blender_ControlHitPitch(void) +static void UpdateHitPitch(void) { - m4aMPlayPitchControl(&gMPlayInfo_SE2, 0xFFFF, 2 * (sBerryBlenderData->field_4C - 128)); + m4aMPlayPitchControl(&gMPlayInfo_SE2, 0xFFFF, 2 * (sBerryBlender->speed - MIN_ARROW_SPEED)); } -static void VBlankCB0_BerryBlender(void) +static void VBlankCB_BerryBlender(void) { - BerryBlender_SetBackgroundsPos(); - SetBgAffine(2, sBerryBlenderData->bgAffineSrc.texX, sBerryBlenderData->bgAffineSrc.texY, - sBerryBlenderData->bgAffineSrc.scrX, sBerryBlenderData->bgAffineSrc.scrY, - sBerryBlenderData->bgAffineSrc.sx, sBerryBlenderData->bgAffineSrc.sy, - sBerryBlenderData->bgAffineSrc.alpha); + SetBgPos(); + SetBgAffine(2, sBerryBlender->bgAffineSrc.texX, sBerryBlender->bgAffineSrc.texY, + sBerryBlender->bgAffineSrc.scrX, sBerryBlender->bgAffineSrc.scrY, + sBerryBlender->bgAffineSrc.sx, sBerryBlender->bgAffineSrc.sy, + sBerryBlender->bgAffineSrc.alpha); LoadOam(); ProcessSpriteCopyRequests(); TransferPlttBuffer(); @@ -861,64 +950,64 @@ static void VBlankCB0_BerryBlender(void) static bool8 LoadBerryBlenderGfx(void) { - switch (sBerryBlenderData->loadGfxState) + switch (sBerryBlender->loadGfxState) { case 0: - sBerryBlenderData->tilesBuffer = AllocZeroed(GetDecompressedDataSize(sBlenderCenterGfx) + 100); - LZDecompressWram(sBlenderCenterGfx, sBerryBlenderData->tilesBuffer); - sBerryBlenderData->loadGfxState++; + sBerryBlender->tilesBuffer = AllocZeroed(GetDecompressedDataSize(gBerryBlenderCenter_Gfx) + 100); + LZDecompressWram(gBerryBlenderCenter_Gfx, sBerryBlender->tilesBuffer); + sBerryBlender->loadGfxState++; break; case 1: - CopyToBgTilemapBuffer(2, sBlenderCenterMap, 0x400, 0); + CopyToBgTilemapBuffer(2, sBlenderCenter_Tilemap, 0x400, 0); CopyBgTilemapBufferToVram(2); - LoadPalette(sBlenderCenterPal, 0, 0x100); - sBerryBlenderData->loadGfxState++; + LoadPalette(sBlenderCenter_Pal, 0, 0x100); + sBerryBlender->loadGfxState++; break; case 2: - LoadBgTiles(2, sBerryBlenderData->tilesBuffer, GetDecompressedDataSize(sBlenderCenterGfx), 0); - sBerryBlenderData->loadGfxState++; + LoadBgTiles(2, sBerryBlender->tilesBuffer, GetDecompressedDataSize(gBerryBlenderCenter_Gfx), 0); + sBerryBlender->loadGfxState++; break; case 3: - LZDecompressWram(gUnknown_08D91DB8, sBerryBlenderData->tilesBuffer); - sBerryBlenderData->loadGfxState++; + LZDecompressWram(gBerryBlenderOuter_Gfx, sBerryBlender->tilesBuffer); + sBerryBlender->loadGfxState++; break; case 4: - LoadBgTiles(1, sBerryBlenderData->tilesBuffer, GetDecompressedDataSize(gUnknown_08D91DB8), 0); - sBerryBlenderData->loadGfxState++; + LoadBgTiles(1, sBerryBlender->tilesBuffer, GetDecompressedDataSize(gBerryBlenderOuter_Gfx), 0); + sBerryBlender->loadGfxState++; break; case 5: - LZDecompressWram(gUnknown_08D927EC, sBerryBlenderData->tilesBuffer); - sBerryBlenderData->loadGfxState++; + LZDecompressWram(gBerryBlenderOuter_Tilemap, sBerryBlender->tilesBuffer); + sBerryBlender->loadGfxState++; break; case 6: - CopyToBgTilemapBuffer(1, sBerryBlenderData->tilesBuffer, GetDecompressedDataSize(gUnknown_08D927EC), 0); + CopyToBgTilemapBuffer(1, sBerryBlender->tilesBuffer, GetDecompressedDataSize(gBerryBlenderOuter_Tilemap), 0); CopyBgTilemapBufferToVram(1); - sBerryBlenderData->loadGfxState++; + sBerryBlender->loadGfxState++; break; case 7: - LoadPalette(sBlenderOuterPal, 0x80, 0x20); - sBerryBlenderData->loadGfxState++; + LoadPalette(sBlenderOuter_Pal, 0x80, 0x20); + sBerryBlender->loadGfxState++; break; case 8: - LoadSpriteSheet(&sSpriteSheet_BlenderArrow); - LoadSpriteSheet(&sUnknown_08339BD8); - LoadSpriteSheet(&sUnknown_08339B38); - sBerryBlenderData->loadGfxState++; + LoadSpriteSheet(&sSpriteSheet_PlayerArrow); + LoadSpriteSheet(&sSpriteSheet_Particles); + LoadSpriteSheet(&sSpriteSheet_ScoreSymbols); + sBerryBlender->loadGfxState++; break; case 9: - LoadSpriteSheet(&sUnknown_08339C24); - LoadSpriteSheet(&sUnknown_08339C58); - LoadSpritePalette(&sSpritePal_BlenderArrow); + LoadSpriteSheet(&sSpriteSheet_CountdownNumbers); + LoadSpriteSheet(&sSpriteSheet_Start); + LoadSpritePalette(&sSpritePal_PlayerArrow); LoadSpritePalette(&sSpritePal_BlenderMisc); - Free(sBerryBlenderData->tilesBuffer); - sBerryBlenderData->loadGfxState = 0; + Free(sBerryBlender->tilesBuffer); + sBerryBlender->loadGfxState = 0; return TRUE; } return FALSE; } -static void sub_807F9D0(void) +static void DrawBlenderBg(void) { FillBgTilemapBufferRect_Palette0(0, 0, 0, 0, 0x1E, 0x14); CopyBgTilemapBufferToVram(0); @@ -933,7 +1022,7 @@ static void sub_807F9D0(void) static void InitBerryBlenderWindows(void) { - if (InitWindows(sBerryBlender_WindowTemplates)) + if (InitWindows(sWindowTemplates)) { s32 i; @@ -946,24 +1035,27 @@ static void InitBerryBlenderWindows(void) } } +// gSpecialVar_0x8004 is the number of NPC opponents +// Set to 0 indicates it's a link blender void DoBerryBlending(void) { - if (sBerryBlenderData == NULL) - sBerryBlenderData = AllocZeroed(sizeof(*sBerryBlenderData)); + if (sBerryBlender == NULL) + sBerryBlender = AllocZeroed(sizeof(*sBerryBlender)); - sBerryBlenderData->gameEndState = 0; - sBerryBlenderData->mainState = 0; - sBerryBlenderData->gameEndState = 0; + sBerryBlender->gameEndState = 0; + sBerryBlender->mainState = 0; + sBerryBlender->gameEndState = 0; - Blender_SetPlayerNamesLocal(gSpecialVar_0x8004); - SetMainCallback2(sub_807FAC8); + InitLocalPlayers(gSpecialVar_0x8004); + SetMainCallback2(CB2_LoadBerryBlender); } -static void sub_807FAC8(void) +// Show the blender screen initially and prompt to choose a berry +static void CB2_LoadBerryBlender(void) { s32 i; - switch (sBerryBlenderData->mainState) + switch (sBerryBlender->mainState) { case 0: SetGpuReg(REG_OFFSET_DISPCNT, 0); @@ -971,68 +1063,69 @@ static void sub_807FAC8(void) FreeAllSpritePalettes(); SetVBlankCallback(NULL); ResetBgsAndClearDma3BusyFlags(0); - InitBgsFromTemplates(1, sBerryBlenderBgTemplates, ARRAY_COUNT(sBerryBlenderBgTemplates)); - SetBgTilemapBuffer(1, sBerryBlenderData->tilemapBuffers[0]); - SetBgTilemapBuffer(2, sBerryBlenderData->tilemapBuffers[1]); + InitBgsFromTemplates(1, sBgTemplates, ARRAY_COUNT(sBgTemplates)); + SetBgTilemapBuffer(1, sBerryBlender->tilemapBuffers[0]); + SetBgTilemapBuffer(2, sBerryBlender->tilemapBuffers[1]); LoadUserWindowBorderGfx(0, 1, 0xD0); LoadMessageBoxGfx(0, 0x14, 0xF0); InitBerryBlenderWindows(); - sBerryBlenderData->mainState++; - sBerryBlenderData->field_118 = 0; - sBerryBlenderData->field_116 = 0; - sBerryBlenderData->field_11A = 0x50; - sBerryBlenderData->bg_X = 0; - sBerryBlenderData->bg_Y = 0; - sBerryBlenderData->loadGfxState = 0; + sBerryBlender->mainState++; + sBerryBlender->maxProgressBarValue = 0; + sBerryBlender->progressBarValue = 0; + sBerryBlender->centerScale = 80; + sBerryBlender->bg_X = 0; + sBerryBlender->bg_Y = 0; + sBerryBlender->loadGfxState = 0; - sub_8082D28(); + UpdateBlenderCenter(); break; case 1: if (LoadBerryBlenderGfx()) { for (i = 0; i < BLENDER_MAX_PLAYERS; i++) { - sBerryBlenderData->syncArrowSpriteIds[i] = CreateSprite(&sBlenderSyncArrow_SpriteTemplate, sBlenderSyncArrowsPos[i][0], sBlenderSyncArrowsPos[i][1], 1); - StartSpriteAnim(&gSprites[sBerryBlenderData->syncArrowSpriteIds[i]], i + 8); + sBerryBlender->playerArrowSpriteIds[i] = CreateSprite(&sSpriteTemplate_PlayerArrow, sPlayerArrowPos[i][0], sPlayerArrowPos[i][1], 1); + StartSpriteAnim(&gSprites[sBerryBlender->playerArrowSpriteIds[i]], i + 8); } - if (gReceivedRemoteLinkPlayers != 0 && gWirelessCommType) + if (gReceivedRemoteLinkPlayers && gWirelessCommType) { LoadWirelessStatusIndicatorSpriteGfx(); CreateWirelessStatusIndicatorSprite(0, 0); } - SetVBlankCallback(VBlankCB0_BerryBlender); - sBerryBlenderData->mainState++; + SetVBlankCallback(VBlankCB_BerryBlender); + sBerryBlender->mainState++; } break; case 2: BeginNormalPaletteFade(0xFFFFFFFF, 0, 0x10, 0, RGB_BLACK); - sub_8082D28(); - sBerryBlenderData->mainState++; + UpdateBlenderCenter(); + sBerryBlender->mainState++; break; case 3: - sub_807F9D0(); + DrawBlenderBg(); if (!gPaletteFade.active) - sBerryBlenderData->mainState++; + sBerryBlender->mainState++; break; case 4: - if (Blender_PrintText(&sBerryBlenderData->textState, sText_BerryBlenderStart, GetPlayerTextSpeedDelay())) - sBerryBlenderData->mainState++; + if (Blender_PrintText(&sBerryBlender->textState, sText_BerryBlenderStart, GetPlayerTextSpeedDelay())) + sBerryBlender->mainState++; break; case 5: BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 0x10, RGB_BLACK); - sBerryBlenderData->mainState++; + sBerryBlender->mainState++; break; case 6: if (!gPaletteFade.active) { + // Go to bag menu to choose berry, set callback to StartBlender FreeAllWindowBuffers(); UnsetBgTilemapBuffer(2); UnsetBgTilemapBuffer(1); SetVBlankCallback(NULL); - ChooseBerrySetCallback(sub_807FFA4); + ChooseBerryForMachine(StartBlender); - sBerryBlenderData->mainState = 0; + sBerryBlender->mainState = 0; } break; } @@ -1043,47 +1136,71 @@ static void sub_807FAC8(void) UpdatePaletteFade(); } -static void sub_807FD08(struct Sprite* sprite) +#define sTargetY data[0] +#define sX data[1] +#define sY data[2] +#define sBounceSpeed data[3] +#define sYUpSpeed data[4] +#define sBounces data[5] +#define sXSpeed data[6] +#define sYDownSpeed data[7] + +// For throwing berries into the machine +static void SpriteCB_Berry(struct Sprite* sprite) { - sprite->data[1] += sprite->data[6]; - sprite->data[2] -= sprite->data[4]; - sprite->data[2] += sprite->data[7]; - sprite->data[0] += sprite->data[7]; - sprite->data[4]--; + sprite->sX += sprite->sXSpeed; + sprite->sY -= sprite->sYUpSpeed; + sprite->sY += sprite->sYDownSpeed; + sprite->sTargetY += sprite->sYDownSpeed; + sprite->sYUpSpeed--; - if (sprite->data[0] < sprite->data[2]) + if (sprite->sTargetY < sprite->sY) { - sprite->data[3] = sprite->data[4] = sprite->data[3] - 1; + sprite->sBounceSpeed = sprite->sYUpSpeed = sprite->sBounceSpeed - 1; - if (++sprite->data[5] > 3) + if (++sprite->sBounces > 3) DestroySprite(sprite); else PlaySE(SE_BALL_TRAY_EXIT); } - sprite->pos1.x = sprite->data[1]; - sprite->pos1.y = sprite->data[2]; + sprite->pos1.x = sprite->sX; + sprite->pos1.y = sprite->sY; } -static void sub_807FD64(struct Sprite* sprite, s16 a2, s16 a3, s16 a4, s16 a5, s16 a6) +static void SetBerrySpriteData(struct Sprite* sprite, s16 x, s16 y, s16 bounceSpeed, s16 xSpeed, s16 ySpeed) { - sprite->data[0] = a3; - sprite->data[1] = a2; - sprite->data[2] = a3; - sprite->data[3] = a4; - sprite->data[4] = 10; - sprite->data[5] = 0; - sprite->data[6] = a5; - sprite->data[7] = a6; - sprite->callback = sub_807FD08; + sprite->sTargetY = y; + sprite->sX = x; + sprite->sY = y; + sprite->sBounceSpeed = bounceSpeed; + sprite->sYUpSpeed = 10; + sprite->sBounces = 0; + sprite->sXSpeed = xSpeed; + sprite->sYDownSpeed = ySpeed; + sprite->callback = SpriteCB_Berry; } -static void sub_807FD90(u16 a0, u8 a1) +#undef sTargetY +#undef sX +#undef sY +#undef sBounceSpeed +#undef sYUpSpeed +#undef sBounces +#undef sXSpeed +#undef sYDownSpeed + +static void CreateBerrySprite(u16 a0, u8 playerId) { - u8 spriteId = LoadSpinningBerryPicGfx(a0 + 123, 0, 80, a1 & 1); - sub_807FD64(&gSprites[spriteId], sUnknown_08339C78[a1][0], sUnknown_08339C78[a1][1], sUnknown_08339C78[a1][2], sUnknown_08339C78[a1][3], sUnknown_08339C78[a1][4]); + u8 spriteId = CreateSpinningBerrySprite(a0 + FIRST_BERRY_INDEX - 10, 0, 80, playerId & 1); + SetBerrySpriteData(&gSprites[spriteId], + sBerrySpriteData[playerId][0], + sBerrySpriteData[playerId][1], + sBerrySpriteData[playerId][2], + sBerrySpriteData[playerId][3], + sBerrySpriteData[playerId][4]); } -static void Blender_CopyBerryData(struct BlenderBerry* berry, u16 itemId) +static void ConvertItemToBlenderBerry(struct BlenderBerry* berry, u16 itemId) { const struct Berry *berryInfo = GetBerryInfo(ITEM_TO_BERRY(itemId)); @@ -1094,19 +1211,19 @@ static void Blender_CopyBerryData(struct BlenderBerry* berry, u16 itemId) berry->flavors[FLAVOR_SWEET] = berryInfo->sweet; berry->flavors[FLAVOR_BITTER] = berryInfo->bitter; berry->flavors[FLAVOR_SOUR] = berryInfo->sour; - berry->smoothness = berryInfo->smoothness; + berry->flavors[FLAVOR_COUNT] = berryInfo->smoothness; } -static void Blender_SetPlayerNamesLocal(u8 opponentsNum) +static void InitLocalPlayers(u8 opponentsNum) { switch (opponentsNum) { - case 0: + case 0: // Link games have 0 in-game opponents gInGameOpponentsNo = 0; break; case 1: gInGameOpponentsNo = 1; - sBerryBlenderData->playersNo = 2; + sBerryBlender->numPlayers = 2; StringCopy(gLinkPlayers[0].name, gSaveBlock2Ptr->playerName); if (!FlagGet(FLAG_HIDE_LILYCOVE_CONTEST_HALL_BLEND_MASTER)) @@ -1119,7 +1236,7 @@ static void Blender_SetPlayerNamesLocal(u8 opponentsNum) break; case 2: gInGameOpponentsNo = 2; - sBerryBlenderData->playersNo = 3; + sBerryBlender->numPlayers = 3; StringCopy(gLinkPlayers[0].name, gSaveBlock2Ptr->playerName); StringCopy(gLinkPlayers[1].name, sBlenderOpponentsNames[BLENDER_DUDE]); StringCopy(gLinkPlayers[2].name, sBlenderOpponentsNames[BLENDER_LASSIE]); @@ -1130,7 +1247,7 @@ static void Blender_SetPlayerNamesLocal(u8 opponentsNum) break; case 3: gInGameOpponentsNo = 3; - sBerryBlenderData->playersNo = 4; + sBerryBlender->numPlayers = 4; StringCopy(gLinkPlayers[0].name, gSaveBlock2Ptr->playerName); StringCopy(gLinkPlayers[1].name, sBlenderOpponentsNames[BLENDER_MISS]); StringCopy(gLinkPlayers[2].name, sBlenderOpponentsNames[BLENDER_LADDIE]); @@ -1144,94 +1261,95 @@ static void Blender_SetPlayerNamesLocal(u8 opponentsNum) } } -static void sub_807FFA4(void) +static void StartBlender(void) { s32 i; SetGpuReg(REG_OFFSET_DISPCNT, 0); - if (sBerryBlenderData == NULL) - sBerryBlenderData = AllocZeroed(sizeof(*sBerryBlenderData)); + if (sBerryBlender == NULL) + sBerryBlender = AllocZeroed(sizeof(*sBerryBlender)); - sBerryBlenderData->mainState = 0; - sBerryBlenderData->field_10C = 0; + sBerryBlender->mainState = 0; + sBerryBlender->unk1 = 0; for (i = 0; i < BLENDER_MAX_PLAYERS; i++) - sBerryBlenderData->chosenItemId[i] = ITEM_NONE; + sBerryBlender->chosenItemId[i] = ITEM_NONE; - Blender_SetPlayerNamesLocal(gSpecialVar_0x8004); + InitLocalPlayers(gSpecialVar_0x8004); if (gSpecialVar_0x8004 == 0) - SetMainCallback2(sub_8080018); + SetMainCallback2(CB2_StartBlenderLink); else - SetMainCallback2(sub_80808D4); + SetMainCallback2(CB2_StartBlenderLocal); } -static void sub_8080018(void) +static void CB2_StartBlenderLink(void) { s32 i, j; - switch (sBerryBlenderData->mainState) + switch (sBerryBlender->mainState) { case 0: - sub_8080588(); + InitBlenderBgs(); gLinkType = LINKTYPE_BERRY_BLENDER; - sBerryBlenderData->field_72 = 0; + sBerryBlender->slowdownTimer = 0; for (i = 0; i < BLENDER_MAX_PLAYERS; i++) { - sBerryBlenderData->field_64[i] = 0; - for (j = 0; j < 3; j++) + sBerryBlender->playerContinueResponses[i] = 0; + for (j = 0; j < NUM_SCORE_TYPES; j++) { - sBerryBlenderData->scores[i][j] = 0; + sBerryBlender->scores[i][j] = 0; } } - sBerryBlenderData->playAgainState = 0; - sBerryBlenderData->max_RPM = 0; - sBerryBlenderData->loadGfxState = 0; - sBerryBlenderData->mainState++; + sBerryBlender->playAgainState = 0; + sBerryBlender->maxRPM = 0; + sBerryBlender->loadGfxState = 0; + sBerryBlender->mainState++; break; case 1: if (LoadBerryBlenderGfx()) { - sBerryBlenderData->mainState++; - sub_8082D28(); + sBerryBlender->mainState++; + UpdateBlenderCenter(); } break; case 2: for (i = 0; i < BLENDER_MAX_PLAYERS; i++) { - sBerryBlenderData->syncArrowSprite2Ids[i] = CreateSprite(&sBlenderSyncArrow_SpriteTemplate, sBlenderSyncArrowsPos[i][0], sBlenderSyncArrowsPos[i][1], 1); - StartSpriteAnim(&gSprites[sBerryBlenderData->syncArrowSprite2Ids[i]], i + 8); + sBerryBlender->playerArrowSpriteIds2[i] = CreateSprite(&sSpriteTemplate_PlayerArrow, sPlayerArrowPos[i][0], sPlayerArrowPos[i][1], 1); + StartSpriteAnim(&gSprites[sBerryBlender->playerArrowSpriteIds2[i]], i + 8); } - if (gReceivedRemoteLinkPlayers != 0 && gWirelessCommType) + if (gReceivedRemoteLinkPlayers && gWirelessCommType) { LoadWirelessStatusIndicatorSpriteGfx(); CreateWirelessStatusIndicatorSprite(0, 0); } - sBerryBlenderData->mainState++; + sBerryBlender->mainState++; break; case 3: BeginNormalPaletteFade(0xFFFFFFFF, 0, 0x10, 0, RGB_BLACK); - sBerryBlenderData->mainState++; + sBerryBlender->mainState++; break; case 4: - sub_807F9D0(); + DrawBlenderBg(); if (!gPaletteFade.active) { - sBerryBlenderData->mainState++; + sBerryBlender->mainState++; } break; case 5: - Blender_PrintText(&sBerryBlenderData->textState, sText_CommunicationStandby, 0); - sBerryBlenderData->mainState = 8; - sBerryBlenderData->framesToWait = 0; + Blender_PrintText(&sBerryBlender->textState, sText_CommunicationStandby, 0); + sBerryBlender->mainState = 8; + sBerryBlender->framesToWait = 0; break; case 8: - sBerryBlenderData->mainState++; - sBerryBlenderData->field_114 = 0; - Blender_CopyBerryData(&sBerryBlenderData->blendedBerries[0], gSpecialVar_ItemId); - memcpy(gBlockSendBuffer, &sBerryBlenderData->blendedBerries[0], sizeof(struct BlenderBerry)); + // Send berry choice to link partners + sBerryBlender->mainState++; + sBerryBlender->playerToThrowBerry = 0; + ConvertItemToBlenderBerry(&sBerryBlender->blendedBerries[0], gSpecialVar_ItemId); + memcpy(gBlockSendBuffer, &sBerryBlender->blendedBerries[0], sizeof(struct BlenderBerry)); SetLinkStandbyCallback(); - sBerryBlenderData->framesToWait = 0; + sBerryBlender->framesToWait = 0; break; case 9: if (IsLinkTaskFinished()) @@ -1239,122 +1357,130 @@ static void sub_8080018(void) ResetBlockReceivedFlags(); if (GetMultiplayerId() == 0) SendBlockRequest(4); - sBerryBlenderData->mainState++; + sBerryBlender->mainState++; } break; case 10: - if (++sBerryBlenderData->framesToWait > 20) + if (++sBerryBlender->framesToWait > 20) { + // Wait for partners' berries ClearDialogWindowAndFrameToTransparent(4, TRUE); if (GetBlockReceivedStatus() == GetLinkPlayerCountAsBitFlags()) { for (i = 0; i < GetLinkPlayerCount(); i++) { - memcpy(&sBerryBlenderData->blendedBerries[i], &gBlockRecvBuffer[i][0], sizeof(struct BlenderBerry)); - sBerryBlenderData->chosenItemId[i] = sBerryBlenderData->blendedBerries[i].itemId; + memcpy(&sBerryBlender->blendedBerries[i], &gBlockRecvBuffer[i][0], sizeof(struct BlenderBerry)); + sBerryBlender->chosenItemId[i] = sBerryBlender->blendedBerries[i].itemId; } ResetBlockReceivedFlags(); - sBerryBlenderData->mainState++; + sBerryBlender->mainState++; } } break; case 11: - sBerryBlenderData->playersNo = GetLinkPlayerCount(); + sBerryBlender->numPlayers = GetLinkPlayerCount(); + // Throw 1 player's berry in for (i = 0; i < BLENDER_MAX_PLAYERS; i++) { - if (sBerryBlenderData->field_114 == sUnknown_083399D0[sBerryBlenderData->playersNo - 2][i]) + if (sBerryBlender->playerToThrowBerry == sPlayerIdMap[sBerryBlender->numPlayers - 2][i]) { - sub_807FD90(sBerryBlenderData->chosenItemId[sBerryBlenderData->field_114], i); + CreateBerrySprite(sBerryBlender->chosenItemId[sBerryBlender->playerToThrowBerry], i); break; } } - sBerryBlenderData->framesToWait = 0; - sBerryBlenderData->mainState++; - sBerryBlenderData->field_114++; + sBerryBlender->framesToWait = 0; + sBerryBlender->mainState++; + sBerryBlender->playerToThrowBerry++; break; case 12: - if (++sBerryBlenderData->framesToWait > 60) + if (++sBerryBlender->framesToWait > 60) { - if (sBerryBlenderData->field_114 >= sBerryBlenderData->playersNo) + if (sBerryBlender->playerToThrowBerry >= sBerryBlender->numPlayers) { - sBerryBlenderData->mainState++; - sBerryBlenderData->arrowPos = sUnknown_083399DC[sUnknown_083399E4[sBerryBlenderData->playersNo - 2]] - 22528; + // Finished throwing berries in + sBerryBlender->mainState++; + sBerryBlender->arrowPos = sArrowStartPos[sArrowStartPosIds[sBerryBlender->numPlayers - 2]] - ARROW_FALL_ROTATION; } else { - sBerryBlenderData->mainState--; + // Haven't finished throwing berries in, go back to prev step + sBerryBlender->mainState--; } - sBerryBlenderData->framesToWait = 0; + sBerryBlender->framesToWait = 0; } break; case 13: if (IsLinkTaskFinished()) { - sBerryBlenderData->mainState++; - sub_8082CB4(&sBerryBlenderData->bgAffineSrc); + sBerryBlender->mainState++; + DrawBlenderCenter(&sBerryBlender->bgAffineSrc); PlaySE(SE_FALL); ShowBg(2); } break; case 14: SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_BG2_ON); - sBerryBlenderData->arrowPos += 0x200; - sBerryBlenderData->field_11A += 4; - if (sBerryBlenderData->field_11A > 0xFF) + sBerryBlender->arrowPos += 0x200; + sBerryBlender->centerScale += 4; + if (sBerryBlender->centerScale > 255) { SetGpuRegBits(REG_OFFSET_BG2CNT, 2); - sBerryBlenderData->mainState++; - sBerryBlenderData->field_11A = 0x100; - sBerryBlenderData->arrowPos = sUnknown_083399DC[sUnknown_083399E4[sBerryBlenderData->playersNo - 2]]; - sBerryBlenderData->framesToWait = 0; + sBerryBlender->mainState++; + sBerryBlender->centerScale = 256; + sBerryBlender->arrowPos = sArrowStartPos[sArrowStartPosIds[sBerryBlender->numPlayers - 2]]; + sBerryBlender->framesToWait = 0; PlaySE(SE_TRUCK_DOOR); - sub_808074C(); - Blender_PrintPlayerNames(); + SetPlayerIdMaps(); + PrintPlayerNames(); } - sub_8082CB4(&sBerryBlenderData->bgAffineSrc); + DrawBlenderCenter(&sBerryBlender->bgAffineSrc); break; case 15: - if (sub_8083380()) + if (UpdateBlenderLandScreenShake()) { - sBerryBlenderData->framesToWait = 0; - sBerryBlenderData->mainState++; + sBerryBlender->framesToWait = 0; + sBerryBlender->mainState++; } - sub_8082CB4(&sBerryBlenderData->bgAffineSrc); + DrawBlenderCenter(&sBerryBlender->bgAffineSrc); break; case 16: - CreateSprite(&sUnknown_08339C2C, 120, -16, 3); - sBerryBlenderData->mainState++; + CreateSprite(&sSpriteTemplate_CountdownNumbers, 120, -16, 3); + sBerryBlender->mainState++; + break; + case 17: + // Wait here for the countdown + // State is progressed in SpriteCB_Start break; case 18: - sBerryBlenderData->mainState++; + sBerryBlender->mainState++; break; case 19: SetLinkStandbyCallback(); - sBerryBlenderData->mainState++; + sBerryBlender->mainState++; break; case 20: if (IsLinkTaskFinished()) { - sub_800A418(); - sBerryBlenderData->mainState++; + SetBerryBlenderLinkCallback(); + sBerryBlender->mainState++; } break; case 21: - sBerryBlenderData->field_4C = 128; - sBerryBlenderData->gameFrameTime = 0; - SetMainCallback2(sub_8081898); + sBerryBlender->speed = MIN_ARROW_SPEED; + sBerryBlender->gameFrameTime = 0; + SetMainCallback2(CB2_PlayBlender); if (GetCurrentMapMusic() != MUS_CYCLING) { - sBerryBlenderData->field_154 = GetCurrentMapMusic(); + sBerryBlender->savedMusic = GetCurrentMapMusic(); } PlayBGM(MUS_CYCLING); break; } - Blender_DummiedOutFunc(sBerryBlenderData->bg_X, sBerryBlenderData->bg_Y); + Blender_DummiedOutFunc(sBerryBlender->bg_X, sBerryBlender->bg_Y); RunTasks(); AnimateSprites(); BuildOamBuffer(); @@ -1362,7 +1488,7 @@ static void sub_8080018(void) UpdatePaletteFade(); } -static void sub_8080588(void) +static void InitBlenderBgs(void) { SetGpuReg(REG_OFFSET_DISPCNT, 0); @@ -1370,47 +1496,47 @@ static void sub_8080588(void) FreeAllSpritePalettes(); ResetTasks(); - SetVBlankCallback(VBlankCB0_BerryBlender); + SetVBlankCallback(VBlankCB_BerryBlender); ResetBgsAndClearDma3BusyFlags(0); - InitBgsFromTemplates(1, sBerryBlenderBgTemplates, ARRAY_COUNT(sBerryBlenderBgTemplates)); + InitBgsFromTemplates(1, sBgTemplates, ARRAY_COUNT(sBgTemplates)); - SetBgTilemapBuffer(1, sBerryBlenderData->tilemapBuffers[0]); - SetBgTilemapBuffer(2, sBerryBlenderData->tilemapBuffers[1]); + SetBgTilemapBuffer(1, sBerryBlender->tilemapBuffers[0]); + SetBgTilemapBuffer(2, sBerryBlender->tilemapBuffers[1]); LoadUserWindowBorderGfx(0, 1, 0xD0); LoadMessageBoxGfx(0, 0x14, 0xF0); InitBerryBlenderWindows(); - sBerryBlenderData->field_44 = 0; - sBerryBlenderData->field_4C = 0; - sBerryBlenderData->arrowPos = 0; - sBerryBlenderData->max_RPM = 0; - sBerryBlenderData->bg_X = 0; - sBerryBlenderData->bg_Y = 0; + sBerryBlender->unk0 = 0; + sBerryBlender->speed = 0; + sBerryBlender->arrowPos = 0; + sBerryBlender->maxRPM = 0; + sBerryBlender->bg_X = 0; + sBerryBlender->bg_Y = 0; } -static u8 sub_8080624(u16 arrowPos, u8 playerId) +static u8 GetArrowProximity(u16 arrowPos, u8 playerId) { - u32 var1 = (arrowPos / 0x100) + 0x18; - u8 arrID = sBerryBlenderData->field_96[playerId]; - u32 var2 = sUnknown_083399E7[arrID]; + u32 pos = (arrowPos / 256) + 24; + u8 arrowId = sBerryBlender->playerIdToArrowId[playerId]; + u32 hitRangeStart = sArrowHitRangeStart[arrowId]; - if (var1 >= var2 && var1 < var2 + 0x30) + if (pos >= hitRangeStart && pos < hitRangeStart + 48) { - if (var1 >= var2 + 20 && var1 < var2 + 28) - return 2; + if (pos >= hitRangeStart + 20 && pos < hitRangeStart + 28) + return PROXIMITY_BEST; else - return 1; + return PROXIMITY_GOOD; } - return 0; + return PROXIMITY_MISS; } -static void Blender_SetOpponentsBerryData(u16 playerBerryItemId, u8 playersNum, struct BlenderBerry* playerBerry) +static void SetOpponentsBerryData(u16 playerBerryItemId, u8 playersNum, struct BlenderBerry* playerBerry) { u16 opponentSetId = 0; u16 opponentBerryId; - u16 var; + u16 berryMasterDiff; u16 i; if (playerBerryItemId == ITEM_ENIGMA_BERRY) @@ -1420,70 +1546,73 @@ static void Blender_SetOpponentsBerryData(u16 playerBerryItemId, u8 playersNum, if (playerBerry->flavors[opponentSetId] > playerBerry->flavors[i]) opponentSetId = i; } - opponentSetId += 5; + opponentSetId += NUM_NPC_BERRIES; } else { - opponentSetId = playerBerryItemId - FIRST_BERRY_INDEX; - if (opponentSetId >= 5) - opponentSetId = (opponentSetId % 5) + 5; + opponentSetId = ITEM_TO_BERRY(playerBerryItemId) - 1; + if (opponentSetId >= NUM_NPC_BERRIES) + opponentSetId = (opponentSetId % NUM_NPC_BERRIES) + NUM_NPC_BERRIES; } for (i = 0; i < playersNum - 1; i++) { opponentBerryId = sOpponentBerrySets[opponentSetId][i]; - var = playerBerryItemId - 163; + berryMasterDiff = ITEM_TO_BERRY(playerBerryItemId) - ITEM_TO_BERRY(ITEM_SPELON_BERRY); if (!FlagGet(FLAG_HIDE_LILYCOVE_CONTEST_HALL_BLEND_MASTER) && gSpecialVar_0x8004 == 1) { - opponentSetId %= 5; - opponentBerryId = sSpecialOpponentBerrySets[opponentSetId]; - if (var <= 4) - opponentBerryId -= 5; + opponentSetId %= ARRAY_COUNT(sBerryMasterBerries); + opponentBerryId = sBerryMasterBerries[opponentSetId]; + + // If the player's berry is any of the Berry Master's berries, + // then use the next lower set of berries + if (berryMasterDiff < ARRAY_COUNT(sBerryMasterBerries)) + opponentBerryId -= ARRAY_COUNT(sBerryMasterBerries); } - Blender_SetParticipantBerryData(i + 1, opponentBerryId + FIRST_BERRY_INDEX); + SetPlayerBerryData(i + 1, opponentBerryId + FIRST_BERRY_INDEX); } } -static void sub_808074C(void) +static void SetPlayerIdMaps(void) { s32 i, j; for (i = 0; i < BLENDER_MAX_PLAYERS; i++) { - sBerryBlenderData->field_96[i] = 0xFF; - sBerryBlenderData->field_8E[i] = sUnknown_083399D0[sBerryBlenderData->playersNo - 2][i]; + sBerryBlender->playerIdToArrowId[i] = NO_PLAYER; + sBerryBlender->arrowIdToPlayerId[i] = sPlayerIdMap[sBerryBlender->numPlayers - 2][i]; } for (j = 0; j < BLENDER_MAX_PLAYERS; j++) { for (i = 0; i < BLENDER_MAX_PLAYERS; i++) { - if (sBerryBlenderData->field_8E[i] == j) - sBerryBlenderData->field_96[j] = i; + if (sBerryBlender->arrowIdToPlayerId[i] == j) + sBerryBlender->playerIdToArrowId[j] = i; } } } -static void Blender_PrintPlayerNames(void) +static void PrintPlayerNames(void) { s32 i, xPos; - u32 multiplayerId = 0; + u32 playerId = 0; u8 text[20]; if (gReceivedRemoteLinkPlayers) - multiplayerId = GetMultiplayerId(); + playerId = GetMultiplayerId(); for (i = 0; i < BLENDER_MAX_PLAYERS; i++) { - if (sBerryBlenderData->field_8E[i] != 0xFF) + if (sBerryBlender->arrowIdToPlayerId[i] != NO_PLAYER) { - sBerryBlenderData->syncArrowSpriteIds[sBerryBlenderData->field_8E[i]] = sBerryBlenderData->syncArrowSprite2Ids[i]; - StartSpriteAnim(&gSprites[sBerryBlenderData->syncArrowSpriteIds[sBerryBlenderData->field_8E[i]]], i); + sBerryBlender->playerArrowSpriteIds[sBerryBlender->arrowIdToPlayerId[i]] = sBerryBlender->playerArrowSpriteIds2[i]; + StartSpriteAnim(&gSprites[sBerryBlender->playerArrowSpriteIds[sBerryBlender->arrowIdToPlayerId[i]]], i); text[0] = EOS; - StringCopy(text, gLinkPlayers[sBerryBlenderData->field_8E[i]].name); + StringCopy(text, gLinkPlayers[sBerryBlender->arrowIdToPlayerId[i]].name); xPos = GetStringCenterAlignXOffset(1, text, 0x38); - if (multiplayerId == sBerryBlenderData->field_8E[i]) - Blender_AddTextPrinter(i, text, xPos, 1, 0, 2); + if (playerId == sBerryBlender->arrowIdToPlayerId[i]) + Blender_AddTextPrinter(i, text, xPos, 1, 0, 2); // Highlight player's name in red else Blender_AddTextPrinter(i, text, xPos, 1, 0, 1); @@ -1493,167 +1622,174 @@ static void Blender_PrintPlayerNames(void) } } -static void sub_80808D4(void) +static void CB2_StartBlenderLocal(void) { s32 i, j; - switch (sBerryBlenderData->mainState) + switch (sBerryBlender->mainState) { case 0: SetWirelessCommType0(); - sub_8080588(); - Blender_SetParticipantBerryData(0, gSpecialVar_ItemId); - Blender_CopyBerryData(&sBerryBlenderData->blendedBerries[0], gSpecialVar_ItemId); - Blender_SetOpponentsBerryData(gSpecialVar_ItemId, sBerryBlenderData->playersNo, &sBerryBlenderData->blendedBerries[0]); + InitBlenderBgs(); + SetPlayerBerryData(0, gSpecialVar_ItemId); + ConvertItemToBlenderBerry(&sBerryBlender->blendedBerries[0], gSpecialVar_ItemId); + SetOpponentsBerryData(gSpecialVar_ItemId, sBerryBlender->numPlayers, &sBerryBlender->blendedBerries[0]); for (i = 0; i < BLENDER_MAX_PLAYERS; i++) { - sBerryBlenderData->field_64[i] = 0; - for (j = 0; j < 3; j++) + sBerryBlender->playerContinueResponses[i] = 0; + for (j = 0; j < NUM_SCORE_TYPES; j++) { - sBerryBlenderData->scores[i][j] = 0; + sBerryBlender->scores[i][j] = 0; } } - sBerryBlenderData->playAgainState = 0; - sBerryBlenderData->loadGfxState = 0; + sBerryBlender->playAgainState = 0; + sBerryBlender->loadGfxState = 0; gLinkType = LINKTYPE_BERRY_BLENDER; - sBerryBlenderData->mainState++; + sBerryBlender->mainState++; break; case 1: if (LoadBerryBlenderGfx()) { - sBerryBlenderData->mainState++; - sub_8082D28(); + sBerryBlender->mainState++; + UpdateBlenderCenter(); } break; case 2: for (i = 0; i < BLENDER_MAX_PLAYERS; i++) { - sBerryBlenderData->syncArrowSprite2Ids[i] = CreateSprite(&sBlenderSyncArrow_SpriteTemplate, sBlenderSyncArrowsPos[i][0], sBlenderSyncArrowsPos[i][1], 1); - StartSpriteAnim(&gSprites[sBerryBlenderData->syncArrowSprite2Ids[i]], i + 8); + sBerryBlender->playerArrowSpriteIds2[i] = CreateSprite(&sSpriteTemplate_PlayerArrow, sPlayerArrowPos[i][0], sPlayerArrowPos[i][1], 1); + StartSpriteAnim(&gSprites[sBerryBlender->playerArrowSpriteIds2[i]], i + 8); } - sBerryBlenderData->mainState++; + sBerryBlender->mainState++; break; case 3: BeginNormalPaletteFade(0xFFFFFFFF, 0, 0x10, 0, RGB_BLACK); - sBerryBlenderData->mainState++; - sBerryBlenderData->framesToWait = 0; + sBerryBlender->mainState++; + sBerryBlender->framesToWait = 0; break; case 4: - if (++sBerryBlenderData->framesToWait == 2) - sub_807F9D0(); + if (++sBerryBlender->framesToWait == 2) + DrawBlenderBg(); if (!gPaletteFade.active) - sBerryBlenderData->mainState = 8; + sBerryBlender->mainState = 8; break; case 8: - sBerryBlenderData->mainState = 11; - sBerryBlenderData->field_114 = 0; + sBerryBlender->mainState = 11; + sBerryBlender->playerToThrowBerry = 0; break; case 11: for (i = 0; i < BLENDER_MAX_PLAYERS; i++) { - u32 var = sUnknown_083399D0[sBerryBlenderData->playersNo - 2][i]; - if (sBerryBlenderData->field_114 == var) + // Throw 1 player's berry in + u32 playerId = sPlayerIdMap[sBerryBlender->numPlayers - 2][i]; + if (sBerryBlender->playerToThrowBerry == playerId) { - sub_807FD90(sBerryBlenderData->chosenItemId[sBerryBlenderData->field_114], i); + CreateBerrySprite(sBerryBlender->chosenItemId[sBerryBlender->playerToThrowBerry], i); break; } } - sBerryBlenderData->framesToWait = 0; - sBerryBlenderData->mainState++; - sBerryBlenderData->field_114++; + sBerryBlender->framesToWait = 0; + sBerryBlender->mainState++; + sBerryBlender->playerToThrowBerry++; break; case 12: - if (++sBerryBlenderData->framesToWait > 60) + if (++sBerryBlender->framesToWait > 60) { - if (sBerryBlenderData->field_114 >= sBerryBlenderData->playersNo) + if (sBerryBlender->playerToThrowBerry >= sBerryBlender->numPlayers) { - sBerryBlenderData->arrowPos = sUnknown_083399DC[sUnknown_083399E4[sBerryBlenderData->playersNo - 2]] - 22528; - sBerryBlenderData->mainState++; + // Finished throwing berries in + sBerryBlender->arrowPos = sArrowStartPos[sArrowStartPosIds[sBerryBlender->numPlayers - 2]] - ARROW_FALL_ROTATION; + sBerryBlender->mainState++; } else { - sBerryBlenderData->mainState--; + // Haven't finished throwing berries in, go back to prev step + sBerryBlender->mainState--; } - sBerryBlenderData->framesToWait = 0; + sBerryBlender->framesToWait = 0; } break; case 13: - sBerryBlenderData->mainState++; - sub_808074C(); + sBerryBlender->mainState++; + SetPlayerIdMaps(); PlaySE(SE_FALL); - sub_8082CB4(&sBerryBlenderData->bgAffineSrc); + DrawBlenderCenter(&sBerryBlender->bgAffineSrc); ShowBg(2); break; case 14: SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_BG2_ON); - sBerryBlenderData->arrowPos += 0x200; - sBerryBlenderData->field_11A += 4; - if (sBerryBlenderData->field_11A > 0xFF) + sBerryBlender->arrowPos += 0x200; + sBerryBlender->centerScale += 4; + if (sBerryBlender->centerScale > 255) { - sBerryBlenderData->mainState++; - sBerryBlenderData->field_11A = 0x100; - sBerryBlenderData->arrowPos = sUnknown_083399DC[sUnknown_083399E4[sBerryBlenderData->playersNo - 2]]; + sBerryBlender->mainState++; + sBerryBlender->centerScale = 256; + sBerryBlender->arrowPos = sArrowStartPos[sArrowStartPosIds[sBerryBlender->numPlayers - 2]]; SetGpuRegBits(REG_OFFSET_BG2CNT, 2); - sBerryBlenderData->framesToWait = 0; + sBerryBlender->framesToWait = 0; PlaySE(SE_TRUCK_DOOR); - Blender_PrintPlayerNames(); + PrintPlayerNames(); } - sub_8082CB4(&sBerryBlenderData->bgAffineSrc); + DrawBlenderCenter(&sBerryBlender->bgAffineSrc); break; case 15: - if (sub_8083380()) + if (UpdateBlenderLandScreenShake()) { - sBerryBlenderData->mainState++; + sBerryBlender->mainState++; } - sub_8082CB4(&sBerryBlenderData->bgAffineSrc); + DrawBlenderCenter(&sBerryBlender->bgAffineSrc); break; case 16: - CreateSprite(&sUnknown_08339C2C, 120, -16, 3); - sBerryBlenderData->mainState++; + CreateSprite(&sSpriteTemplate_CountdownNumbers, 120, -16, 3); + sBerryBlender->mainState++; + break; + case 17: + // Wait here for the countdown + // State is progressed in SpriteCB_Start break; case 18: - sBerryBlenderData->mainState++; + sBerryBlender->mainState++; break; case 19: - sBerryBlenderData->mainState++; + sBerryBlender->mainState++; break; case 20: - sBerryBlenderData->mainState++; + sBerryBlender->mainState++; break; case 21: - sub_8080DF8(); - sBerryBlenderData->field_4C = 0x80; - sBerryBlenderData->gameFrameTime = 0; - sBerryBlenderData->field_123 = 0; - sBerryBlenderData->field_72 = 0; - SetMainCallback2(sub_8081898); + ResetLinkCmds(); + sBerryBlender->speed = MIN_ARROW_SPEED; + sBerryBlender->gameFrameTime = 0; + sBerryBlender->perfectOpponents = FALSE; + sBerryBlender->slowdownTimer = 0; + SetMainCallback2(CB2_PlayBlender); if (gSpecialVar_0x8004 == 1) { if (!FlagGet(FLAG_HIDE_LILYCOVE_CONTEST_HALL_BLEND_MASTER)) - sBerryBlenderData->field_120[0] = CreateTask(sub_8081224, 10); + sBerryBlender->opponentTaskIds[0] = CreateTask(Task_HandleBerryMaster, 10); else - sBerryBlenderData->field_120[0] = CreateTask(sUnknown_083399EC[0], 10); + sBerryBlender->opponentTaskIds[0] = CreateTask(sLocalOpponentTasks[0], 10); } if (gSpecialVar_0x8004 > 1) { for (i = 0; i < gSpecialVar_0x8004; i++) - sBerryBlenderData->field_120[i] = CreateTask(sUnknown_083399EC[i], 10 + i); + sBerryBlender->opponentTaskIds[i] = CreateTask(sLocalOpponentTasks[i], 10 + i); } if (GetCurrentMapMusic() != MUS_CYCLING) - sBerryBlenderData->field_154 = GetCurrentMapMusic(); + sBerryBlender->savedMusic = GetCurrentMapMusic(); PlayBGM(MUS_CYCLING); PlaySE(SE_BERRY_BLENDER); - Blender_ControlHitPitch(); + UpdateHitPitch(); break; } - Blender_DummiedOutFunc(sBerryBlenderData->bg_X, sBerryBlenderData->bg_Y); + Blender_DummiedOutFunc(sBerryBlender->bg_X, sBerryBlender->bg_Y); RunTasks(); AnimateSprites(); BuildOamBuffer(); @@ -1661,410 +1797,433 @@ static void sub_80808D4(void) UpdatePaletteFade(); } -static void sub_8080DF8(void) +static void ResetLinkCmds(void) { s32 i; - for (i = 0; i < CMD_LENGTH / 2; i++) + for (i = 0; i < BLENDER_MAX_PLAYERS; i++) { - gSendCmd[0] = 0; - gSendCmd[2] = 0; - gRecvCmds[i][0] = 0; - gRecvCmds[i][2] = 0; + gSendCmd[BLENDER_COMM_INPUT_STATE] = 0; + gSendCmd[BLENDER_COMM_SCORE] = 0; + gRecvCmds[i][BLENDER_COMM_INPUT_STATE] = 0; + gRecvCmds[i][BLENDER_COMM_SCORE] = 0; } } -static void sub_8080E20(u8 taskId) +#define tTimer data[0] +#define tDelay data[1] +#define tPlayerId data[2] + +static void Task_OpponentMiss(u8 taskId) { - if(++gTasks[taskId].data[0] > gTasks[taskId].data[1]) + if(++gTasks[taskId].tTimer > gTasks[taskId].tDelay) { - gRecvCmds[gTasks[taskId].data[2]][2] = 0x2345; + gRecvCmds[gTasks[taskId].tPlayerId][BLENDER_COMM_SCORE] = LINKCMD_BLENDER_SCORE_MISS; DestroyTask(taskId); } } -static void sub_8080E6C(u8 a0, u8 a1) +static void CreateOpponentMissTask(u8 playerId, u8 delay) { - u8 taskId = CreateTask(sub_8080E20, 80); - gTasks[taskId].data[1] = a1; - gTasks[taskId].data[2] = a0; + u8 taskId = CreateTask(Task_OpponentMiss, 80); + gTasks[taskId].tDelay = delay; + gTasks[taskId].tPlayerId = playerId; } -static void sub_8080EA4(u8 taskId) +#undef tTimer +#undef tDelay +#undef tPlayerId + +#define tDidInput data[0] + +static void Task_HandleOpponent1(u8 taskId) { - if (sub_8080624(sBerryBlenderData->arrowPos, 1) == 2) + if (GetArrowProximity(sBerryBlender->arrowPos, 1) == PROXIMITY_BEST) { - if (gTasks[taskId].data[0] == 0) + if (!gTasks[taskId].tDidInput) { - if (sBerryBlenderData->field_123 == 0) + if (!sBerryBlender->perfectOpponents) { u8 rand = Random() / 655; - if (sBerryBlenderData->field_4C < 500) + if (sBerryBlender->speed < 500) { if (rand > 75) - gRecvCmds[1][2] = 0x4523; + gRecvCmds[1][BLENDER_COMM_SCORE] = LINKCMD_BLENDER_SCORE_BEST; else - gRecvCmds[1][2] = 0x5432; + gRecvCmds[1][BLENDER_COMM_SCORE] = LINKCMD_BLENDER_SCORE_GOOD; - gRecvCmds[1][2] = 0x5432; + // BUG: Overrwrote above assignment. Opponent 1 can't get Best at low speed + gRecvCmds[1][BLENDER_COMM_SCORE] = LINKCMD_BLENDER_SCORE_GOOD; } - else if (sBerryBlenderData->field_4C < 1500) + else if (sBerryBlender->speed < 1500) { if (rand > 80) { - gRecvCmds[1][2] = 0x4523; + gRecvCmds[1][BLENDER_COMM_SCORE] = LINKCMD_BLENDER_SCORE_BEST; } else { u8 value = rand - 21; if (value < 60) - gRecvCmds[1][2] = 0x5432; + gRecvCmds[1][BLENDER_COMM_SCORE] = LINKCMD_BLENDER_SCORE_GOOD; else if (rand < 10) - sub_8080E6C(1, 5); + CreateOpponentMissTask(1, 5); } } else if (rand <= 90) { u8 value = rand - 71; if (value < 20) - gRecvCmds[1][2] = 0x5432; + gRecvCmds[1][BLENDER_COMM_SCORE] = LINKCMD_BLENDER_SCORE_GOOD; else if (rand < 30) - sub_8080E6C(1, 5); + CreateOpponentMissTask(1, 5); } else { - gRecvCmds[1][2] = 0x4523; + gRecvCmds[1][BLENDER_COMM_SCORE] = LINKCMD_BLENDER_SCORE_BEST; } } else { - gRecvCmds[1][2] = 0x4523; + gRecvCmds[1][BLENDER_COMM_SCORE] = LINKCMD_BLENDER_SCORE_BEST; } - gTasks[taskId].data[0] = 1; + gTasks[taskId].tDidInput = TRUE; } } else { - gTasks[taskId].data[0] = 0; + gTasks[taskId].tDidInput = FALSE; } } -static void sub_8080FD0(u8 taskId) +static void Task_HandleOpponent2(u8 taskId) { - u32 var1 = (sBerryBlenderData->arrowPos + 0x1800) & 0xFFFF; - u32 var2 = sBerryBlenderData->field_96[2] & 0xFF; - if ((var1 >> 8) > sUnknown_083399E7[var2] + 20 && (var1 >> 8) < sUnknown_083399E7[var2] + 40) + u32 var1 = (sBerryBlender->arrowPos + 0x1800) & 0xFFFF; + u32 arrowId = sBerryBlender->playerIdToArrowId[2] & 0xFF; + if ((var1 >> 8) > sArrowHitRangeStart[arrowId] + 20 && (var1 >> 8) < sArrowHitRangeStart[arrowId] + 40) { - if (gTasks[taskId].data[0] == 0) + if (!gTasks[taskId].tDidInput) { - if (sBerryBlenderData->field_123 == 0) + if (!sBerryBlender->perfectOpponents) { u8 rand = Random() / 655; - if (sBerryBlenderData->field_4C < 500) + if (sBerryBlender->speed < 500) { if (rand > 66) - gRecvCmds[2][2] = 0x4523; + gRecvCmds[2][BLENDER_COMM_SCORE] = LINKCMD_BLENDER_SCORE_BEST; else - gRecvCmds[2][2] = 0x5432; + gRecvCmds[2][BLENDER_COMM_SCORE] = LINKCMD_BLENDER_SCORE_GOOD; } else { u8 value; if (rand > 65) - gRecvCmds[2][2] = 0x4523; + gRecvCmds[2][BLENDER_COMM_SCORE] = LINKCMD_BLENDER_SCORE_BEST; value = rand - 41; if (value < 25) - gRecvCmds[2][2] = 0x5432; + gRecvCmds[2][BLENDER_COMM_SCORE] = LINKCMD_BLENDER_SCORE_GOOD; if (rand < 10) - sub_8080E6C(2, 5); + CreateOpponentMissTask(2, 5); } - gTasks[taskId].data[0] = 1; + gTasks[taskId].tDidInput = TRUE; } else { - gRecvCmds[2][2] = 0x4523; - gTasks[taskId].data[0] = 1; + gRecvCmds[2][BLENDER_COMM_SCORE] = LINKCMD_BLENDER_SCORE_BEST; + gTasks[taskId].tDidInput = TRUE; } } } else { - gTasks[taskId].data[0] = 0; + gTasks[taskId].tDidInput = FALSE; } } -static void sub_80810F8(u8 taskId) +static void Task_HandleOpponent3(u8 taskId) { - u32 var1, var2; - - var1 = (sBerryBlenderData->arrowPos + 0x1800) & 0xFFFF; - var2 = sBerryBlenderData->field_96[3] & 0xFF; - if ((var1 >> 8) > sUnknown_083399E7[var2] + 20 && (var1 >> 8) < sUnknown_083399E7[var2] + 40) + u32 var1 = (sBerryBlender->arrowPos + 0x1800) & 0xFFFF; + u32 arrowId = sBerryBlender->playerIdToArrowId[3] & 0xFF; + if ((var1 >> 8) > sArrowHitRangeStart[arrowId] + 20 && (var1 >> 8) < sArrowHitRangeStart[arrowId] + 40) { if (gTasks[taskId].data[0] == 0) { - if (sBerryBlenderData->field_123 == 0) + if (!sBerryBlender->perfectOpponents) { u8 rand = (Random() / 655); - if (sBerryBlenderData->field_4C < 500) + if (sBerryBlender->speed < 500) { if (rand > 88) - gRecvCmds[3][2] = 0x4523; + gRecvCmds[3][BLENDER_COMM_SCORE] = LINKCMD_BLENDER_SCORE_BEST; else - gRecvCmds[3][2] = 0x5432; + gRecvCmds[3][BLENDER_COMM_SCORE] = LINKCMD_BLENDER_SCORE_GOOD; } else { if (rand > 60) { - gRecvCmds[3][2] = 0x4523; + gRecvCmds[3][BLENDER_COMM_SCORE] = LINKCMD_BLENDER_SCORE_BEST; } else { s8 value = rand - 56; // makes me wonder what the original code was u8 value2 = value; if (value2 < 5) - gRecvCmds[3][2] = 0x5432; + gRecvCmds[3][BLENDER_COMM_SCORE] = LINKCMD_BLENDER_SCORE_GOOD; } if (rand < 5) - sub_8080E6C(3, 5); + CreateOpponentMissTask(3, 5); } - gTasks[taskId].data[0] = 1; + gTasks[taskId].tDidInput = TRUE; } else { - gRecvCmds[3][2] = 0x4523; - gTasks[taskId].data[0] = 1; + gRecvCmds[3][BLENDER_COMM_SCORE] = LINKCMD_BLENDER_SCORE_BEST; + gTasks[taskId].tDidInput = TRUE; } } } else { - gTasks[taskId].data[0] = 0; + gTasks[taskId].tDidInput = FALSE; } } -static void sub_8081224(u8 taskId) +static void Task_HandleBerryMaster(u8 taskId) { - if (sub_8080624(sBerryBlenderData->arrowPos, 1) == 2) + if (GetArrowProximity(sBerryBlender->arrowPos, 1) == PROXIMITY_BEST) { - if (gTasks[taskId].data[0] == 0) + if (!gTasks[taskId].tDidInput) { - gRecvCmds[1][2] = 0x4523; - gTasks[taskId].data[0] = 1; + gRecvCmds[1][BLENDER_COMM_SCORE] = LINKCMD_BLENDER_SCORE_BEST; + gTasks[taskId].tDidInput = TRUE; } } else { - gTasks[taskId].data[0] = 0; + gTasks[taskId].tDidInput = FALSE; } } -static void sub_8081288(u16 a0, u8 a1) +#undef tDidInput + +static void CreateScoreSymbolSprite(u16 cmd, u8 arrowId) { u8 spriteId; - spriteId = CreateSprite(&sUnknown_08339B40, - sBlenderSyncArrowsPos[a1][0] - (10 * sUnknown_083399C0[a1][0]), - sBlenderSyncArrowsPos[a1][1] - (10 * sUnknown_083399C0[a1][1]), + spriteId = CreateSprite(&sSpriteTemplate_ScoreSymbols, + sPlayerArrowPos[arrowId][0] - (10 * sPlayerArrowQuadrant[arrowId][0]), + sPlayerArrowPos[arrowId][1] - (10 * sPlayerArrowQuadrant[arrowId][1]), 1); - if (a0 == 0x4523) + if (cmd == LINKCMD_BLENDER_SCORE_BEST) { - StartSpriteAnim(&gSprites[spriteId], 2); - gSprites[spriteId].callback = sub_8082F9C; + StartSpriteAnim(&gSprites[spriteId], SCOREANIM_BEST_FLASH); + gSprites[spriteId].callback = SpriteCB_ScoreSymbolBest; PlaySE(SE_ICE_STAIRS); } - else if (a0 == 0x5432) + else if (cmd == LINKCMD_BLENDER_SCORE_GOOD) { - StartSpriteAnim(&gSprites[spriteId], 0); + StartSpriteAnim(&gSprites[spriteId], SCOREANIM_GOOD); PlaySE(SE_SUCCESS); } - else if (a0 == 0x2345) + else if (cmd == LINKCMD_BLENDER_SCORE_MISS) { - StartSpriteAnim(&gSprites[spriteId], 1); + StartSpriteAnim(&gSprites[spriteId], SCOREANIM_MISS); PlaySE(SE_FAILURE); } - sub_8082E84(); + CreateParticleSprites(); } -static void sub_8081370(u16 a0) +static void UpdateSpeedFromHit(u16 cmd) { - Blender_ControlHitPitch(); - switch (a0) + UpdateHitPitch(); + switch (cmd) { - case 0x4523: - if (sBerryBlenderData->field_4C < 1500) - sBerryBlenderData->field_4C += (0x180 / sUnknown_08339CC3[sBerryBlenderData->playersNo]); + case LINKCMD_BLENDER_SCORE_BEST: + if (sBerryBlender->speed < 1500) { + sBerryBlender->speed += (384 / sNumPlayersToSpeedDivisor[sBerryBlender->numPlayers]); + } else { - sBerryBlenderData->field_4C += (128 / sUnknown_08339CC3[sBerryBlenderData->playersNo]); - sub_80832BC(&sBerryBlenderData->bg_X, (sBerryBlenderData->field_4C / 100) - 10); - sub_80832BC(&sBerryBlenderData->bg_Y, (sBerryBlenderData->field_4C / 100) - 10); + sBerryBlender->speed += (128 / sNumPlayersToSpeedDivisor[sBerryBlender->numPlayers]); + ShakeBgCoordForHit(&sBerryBlender->bg_X, (sBerryBlender->speed / 100) - 10); + ShakeBgCoordForHit(&sBerryBlender->bg_Y, (sBerryBlender->speed / 100) - 10); } break; - case 0x5432: - if (sBerryBlenderData->field_4C < 1500) - sBerryBlenderData->field_4C += (0x100 / sUnknown_08339CC3[sBerryBlenderData->playersNo]); + case LINKCMD_BLENDER_SCORE_GOOD: + if (sBerryBlender->speed < 1500) + sBerryBlender->speed += (256 / sNumPlayersToSpeedDivisor[sBerryBlender->numPlayers]); break; - case 0x2345: - sBerryBlenderData->field_4C -= (0x100 / sUnknown_08339CC3[sBerryBlenderData->playersNo]); - if (sBerryBlenderData->field_4C < 0x80) - sBerryBlenderData->field_4C = 0x80; + case LINKCMD_BLENDER_SCORE_MISS: + sBerryBlender->speed -= (256 / sNumPlayersToSpeedDivisor[sBerryBlender->numPlayers]); + if (sBerryBlender->speed < MIN_ARROW_SPEED) + sBerryBlender->speed = MIN_ARROW_SPEED; break; } } -static bool32 sub_80814B0(u16 arg0, u16 arg1, u16 arg2) +// Return TRUE if the received command matches the corresponding Link or RFU command +static bool32 CheckRecvCmdMatches(u16 recvCmd, u16 linkCmd, u16 rfuCmd) { - if (gReceivedRemoteLinkPlayers != 0 && gWirelessCommType) + if (gReceivedRemoteLinkPlayers && gWirelessCommType) { - if ((arg0 & 0xFF00) == arg2) + if ((recvCmd & 0xFF00) == rfuCmd) return TRUE; } else { - if (arg0 == arg1) + if (recvCmd == linkCmd) return TRUE; } return FALSE; } -static void sub_80814F4(void) +static void UpdateOpponentScores(void) { s32 i; if (gSpecialVar_0x8004 != 0) { - if (gSendCmd[2] != 0) + // Local game, "send" players score to itself + if (gSendCmd[BLENDER_COMM_SCORE] != 0) { - gRecvCmds[0][2] = gSendCmd[2]; - gRecvCmds[0][0] = 0x4444; - gSendCmd[2] = 0; + gRecvCmds[0][BLENDER_COMM_SCORE] = gSendCmd[BLENDER_COMM_SCORE]; + gRecvCmds[0][BLENDER_COMM_INPUT_STATE] = LINKCMD_BLENDER_SEND_KEYS; + gSendCmd[BLENDER_COMM_SCORE] = 0; } - for (i = 1; i < 4; i++) + + // Local game, simulate NPCs sending keys + // Their actual inputs are handled by Task_HandleOpponent + for (i = 1; i < BLENDER_MAX_PLAYERS; i++) { - if (gRecvCmds[i][2] != 0) - gRecvCmds[i][0] = 0x4444; + if (gRecvCmds[i][BLENDER_COMM_SCORE] != 0) + gRecvCmds[i][BLENDER_COMM_INPUT_STATE] = LINKCMD_BLENDER_SEND_KEYS; } } - for (i = 0; i < sBerryBlenderData->playersNo; i++) + for (i = 0; i < sBerryBlender->numPlayers; i++) { - if (sub_80814B0(gRecvCmds[i][0], 0x4444, 0x4400)) + if (CheckRecvCmdMatches(gRecvCmds[i][BLENDER_COMM_INPUT_STATE], LINKCMD_BLENDER_SEND_KEYS, RFUCMD_BLENDER_SEND_KEYS)) { - u32 var = sBerryBlenderData->field_96[i]; - if (gRecvCmds[i][2] == 0x4523) + u32 arrowId = sBerryBlender->playerIdToArrowId[i]; + if (gRecvCmds[i][BLENDER_COMM_SCORE] == LINKCMD_BLENDER_SCORE_BEST) { - sub_8081370(0x4523); - sBerryBlenderData->field_116 += (sBerryBlenderData->field_4C / 55); - if (sBerryBlenderData->field_116 >= 1000) - sBerryBlenderData->field_116 = 1000; - sub_8081288(0x4523, var); - sBerryBlenderData->scores[i][BLENDER_SCORE_BEST]++; + UpdateSpeedFromHit(LINKCMD_BLENDER_SCORE_BEST); + sBerryBlender->progressBarValue += (sBerryBlender->speed / 55); + if (sBerryBlender->progressBarValue >= MAX_PROGRESS_BAR) + sBerryBlender->progressBarValue = MAX_PROGRESS_BAR; + CreateScoreSymbolSprite(LINKCMD_BLENDER_SCORE_BEST, arrowId); + sBerryBlender->scores[i][SCORE_BEST]++; } - else if (gRecvCmds[i][2] == 0x5432) + else if (gRecvCmds[i][BLENDER_COMM_SCORE] == LINKCMD_BLENDER_SCORE_GOOD) { - sub_8081370(0x5432); - sBerryBlenderData->field_116 += (sBerryBlenderData->field_4C / 70); - sub_8081288(0x5432, var); - sBerryBlenderData->scores[i][BLENDER_SCORE_GOOD]++; + UpdateSpeedFromHit(LINKCMD_BLENDER_SCORE_GOOD); + sBerryBlender->progressBarValue += (sBerryBlender->speed / 70); + CreateScoreSymbolSprite(LINKCMD_BLENDER_SCORE_GOOD, arrowId); + sBerryBlender->scores[i][SCORE_GOOD]++; } - else if (gRecvCmds[i][2] == 0x2345) + else if (gRecvCmds[i][BLENDER_COMM_SCORE] == LINKCMD_BLENDER_SCORE_MISS) { - sub_8081288(0x2345, var); - sub_8081370(0x2345); - if (sBerryBlenderData->scores[i][BLENDER_SCORE_MISS] < 999) - sBerryBlenderData->scores[i][BLENDER_SCORE_MISS]++; + CreateScoreSymbolSprite(LINKCMD_BLENDER_SCORE_MISS, arrowId); + UpdateSpeedFromHit(LINKCMD_BLENDER_SCORE_MISS); + if (sBerryBlender->scores[i][SCORE_MISS] < 999) + sBerryBlender->scores[i][SCORE_MISS]++; } - if (gRecvCmds[i][2] == 0x2345 || gRecvCmds[2][i] == 0x4523 || gRecvCmds[2][i] == 0x5432) // could be a bug, 2 and i are reversed + + // BUG: Should [i][BLENDER_COMM_SCORE] below, not [BLENDER_COMM_SCORE][i] + // As a result the music tempo updates if any player misses, but only if 1 specific player hits + if (gRecvCmds[i][BLENDER_COMM_SCORE] == LINKCMD_BLENDER_SCORE_MISS + || gRecvCmds[BLENDER_COMM_SCORE][i] == LINKCMD_BLENDER_SCORE_BEST + || gRecvCmds[BLENDER_COMM_SCORE][i] == LINKCMD_BLENDER_SCORE_GOOD) { - if (sBerryBlenderData->field_4C > 1500) - m4aMPlayTempoControl(&gMPlayInfo_BGM, ((sBerryBlenderData->field_4C - 750) / 20) + 256); + if (sBerryBlender->speed > 1500) + m4aMPlayTempoControl(&gMPlayInfo_BGM, ((sBerryBlender->speed - 750) / 20) + 256); else - m4aMPlayTempoControl(&gMPlayInfo_BGM, 0x100); + m4aMPlayTempoControl(&gMPlayInfo_BGM, 256); } } } if (gSpecialVar_0x8004 != 0) { - for (i = 0; i < sBerryBlenderData->playersNo; i++) + for (i = 0; i < sBerryBlender->numPlayers; i++) { - gRecvCmds[i][0] = 0; - gRecvCmds[i][2] = 0; + gRecvCmds[i][BLENDER_COMM_INPUT_STATE] = 0; + gRecvCmds[i][BLENDER_COMM_SCORE] = 0; } } } -static void sub_8081744(void) +static void HandlePlayerInput(void) { - u8 var2; - bool8 A_pressed = FALSE; + u8 arrowId; + bool8 pressedA = FALSE; u8 playerId = 0; - if (gReceivedRemoteLinkPlayers != 0) + if (gReceivedRemoteLinkPlayers) playerId = GetMultiplayerId(); - var2 = sBerryBlenderData->field_96[playerId]; + arrowId = sBerryBlender->playerIdToArrowId[playerId]; - if (sBerryBlenderData->gameEndState == 0) + if (sBerryBlender->gameEndState == 0) { - if (gSaveBlock2Ptr->optionsButtonMode == OPTIONS_BUTTON_MODE_L_EQUALS_A && gMain.newKeys & A_BUTTON) + if (gSaveBlock2Ptr->optionsButtonMode == OPTIONS_BUTTON_MODE_L_EQUALS_A && JOY_NEW(A_BUTTON)) { - if ((gMain.heldKeysRaw & (A_BUTTON | L_BUTTON)) != (A_BUTTON | L_BUTTON)) - A_pressed = TRUE; + if (JOY_HELD_RAW(A_BUTTON | L_BUTTON) != (A_BUTTON | L_BUTTON)) + pressedA = TRUE; } - else if (gMain.newKeys & A_BUTTON) + else if (JOY_NEW(A_BUTTON)) { - A_pressed = TRUE; + pressedA = TRUE; } - if (A_pressed) + if (pressedA) { - u8 var3; - StartSpriteAnim(&gSprites[sBerryBlenderData->syncArrowSpriteIds[sBerryBlenderData->field_8E[var2]]], var2 + 4); - var3 = sub_8080624(sBerryBlenderData->arrowPos, playerId); + u8 proximity; + StartSpriteAnim(&gSprites[sBerryBlender->playerArrowSpriteIds[sBerryBlender->arrowIdToPlayerId[arrowId]]], arrowId + 4); + proximity = GetArrowProximity(sBerryBlender->arrowPos, playerId); - if (var3 == 2) - gSendCmd[2] = 0x4523; - else if (var3 == 1) - gSendCmd[2] = 0x5432; + if (proximity == PROXIMITY_BEST) + gSendCmd[BLENDER_COMM_SCORE] = LINKCMD_BLENDER_SCORE_BEST; + else if (proximity == PROXIMITY_GOOD) + gSendCmd[BLENDER_COMM_SCORE] = LINKCMD_BLENDER_SCORE_GOOD; else - gSendCmd[2] = 0x2345; + gSendCmd[BLENDER_COMM_SCORE] = LINKCMD_BLENDER_SCORE_MISS; } } - if (++sBerryBlenderData->field_72 > 5) + if (++sBerryBlender->slowdownTimer > 5) { - if (sBerryBlenderData->field_4C > 128) - sBerryBlenderData->field_4C--; - sBerryBlenderData->field_72 = 0; + if (sBerryBlender->speed > MIN_ARROW_SPEED) + sBerryBlender->speed--; + sBerryBlender->slowdownTimer = 0; } - if (gEnableContestDebugging && gMain.newKeys & L_BUTTON) - sBerryBlenderData->field_123 ^= 1; + + if (gEnableContestDebugging && JOY_NEW(L_BUTTON)) + sBerryBlender->perfectOpponents ^= 1; } -static void sub_8081898(void) +static void CB2_PlayBlender(void) { - sub_8082D28(); + UpdateBlenderCenter(); - if (sBerryBlenderData->gameFrameTime < (99 * 60 * 60) + (59 * 60)) // game time can't be longer than 99 minutes and 59 seconds, can't print 3 digits - sBerryBlenderData->gameFrameTime++; + if (sBerryBlender->gameFrameTime < (99 * 60 * 60) + (59 * 60)) // game time can't be longer than 99 minutes and 59 seconds, can't print 3 digits + sBerryBlender->gameFrameTime++; - sub_8081744(); - SetLinkDebugValues((u16)(sBerryBlenderData->field_4C), sBerryBlenderData->field_116); - sub_80814F4(); - sub_8083140(sBerryBlenderData->field_116, 1000); - sub_8083230(sBerryBlenderData->field_4C); - sub_808330C(); - sub_8082AD4(); - if (sBerryBlenderData->gameEndState == 0 && sBerryBlenderData->field_118 >= 1000) + HandlePlayerInput(); + SetLinkDebugValues((u16)(sBerryBlender->speed), sBerryBlender->progressBarValue); + UpdateOpponentScores(); + TryUpdateProgressBar(sBerryBlender->progressBarValue, MAX_PROGRESS_BAR); + UpdateRPM(sBerryBlender->speed); + RestoreBgCoords(); + ProcessLinkPlayerCmds(); + if (sBerryBlender->gameEndState == 0 && sBerryBlender->maxProgressBarValue >= MAX_PROGRESS_BAR) { - sBerryBlenderData->field_116 = 1000; - sBerryBlenderData->gameEndState = 1; - SetMainCallback2(CB2_HandleBlenderEndGame); + sBerryBlender->progressBarValue = MAX_PROGRESS_BAR; + sBerryBlender->gameEndState = 1; + SetMainCallback2(CB2_EndBlenderGame); } - Blender_DummiedOutFunc(sBerryBlenderData->bg_X, sBerryBlenderData->bg_Y); + Blender_DummiedOutFunc(sBerryBlender->bg_X, sBerryBlender->bg_Y); RunTasks(); AnimateSprites(); BuildOamBuffer(); @@ -2077,362 +2236,380 @@ static void Blender_DummiedOutFunc(s16 a0, s16 a1) } -static bool8 sub_8081964(struct BlenderBerry* berries, u8 index1, u8 index2) +static bool8 AreBlenderBerriesSame(struct BlenderBerry* berries, u8 a, u8 b) { - if (berries[index1].itemId != berries[index2].itemId - || (StringCompare(berries[index1].name, berries[index2].name) == 0 - && (berries[index1].flavors[FLAVOR_SPICY] == berries[index2].flavors[FLAVOR_SPICY] - && berries[index1].flavors[FLAVOR_DRY] == berries[index2].flavors[FLAVOR_DRY] - && berries[index1].flavors[FLAVOR_SWEET] == berries[index2].flavors[FLAVOR_SWEET] - && berries[index1].flavors[FLAVOR_BITTER] == berries[index2].flavors[FLAVOR_BITTER] - && berries[index1].flavors[FLAVOR_SOUR] == berries[index2].flavors[FLAVOR_SOUR] - && berries[index1].smoothness == berries[index2].smoothness))) + // First check to itemId is pointless (and wrong anyway?), always false when this is called + // Only used to determine if two enigma berries are equivalent + if (berries[a].itemId != berries[b].itemId + || (StringCompare(berries[a].name, berries[b].name) == 0 + && (berries[a].flavors[FLAVOR_SPICY] == berries[b].flavors[FLAVOR_SPICY] + && berries[a].flavors[FLAVOR_DRY] == berries[b].flavors[FLAVOR_DRY] + && berries[a].flavors[FLAVOR_SWEET] == berries[b].flavors[FLAVOR_SWEET] + && berries[a].flavors[FLAVOR_BITTER] == berries[b].flavors[FLAVOR_BITTER] + && berries[a].flavors[FLAVOR_SOUR] == berries[b].flavors[FLAVOR_SOUR] + && berries[a].flavors[FLAVOR_COUNT] == berries[b].flavors[FLAVOR_COUNT]))) return TRUE; else return FALSE; } -static u32 Blender_GetPokeblockColor(struct BlenderBerry* berries, s16* a1, u8 playersNo, u8 a3) +static u32 CalculatePokeblockColor(struct BlenderBerry* berries, s16* _flavors, u8 numPlayers, u8 negativeFlavors) { - s16 vars[6]; - s32 i; - s32 r6; - u8 r2; + s16 flavors[FLAVOR_COUNT + 1]; + s32 i, j; + u8 numFlavors; - for (i = 0; i < 6; i++) - vars[i] = a1[i]; + for (i = 0; i < FLAVOR_COUNT + 1; i++) + flavors[i] = _flavors[i]; - r6 = 0; - for (i = 0; i < 5; i++) + j = 0; + for (i = 0; i < FLAVOR_COUNT; i++) { - if (vars[i] == 0) - r6++; + if (flavors[i] == 0) + j++; } - if (r6 == 5 || a3 > 3) - return 12; - for (i = 0; i < playersNo; i++) + + // If all flavors are 0, or at least 3 were negative/0 + // or if players used the same berry, color is black + if (j == 5 || negativeFlavors > 3) + return PBLOCK_CLR_BLACK; + + for (i = 0; i < numPlayers; i++) { - for (r6 = 0; r6 < playersNo; r6++) + for (j = 0; j < numPlayers; j++) { - if (berries[i].itemId == berries[r6].itemId && i != r6 - && (berries[i].itemId != ITEM_ENIGMA_BERRY || sub_8081964(berries, i, r6))) - return 12; + if (berries[i].itemId == berries[j].itemId && i != j + && (berries[i].itemId != ITEM_ENIGMA_BERRY || AreBlenderBerriesSame(berries, i, j))) + return PBLOCK_CLR_BLACK; } } - r2 = 0; - for (r2 = 0, i = 0; i < 5; i++) + + numFlavors = 0; + for (numFlavors = 0, i = 0; i < FLAVOR_COUNT; i++) { - if (vars[i] > 0) - r2++; + if (flavors[i] > 0) + numFlavors++; } - if (r2 > 3) - return 13; - if (r2 == 3) - return 11; - for (i = 0; i < 5; i++) + + // Check for special colors (White/Gray/Gold) + if (numFlavors > 3) + return PBLOCK_CLR_WHITE; + + if (numFlavors == 3) + return PBLOCK_CLR_GRAY; + + for (i = 0; i < FLAVOR_COUNT; i++) { - if (vars[i] > 50) - return 14; + if (flavors[i] > 50) + return PBLOCK_CLR_GOLD; } - if (r2 == 1 && vars[0] > 0) - return 1; - if (r2 == 1 && vars[1] > 0) - return 2; - if (r2 == 1 && vars[2] > 0) - return 3; - if (r2 == 1 && vars[3] > 0) - return 4; - if (r2 == 1 && vars[4] > 0) - return 5; - if (r2 == 2) + + // Only 1 flavor present, return corresponding color + if (numFlavors == 1 && flavors[FLAVOR_SPICY] > 0) + return PBLOCK_CLR_RED; + if (numFlavors == 1 && flavors[FLAVOR_DRY] > 0) + return PBLOCK_CLR_BLUE; + if (numFlavors == 1 && flavors[FLAVOR_SWEET] > 0) + return PBLOCK_CLR_PINK; + if (numFlavors == 1 && flavors[FLAVOR_BITTER] > 0) + return PBLOCK_CLR_GREEN; + if (numFlavors == 1 && flavors[FLAVOR_SOUR] > 0) + return PBLOCK_CLR_YELLOW; + + if (numFlavors == 2) { - s32 var = 0; - for (i = 0; i < 5; i++) + // Determine which 2 flavors are present + s32 idx = 0; + for (i = 0; i < FLAVOR_COUNT; i++) { - if (vars[i] > 0) - sUnknown_03000DF8[var++] = i; + if (flavors[i] > 0) + sPokeblockPresentFlavors[idx++] = i; } - if (vars[sUnknown_03000DF8[0]] >= vars[sUnknown_03000DF8[1]]) + // Use the stronger flavor to determine color + // The weaker flavor is returned in the upper 16 bits, but this is ignored in the color assignment + if (flavors[sPokeblockPresentFlavors[0]] >= flavors[sPokeblockPresentFlavors[1]]) { - if (sUnknown_03000DF8[0] == 0) - return (sUnknown_03000DF8[1] << 16) | 6; - if (sUnknown_03000DF8[0] == 1) - return (sUnknown_03000DF8[1] << 16) | 7; - if (sUnknown_03000DF8[0] == 2) - return (sUnknown_03000DF8[1] << 16) | 8; - if (sUnknown_03000DF8[0] == 3) - return (sUnknown_03000DF8[1] << 16) | 9; - if (sUnknown_03000DF8[0] == 4) - return (sUnknown_03000DF8[1] << 16) | 10; + if (sPokeblockPresentFlavors[0] == FLAVOR_SPICY) + return (sPokeblockPresentFlavors[1] << 16) | PBLOCK_CLR_PURPLE; + if (sPokeblockPresentFlavors[0] == FLAVOR_DRY) + return (sPokeblockPresentFlavors[1] << 16) | PBLOCK_CLR_INDIGO; + if (sPokeblockPresentFlavors[0] == FLAVOR_SWEET) + return (sPokeblockPresentFlavors[1] << 16) | PBLOCK_CLR_BROWN; + if (sPokeblockPresentFlavors[0] == FLAVOR_BITTER) + return (sPokeblockPresentFlavors[1] << 16) | PBLOCK_CLR_LITE_BLUE; + if (sPokeblockPresentFlavors[0] == FLAVOR_SOUR) + return (sPokeblockPresentFlavors[1] << 16) | PBLOCK_CLR_OLIVE; } else { - if (sUnknown_03000DF8[1] == 0) - return (sUnknown_03000DF8[0] << 16) | 6; - if (sUnknown_03000DF8[1] == 1) - return (sUnknown_03000DF8[0] << 16) | 7; - if (sUnknown_03000DF8[1] == 2) - return (sUnknown_03000DF8[0] << 16) | 8; - if (sUnknown_03000DF8[1] == 3) - return (sUnknown_03000DF8[0] << 16) | 9; - if (sUnknown_03000DF8[1] == 4) - return (sUnknown_03000DF8[0] << 16) | 10; + if (sPokeblockPresentFlavors[1] == FLAVOR_SPICY) + return (sPokeblockPresentFlavors[0] << 16) | PBLOCK_CLR_PURPLE; + if (sPokeblockPresentFlavors[1] == FLAVOR_DRY) + return (sPokeblockPresentFlavors[0] << 16) | PBLOCK_CLR_INDIGO; + if (sPokeblockPresentFlavors[1] == FLAVOR_SWEET) + return (sPokeblockPresentFlavors[0] << 16) | PBLOCK_CLR_BROWN; + if (sPokeblockPresentFlavors[1] == FLAVOR_BITTER) + return (sPokeblockPresentFlavors[0] << 16) | PBLOCK_CLR_LITE_BLUE; + if (sPokeblockPresentFlavors[1] == FLAVOR_SOUR) + return (sPokeblockPresentFlavors[0] << 16) | PBLOCK_CLR_OLIVE; } } - return 0; + return PBLOCK_CLR_NONE; } -static void sub_8081BB0(s16 value) +static void Debug_SetMaxRPMStage(s16 value) { - sUnknown_03000E04 = value; + sDebug_MaxRPMStage = value; } -static s16 sub_8081BBC(void) +// Unused +static s16 Debug_GetMaxRPMStage(void) { - return sUnknown_03000E04; + return sDebug_MaxRPMStage; } -static void sub_8081BC8(s16 value) +static void Debug_SetGameTimeStage(s16 value) { - sUnknown_03000E06 = value; + sDebug_GameTimeStage = value; } -static s16 sub_8081BD4(void) +// Unued +static s16 Debug_GetGameTimeStage(void) { - return sUnknown_03000E06; + return sDebug_GameTimeStage; } -#if MODERN -// TODO remove this as soon as the code below is understood -// add a UBFIX if required (code buggy?) -__attribute__((optimize("no-aggressive-loop-optimizations"))) -#endif -static void Blender_CalculatePokeblock(struct BlenderBerry *berries, struct Pokeblock *pokeblock, u8 playersNo, u8 *flavors, u16 maxRPM) +static void CalculatePokeblock(struct BlenderBerry *berries, struct Pokeblock *pokeblock, u8 numPlayers, u8 *flavors, u16 maxRPM) { s32 i, j; s32 multiuseVar, var2; - u8 var3; + u8 numNegatives; - for (i = 0; i < 6; i++) - sUnknown_03000DE8[i] = 0; + for (i = 0; i < FLAVOR_COUNT + 1; i++) + sPokeblockFlavors[i] = 0; - for (i = 0; i < playersNo; i++) + // Add up the flavor + feel of each players berry + for (i = 0; i < numPlayers; i++) { - for (j = 0; j < 6; j++) - sUnknown_03000DE8[j] += berries[i].flavors[j]; + for (j = 0; j < FLAVOR_COUNT + 1; j++) + sPokeblockFlavors[j] += berries[i].flavors[j]; } - multiuseVar = sUnknown_03000DE8[0]; - sUnknown_03000DE8[0] -= sUnknown_03000DE8[1]; - sUnknown_03000DE8[1] -= sUnknown_03000DE8[2]; - sUnknown_03000DE8[2] -= sUnknown_03000DE8[3]; - sUnknown_03000DE8[3] -= sUnknown_03000DE8[4]; - sUnknown_03000DE8[4] -= multiuseVar; + // Subtract each flavor total from the prev one + // The idea is to focus on only the flavors with the highest totals + // Bad way to do it though (order matters here) + multiuseVar = sPokeblockFlavors[0]; + sPokeblockFlavors[FLAVOR_SPICY] -= sPokeblockFlavors[FLAVOR_DRY]; + sPokeblockFlavors[FLAVOR_DRY] -= sPokeblockFlavors[FLAVOR_SWEET]; + sPokeblockFlavors[FLAVOR_SWEET] -= sPokeblockFlavors[FLAVOR_BITTER]; + sPokeblockFlavors[FLAVOR_BITTER] -= sPokeblockFlavors[FLAVOR_SOUR]; + sPokeblockFlavors[FLAVOR_SOUR] -= multiuseVar; + // Count (and reset) the resulting negative flavors multiuseVar = 0; - for (i = 0; i < 5; i++) + for (i = 0; i < FLAVOR_COUNT; i++) { - if (sUnknown_03000DE8[i] < 0) + if (sPokeblockFlavors[i] < 0) { - sUnknown_03000DE8[i] = 0; + sPokeblockFlavors[i] = 0; multiuseVar++; } } - var3 = multiuseVar; - for (i = 0; i < 5; i++) + numNegatives = multiuseVar; + + // Subtract the number of negative flavor totals from each positive total (without going below 0) + for (i = 0; i < FLAVOR_COUNT; i++) { - if (sUnknown_03000DE8[i] > 0) + if (sPokeblockFlavors[i] > 0) { - if (sUnknown_03000DE8[i] < multiuseVar) - sUnknown_03000DE8[i] = 0; + if (sPokeblockFlavors[i] < multiuseVar) + sPokeblockFlavors[i] = 0; else - sUnknown_03000DE8[i] -= multiuseVar; - } - } - for (i = 0; i < 5; i++) - { - sUnknown_020322A8[i] = sUnknown_03000DE8[i]; - } - - multiuseVar = maxRPM / 333 + 100; - sUnknown_020322D0 = multiuseVar; - - for (i = 0; i < 5; i++) - { - s32 r4; - s32 r5 = sUnknown_03000DE8[i]; - r5 = (r5 * multiuseVar) / 10; - r4 = r5 % 10; - r5 /= 10; - if (r4 > 4) - r5++; - sUnknown_03000DE8[i] = r5; - } - for (i = 0; i < 5; i++) - { - sUnknown_020322BC[i] = sUnknown_03000DE8[i]; - } - - pokeblock->color = Blender_GetPokeblockColor(berries, &sUnknown_03000DE8[0], playersNo, var3); - sUnknown_03000DE8[5] = (sUnknown_03000DE8[5] / playersNo) - playersNo; - - if (sUnknown_03000DE8[5] < 0) - sUnknown_03000DE8[5] = 0; - - if (pokeblock->color == 12) - { - multiuseVar = Random() % 10; - for (i = 0; i < 5; i++) - { - if ((sUnknown_08339CC8[multiuseVar] >> i) & 1) - sUnknown_03000DE8[i] = 2; - else - sUnknown_03000DE8[i] = 0; + sPokeblockFlavors[i] -= multiuseVar; } } - for (i = 0; i < 6; i++) + for (i = 0; i < FLAVOR_COUNT; i++) + sDebug_PokeblockFactorFlavors[i] = sPokeblockFlavors[i]; + + // Factor in max RPM and round + sDebug_PokeblockFactorRPM = multiuseVar = maxRPM / 333 + 100; + for (i = 0; i < FLAVOR_COUNT; i++) { - if (sUnknown_03000DE8[i] > 255) - sUnknown_03000DE8[i] = 255; + s32 remainder; + s32 flavor = sPokeblockFlavors[i]; + flavor = (flavor * multiuseVar) / 10; + remainder = flavor % 10; + flavor /= 10; + if (remainder > 4) + flavor++; + sPokeblockFlavors[i] = flavor; } - pokeblock->spicy = sUnknown_03000DE8[0]; - pokeblock->dry = sUnknown_03000DE8[1]; - pokeblock->sweet = sUnknown_03000DE8[2]; - pokeblock->bitter = sUnknown_03000DE8[3]; - pokeblock->sour = sUnknown_03000DE8[4]; - pokeblock->feel = sUnknown_03000DE8[5]; + for (i = 0; i < FLAVOR_COUNT; i++) + sDebug_PokeblockFactorFlavorsAfterRPM[i] = sPokeblockFlavors[i]; - for (i = 0; i < 6; i++) + // Calculate color and feel of pokeblock + pokeblock->color = CalculatePokeblockColor(berries, &sPokeblockFlavors[0], numPlayers, numNegatives); + sPokeblockFlavors[FLAVOR_COUNT] = (sPokeblockFlavors[FLAVOR_COUNT] / numPlayers) - numPlayers; + + if (sPokeblockFlavors[FLAVOR_COUNT] < 0) + sPokeblockFlavors[FLAVOR_COUNT] = 0; + + if (pokeblock->color == PBLOCK_CLR_BLACK) { - flavors[i] = sUnknown_03000DE8[i]; + // Black pokeblocks get their flavors randomly reassigned + multiuseVar = Random() % ARRAY_COUNT(sBlackPokeblockFlavorFlags); + for (i = 0; i < FLAVOR_COUNT; i++) + { + if ((sBlackPokeblockFlavorFlags[multiuseVar] >> i) & 1) + sPokeblockFlavors[i] = 2; + else + sPokeblockFlavors[i] = 0; + } } + + for (i = 0; i < FLAVOR_COUNT + 1; i++) + { + if (sPokeblockFlavors[i] > 255) + sPokeblockFlavors[i] = 255; + } + + pokeblock->spicy = sPokeblockFlavors[FLAVOR_SPICY]; + pokeblock->dry = sPokeblockFlavors[FLAVOR_DRY]; + pokeblock->sweet = sPokeblockFlavors[FLAVOR_SWEET]; + pokeblock->bitter = sPokeblockFlavors[FLAVOR_BITTER]; + pokeblock->sour = sPokeblockFlavors[FLAVOR_SOUR]; + pokeblock->feel = sPokeblockFlavors[FLAVOR_COUNT]; + + for (i = 0; i < FLAVOR_COUNT + 1; i++) + flavors[i] = sPokeblockFlavors[i]; } -static void BlenderDebug_CalculatePokeblock(struct BlenderBerry* berries, struct Pokeblock* pokeblock, u8 playersNo, u8* flavors, u16 a4) +// Unused +static void Debug_CalculatePokeblock(struct BlenderBerry* berries, struct Pokeblock* pokeblock, u8 numPlayers, u8* flavors, u16 maxRPM) { - Blender_CalculatePokeblock(berries, pokeblock, playersNo, flavors, a4); + CalculatePokeblock(berries, pokeblock, numPlayers, flavors, maxRPM); } -static void sub_8081E20(void) +static void Debug_SetStageVars(void) { - u32 frames = (u16)(sBerryBlenderData->gameFrameTime); - u16 max_RPM = sBerryBlenderData->max_RPM; - s16 var = 0; + u32 frames = (u16)(sBerryBlender->gameFrameTime); + u16 maxRPM = sBerryBlender->maxRPM; + s16 stage = 0; if (frames < 900) - var = 5; + stage = 5; else if ((u16)(frames - 900) < 600) - var = 4; + stage = 4; else if ((u16)(frames - 1500) < 600) - var = 3; + stage = 3; else if ((u16)(frames - 2100) < 900) - var = 2; + stage = 2; else if ((u16)(frames - 3300) < 300) - var = 1; + stage = 1; - sub_8081BC8(var); + Debug_SetGameTimeStage(stage); - var = 0; - if (max_RPM <= 64) + stage = 0; + if (maxRPM <= 64) { - if (max_RPM >= 50 && max_RPM < 100) - var = -1; - else if (max_RPM >= 100 && max_RPM < 150) - var = -2; - else if (max_RPM >= 150 && max_RPM < 200) - var = -3; - else if (max_RPM >= 200 && max_RPM < 250) - var = -4; - else if (max_RPM >= 250 && max_RPM < 300) - var = -5; - else if (max_RPM >= 350 && max_RPM < 400) - var = -6; - else if (max_RPM >= 400 && max_RPM < 450) - var = -7; - else if (max_RPM >= 500 && max_RPM < 550) - var = -8; - else if (max_RPM >= 550 && max_RPM < 600) - var = -9; - else if (max_RPM >= 600) - var = -10; + if (maxRPM >= 50 && maxRPM < 100) + stage = -1; + else if (maxRPM >= 100 && maxRPM < 150) + stage = -2; + else if (maxRPM >= 150 && maxRPM < 200) + stage = -3; + else if (maxRPM >= 200 && maxRPM < 250) + stage = -4; + else if (maxRPM >= 250 && maxRPM < 300) + stage = -5; + else if (maxRPM >= 350 && maxRPM < 400) + stage = -6; + else if (maxRPM >= 400 && maxRPM < 450) + stage = -7; + else if (maxRPM >= 500 && maxRPM < 550) + stage = -8; + else if (maxRPM >= 550 && maxRPM < 600) + stage = -9; + else if (maxRPM >= 600) + stage = -10; } - sub_8081BB0(var); + Debug_SetMaxRPMStage(stage); } -static void sub_8081F94(u16 *a0) +static void SendContinuePromptResponse(u16 *cmd) { - if (gReceivedRemoteLinkPlayers != 0 && gWirelessCommType) - *a0 = 0x2F00; + if (gReceivedRemoteLinkPlayers && gWirelessCommType) + *cmd = RFUCMD_SEND_PACKET; else - *a0 = 0x2FFF; + *cmd = LINKCMD_SEND_PACKET; } -static void CB2_HandleBlenderEndGame(void) +static void CB2_EndBlenderGame(void) { u8 i, j; - if (sBerryBlenderData->gameEndState < 3) - sub_8082D28(); + if (sBerryBlender->gameEndState < 3) + UpdateBlenderCenter(); GetMultiplayerId(); // unused return value - switch (sBerryBlenderData->gameEndState) + switch (sBerryBlender->gameEndState) { case 1: m4aMPlayTempoControl(&gMPlayInfo_BGM, 256); for (i = 0; i < gSpecialVar_0x8004; i++) { - DestroyTask(sBerryBlenderData->field_120[i]); + DestroyTask(sBerryBlender->opponentTaskIds[i]); } - sBerryBlenderData->gameEndState++; + sBerryBlender->gameEndState++; break; case 2: - sBerryBlenderData->field_4C -= 32; - if (sBerryBlenderData->field_4C <= 0) + sBerryBlender->speed -= 32; + if (sBerryBlender->speed <= 0) { ClearLinkCallback(); - sBerryBlenderData->field_4C = 0; + sBerryBlender->speed = 0; - if (gReceivedRemoteLinkPlayers != 0) - sBerryBlenderData->gameEndState++; + if (gReceivedRemoteLinkPlayers) + sBerryBlender->gameEndState++; else - sBerryBlenderData->gameEndState = 5; + sBerryBlender->gameEndState = 5; - sBerryBlenderData->mainState = 0; + sBerryBlender->mainState = 0; m4aMPlayStop(&gMPlayInfo_SE2); } - Blender_ControlHitPitch(); + UpdateHitPitch(); break; case 3: if (GetMultiplayerId() != 0) { - sBerryBlenderData->gameEndState++; + sBerryBlender->gameEndState++; } else if (IsLinkTaskFinished()) { - if (gReceivedRemoteLinkPlayers != 0 && gWirelessCommType) + if (gReceivedRemoteLinkPlayers && gWirelessCommType) { - sBerryBlenderData->gameBlock.timeRPM.time = sBerryBlenderData->gameFrameTime; - sBerryBlenderData->gameBlock.timeRPM.max_RPM = sBerryBlenderData->max_RPM; + sBerryBlender->gameBlock.timeRPM.time = sBerryBlender->gameFrameTime; + sBerryBlender->gameBlock.timeRPM.maxRPM = sBerryBlender->maxRPM; for (i = 0; i < BLENDER_MAX_PLAYERS; i++) { - for (j = 0; j < BLENDER_SCORES_NO; j++) - sBerryBlenderData->gameBlock.scores[i][j] = sBerryBlenderData->scores[i][j]; + for (j = 0; j < NUM_SCORE_TYPES; j++) + sBerryBlender->gameBlock.scores[i][j] = sBerryBlender->scores[i][j]; } - if (SendBlock(0, &sBerryBlenderData->gameBlock, sizeof(sBerryBlenderData->gameBlock))) - sBerryBlenderData->gameEndState++; + if (SendBlock(0, &sBerryBlender->gameBlock, sizeof(sBerryBlender->gameBlock))) + sBerryBlender->gameEndState++; } else { - sBerryBlenderData->smallBlock.time = sBerryBlenderData->gameFrameTime; - sBerryBlenderData->smallBlock.max_RPM = sBerryBlenderData->max_RPM; - if (SendBlock(0, &sBerryBlenderData->smallBlock, sizeof(sBerryBlenderData->smallBlock) + 32)) - sBerryBlenderData->gameEndState++; + sBerryBlender->smallBlock.time = sBerryBlender->gameFrameTime; + sBerryBlender->smallBlock.maxRPM = sBerryBlender->maxRPM; + if (SendBlock(0, &sBerryBlender->smallBlock, sizeof(sBerryBlender->smallBlock) + 32)) + sBerryBlender->gameEndState++; } } break; @@ -2440,64 +2617,64 @@ static void CB2_HandleBlenderEndGame(void) if (GetBlockReceivedStatus()) { ResetBlockReceivedFlags(); - sBerryBlenderData->gameEndState++; + sBerryBlender->gameEndState++; - if (gReceivedRemoteLinkPlayers != 0 && gWirelessCommType) + if (gReceivedRemoteLinkPlayers && gWirelessCommType) { struct BlenderGameBlock *receivedBlock = (struct BlenderGameBlock*)(&gBlockRecvBuffer); - sBerryBlenderData->max_RPM = receivedBlock->timeRPM.max_RPM; - sBerryBlenderData->gameFrameTime = receivedBlock->timeRPM.time; + sBerryBlender->maxRPM = receivedBlock->timeRPM.maxRPM; + sBerryBlender->gameFrameTime = receivedBlock->timeRPM.time; for (i = 0; i < BLENDER_MAX_PLAYERS; i++) { - for (j = 0; j < BLENDER_SCORES_NO; j++) - sBerryBlenderData->scores[i][j] = receivedBlock->scores[i][j]; + for (j = 0; j < NUM_SCORE_TYPES; j++) + sBerryBlender->scores[i][j] = receivedBlock->scores[i][j]; } } else { struct TimeAndRPM *receivedBlock = (struct TimeAndRPM*)(&gBlockRecvBuffer); - sBerryBlenderData->max_RPM = receivedBlock->max_RPM; - sBerryBlenderData->gameFrameTime = receivedBlock->time; + sBerryBlender->maxRPM = receivedBlock->maxRPM; + sBerryBlender->gameFrameTime = receivedBlock->time; } } break; case 5: - if (Blender_PrintBlendingRanking()) - sBerryBlenderData->gameEndState++; + if (PrintBlendingRanking()) + sBerryBlender->gameEndState++; break; case 6: - if (Blender_PrintBlendingResults()) + if (PrintBlendingResults()) { if (gInGameOpponentsNo == 0) IncrementGameStat(GAME_STAT_POKEBLOCKS_WITH_FRIENDS); else IncrementGameStat(GAME_STAT_POKEBLOCKS); - sBerryBlenderData->gameEndState++; + sBerryBlender->gameEndState++; } break; case 7: - if (Blender_PrintText(&sBerryBlenderData->textState, sText_WouldLikeToBlendAnotherBerry, GetPlayerTextSpeedDelay())) - sBerryBlenderData->gameEndState++; + if (Blender_PrintText(&sBerryBlender->textState, sText_WouldLikeToBlendAnotherBerry, GetPlayerTextSpeedDelay())) + sBerryBlender->gameEndState++; break; case 9: - sBerryBlenderData->yesNoAnswer = 0; - CreateYesNoMenu(&sBlender_YesNoWindowTemplate, 1, 0xD, 0); - sBerryBlenderData->gameEndState++; + sBerryBlender->yesNoAnswer = 0; + CreateYesNoMenu(&sYesNoWindowTemplate_ContinuePlaying, 1, 0xD, 0); + sBerryBlender->gameEndState++; break; case 10: switch (Menu_ProcessInputNoWrapClearOnChoose()) { case 1: case -1: - sBerryBlenderData->yesNoAnswer = 1; - sBerryBlenderData->gameEndState++; - for (i = 0; i yesNoAnswer = 1; + sBerryBlender->gameEndState++; + for (i = 0; i < BLENDER_MAX_PLAYERS; i++) { - if (sBerryBlenderData->field_8E[i] != 0xFF) + if (sBerryBlender->arrowIdToPlayerId[i] != NO_PLAYER) { PutWindowTilemap(i); CopyWindowToVram(i, 3); @@ -2505,11 +2682,11 @@ static void CB2_HandleBlenderEndGame(void) } break; case 0: - sBerryBlenderData->yesNoAnswer = 0; - sBerryBlenderData->gameEndState++; - for (i = 0; i yesNoAnswer = 0; + sBerryBlender->gameEndState++; + for (i = 0; i < BLENDER_MAX_PLAYERS; i++) { - if (sBerryBlenderData->field_8E[i] != 0xFF) + if (sBerryBlender->arrowIdToPlayerId[i] != NO_PLAYER) { PutWindowTilemap(i); CopyWindowToVram(i, 3); @@ -2519,62 +2696,64 @@ static void CB2_HandleBlenderEndGame(void) } break; case 11: - sub_8081F94(&gSendCmd[0]); - if (sBerryBlenderData->yesNoAnswer == 0) + SendContinuePromptResponse(&gSendCmd[BLENDER_COMM_INPUT_STATE]); + if (sBerryBlender->yesNoAnswer == 0) { - if (IsBagPocketNonEmpty(POCKET_BERRIES) == FALSE) // no berries + if (IsBagPocketNonEmpty(POCKET_BERRIES) == FALSE) { - sBerryBlenderData->playAgainState = CANT_PLAY_NO_BERRIES; - gSendCmd[1] = 0x9999; + // No berries + sBerryBlender->playAgainState = CANT_PLAY_NO_BERRIES; + gSendCmd[BLENDER_COMM_RESP] = LINKCMD_BLENDER_NO_BERRIES; } - else if (GetFirstFreePokeblockSlot() == -1) // no space for pokeblocks + else if (GetFirstFreePokeblockSlot() == -1) { - sBerryBlenderData->playAgainState = CANT_PLAY_NO_PKBLCK_SPACE; - gSendCmd[1] = 0xAAAA; + // No space for pokeblocks + sBerryBlender->playAgainState = CANT_PLAY_NO_PKBLCK_SPACE; + gSendCmd[BLENDER_COMM_RESP] = LINKCMD_BLENDER_NO_PBLOCK_SPACE; } else { - sBerryBlenderData->playAgainState = PLAY_AGAIN_OK; - gSendCmd[1] = 0x7779; + sBerryBlender->playAgainState = PLAY_AGAIN_YES; + gSendCmd[BLENDER_COMM_RESP] = LINKCMD_BLENDER_PLAY_AGAIN; } - sBerryBlenderData->gameEndState++; + sBerryBlender->gameEndState++; } else { - sBerryBlenderData->playAgainState = DONT_PLAY_AGAIN; - gSendCmd[1] = 0x8888; - sBerryBlenderData->gameEndState++; + sBerryBlender->playAgainState = PLAY_AGAIN_NO; + gSendCmd[BLENDER_COMM_RESP] = LINKCMD_CONT_BLOCK; + sBerryBlender->gameEndState++; } break; case 12: if (gInGameOpponentsNo) { - SetMainCallback2(CB2_HandlePlayerPlayAgainChoice); - sBerryBlenderData->gameEndState = 0; - sBerryBlenderData->mainState = 0; + SetMainCallback2(CB2_CheckPlayAgainLocal); + sBerryBlender->gameEndState = 0; + sBerryBlender->mainState = 0; } else { - sBerryBlenderData->gameEndState++; + sBerryBlender->gameEndState++; } break; case 8: - sBerryBlenderData->gameEndState++; + sBerryBlender->gameEndState++; break; case 13: - if (Blender_PrintText(&sBerryBlenderData->textState, sText_CommunicationStandby, GetPlayerTextSpeedDelay())) + if (Blender_PrintText(&sBerryBlender->textState, sText_CommunicationStandby, GetPlayerTextSpeedDelay())) { - SetMainCallback2(CB2_HandlePlayerLinkPlayAgainChoice); - sBerryBlenderData->gameEndState = 0; - sBerryBlenderData->mainState = 0; + SetMainCallback2(CB2_CheckPlayAgainLink); + sBerryBlender->gameEndState = 0; + sBerryBlender->mainState = 0; } break; } - sub_808330C(); - sub_8083230(sBerryBlenderData->field_4C); - sub_8082AD4(); - Blender_DummiedOutFunc(sBerryBlenderData->bg_X, sBerryBlenderData->bg_Y); + RestoreBgCoords(); + UpdateRPM(sBerryBlender->speed); + ProcessLinkPlayerCmds(); + Blender_DummiedOutFunc(sBerryBlender->bg_X, sBerryBlender->bg_Y); RunTasks(); AnimateSprites(); BuildOamBuffer(); @@ -2584,30 +2763,30 @@ static void CB2_HandleBlenderEndGame(void) static bool8 LinkPlayAgainHandleSaving(void) { - switch (sBerryBlenderData->field_1A0) + switch (sBerryBlender->linkPlayAgainState) { case 0: SetLinkStandbyCallback(); - sBerryBlenderData->field_1A0 = 1; - sBerryBlenderData->framesToWait = 0; + sBerryBlender->linkPlayAgainState = 1; + sBerryBlender->framesToWait = 0; break; case 1: if (IsLinkTaskFinished()) { - sBerryBlenderData->field_1A0++; + sBerryBlender->linkPlayAgainState++; gSoftResetDisabled = TRUE; } break; case 2: FullSaveGame(); - sBerryBlenderData->field_1A0++; - sBerryBlenderData->framesToWait = 0; + sBerryBlender->linkPlayAgainState++; + sBerryBlender->framesToWait = 0; break; case 3: - if (++sBerryBlenderData->framesToWait == 10) + if (++sBerryBlender->framesToWait == 10) { SetLinkStandbyCallback(); - sBerryBlenderData->field_1A0++; + sBerryBlender->linkPlayAgainState++; } break; case 4: @@ -2615,21 +2794,21 @@ static bool8 LinkPlayAgainHandleSaving(void) { if (CheckSaveFile()) { - sBerryBlenderData->field_1A0 = 5; + sBerryBlender->linkPlayAgainState = 5; } else { - sBerryBlenderData->framesToWait = 0; - sBerryBlenderData->field_1A0 = 3; + sBerryBlender->framesToWait = 0; + sBerryBlender->linkPlayAgainState = 3; } } break; case 5: - sBerryBlenderData->field_1A0++; - sBerryBlenderData->framesToWait = 0; + sBerryBlender->linkPlayAgainState++; + sBerryBlender->framesToWait = 0; break; case 6: - if (++sBerryBlenderData->framesToWait > 5) + if (++sBerryBlender->framesToWait > 5) { gSoftResetDisabled = FALSE; return TRUE; @@ -2640,113 +2819,115 @@ static bool8 LinkPlayAgainHandleSaving(void) return FALSE; } -static void CB2_HandlePlayerLinkPlayAgainChoice(void) +static void CB2_CheckPlayAgainLink(void) { - switch (sBerryBlenderData->gameEndState) + switch (sBerryBlender->gameEndState) { case 0: - if (sBerryBlenderData->field_64[0] == 0x2222) + if (sBerryBlender->playerContinueResponses[0] == LINKCMD_SEND_LINK_TYPE) { - sBerryBlenderData->gameEndState = 5; + // Link leader says game will continue + sBerryBlender->gameEndState = 5; } - else if (sBerryBlenderData->field_64[0] == 0x1111) + else if (sBerryBlender->playerContinueResponses[0] == LINKCMD_BLENDER_STOP) { - if (sBerryBlenderData->field_6C == 0x9999) - sBerryBlenderData->gameEndState = 2; - else if (sBerryBlenderData->field_6C == 0xAAAA) - sBerryBlenderData->gameEndState = 1; + // Link leader says game will stop, if necessary print why + if (sBerryBlender->canceledPlayerCmd == LINKCMD_BLENDER_NO_BERRIES) + sBerryBlender->gameEndState = 2; + else if (sBerryBlender->canceledPlayerCmd == LINKCMD_BLENDER_NO_PBLOCK_SPACE) + sBerryBlender->gameEndState = 1; else - sBerryBlenderData->gameEndState = 5; + sBerryBlender->gameEndState = 5; } break; case 1: - sBerryBlenderData->gameEndState = 3; - StringCopy(gStringVar4, gLinkPlayers[sBerryBlenderData->field_6E].name); + sBerryBlender->gameEndState = 3; + StringCopy(gStringVar4, gLinkPlayers[sBerryBlender->canceledPlayerId].name); StringAppend(gStringVar4, sText_ApostropheSPokeblockCaseIsFull); break; case 2: - sBerryBlenderData->gameEndState++; - StringCopy(gStringVar4, gLinkPlayers[sBerryBlenderData->field_6E].name); + sBerryBlender->gameEndState++; + StringCopy(gStringVar4, gLinkPlayers[sBerryBlender->canceledPlayerId].name); StringAppend(gStringVar4, sText_HasNoBerriesToPut); break; case 3: - if (Blender_PrintText(&sBerryBlenderData->textState, gStringVar4, GetPlayerTextSpeedDelay())) + if (Blender_PrintText(&sBerryBlender->textState, gStringVar4, GetPlayerTextSpeedDelay())) { - sBerryBlenderData->framesToWait = 0; - sBerryBlenderData->gameEndState++; + sBerryBlender->framesToWait = 0; + sBerryBlender->gameEndState++; } break; case 4: - if (++sBerryBlenderData->framesToWait > 60) - sBerryBlenderData->gameEndState = 5; + if (++sBerryBlender->framesToWait > 60) + sBerryBlender->gameEndState = 5; break; case 5: - Blender_PrintText(&sBerryBlenderData->textState, gText_SavingDontTurnOff2, 0); + Blender_PrintText(&sBerryBlender->textState, gText_SavingDontTurnOff2, 0); SetLinkStandbyCallback(); - sBerryBlenderData->gameEndState++; + sBerryBlender->gameEndState++; break; case 6: if (IsLinkTaskFinished()) { - sBerryBlenderData->framesToWait = 0; - sBerryBlenderData->gameEndState++; - sBerryBlenderData->field_1A0 = 0; + sBerryBlender->framesToWait = 0; + sBerryBlender->gameEndState++; + sBerryBlender->linkPlayAgainState = 0; } break; case 7: if (LinkPlayAgainHandleSaving()) { PlaySE(SE_SAVE); - sBerryBlenderData->gameEndState++; + sBerryBlender->gameEndState++; } break; case 8: - sBerryBlenderData->gameEndState++; + sBerryBlender->gameEndState++; SetLinkStandbyCallback(); break; case 9: if (IsLinkTaskFinished()) { BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 0x10, RGB_BLACK); - sBerryBlenderData->gameEndState++; + sBerryBlender->gameEndState++; } break; case 10: if (!gPaletteFade.active) { - if (sBerryBlenderData->field_64[0] == 0x2222) + if (sBerryBlender->playerContinueResponses[0] == LINKCMD_SEND_LINK_TYPE) { FreeAllWindowBuffers(); UnsetBgTilemapBuffer(2); UnsetBgTilemapBuffer(1); - FREE_AND_SET_NULL(sBerryBlenderData); + FREE_AND_SET_NULL(sBerryBlender); SetMainCallback2(DoBerryBlending); } else { - sBerryBlenderData->framesToWait = 0; - sBerryBlenderData->gameEndState++; + sBerryBlender->framesToWait = 0; + sBerryBlender->gameEndState++; } } break; case 11: - if (++sBerryBlenderData->framesToWait > 30) + if (++sBerryBlender->framesToWait > 30) { SetCloseLinkCallback(); - sBerryBlenderData->gameEndState++; + sBerryBlender->gameEndState++; } break; case 12: - if (gReceivedRemoteLinkPlayers == 0) + if (!gReceivedRemoteLinkPlayers) { - FREE_AND_SET_NULL(sBerryBlenderData); + FREE_AND_SET_NULL(sBerryBlender); SetMainCallback2(CB2_ReturnToFieldContinueScriptPlayMapMusic); } break; } - sub_8082AD4(); - Blender_DummiedOutFunc(sBerryBlenderData->bg_X, sBerryBlenderData->bg_Y); + ProcessLinkPlayerCmds(); + Blender_DummiedOutFunc(sBerryBlender->bg_X, sBerryBlender->bg_Y); RunTasks(); AnimateSprites(); BuildOamBuffer(); @@ -2754,40 +2935,40 @@ static void CB2_HandlePlayerLinkPlayAgainChoice(void) UpdatePaletteFade(); } -static void CB2_HandlePlayerPlayAgainChoice(void) +static void CB2_CheckPlayAgainLocal(void) { - switch (sBerryBlenderData->gameEndState) + switch (sBerryBlender->gameEndState) { case 0: - if (sBerryBlenderData->playAgainState == PLAY_AGAIN_OK || sBerryBlenderData->playAgainState == DONT_PLAY_AGAIN) - sBerryBlenderData->gameEndState = 9; - if (sBerryBlenderData->playAgainState == CANT_PLAY_NO_BERRIES) - sBerryBlenderData->gameEndState = 2; - if (sBerryBlenderData->playAgainState == CANT_PLAY_NO_PKBLCK_SPACE) - sBerryBlenderData->gameEndState = 1; + if (sBerryBlender->playAgainState == PLAY_AGAIN_YES || sBerryBlender->playAgainState == PLAY_AGAIN_NO) + sBerryBlender->gameEndState = 9; + if (sBerryBlender->playAgainState == CANT_PLAY_NO_BERRIES) + sBerryBlender->gameEndState = 2; + if (sBerryBlender->playAgainState == CANT_PLAY_NO_PKBLCK_SPACE) + sBerryBlender->gameEndState = 1; break; case 1: - sBerryBlenderData->gameEndState = 3; - sBerryBlenderData->textState = 0; + sBerryBlender->gameEndState = 3; + sBerryBlender->textState = 0; StringCopy(gStringVar4, sText_YourPokeblockCaseIsFull); break; case 2: - sBerryBlenderData->gameEndState++; - sBerryBlenderData->textState = 0; + sBerryBlender->gameEndState++; + sBerryBlender->textState = 0; StringCopy(gStringVar4, sText_RunOutOfBerriesForBlending); break; case 3: - if (Blender_PrintText(&sBerryBlenderData->textState, gStringVar4, GetPlayerTextSpeedDelay())) - sBerryBlenderData->gameEndState = 9; + if (Blender_PrintText(&sBerryBlender->textState, gStringVar4, GetPlayerTextSpeedDelay())) + sBerryBlender->gameEndState = 9; break; case 9: BeginFastPaletteFade(3); - sBerryBlenderData->gameEndState++; + sBerryBlender->gameEndState++; break; case 10: if (!gPaletteFade.active) { - if (sBerryBlenderData->playAgainState == PLAY_AGAIN_OK) + if (sBerryBlender->playAgainState == PLAY_AGAIN_YES) SetMainCallback2(DoBerryBlending); else SetMainCallback2(CB2_ReturnToFieldContinueScriptPlayMapMusic); @@ -2795,13 +2976,13 @@ static void CB2_HandlePlayerPlayAgainChoice(void) FreeAllWindowBuffers(); UnsetBgTilemapBuffer(2); UnsetBgTilemapBuffer(1); - FREE_AND_SET_NULL(sBerryBlenderData); + FREE_AND_SET_NULL(sBerryBlender); } break; } - sub_8082AD4(); - Blender_DummiedOutFunc(sBerryBlenderData->bg_X, sBerryBlenderData->bg_Y); + ProcessLinkPlayerCmds(); + Blender_DummiedOutFunc(sBerryBlender->bg_X, sBerryBlender->bg_Y); RunTasks(); AnimateSprites(); BuildOamBuffer(); @@ -2809,152 +2990,169 @@ static void CB2_HandlePlayerPlayAgainChoice(void) UpdatePaletteFade(); } -static void sub_8082AD4(void) +static void ProcessLinkPlayerCmds(void) { if (gReceivedRemoteLinkPlayers) { - if (sub_80814B0(gRecvCmds[0][0], 0x2FFF, 0x2F00)) + if (CheckRecvCmdMatches(gRecvCmds[0][BLENDER_COMM_INPUT_STATE], LINKCMD_SEND_PACKET, RFUCMD_SEND_PACKET)) { - if (gRecvCmds[0][1] == 0x1111) + if (gRecvCmds[0][BLENDER_COMM_RESP] == LINKCMD_BLENDER_STOP) { - switch (gRecvCmds[0][2]) + // Link leader has indicated play is stopping, read signal to determine why + switch (gRecvCmds[0][BLENDER_COMM_STOP_TYPE]) { - case 0x8888: - sBerryBlenderData->field_6C = 0x8888; - sBerryBlenderData->field_6E = gRecvCmds[0][3]; + case LINKCMD_CONT_BLOCK: // Someone selected "No" to continue playing + sBerryBlender->canceledPlayerCmd = LINKCMD_CONT_BLOCK; + sBerryBlender->canceledPlayerId = gRecvCmds[0][BLENDER_COMM_PLAYER_ID]; break; - case 0x9999: - sBerryBlenderData->field_6C = 0x9999; - sBerryBlenderData->field_6E = gRecvCmds[0][3]; + case LINKCMD_BLENDER_NO_BERRIES: + sBerryBlender->canceledPlayerCmd = LINKCMD_BLENDER_NO_BERRIES; + sBerryBlender->canceledPlayerId = gRecvCmds[0][BLENDER_COMM_PLAYER_ID]; break; - case 0xAAAA: - sBerryBlenderData->field_6C = 0xAAAA; - sBerryBlenderData->field_6E = gRecvCmds[0][3]; + case LINKCMD_BLENDER_NO_PBLOCK_SPACE: + sBerryBlender->canceledPlayerCmd = LINKCMD_BLENDER_NO_PBLOCK_SPACE; + sBerryBlender->canceledPlayerId = gRecvCmds[0][BLENDER_COMM_PLAYER_ID]; break; } - sBerryBlenderData->field_64[0] = 0x1111; + sBerryBlender->playerContinueResponses[0] = LINKCMD_BLENDER_STOP; } - else if (gRecvCmds[0][1] == 0x2222) + else if (gRecvCmds[0][BLENDER_COMM_RESP] == LINKCMD_SEND_LINK_TYPE) { - sBerryBlenderData->field_64[0] = 0x2222; + // Link leader has indicated play will continue + sBerryBlender->playerContinueResponses[0] = LINKCMD_SEND_LINK_TYPE; } } - if (GetMultiplayerId() == 0 && sBerryBlenderData->field_64[0] != 0x1111 && sBerryBlenderData->field_64[0] != 0x2222) + + // If player is link leader, check for responses to the "Continue playing" prompt (even if it's not up yet) + if (GetMultiplayerId() == 0 + && sBerryBlender->playerContinueResponses[0] != LINKCMD_BLENDER_STOP + && sBerryBlender->playerContinueResponses[0] != LINKCMD_SEND_LINK_TYPE) { u8 i; + + // Try to gather responses for (i = 0; i < GetLinkPlayerCount(); i++) { - if (sub_80814B0(gRecvCmds[i][0], 0x2FFF, 0x2F00)) + if (CheckRecvCmdMatches(gRecvCmds[i][BLENDER_COMM_INPUT_STATE], LINKCMD_SEND_PACKET, RFUCMD_SEND_PACKET)) { - switch (gRecvCmds[i][1]) + switch (gRecvCmds[i][BLENDER_COMM_RESP]) { - case 0x8888: - sBerryBlenderData->field_64[i] = 0x8888; + case LINKCMD_CONT_BLOCK: // Selected "No" + sBerryBlender->playerContinueResponses[i] = LINKCMD_CONT_BLOCK; break; - case 0x7779: - sBerryBlenderData->field_64[i] = 0x7779; + case LINKCMD_BLENDER_PLAY_AGAIN: // Selected "Yes" + sBerryBlender->playerContinueResponses[i] = LINKCMD_BLENDER_PLAY_AGAIN; break; - case 0x9999: - sBerryBlenderData->field_64[i] = 0x9999; + case LINKCMD_BLENDER_NO_BERRIES: + sBerryBlender->playerContinueResponses[i] = LINKCMD_BLENDER_NO_BERRIES; break; - case 0xAAAA: - sBerryBlenderData->field_64[i] = 0xAAAA; + case LINKCMD_BLENDER_NO_PBLOCK_SPACE: + sBerryBlender->playerContinueResponses[i] = LINKCMD_BLENDER_NO_PBLOCK_SPACE; break; } } } + + // Count players that have responded, stopping at first non-response for (i = 0; i < GetLinkPlayerCount(); i++) { - if (sBerryBlenderData->field_64[i] == 0) + if (sBerryBlender->playerContinueResponses[i] == 0) break; } + + // If all players responded, handle response if (i == GetLinkPlayerCount()) { + // Count players that decided to play again, stopping at first negative response for (i = 0; i < GetLinkPlayerCount(); i++) { - if (sBerryBlenderData->field_64[i] != 0x7779) + if (sBerryBlender->playerContinueResponses[i] != LINKCMD_BLENDER_PLAY_AGAIN) break; } - sub_8081F94(&gSendCmd[0]); + + // Schedule signal to other players about whether or not play will continue + SendContinuePromptResponse(&gSendCmd[BLENDER_COMM_INPUT_STATE]); if (i == GetLinkPlayerCount()) { - gSendCmd[1] = 0x2222; + // All players chose to continue playing + gSendCmd[BLENDER_COMM_RESP] = LINKCMD_SEND_LINK_TYPE; } else { - gSendCmd[1] = 0x1111; - gSendCmd[2] = sBerryBlenderData->field_64[i]; - gSendCmd[3] = i; + // At least 1 player decided to stop playing, or can't continue playing + gSendCmd[BLENDER_COMM_RESP] = LINKCMD_BLENDER_STOP; + gSendCmd[BLENDER_COMM_STOP_TYPE] = sBerryBlender->playerContinueResponses[i]; + gSendCmd[BLENDER_COMM_PLAYER_ID] = i; } } } } } -static void sub_8082CB4(struct BgAffineSrcData *dest) +static void DrawBlenderCenter(struct BgAffineSrcData *dest) { struct BgAffineSrcData affineSrc; affineSrc.texX = 0x7800; affineSrc.texY = 0x5000; - affineSrc.scrX = 0x78 - sBerryBlenderData->bg_X; - affineSrc.scrY = 0x50 - sBerryBlenderData->bg_Y; - affineSrc.sx = sBerryBlenderData->field_11A; - affineSrc.sy = sBerryBlenderData->field_11A; - affineSrc.alpha = sBerryBlenderData->arrowPos; + affineSrc.scrX = 0x78 - sBerryBlender->bg_X; + affineSrc.scrY = 0x50 - sBerryBlender->bg_Y; + affineSrc.sx = sBerryBlender->centerScale; + affineSrc.sy = sBerryBlender->centerScale; + affineSrc.alpha = sBerryBlender->arrowPos; *dest = affineSrc; } u16 GetBlenderArrowPosition(void) { - return sBerryBlenderData->arrowPos; + return sBerryBlender->arrowPos; } -static void sub_8082D28(void) +static void UpdateBlenderCenter(void) { u8 playerId = 0; - if (gReceivedRemoteLinkPlayers != 0) + if (gReceivedRemoteLinkPlayers) playerId = GetMultiplayerId(); - if (gWirelessCommType && gReceivedRemoteLinkPlayers != 0) + if (gWirelessCommType && gReceivedRemoteLinkPlayers) { if (playerId == 0) { - sBerryBlenderData->arrowPos += sBerryBlenderData->field_4C; - gSendCmd[5] = sBerryBlenderData->field_116; - gSendCmd[6] = sBerryBlenderData->arrowPos; - sub_8082CB4(&sBerryBlenderData->bgAffineSrc); + sBerryBlender->arrowPos += sBerryBlender->speed; + gSendCmd[BLENDER_COMM_PROGRESS_BAR] = sBerryBlender->progressBarValue; + gSendCmd[BLENDER_COMM_ARROW_POS] = sBerryBlender->arrowPos; + DrawBlenderCenter(&sBerryBlender->bgAffineSrc); } else { - if ((gRecvCmds[0][0] & 0xFF00) == 0x4400) + if ((gRecvCmds[0][BLENDER_COMM_INPUT_STATE] & 0xFF00) == RFUCMD_BLENDER_SEND_KEYS) { - sBerryBlenderData->field_116 = gRecvCmds[0][5]; - sBerryBlenderData->arrowPos = gRecvCmds[0][6]; - sub_8082CB4(&sBerryBlenderData->bgAffineSrc); + sBerryBlender->progressBarValue = gRecvCmds[0][BLENDER_COMM_PROGRESS_BAR]; + sBerryBlender->arrowPos = gRecvCmds[0][BLENDER_COMM_ARROW_POS]; + DrawBlenderCenter(&sBerryBlender->bgAffineSrc); } } } else { - sBerryBlenderData->arrowPos += sBerryBlenderData->field_4C; - sub_8082CB4(&sBerryBlenderData->bgAffineSrc); + sBerryBlender->arrowPos += sBerryBlender->speed; + DrawBlenderCenter(&sBerryBlender->bgAffineSrc); } } -static void BerryBlender_SetBackgroundsPos(void) +static void SetBgPos(void) { - SetGpuReg(REG_OFFSET_BG1HOFS, sBerryBlenderData->bg_X); - SetGpuReg(REG_OFFSET_BG1VOFS, sBerryBlenderData->bg_Y); + SetGpuReg(REG_OFFSET_BG1HOFS, sBerryBlender->bg_X); + SetGpuReg(REG_OFFSET_BG1VOFS, sBerryBlender->bg_Y); - SetGpuReg(REG_OFFSET_BG0HOFS, sBerryBlenderData->bg_X); - SetGpuReg(REG_OFFSET_BG0VOFS, sBerryBlenderData->bg_Y); + SetGpuReg(REG_OFFSET_BG0HOFS, sBerryBlender->bg_X); + SetGpuReg(REG_OFFSET_BG0VOFS, sBerryBlender->bg_Y); } -static void sub_8082E3C(struct Sprite* sprite) +static void SpriteCB_Particle(struct Sprite* sprite) { sprite->data[2] += sprite->data[0]; sprite->data[3] += sprite->data[1]; @@ -2965,7 +3163,7 @@ static void sub_8082E3C(struct Sprite* sprite) DestroySprite(sprite); } -static void sub_8082E84(void) +static void CreateParticleSprites(void) { s32 limit = (Random() % 2) + 1; s32 i; @@ -2976,20 +3174,20 @@ static void sub_8082E84(void) s32 x, y; u8 spriteId; - rand = sBerryBlenderData->arrowPos + (Random() % 20); + rand = sBerryBlender->arrowPos + (Random() % 20); x = gSineTable[(rand & 0xFF) + 64] / 4; y = gSineTable[(rand & 0xFF)] / 4; - spriteId = CreateSprite(&sUnknown_08339BE0, x + 120, y + 80, 1); + spriteId = CreateSprite(&sSpriteTemplate_Particles, x + 120, y + 80, 1); gSprites[spriteId].data[0] = 16 - (Random() % 32); gSprites[spriteId].data[1] = 16 - (Random() % 32); - gSprites[spriteId].callback = sub_8082E3C; + gSprites[spriteId].callback = SpriteCB_Particle; } } -static void sub_8082F68(struct Sprite* sprite) +static void SpriteCB_ScoreSymbol(struct Sprite* sprite) { sprite->data[0]++; sprite->pos2.y = -(sprite->data[0] / 3); @@ -2998,7 +3196,7 @@ static void sub_8082F68(struct Sprite* sprite) DestroySprite(sprite); } -static void sub_8082F9C(struct Sprite* sprite) +static void SpriteCB_ScoreSymbolBest(struct Sprite* sprite) { sprite->data[0]++; sprite->pos2.y = -(sprite->data[0] * 2); @@ -3009,56 +3207,65 @@ static void sub_8082F9C(struct Sprite* sprite) DestroySprite(sprite); } -static void Blender_SetParticipantBerryData(u8 participantId, u16 itemId) +static void SetPlayerBerryData(u8 playerId, u16 itemId) { - sBerryBlenderData->chosenItemId[participantId] = itemId; - Blender_CopyBerryData(&sBerryBlenderData->blendedBerries[participantId], itemId); + sBerryBlender->chosenItemId[playerId] = itemId; + ConvertItemToBlenderBerry(&sBerryBlender->blendedBerries[playerId], itemId); } -static void sub_8083010(struct Sprite* sprite) +#define sState data[0] +#define sYPos data[1] +#define sDelay data[2] +#define sAnimId data[3] + +static void SpriteCB_CountdownNumber(struct Sprite* sprite) { - switch (sprite->data[0]) + switch (sprite->sState) { case 0: - sprite->data[1] += 8; - if (sprite->data[1] > 88) + sprite->sYPos += 8; + if (sprite->sYPos > DISPLAY_HEIGHT / 2 + 8) { - sprite->data[1] = 88; - sprite->data[0]++; + sprite->sYPos = DISPLAY_HEIGHT / 2 + 8; + sprite->sState++; PlaySE(SE_BALL_BOUNCE_1); } break; case 1: - sprite->data[2] += 1; - if (sprite->data[2] > 20) + if (++sprite->sDelay > 20) { - sprite->data[0]++; - sprite->data[2] = 0; + sprite->sState++; + sprite->sDelay = 0; } break; case 2: - sprite->data[1] += 4; - if (sprite->data[1] > 176) + sprite->sYPos += 4; + if (sprite->sYPos > DISPLAY_HEIGHT + 16) { - if (++sprite->data[3] == 3) + if (++sprite->sAnimId == 3) { DestroySprite(sprite); - CreateSprite(&sUnknown_08339C60, 120, -20, 2); + CreateSprite(&sSpriteTemplate_Start, 120, -20, 2); } else { - sprite->data[0] = 0; - sprite->data[1] = -16; - StartSpriteAnim(sprite, sprite->data[3]); + sprite->sState = 0; + sprite->sYPos = -16; + StartSpriteAnim(sprite, sprite->sAnimId); } } break; } - sprite->pos2.y = sprite->data[1]; + sprite->pos2.y = sprite->sYPos; } -static void sub_80830C0(struct Sprite* sprite) +#undef sState +#undef sYPos +#undef sDelay +#undef sAnimId + +static void SpriteCB_Start(struct Sprite* sprite) { switch (sprite->data[0]) { @@ -3078,9 +3285,9 @@ static void sub_80830C0(struct Sprite* sprite) break; case 2: sprite->data[1] += 4; - if (sprite->data[1] > 176) + if (sprite->data[1] > DISPLAY_HEIGHT + 16) { - sBerryBlenderData->mainState++; + sBerryBlender->mainState++; DestroySprite(sprite); } break; @@ -3089,175 +3296,190 @@ static void sub_80830C0(struct Sprite* sprite) sprite->pos2.y = sprite->data[1]; } -static void sub_8083140(u16 a0, u16 a1) +static void TryUpdateProgressBar(u16 current, u16 limit) { - if (sBerryBlenderData->field_118 < a0) + // Progress bar doesn't move unless it's going up + if (sBerryBlender->maxProgressBarValue < current) { - sBerryBlenderData->field_118 += 2; - sub_8083170(sBerryBlenderData->field_118, a1); + sBerryBlender->maxProgressBarValue += 2; + UpdateProgressBar(sBerryBlender->maxProgressBarValue, limit); } } -static void sub_8083170(u16 a0, u16 a1) +static void UpdateProgressBar(u16 value, u16 limit) { - s32 var1, var2, var3, var4; + s32 amountFilled, maxFilledSegment, subSegmentsFilled, i; u16 *vram; vram = (u16*)(BG_SCREEN_ADDR(12)); - var1 = (a0 * 64) / a1; - var2 = var1 / 8; - for (var4 = 0; var4 < var2; var4++) + amountFilled = (value * 64) / limit; + maxFilledSegment = amountFilled / 8; + + // Set filled progress bar tiles in full segments + for (i = 0; i < maxFilledSegment; i++) { - vram[11 + var4] = 0x80E9; - vram[43 + var4] = 0x80F9; + vram[11 + i] = PROGRESS_BAR_FILLED_TOP; + vram[43 + i] = PROGRESS_BAR_FILLED_BOTTOM; } - var3 = var1 % 8; - if (var3 != 0) + + // If progress bar between segments, fill with the corresponding partial segment tiles + subSegmentsFilled = amountFilled % 8; + if (subSegmentsFilled != 0) { - vram[11 + var4] = var3 + 0x80E1; - vram[43 + var4] = var3 + 0x80F1; - var4++; + vram[11 + i] = subSegmentsFilled + PROGRESS_BAR_EMPTY_TOP; + vram[43 + i] = subSegmentsFilled + PROGRESS_BAR_EMPTY_BOTTOM; + i++; } - for (; var4 < 8; var4++) + + // Fill the remaining full segments with empty progress tiles + // Essentially unnecessary, given that it starts empty and progress only goes up + for (; i < 8; i++) { - vram[11 + var4] = 0x80E1; - vram[43 + var4] = 0x80F1; + vram[11 + i] = PROGRESS_BAR_EMPTY_TOP; + vram[43 + i] = PROGRESS_BAR_EMPTY_BOTTOM; } } -static u32 sub_8083210(u16 a0) +static u32 ArrowSpeedToRPM(u16 speed) { - return 0x57E40 * a0 / 0x10000; + return 60 * 60 * 100 * speed / MAX_ARROW_POS; } -static void sub_8083230(u16 a0) +static void UpdateRPM(u16 speed) { u8 i; - u8 palAdders[5]; + u8 digits[5]; - u32 var = sub_8083210(a0); - if (sBerryBlenderData->max_RPM < var) - sBerryBlenderData->max_RPM = var; + // Check if new max RPM has been reached + u32 currentRPM = ArrowSpeedToRPM(speed); + if (sBerryBlender->maxRPM < currentRPM) + sBerryBlender->maxRPM = currentRPM; + + // Draw the current RPM number at the bottom of the screen for (i = 0; i < 5; i++) { - palAdders[i] = var % 10; - var /= 10; + digits[i] = currentRPM % 10; + currentRPM /= 10; } - *((u16*)(VRAM + 0x6458)) = palAdders[4] + 0x8072; - *((u16*)(VRAM + 0x645A)) = palAdders[3] + 0x8072; - *((u16*)(VRAM + 0x645C)) = palAdders[2] + 0x8072; - *((u16*)(VRAM + 0x6460)) = palAdders[1] + 0x8072; - *((u16*)(VRAM + 0x6462)) = palAdders[0] + 0x8072; + *((u16*)(BG_SCREEN_ADDR(12) + 0x458)) = digits[4] + RPM_DIGIT; + *((u16*)(BG_SCREEN_ADDR(12) + 0x45A)) = digits[3] + RPM_DIGIT; + *((u16*)(BG_SCREEN_ADDR(12) + 0x45C)) = digits[2] + RPM_DIGIT; + *((u16*)(BG_SCREEN_ADDR(12) + 0x460)) = digits[1] + RPM_DIGIT; + *((u16*)(BG_SCREEN_ADDR(12) + 0x462)) = digits[0] + RPM_DIGIT; } -static void sub_80832BC(s16* a0, u16 a1) +// Passed a pointer to the bg x/y +// Used when hitting a Best at high RPM +static void ShakeBgCoordForHit(s16* coord, u16 speed) { - if (*a0 == 0) - *a0 = (Random() % a1) - (a1 / 2); + if (*coord == 0) + *coord = (Random() % speed) - (speed / 2); } -static void sub_80832E8(s16* a0) +static void RestoreBgCoord(s16* coord) { - if (*a0 < 0) - (*a0)++; - if (*a0 > 0) - (*a0)--; + if (*coord < 0) + (*coord)++; + if (*coord > 0) + (*coord)--; } -static void sub_808330C(void) +// For "unshaking" the screen after ShakeBgCoordForHit is called +static void RestoreBgCoords(void) { - sub_80832E8((s16 *)&sBerryBlenderData->bg_X); - sub_80832E8((s16 *)&sBerryBlenderData->bg_Y); + RestoreBgCoord((s16 *)&sBerryBlender->bg_X); + RestoreBgCoord((s16 *)&sBerryBlender->bg_Y); } -static void sub_8083334(s16* a0, u16 a1) +static void BlenderLandShakeBgCoord(s16* coord, u16 timer) { - u8 var; + u8 strength; - if (a1 < 10) - var = 16; + if (timer < 10) + strength = 16; else - var = 8; + strength = 8; - if (*a0 == 0) + if (*coord == 0) { - *a0 = (Random() % var) - (var / 2); + *coord = (Random() % strength) - (strength / 2); } else { - if (*a0 < 0) - (*a0)++; - if (*a0 > 0) - (*a0)--; + if (*coord < 0) + (*coord)++; + if (*coord > 0) + (*coord)--; } } -static bool8 sub_8083380(void) +// For shaking the screen when the blender lands after falling in at the start +static bool8 UpdateBlenderLandScreenShake(void) { - if (sBerryBlenderData->framesToWait == 0) + if (sBerryBlender->framesToWait == 0) { - sBerryBlenderData->bg_X = 0; - sBerryBlenderData->bg_Y = 0; + sBerryBlender->bg_X = 0; + sBerryBlender->bg_Y = 0; } - sBerryBlenderData->framesToWait++; - sub_8083334(&sBerryBlenderData->bg_X, sBerryBlenderData->framesToWait); - sub_8083334(&sBerryBlenderData->bg_Y, sBerryBlenderData->framesToWait); + sBerryBlender->framesToWait++; + BlenderLandShakeBgCoord(&sBerryBlender->bg_X, sBerryBlender->framesToWait); + BlenderLandShakeBgCoord(&sBerryBlender->bg_Y, sBerryBlender->framesToWait); - if (sBerryBlenderData->framesToWait == 20) + if (sBerryBlender->framesToWait == 20) { - sBerryBlenderData->bg_X = 0; - sBerryBlenderData->bg_Y = 0; + sBerryBlender->bg_X = 0; + sBerryBlender->bg_Y = 0; return TRUE; } return FALSE; } -static void sub_80833F8(struct Sprite* sprite) +static void SpriteCB_PlayerArrow(struct Sprite* sprite) { - sprite->pos2.x = -(sBerryBlenderData->bg_X); - sprite->pos2.y = -(sBerryBlenderData->bg_Y); + sprite->pos2.x = -(sBerryBlender->bg_X); + sprite->pos2.y = -(sBerryBlender->bg_Y); } static void TryUpdateBerryBlenderRecord(void) { - if (gSaveBlock1Ptr->berryBlenderRecords[sBerryBlenderData->playersNo - 2] < sBerryBlenderData->max_RPM) - gSaveBlock1Ptr->berryBlenderRecords[sBerryBlenderData->playersNo - 2] = sBerryBlenderData->max_RPM; + if (gSaveBlock1Ptr->berryBlenderRecords[sBerryBlender->numPlayers - 2] < sBerryBlender->maxRPM) + gSaveBlock1Ptr->berryBlenderRecords[sBerryBlender->numPlayers - 2] = sBerryBlender->maxRPM; } -static bool8 Blender_PrintBlendingResults(void) +static bool8 PrintBlendingResults(void) { u16 i; s32 xPos, yPos; struct Pokeblock pokeblock; - u8 flavors[6]; + u8 flavors[FLAVOR_COUNT + 1]; u8 text[40]; u16 berryIds[4]; // unused - switch (sBerryBlenderData->mainState) + switch (sBerryBlender->mainState) { case 0: - sBerryBlenderData->mainState++; - sBerryBlenderData->framesToWait = 17; + sBerryBlender->mainState++; + sBerryBlender->framesToWait = 17; break; case 1: - sBerryBlenderData->framesToWait -= 10; - if (sBerryBlenderData->framesToWait < 0) + sBerryBlender->framesToWait -= 10; + if (sBerryBlender->framesToWait < 0) { - sBerryBlenderData->framesToWait = 0; - sBerryBlenderData->mainState++; + sBerryBlender->framesToWait = 0; + sBerryBlender->mainState++; } break; case 2: - if (++sBerryBlenderData->framesToWait > 20) + if (++sBerryBlender->framesToWait > 20) { - for (i = 0; i < BLENDER_SCORES_NO; i++) - DestroySprite(&gSprites[sBerryBlenderData->scoreIconIds[i]]); + for (i = 0; i < NUM_SCORE_TYPES; i++) + DestroySprite(&gSprites[sBerryBlender->scoreIconIds[i]]); - sBerryBlenderData->framesToWait = 0; - sBerryBlenderData->mainState++; + sBerryBlender->framesToWait = 0; + sBerryBlender->mainState++; } break; case 3: @@ -3268,92 +3490,91 @@ static bool8 Blender_PrintBlendingResults(void) xPos = GetStringCenterAlignXOffset(1, sText_BlendingResults, 0xA8); Blender_AddTextPrinter(5, sText_BlendingResults, xPos, 1, TEXT_SPEED_FF, 0); - if (sBerryBlenderData->playersNo == 4) + if (sBerryBlender->numPlayers == BLENDER_MAX_PLAYERS) yPos = 17; else yPos = 21; - for (i = 0; i < sBerryBlenderData->playersNo; yPos += 16, i++) + for (i = 0; i < sBerryBlender->numPlayers; yPos += 16, i++) { - u8 place = sBerryBlenderData->playerPlaces[i]; + u8 place = sBerryBlender->playerPlaces[i]; - ConvertIntToDecimalStringN(sBerryBlenderData->stringVar, i + 1, STR_CONV_MODE_LEFT_ALIGN, 1); - StringAppend(sBerryBlenderData->stringVar, sText_Dot); - StringAppend(sBerryBlenderData->stringVar, gText_Space); - StringAppend(sBerryBlenderData->stringVar, gLinkPlayers[place].name); - Blender_AddTextPrinter(5, sBerryBlenderData->stringVar, 8, yPos, TEXT_SPEED_FF, 3); + ConvertIntToDecimalStringN(sBerryBlender->stringVar, i + 1, STR_CONV_MODE_LEFT_ALIGN, 1); + StringAppend(sBerryBlender->stringVar, sText_Dot); + StringAppend(sBerryBlender->stringVar, gText_Space); + StringAppend(sBerryBlender->stringVar, gLinkPlayers[place].name); + Blender_AddTextPrinter(5, sBerryBlender->stringVar, 8, yPos, TEXT_SPEED_FF, 3); - StringCopy(sBerryBlenderData->stringVar, sBerryBlenderData->blendedBerries[place].name); - ConvertInternationalString(sBerryBlenderData->stringVar, gLinkPlayers[place].language); - StringAppend(sBerryBlenderData->stringVar, sText_SpaceBerry); - Blender_AddTextPrinter(5, sBerryBlenderData->stringVar, 0x54, yPos, TEXT_SPEED_FF, 3); + StringCopy(sBerryBlender->stringVar, sBerryBlender->blendedBerries[place].name); + ConvertInternationalString(sBerryBlender->stringVar, gLinkPlayers[place].language); + StringAppend(sBerryBlender->stringVar, sText_SpaceBerry); + Blender_AddTextPrinter(5, sBerryBlender->stringVar, 0x54, yPos, TEXT_SPEED_FF, 3); } Blender_AddTextPrinter(5, sText_MaximumSpeed, 0, 0x51, TEXT_SPEED_FF, 3); - ConvertIntToDecimalStringN(sBerryBlenderData->stringVar, sBerryBlenderData->max_RPM / 100, STR_CONV_MODE_RIGHT_ALIGN, 3); - StringAppend(sBerryBlenderData->stringVar, sText_Dot); + ConvertIntToDecimalStringN(sBerryBlender->stringVar, sBerryBlender->maxRPM / 100, STR_CONV_MODE_RIGHT_ALIGN, 3); + StringAppend(sBerryBlender->stringVar, sText_Dot); - ConvertIntToDecimalStringN(text, sBerryBlenderData->max_RPM % 100, STR_CONV_MODE_LEADING_ZEROS, 2); - StringAppend(sBerryBlenderData->stringVar, text); - StringAppend(sBerryBlenderData->stringVar, sText_RPM); + ConvertIntToDecimalStringN(text, sBerryBlender->maxRPM % 100, STR_CONV_MODE_LEADING_ZEROS, 2); + StringAppend(sBerryBlender->stringVar, text); + StringAppend(sBerryBlender->stringVar, sText_RPM); - xPos = GetStringRightAlignXOffset(1, sBerryBlenderData->stringVar, 0xA8); - Blender_AddTextPrinter(5, sBerryBlenderData->stringVar, xPos, 0x51, TEXT_SPEED_FF, 3); + xPos = GetStringRightAlignXOffset(1, sBerryBlender->stringVar, 0xA8); + Blender_AddTextPrinter(5, sBerryBlender->stringVar, xPos, 0x51, TEXT_SPEED_FF, 3); Blender_AddTextPrinter(5, sText_Time, 0, 0x61, TEXT_SPEED_FF, 3); - seconds = (sBerryBlenderData->gameFrameTime / 60) % 60; - minutes = (sBerryBlenderData->gameFrameTime / (60 * 60)); + seconds = (sBerryBlender->gameFrameTime / 60) % 60; + minutes = (sBerryBlender->gameFrameTime / (60 * 60)); - ConvertIntToDecimalStringN(sBerryBlenderData->stringVar, minutes, STR_CONV_MODE_LEADING_ZEROS, 2); - txtPtr = StringAppend(sBerryBlenderData->stringVar, sText_Min); + ConvertIntToDecimalStringN(sBerryBlender->stringVar, minutes, STR_CONV_MODE_LEADING_ZEROS, 2); + txtPtr = StringAppend(sBerryBlender->stringVar, sText_Min); ConvertIntToDecimalStringN(txtPtr, seconds, STR_CONV_MODE_LEADING_ZEROS, 2); - StringAppend(sBerryBlenderData->stringVar, sText_Sec); + StringAppend(sBerryBlender->stringVar, sText_Sec); - xPos = GetStringRightAlignXOffset(1, sBerryBlenderData->stringVar, 0xA8); - Blender_AddTextPrinter(5, sBerryBlenderData->stringVar, xPos, 0x61, TEXT_SPEED_FF, 3); + xPos = GetStringRightAlignXOffset(1, sBerryBlender->stringVar, 0xA8); + Blender_AddTextPrinter(5, sBerryBlender->stringVar, xPos, 0x61, TEXT_SPEED_FF, 3); - sBerryBlenderData->framesToWait = 0; - sBerryBlenderData->mainState++; + sBerryBlender->framesToWait = 0; + sBerryBlender->mainState++; CopyWindowToVram(5, 2); } break; case 4: - if (gMain.newKeys & A_BUTTON) - sBerryBlenderData->mainState++; + if (JOY_NEW(A_BUTTON)) + sBerryBlender->mainState++; break; case 5: ClearStdWindowAndFrameToTransparent(5, 1); for (i = 0; i < BLENDER_MAX_PLAYERS; i++) { - if (sBerryBlenderData->chosenItemId[i] != 0) - berryIds[i] = sBerryBlenderData->chosenItemId[i] - FIRST_BERRY_INDEX; - if (sBerryBlenderData->field_8E[i] != 0xFF) + if (sBerryBlender->chosenItemId[i] != 0) + berryIds[i] = sBerryBlender->chosenItemId[i] - FIRST_BERRY_INDEX; + if (sBerryBlender->arrowIdToPlayerId[i] != NO_PLAYER) { PutWindowTilemap(i); CopyWindowToVram(i, 3); } } - sub_8081E20(); + Debug_SetStageVars(); + CalculatePokeblock(sBerryBlender->blendedBerries, &pokeblock, sBerryBlender->numPlayers, flavors, sBerryBlender->maxRPM); + PrintMadePokeblockString(&pokeblock, sBerryBlender->stringVar); + TryAddContestLinkTvShow(&pokeblock, &sBerryBlender->tvBlender); - Blender_CalculatePokeblock(sBerryBlenderData->blendedBerries, &pokeblock, sBerryBlenderData->playersNo, flavors, sBerryBlenderData->max_RPM); - Blender_PrintMadePokeblockString(&pokeblock, sBerryBlenderData->stringVar); - TryAddContestLinkTvShow(&pokeblock, &sBerryBlenderData->tvBlender); - - CreateTask(sub_8083F3C, 6); + CreateTask(Task_PlayPokeblockFanfare, 6); IncrementDailyBerryBlender(); RemoveBagItem(gSpecialVar_ItemId, 1); AddPokeblock(&pokeblock); - sBerryBlenderData->textState = 0; - sBerryBlenderData->mainState++; + sBerryBlender->textState = 0; + sBerryBlender->mainState++; break; case 6: - if (Blender_PrintText(&sBerryBlenderData->textState, sBerryBlenderData->stringVar, GetPlayerTextSpeedDelay())) + if (Blender_PrintText(&sBerryBlender->textState, sBerryBlender->stringVar, GetPlayerTextSpeedDelay())) { TryUpdateBerryBlenderRecord(); return TRUE; @@ -3364,7 +3585,7 @@ static bool8 Blender_PrintBlendingResults(void) return FALSE; } -static void Blender_PrintMadePokeblockString(struct Pokeblock *pokeblock, u8 *dst) +static void PrintMadePokeblockString(struct Pokeblock *pokeblock, u8 *dst) { u8 text[12]; u8 flavorLvl, feel; @@ -3389,7 +3610,7 @@ static void Blender_PrintMadePokeblockString(struct Pokeblock *pokeblock, u8 *ds StringAppend(dst, sText_NewParagraph); } -static void Blender_SortBasedOnPoints(u8 *places, u8 playersNum, u32 *scores) +static void SortBasedOnPoints(u8 *places, u8 playersNum, u32 *scores) { s32 i, j; @@ -3399,128 +3620,128 @@ static void Blender_SortBasedOnPoints(u8 *places, u8 playersNum, u32 *scores) { if (scores[places[i]] > scores[places[j]]) { - u8 temp = places[i]; - places[i] = places[j]; - places[j] = temp; + u8 temp; + SWAP(places[i], places[j], temp); } } } } -static void Blender_SortScores(void) +static void SortScores(void) { u8 playerId; u8 i; u8 places[BLENDER_MAX_PLAYERS]; u32 points[BLENDER_MAX_PLAYERS]; - for (i = 0; i < sBerryBlenderData->playersNo; i++) + for (i = 0; i < sBerryBlender->numPlayers; i++) places[i] = i; - for (i = 0; i < sBerryBlenderData->playersNo; i++) + for (i = 0; i < sBerryBlender->numPlayers; i++) { - points[i] = 1000000 * sBerryBlenderData->scores[i][BLENDER_SCORE_BEST]; - points[i] += 1000 * sBerryBlenderData->scores[i][BLENDER_SCORE_GOOD]; - points[i] += 1000 - sBerryBlenderData->scores[i][BLENDER_SCORE_MISS]; + points[i] = 1000000 * sBerryBlender->scores[i][SCORE_BEST]; + points[i] += 1000 * sBerryBlender->scores[i][SCORE_GOOD]; + points[i] += 1000 - sBerryBlender->scores[i][SCORE_MISS]; } - Blender_SortBasedOnPoints(places, sBerryBlenderData->playersNo, points); - for (i = 0; i < sBerryBlenderData->playersNo; i++) - sBerryBlenderData->playerPlaces[i] = places[i]; + SortBasedOnPoints(places, sBerryBlender->numPlayers, points); + for (i = 0; i < sBerryBlender->numPlayers; i++) + sBerryBlender->playerPlaces[i] = places[i]; - if (gReceivedRemoteLinkPlayers == 0) + if (!gReceivedRemoteLinkPlayers) playerId = 0; else playerId = GetMultiplayerId(); - for (i = 0; i < sBerryBlenderData->playersNo; i++) + for (i = 0; i < sBerryBlender->numPlayers; i++) { - if (sBerryBlenderData->playerPlaces[i] == playerId) - sBerryBlenderData->field_1A4 = i; + if (sBerryBlender->playerPlaces[i] == playerId) + sBerryBlender->ownRanking = i; } } -static bool8 Blender_PrintBlendingRanking(void) +static bool8 PrintBlendingRanking(void) { u16 i; s32 xPos, yPos; - switch (sBerryBlenderData->mainState) + switch (sBerryBlender->mainState) { case 0: - sBerryBlenderData->mainState++; - sBerryBlenderData->framesToWait = 255; + sBerryBlender->mainState++; + sBerryBlender->framesToWait = 255; break; case 1: - sBerryBlenderData->framesToWait -= 10; - if (sBerryBlenderData->framesToWait < 0) + sBerryBlender->framesToWait -= 10; + if (sBerryBlender->framesToWait < 0) { - sBerryBlenderData->framesToWait = 0; - sBerryBlenderData->mainState++; + sBerryBlender->framesToWait = 0; + sBerryBlender->mainState++; } break; case 2: - if (++sBerryBlenderData->framesToWait > 20) + if (++sBerryBlender->framesToWait > 20) { - sBerryBlenderData->framesToWait = 0; - sBerryBlenderData->mainState++; + sBerryBlender->framesToWait = 0; + sBerryBlender->mainState++; } break; case 3: DrawStdFrameWithCustomTileAndPalette(5, 0, 1, 0xD); - xPos = GetStringCenterAlignXOffset(1, sText_Ranking, 0xA8); + xPos = GetStringCenterAlignXOffset(1, sText_Ranking, 168); Blender_AddTextPrinter(5, sText_Ranking, xPos, 1, TEXT_SPEED_FF, 0); - sBerryBlenderData->scoreIconIds[BLENDER_SCORE_BEST] = CreateSprite(&sUnknown_08339B40, 128, 52, 0); - StartSpriteAnim(&gSprites[sBerryBlenderData->scoreIconIds[BLENDER_SCORE_BEST]], 3); - gSprites[sBerryBlenderData->scoreIconIds[BLENDER_SCORE_BEST]].callback = SpriteCallbackDummy; + sBerryBlender->scoreIconIds[SCORE_BEST] = CreateSprite(&sSpriteTemplate_ScoreSymbols, 128, 52, 0); + StartSpriteAnim(&gSprites[sBerryBlender->scoreIconIds[SCORE_BEST]], SCOREANIM_BEST_STATIC); + gSprites[sBerryBlender->scoreIconIds[SCORE_BEST]].callback = SpriteCallbackDummy; - sBerryBlenderData->scoreIconIds[BLENDER_SCORE_GOOD] = CreateSprite(&sUnknown_08339B40, 160, 52, 0); - gSprites[sBerryBlenderData->scoreIconIds[BLENDER_SCORE_GOOD]].callback = SpriteCallbackDummy; + sBerryBlender->scoreIconIds[SCORE_GOOD] = CreateSprite(&sSpriteTemplate_ScoreSymbols, 160, 52, 0); + // implicitly uses SCOREANIM_GOOD, no need to assign + gSprites[sBerryBlender->scoreIconIds[SCORE_GOOD]].callback = SpriteCallbackDummy; - sBerryBlenderData->scoreIconIds[BLENDER_SCORE_MISS] = CreateSprite(&sUnknown_08339B40, 192, 52, 0); - StartSpriteAnim(&gSprites[sBerryBlenderData->scoreIconIds[BLENDER_SCORE_MISS]], 1); - gSprites[sBerryBlenderData->scoreIconIds[BLENDER_SCORE_MISS]].callback = SpriteCallbackDummy; + sBerryBlender->scoreIconIds[SCORE_MISS] = CreateSprite(&sSpriteTemplate_ScoreSymbols, 192, 52, 0); + StartSpriteAnim(&gSprites[sBerryBlender->scoreIconIds[SCORE_MISS]], SCOREANIM_MISS); + gSprites[sBerryBlender->scoreIconIds[SCORE_MISS]].callback = SpriteCallbackDummy; - Blender_SortScores(); + SortScores(); - for (yPos = 0x29, i = 0; i < sBerryBlenderData->playersNo; yPos += 0x10, i++) + for (yPos = 41, i = 0; i < sBerryBlender->numPlayers; yPos += 16, i++) { - u8 place = sBerryBlenderData->playerPlaces[i]; + u8 place = sBerryBlender->playerPlaces[i]; - ConvertIntToDecimalStringN(sBerryBlenderData->stringVar, i + 1, STR_CONV_MODE_LEFT_ALIGN, 1); - StringAppend(sBerryBlenderData->stringVar, sText_Dot); - StringAppend(sBerryBlenderData->stringVar, gText_Space); - StringAppend(sBerryBlenderData->stringVar, gLinkPlayers[place].name); - Blender_AddTextPrinter(5, sBerryBlenderData->stringVar, 0, yPos, TEXT_SPEED_FF, 3); + ConvertIntToDecimalStringN(sBerryBlender->stringVar, i + 1, STR_CONV_MODE_LEFT_ALIGN, 1); + StringAppend(sBerryBlender->stringVar, sText_Dot); + StringAppend(sBerryBlender->stringVar, gText_Space); + StringAppend(sBerryBlender->stringVar, gLinkPlayers[place].name); + Blender_AddTextPrinter(5, sBerryBlender->stringVar, 0, yPos, TEXT_SPEED_FF, 3); - ConvertIntToDecimalStringN(sBerryBlenderData->stringVar, sBerryBlenderData->scores[place][BLENDER_SCORE_BEST], STR_CONV_MODE_RIGHT_ALIGN, 3); - Blender_AddTextPrinter(5, sBerryBlenderData->stringVar, 0x4E, yPos, TEXT_SPEED_FF, 3); + ConvertIntToDecimalStringN(sBerryBlender->stringVar, sBerryBlender->scores[place][SCORE_BEST], STR_CONV_MODE_RIGHT_ALIGN, 3); + Blender_AddTextPrinter(5, sBerryBlender->stringVar, 78, yPos, TEXT_SPEED_FF, 3); - ConvertIntToDecimalStringN(sBerryBlenderData->stringVar, sBerryBlenderData->scores[place][BLENDER_SCORE_GOOD], STR_CONV_MODE_RIGHT_ALIGN, 3); - Blender_AddTextPrinter(5, sBerryBlenderData->stringVar, 0x6E, yPos, TEXT_SPEED_FF, 3); + ConvertIntToDecimalStringN(sBerryBlender->stringVar, sBerryBlender->scores[place][SCORE_GOOD], STR_CONV_MODE_RIGHT_ALIGN, 3); + Blender_AddTextPrinter(5, sBerryBlender->stringVar, 78 + 32, yPos, TEXT_SPEED_FF, 3); - ConvertIntToDecimalStringN(sBerryBlenderData->stringVar, sBerryBlenderData->scores[place][BLENDER_SCORE_MISS], STR_CONV_MODE_RIGHT_ALIGN, 3); - Blender_AddTextPrinter(5, sBerryBlenderData->stringVar, 0x8E, yPos, TEXT_SPEED_FF, 3); + ConvertIntToDecimalStringN(sBerryBlender->stringVar, sBerryBlender->scores[place][SCORE_MISS], STR_CONV_MODE_RIGHT_ALIGN, 3); + Blender_AddTextPrinter(5, sBerryBlender->stringVar, 78 + 64, yPos, TEXT_SPEED_FF, 3); } PutWindowTilemap(5); CopyWindowToVram(5, 3); - sBerryBlenderData->framesToWait = 0; - sBerryBlenderData->mainState++; + sBerryBlender->framesToWait = 0; + sBerryBlender->mainState++; break; case 4: - if (++sBerryBlenderData->framesToWait > 20) - sBerryBlenderData->mainState++; + if (++sBerryBlender->framesToWait > 20) + sBerryBlender->mainState++; break; case 5: - if (gMain.newKeys & A_BUTTON) + if (JOY_NEW(A_BUTTON)) { PlaySE(SE_SELECT); - sBerryBlenderData->mainState++; + sBerryBlender->mainState++; } break; case 6: - sBerryBlenderData->mainState = 0; + sBerryBlender->mainState = 0; return TRUE; } @@ -3539,11 +3760,11 @@ void ShowBerryBlenderRecordWindow(void) DrawStdWindowFrame(gRecordsWindowId, 0); FillWindowPixelBuffer(gRecordsWindowId, PIXEL_FILL(1)); - xPos = GetStringCenterAlignXOffset(1, gText_BlenderMaxSpeedRecord, 0x90); + xPos = GetStringCenterAlignXOffset(1, gText_BlenderMaxSpeedRecord, 144); AddTextPrinterParameterized(gRecordsWindowId, 1, gText_BlenderMaxSpeedRecord, xPos, 1, 0, NULL); - AddTextPrinterParameterized(gRecordsWindowId, 1, gText_234Players, 4, 0x29, 0, NULL); + AddTextPrinterParameterized(gRecordsWindowId, 1, gText_234Players, 4, 41, 0, NULL); - for (i = 0, yPos = 0x29; i < BLENDER_SCORES_NO; i++) + for (i = 0, yPos = 41; i < NUM_SCORE_TYPES; i++) { u8 *txtPtr; u32 record; @@ -3555,7 +3776,7 @@ void ShowBerryBlenderRecordWindow(void) txtPtr = ConvertIntToDecimalStringN(txtPtr, record % 100, STR_CONV_MODE_LEADING_ZEROS, 2); txtPtr = StringAppend(txtPtr, sText_RPM); - xPos = GetStringRightAlignXOffset(1, text, 0x8C); + xPos = GetStringRightAlignXOffset(1, text, 140); AddTextPrinterParameterized(gRecordsWindowId, 1, text, xPos, yPos + (i * 16), 0, NULL); } @@ -3563,7 +3784,7 @@ void ShowBerryBlenderRecordWindow(void) CopyWindowToVram(gRecordsWindowId, 3); } -static void sub_8083F3C(u8 taskId) +static void Task_PlayPokeblockFanfare(u8 taskId) { if (gTasks[taskId].data[0] == 0) { @@ -3572,7 +3793,7 @@ static void sub_8083F3C(u8 taskId) } if (IsFanfareTaskInactive()) { - PlayBGM(sBerryBlenderData->field_154); + PlayBGM(sBerryBlender->savedMusic); DestroyTask(taskId); } } @@ -3586,28 +3807,30 @@ static bool32 TryAddContestLinkTvShow(struct Pokeblock *pokeblock, struct TvBlen tvBlender->pokeblockColor = pokeblock->color; tvBlender->name[0] = EOS; - if (gReceivedRemoteLinkPlayers != 0) + if (gReceivedRemoteLinkPlayers) { - if (sBerryBlenderData->field_1A4 == 0 && sheen > 20) + if (sBerryBlender->ownRanking == 0 && sheen > 20) { - StringCopy(tvBlender->name, gLinkPlayers[sBerryBlenderData->playerPlaces[sBerryBlenderData->playersNo - 1]].name); + // Player came first, try to put on air + StringCopy(tvBlender->name, gLinkPlayers[sBerryBlender->playerPlaces[sBerryBlender->numPlayers - 1]].name); tvBlender->pokeblockFlavor = GetPokeblocksFlavor(pokeblock); if (Put3CheersForPokeblocksOnTheAir(tvBlender->name, tvBlender->pokeblockFlavor, tvBlender->pokeblockColor, tvBlender->pokeblockSheen, - gLinkPlayers[sBerryBlenderData->playerPlaces[sBerryBlenderData->playersNo - 1]].language)) + gLinkPlayers[sBerryBlender->playerPlaces[sBerryBlender->numPlayers - 1]].language)) { return TRUE; } return FALSE; } - else if (sBerryBlenderData->field_1A4 == sBerryBlenderData->playersNo - 1 && sheen <= 20) + else if (sBerryBlender->ownRanking == sBerryBlender->numPlayers - 1 && sheen <= 20) { - StringCopy(tvBlender->name, gLinkPlayers[sBerryBlenderData->playerPlaces[0]].name); + // Player came last, try to put on air + StringCopy(tvBlender->name, gLinkPlayers[sBerryBlender->playerPlaces[0]].name); tvBlender->pokeblockFlavor = GetPokeblocksFlavor(pokeblock); if (Put3CheersForPokeblocksOnTheAir(tvBlender->name, tvBlender->pokeblockFlavor, tvBlender->pokeblockColor, tvBlender->pokeblockSheen, - gLinkPlayers[sBerryBlenderData->playerPlaces[0]].language)) + gLinkPlayers[sBerryBlender->playerPlaces[0]].language)) { return TRUE; } @@ -3628,19 +3851,19 @@ static void Blender_AddTextPrinter(u8 windowId, const u8 *string, u8 x, u8 y, s3 { case 0: case 3: - txtColor[0] = 1; - txtColor[1] = 2; - txtColor[2] = 3; + txtColor[0] = TEXT_COLOR_WHITE; + txtColor[1] = TEXT_COLOR_DARK_GREY; + txtColor[2] = TEXT_COLOR_LIGHT_GREY; break; case 1: - txtColor[0] = 0; - txtColor[1] = 2; - txtColor[2] = 3; + txtColor[0] = TEXT_COLOR_TRANSPARENT; + txtColor[1] = TEXT_COLOR_DARK_GREY; + txtColor[2] = TEXT_COLOR_LIGHT_GREY; break; case 2: - txtColor[0] = 0; - txtColor[1] = 4; - txtColor[2] = 5; + txtColor[0] = TEXT_COLOR_TRANSPARENT; + txtColor[1] = TEXT_COLOR_RED; + txtColor[2] = TEXT_COLOR_LIGHT_RED; break; } diff --git a/src/berry_crush.c b/src/berry_crush.c index 6269f0ad9..d753e603c 100755 --- a/src/berry_crush.c +++ b/src/berry_crush.c @@ -900,7 +900,7 @@ static void sub_8020D8C(void) void sub_8020E1C(void) { DestroyTask(gUnknown_02022C90->unkA); - ChooseBerrySetCallback(sub_8020D8C); + ChooseBerryForMachine(sub_8020D8C); } static void sub_8020E3C(void) @@ -2357,7 +2357,7 @@ void sub_802339C(struct BerryCrushGame *r4) for (r7 = 0; r7 < r4->unk9; ++r7) { r2 = gRecvCmds[r7]; - if ((r2[0] & 0xFF00) == 0x2F00 + if ((r2[0] & 0xFF00) == RFUCMD_SEND_PACKET && r2[1] == 2) { if ((u8)r2[2] & 4) @@ -2559,7 +2559,7 @@ void sub_80236B8(struct BerryCrushGame *r5) r5->unk5C.unk02_1 = r5->unk25_4; r5->unk5C.unk0A = r5->unk25_5; memcpy(r5->unk40.unk2, &r5->unk5C, sizeof(r5->unk40.unk2)); - sub_800FE50(r5->unk40.unk2); + Rfu_SendPacket(r5->unk40.unk2); } void sub_802385C(struct BerryCrushGame *r5) @@ -2580,7 +2580,7 @@ void sub_802385C(struct BerryCrushGame *r5) for (r4 = 0; r4 < r5->unk9; ++r4) r5->unk68.as_four_players.others[r4].unk4.as_2d_bytes[1][5] = 0; #endif - if ((gRecvCmds[0][0] & 0xFF00) != 0x2F00 + if ((gRecvCmds[0][0] & 0xFF00) != RFUCMD_SEND_PACKET || gRecvCmds[0][1] != 2) { r5->unk25_2 = 0; diff --git a/src/dodrio_berry_picking.c b/src/dodrio_berry_picking.c index f44ecb31c..34f73126b 100644 --- a/src/dodrio_berry_picking.c +++ b/src/dodrio_berry_picking.c @@ -2748,14 +2748,14 @@ static void sub_8027DD0(u32 arg0) struct UnkPacket1 packet; packet.id = 1; packet.unk4 = arg0; - sub_800FE50(&packet); + Rfu_SendPacket(&packet); } static u32 sub_8027DFC(u32 arg0) { struct UnkPacket1 *packet; - if ((gRecvCmds[0][0] & 0xFF00) != 0x2F00) + if ((gRecvCmds[0][0] & 0xFF00) != RFUCMD_SEND_PACKET) return 0; packet = (void *)&gRecvCmds[arg0][1]; @@ -2857,7 +2857,7 @@ static void sub_8027E30(struct DodrioSubstruct_31A0 *arg0, struct DodrioSubstruc packet.unkA_3 = arg6; packet.unkB_1 = arg7; packet.unkB_0 = arg8; - sub_800FE50(&packet); + Rfu_SendPacket(&packet); } static u32 sub_8028164(u32 unused, struct DodrioSubstruct_31A0 *arg0, struct DodrioSubstruct_31A0_2C *arg1, struct DodrioSubstruct_31A0_2C *arg2, struct DodrioSubstruct_31A0_2C *arg3, struct DodrioSubstruct_31A0_2C *arg4, struct DodrioSubstruct_31A0_2C *arg5, u8 *arg6, u32 *arg7, u32 *arg8) @@ -2865,7 +2865,7 @@ static u32 sub_8028164(u32 unused, struct DodrioSubstruct_31A0 *arg0, struct Dod struct UnkPacket2 *packet; struct DodrioSubstruct_31A0_14 *ptr = &arg0->unk14; - if ((gRecvCmds[0][0] & 0xFF00) != 0x2F00) + if ((gRecvCmds[0][0] & 0xFF00) != RFUCMD_SEND_PACKET) return 0; packet = (void *)&gRecvCmds[0][1]; @@ -2935,14 +2935,14 @@ static void sub_80282EC(u8 arg0) struct UnkPacket3 packet; packet.id = 3; packet.unk4 = arg0; - sub_800FE50(&packet); + Rfu_SendPacket(&packet); } static u32 sub_8028318(u32 arg0, u8 *arg1) { struct UnkPacket3 *packet; - if ((gRecvCmds[0][0] & 0xFF00) != 0x2F00) + if ((gRecvCmds[0][0] & 0xFF00) != RFUCMD_SEND_PACKET) return 0; packet = (void *)&gRecvCmds[arg0][1]; @@ -2966,14 +2966,14 @@ static void sub_8028350(u32 arg0) struct UnkPacket4 packet; packet.id = 4; packet.unk4 = arg0; - sub_800FE50(&packet); + Rfu_SendPacket(&packet); } static u32 sub_8028374(u32 arg0) { struct UnkPacket4 *packet; - if ((gRecvCmds[0][0] & 0xFF00) != 0x2F00) + if ((gRecvCmds[0][0] & 0xFF00) != RFUCMD_SEND_PACKET) return 0; packet = (void *)&gRecvCmds[arg0][1]; diff --git a/src/graphics.c b/src/graphics.c index 9a8d9f845..21aa7b50f 100644 --- a/src/graphics.c +++ b/src/graphics.c @@ -1067,10 +1067,9 @@ const u32 gBattleAnimBgPalette_Solarbeam[] = INCBIN_U32("graphics/battle_anims/b const u32 gUnknown_E6BC04[] = INCBIN_U32("graphics/unknown/unknown_E6BC04.bin.lz"); -const u32 sBlenderCenterGfx[] = INCBIN_U32("graphics/berry_blender/center.8bpp.lz"); - -const u32 gUnknown_08D91DB8[] = INCBIN_U32("graphics/berry_blender/outer.4bpp.lz"); -const u32 gUnknown_08D927EC[] = INCBIN_U32("graphics/berry_blender/outer_map.bin.lz"); +const u32 gBerryBlenderCenter_Gfx[] = INCBIN_U32("graphics/berry_blender/center.8bpp.lz"); +const u32 gBerryBlenderOuter_Gfx[] = INCBIN_U32("graphics/berry_blender/outer.4bpp.lz"); +const u32 gBerryBlenderOuter_Tilemap[] = INCBIN_U32("graphics/berry_blender/outer_map.bin.lz"); const u32 gBattleAnimBgPalette_Cosmic[] = INCBIN_U32("graphics/battle_anims/backgrounds/cosmic.gbapal.lz"); const u32 gBattleAnimBgImage_Cosmic[] = INCBIN_U32("graphics/battle_anims/backgrounds/cosmic.4bpp.lz"); @@ -1352,25 +1351,15 @@ const u16 gPokenavConditionMarker_Pal[] = INCBIN_U16("graphics/pokenav/condition const u8 gPokenavConditionMarker_Gfx[] = INCBIN_U8("graphics/pokenav/condition/marker.4bpp"); const u16 gBerryBlenderMiscPalette[] = INCBIN_U16("graphics/berry_blender/misc.gbapal"); - const u16 gBerryBlenderArrowPalette[] = INCBIN_U16("graphics/berry_blender/arrow.gbapal"); - const u8 gBerryBlenderBetaArrow_Gfx[] = INCBIN_U8("graphics/berry_blender/arrow_old.4bpp"); //unused - -const u8 gBerryBlenderMarubatsuTiles[] = INCBIN_U8("graphics/berry_blender/marubatsu.4bpp"); - -const u8 gBerryBlenderParticlesTiles[] = INCBIN_U8("graphics/berry_blender/particles.4bpp"); - +const u8 gBerryBlenderScoreSymbols_Gfx[] = INCBIN_U8("graphics/berry_blender/score_symbols.4bpp"); +const u8 gBerryBlenderParticles_Gfx[] = INCBIN_U8("graphics/berry_blender/particles.4bpp"); static const u8 sEmpty0[0x120] = {0}; - -const u8 gBerryBlenderCountdownNumbersTiles[] = INCBIN_U8("graphics/berry_blender/countdown_numbers.4bpp"); - -const u8 gBerryBlenderStartTiles[] = INCBIN_U8("graphics/berry_blender/start.4bpp"); - +const u8 gBerryBlenderCountdownNumbers_Gfx[] = INCBIN_U8("graphics/berry_blender/countdown_numbers.4bpp"); +const u8 gBerryBlenderStart_Gfx[] = INCBIN_U8("graphics/berry_blender/start.4bpp"); static const u8 sEmpty1[0x200] = {0}; - -const u8 gBerryBlenderArrowTiles[] = INCBIN_U8("graphics/berry_blender/arrow.4bpp"); - +const u8 gBerryBlenderPlayerArrow_Gfx[] = INCBIN_U8("graphics/berry_blender/arrow.4bpp"); static const u8 sEmpty2[0x2C0] = {0}; const u16 gEasyChatCursor_Pal[] = INCBIN_U16("graphics/easy_chat/cursor.gbapal"); diff --git a/src/item_menu.c b/src/item_menu.c index f2c7b25d8..ace2fd11e 100755 --- a/src/item_menu.c +++ b/src/item_menu.c @@ -534,14 +534,16 @@ void CB2_BagMenuFromBattle(void) GoToBattlePyramidBagMenu(1, CB2_SetUpReshowBattleScreenAfterMenu2); } +// Choosing berry to plant void CB2_ChooseBerry(void) { GoToBagMenu(ITEMMENULOCATION_BERRY_TREE, BERRIES_POCKET, CB2_ReturnToFieldContinueScript); } -void ChooseBerrySetCallback(void (*callback)(void)) +// Choosing berry for Berry Blender or Berry Crush +void ChooseBerryForMachine(void (*exitCallback)(void)) { - GoToBagMenu(ITEMMENULOCATION_BERRY_BLENDER_CRUSH, BERRIES_POCKET, callback); + GoToBagMenu(ITEMMENULOCATION_BERRY_BLENDER_CRUSH, BERRIES_POCKET, exitCallback); } void CB2_GoToSellMenu(void) diff --git a/src/item_menu_icons.c b/src/item_menu_icons.c index cfafcbb75..cc51236c8 100644 --- a/src/item_menu_icons.c +++ b/src/item_menu_icons.c @@ -310,51 +310,51 @@ static const struct SpriteTemplate gBerryPicRotatingSpriteTemplate = .callback = SpriteCallbackDummy, }; -static const struct CompressedTilesPal gBerryPicTable[] = +static const struct CompressedTilesPal sBerryPicTable[] = { - {gBerryPic_Cheri, gBerryPalette_Cheri}, - {gBerryPic_Chesto, gBerryPalette_Chesto}, - {gBerryPic_Pecha, gBerryPalette_Pecha}, - {gBerryPic_Rawst, gBerryPalette_Rawst}, - {gBerryPic_Aspear, gBerryPalette_Aspear}, - {gBerryPic_Leppa, gBerryPalette_Leppa}, - {gBerryPic_Oran, gBerryPalette_Oran}, - {gBerryPic_Persim, gBerryPalette_Persim}, - {gBerryPic_Lum, gBerryPalette_Lum}, - {gBerryPic_Sitrus, gBerryPalette_Sitrus}, - {gBerryPic_Figy, gBerryPalette_Figy}, - {gBerryPic_Wiki, gBerryPalette_Wiki}, - {gBerryPic_Mago, gBerryPalette_Mago}, - {gBerryPic_Aguav, gBerryPalette_Aguav}, - {gBerryPic_Iapapa, gBerryPalette_Iapapa}, - {gBerryPic_Razz, gBerryPalette_Razz}, - {gBerryPic_Bluk, gBerryPalette_Bluk}, - {gBerryPic_Nanab, gBerryPalette_Nanab}, - {gBerryPic_Wepear, gBerryPalette_Wepear}, - {gBerryPic_Pinap, gBerryPalette_Pinap}, - {gBerryPic_Pomeg, gBerryPalette_Pomeg}, - {gBerryPic_Kelpsy, gBerryPalette_Kelpsy}, - {gBerryPic_Qualot, gBerryPalette_Qualot}, - {gBerryPic_Hondew, gBerryPalette_Hondew}, - {gBerryPic_Grepa, gBerryPalette_Grepa}, - {gBerryPic_Tamato, gBerryPalette_Tamato}, - {gBerryPic_Cornn, gBerryPalette_Cornn}, - {gBerryPic_Magost, gBerryPalette_Magost}, - {gBerryPic_Rabuta, gBerryPalette_Rabuta}, - {gBerryPic_Nomel, gBerryPalette_Nomel}, - {gBerryPic_Spelon, gBerryPalette_Spelon}, - {gBerryPic_Pamtre, gBerryPalette_Pamtre}, - {gBerryPic_Watmel, gBerryPalette_Watmel}, - {gBerryPic_Durin, gBerryPalette_Durin}, - {gBerryPic_Belue, gBerryPalette_Belue}, - {gBerryPic_Liechi, gBerryPalette_Liechi}, - {gBerryPic_Ganlon, gBerryPalette_Ganlon}, - {gBerryPic_Salac, gBerryPalette_Salac}, - {gBerryPic_Petaya, gBerryPalette_Petaya}, - {gBerryPic_Apicot, gBerryPalette_Apicot}, - {gBerryPic_Lansat, gBerryPalette_Lansat}, - {gBerryPic_Starf, gBerryPalette_Starf}, - {gBerryPic_Enigma, gBerryPalette_Enigma}, + [ITEM_TO_BERRY(ITEM_CHERI_BERRY) - 1] = {gBerryPic_Cheri, gBerryPalette_Cheri}, + [ITEM_TO_BERRY(ITEM_CHESTO_BERRY) - 1] = {gBerryPic_Chesto, gBerryPalette_Chesto}, + [ITEM_TO_BERRY(ITEM_PECHA_BERRY) - 1] = {gBerryPic_Pecha, gBerryPalette_Pecha}, + [ITEM_TO_BERRY(ITEM_RAWST_BERRY) - 1] = {gBerryPic_Rawst, gBerryPalette_Rawst}, + [ITEM_TO_BERRY(ITEM_ASPEAR_BERRY) - 1] = {gBerryPic_Aspear, gBerryPalette_Aspear}, + [ITEM_TO_BERRY(ITEM_LEPPA_BERRY) - 1] = {gBerryPic_Leppa, gBerryPalette_Leppa}, + [ITEM_TO_BERRY(ITEM_ORAN_BERRY) - 1] = {gBerryPic_Oran, gBerryPalette_Oran}, + [ITEM_TO_BERRY(ITEM_PERSIM_BERRY) - 1] = {gBerryPic_Persim, gBerryPalette_Persim}, + [ITEM_TO_BERRY(ITEM_LUM_BERRY) - 1] = {gBerryPic_Lum, gBerryPalette_Lum}, + [ITEM_TO_BERRY(ITEM_SITRUS_BERRY) - 1] = {gBerryPic_Sitrus, gBerryPalette_Sitrus}, + [ITEM_TO_BERRY(ITEM_FIGY_BERRY) - 1] = {gBerryPic_Figy, gBerryPalette_Figy}, + [ITEM_TO_BERRY(ITEM_WIKI_BERRY) - 1] = {gBerryPic_Wiki, gBerryPalette_Wiki}, + [ITEM_TO_BERRY(ITEM_MAGO_BERRY) - 1] = {gBerryPic_Mago, gBerryPalette_Mago}, + [ITEM_TO_BERRY(ITEM_AGUAV_BERRY) - 1] = {gBerryPic_Aguav, gBerryPalette_Aguav}, + [ITEM_TO_BERRY(ITEM_IAPAPA_BERRY) - 1] = {gBerryPic_Iapapa, gBerryPalette_Iapapa}, + [ITEM_TO_BERRY(ITEM_RAZZ_BERRY) - 1] = {gBerryPic_Razz, gBerryPalette_Razz}, + [ITEM_TO_BERRY(ITEM_BLUK_BERRY) - 1] = {gBerryPic_Bluk, gBerryPalette_Bluk}, + [ITEM_TO_BERRY(ITEM_NANAB_BERRY) - 1] = {gBerryPic_Nanab, gBerryPalette_Nanab}, + [ITEM_TO_BERRY(ITEM_WEPEAR_BERRY) - 1] = {gBerryPic_Wepear, gBerryPalette_Wepear}, + [ITEM_TO_BERRY(ITEM_PINAP_BERRY) - 1] = {gBerryPic_Pinap, gBerryPalette_Pinap}, + [ITEM_TO_BERRY(ITEM_POMEG_BERRY) - 1] = {gBerryPic_Pomeg, gBerryPalette_Pomeg}, + [ITEM_TO_BERRY(ITEM_KELPSY_BERRY) - 1] = {gBerryPic_Kelpsy, gBerryPalette_Kelpsy}, + [ITEM_TO_BERRY(ITEM_QUALOT_BERRY) - 1] = {gBerryPic_Qualot, gBerryPalette_Qualot}, + [ITEM_TO_BERRY(ITEM_HONDEW_BERRY) - 1] = {gBerryPic_Hondew, gBerryPalette_Hondew}, + [ITEM_TO_BERRY(ITEM_GREPA_BERRY) - 1] = {gBerryPic_Grepa, gBerryPalette_Grepa}, + [ITEM_TO_BERRY(ITEM_TAMATO_BERRY) - 1] = {gBerryPic_Tamato, gBerryPalette_Tamato}, + [ITEM_TO_BERRY(ITEM_CORNN_BERRY) - 1] = {gBerryPic_Cornn, gBerryPalette_Cornn}, + [ITEM_TO_BERRY(ITEM_MAGOST_BERRY) - 1] = {gBerryPic_Magost, gBerryPalette_Magost}, + [ITEM_TO_BERRY(ITEM_RABUTA_BERRY) - 1] = {gBerryPic_Rabuta, gBerryPalette_Rabuta}, + [ITEM_TO_BERRY(ITEM_NOMEL_BERRY) - 1] = {gBerryPic_Nomel, gBerryPalette_Nomel}, + [ITEM_TO_BERRY(ITEM_SPELON_BERRY) - 1] = {gBerryPic_Spelon, gBerryPalette_Spelon}, + [ITEM_TO_BERRY(ITEM_PAMTRE_BERRY) - 1] = {gBerryPic_Pamtre, gBerryPalette_Pamtre}, + [ITEM_TO_BERRY(ITEM_WATMEL_BERRY) - 1] = {gBerryPic_Watmel, gBerryPalette_Watmel}, + [ITEM_TO_BERRY(ITEM_DURIN_BERRY) - 1] = {gBerryPic_Durin, gBerryPalette_Durin}, + [ITEM_TO_BERRY(ITEM_BELUE_BERRY) - 1] = {gBerryPic_Belue, gBerryPalette_Belue}, + [ITEM_TO_BERRY(ITEM_LIECHI_BERRY) - 1] = {gBerryPic_Liechi, gBerryPalette_Liechi}, + [ITEM_TO_BERRY(ITEM_GANLON_BERRY) - 1] = {gBerryPic_Ganlon, gBerryPalette_Ganlon}, + [ITEM_TO_BERRY(ITEM_SALAC_BERRY) - 1] = {gBerryPic_Salac, gBerryPalette_Salac}, + [ITEM_TO_BERRY(ITEM_PETAYA_BERRY) - 1] = {gBerryPic_Petaya, gBerryPalette_Petaya}, + [ITEM_TO_BERRY(ITEM_APICOT_BERRY) - 1] = {gBerryPic_Apicot, gBerryPalette_Apicot}, + [ITEM_TO_BERRY(ITEM_LANSAT_BERRY) - 1] = {gBerryPic_Lansat, gBerryPalette_Lansat}, + [ITEM_TO_BERRY(ITEM_STARF_BERRY) - 1] = {gBerryPic_Starf, gBerryPalette_Starf}, + [ITEM_TO_BERRY(ITEM_ENIGMA_BERRY) - 1] = {gBerryPic_Enigma, gBerryPalette_Enigma}, }; const struct CompressedSpriteSheet gBerryCheckCircleSpriteSheet = @@ -581,10 +581,10 @@ static void LoadBerryGfx(u8 berryId) // unknown empty if statement } - pal.data = gBerryPicTable[berryId].pal; + pal.data = sBerryPicTable[berryId].pal; pal.tag = TAG_BERRY_PIC_PAL; LoadCompressedSpritePalette(&pal); - LZDecompressWram(gBerryPicTable[berryId].tiles, &gDecompressionBuffer[0x1000]); + LZDecompressWram(sBerryPicTable[berryId].tiles, &gDecompressionBuffer[0x1000]); sub_80D5018(&gDecompressionBuffer[0x1000], &gDecompressionBuffer[0]); } @@ -599,7 +599,8 @@ void FreeBerryTagSpritePalette(void) FreeSpritePaletteByTag(TAG_BERRY_PIC_PAL); } -u8 LoadSpinningBerryPicGfx(u8 berryId, u8 x, u8 y, bool8 startAffine) +// For throwing berries into the Berry Blender +u8 CreateSpinningBerrySprite(u8 berryId, u8 x, u8 y, bool8 startAffine) { u8 spriteId; diff --git a/src/link.c b/src/link.c index 62a9e4151..cdaf58469 100644 --- a/src/link.c +++ b/src/link.c @@ -99,7 +99,7 @@ u16 gLinkSavedIme; EWRAM_DATA u8 gLinkTestDebugValuesEnabled = 0; EWRAM_DATA u8 gUnknown_020223BD = 0; -EWRAM_DATA u32 gUnknown_020223C0 = 0; +EWRAM_DATA u32 gBerryBlenderKeySendAttempts = 0; EWRAM_DATA u16 gBlockRecvBuffer[MAX_RFU_PLAYERS][BLOCK_BUFFER_SIZE / 2] = {}; EWRAM_DATA u8 gBlockSendBuffer[BLOCK_BUFFER_SIZE] = {}; EWRAM_DATA bool8 gLinkOpen = FALSE; @@ -552,7 +552,7 @@ static void ProcessRecvCmds(u8 unused) InitBlockSend(block, sizeof(*block)); break; } - case LINKCMD_SEND_HELD_KEYS: + case LINKCMD_BLENDER_SEND_KEYS: gLinkPartnersHeldKeys[i] = gRecvCmds[i][1]; break; case LINKCMD_0x5555: @@ -636,13 +636,13 @@ static void ProcessRecvCmds(u8 unused) case LINKCMD_READY_EXIT_STANDBY: gReadyToExitStandby[i] = TRUE; break; - case LINKCMD_0xAAAA: - sub_800A418(); + case LINKCMD_BLENDER_NO_PBLOCK_SPACE: + SetBerryBlenderLinkCallback(); break; case LINKCMD_SEND_BLOCK_REQ: SendBlock(0, sBlockRequests[gRecvCmds[i][1]].address, sBlockRequests[gRecvCmds[i][1]].size); break; - case LINKCMD_SEND_HELD_KEYS_2: + case LINKCMD_SEND_HELD_KEYS: gLinkPartnersHeldKeys[i] = gRecvCmds[i][1]; break; } @@ -660,8 +660,8 @@ static void BuildSendCmd(u16 command) case LINKCMD_READY_EXIT_STANDBY: gSendCmd[0] = LINKCMD_READY_EXIT_STANDBY; break; - case LINKCMD_SEND_HELD_KEYS: - gSendCmd[0] = LINKCMD_SEND_HELD_KEYS; + case LINKCMD_BLENDER_SEND_KEYS: + gSendCmd[0] = LINKCMD_BLENDER_SEND_KEYS; gSendCmd[1] = gMain.heldKeys; break; case LINKCMD_0x5555: @@ -687,8 +687,8 @@ static void BuildSendCmd(u16 command) gSendCmd[1] = sBlockSend.size; gSendCmd[2] = sBlockSend.multiplayerId + 0x80; break; - case LINKCMD_0xAAAA: - gSendCmd[0] = LINKCMD_0xAAAA; + case LINKCMD_BLENDER_NO_PBLOCK_SPACE: + gSendCmd[0] = LINKCMD_BLENDER_NO_PBLOCK_SPACE; break; case LINKCMD_0xAAAB: gSendCmd[0] = LINKCMD_0xAAAB; @@ -705,12 +705,12 @@ static void BuildSendCmd(u16 command) case LINKCMD_0x5566: gSendCmd[0] = LINKCMD_0x5566; break; - case LINKCMD_SEND_HELD_KEYS_2: + case LINKCMD_SEND_HELD_KEYS: if (gHeldKeyCodeToSend == 0 || gLinkTransferringData) { break; } - gSendCmd[0] = LINKCMD_SEND_HELD_KEYS_2; + gSendCmd[0] = LINKCMD_SEND_HELD_KEYS; gSendCmd[1] = gHeldKeyCodeToSend; break; } @@ -738,7 +738,7 @@ bool32 IsSendingKeysToLink(void) static void LinkCB_SendHeldKeys(void) { if (gReceivedRemoteLinkPlayers == TRUE) - BuildSendCmd(LINKCMD_SEND_HELD_KEYS_2); + BuildSendCmd(LINKCMD_SEND_HELD_KEYS); } void ClearLinkCallback(void) @@ -1009,34 +1009,36 @@ static void LinkCB_BlockSendEnd(void) gLinkCallback = NULL; } -static void sub_800A3F8(void) +static void LinkCB_BerryBlenderSendHeldKeys(void) { GetMultiplayerId(); - BuildSendCmd(LINKCMD_SEND_HELD_KEYS); - gUnknown_020223C0++; + BuildSendCmd(LINKCMD_BLENDER_SEND_KEYS); + gBerryBlenderKeySendAttempts++; } -void sub_800A418(void) +void SetBerryBlenderLinkCallback(void) { - gUnknown_020223C0 = 0; + gBerryBlenderKeySendAttempts = 0; if (gWirelessCommType) { - sub_800F850(); + Rfu_SetBerryBlenderLinkCallback(); } else { - gLinkCallback = sub_800A3F8; + gLinkCallback = LinkCB_BerryBlenderSendHeldKeys; } } -u32 sub_800A44C(void) +// Unused +static u32 GetBerryBlenderKeySendAttempts(void) { - return gUnknown_020223C0; + return gBerryBlenderKeySendAttempts; } -void sub_800A458(void) +// Unused +static void SendBerryBlenderNoSpaceForPokeblocks(void) { - BuildSendCmd(LINKCMD_0xAAAA); + BuildSendCmd(LINKCMD_BLENDER_NO_PBLOCK_SPACE); } u8 GetMultiplayerId(void) diff --git a/src/link_rfu_2.c b/src/link_rfu_2.c index a8ead95d6..1ea6f4fce 100644 --- a/src/link_rfu_2.c +++ b/src/link_rfu_2.c @@ -929,7 +929,7 @@ static void HandleSendFailure(u8 unused, u32 flags) { if (!(flags & 1)) { - sResendBlock16[0] = RFU_COMMAND_0x8900 | i; + sResendBlock16[0] = RFUCMD_0x8900 | i; for (j = 0; j < 7; j++) { temp = j << 1; @@ -984,7 +984,7 @@ static void RfuFunc_SendKeysToRfu(void) { sHeldKeyCount++; gHeldKeyCodeToSend |= (sHeldKeyCount << 8); - RfuPrepareSendBuffer(RFU_COMMAND_0xBE00); + RfuPrepareSendBuffer(RFUCMD_SEND_HELD_KEYS); } } @@ -1008,18 +1008,18 @@ void ClearLinkRfuCallback(void) Rfu.callback = NULL; } -void sub_800F820(void) +static void Rfu_BerryBlenderSendHeldKeys(void) { - RfuPrepareSendBuffer(RFU_COMMAND_0x4400); + RfuPrepareSendBuffer(RFUCMD_BLENDER_SEND_KEYS); if (GetMultiplayerId() == 0) - gSendCmd[6] = GetBlenderArrowPosition(); - gUnknown_020223C0++; + gSendCmd[BLENDER_COMM_ARROW_POS] = GetBlenderArrowPosition(); + gBerryBlenderKeySendAttempts++; } -void sub_800F850(void) +void Rfu_SetBerryBlenderLinkCallback(void) { if (Rfu.callback == NULL) - Rfu.callback = sub_800F820; + Rfu.callback = Rfu_BerryBlenderSendHeldKeys; } static void RfuHandleReceiveCommand(u8 unused) @@ -1030,18 +1030,18 @@ static void RfuHandleReceiveCommand(u8 unused) { switch (gRecvCmds[i][0] & 0xff00) { - case RFU_COMMAND_0x7800: + case RFUCMD_0x7800: if (Rfu.parentChild == MODE_CHILD && gReceivedRemoteLinkPlayers) return; // fallthrough - case RFU_COMMAND_0x7700: + case RFUCMD_0x7700: if (gRfuLinkStatus->parentChild == MODE_CHILD) { Rfu.playerCount = gRecvCmds[i][1]; Rfu.multiplayerId = sub_800F74C((u8 *)(&gRecvCmds[i][2])); } break; - case RFU_COMMAND_0x8800: + case RFUCMD_0x8800: if (Rfu.recvBlock[i].receiving == 0) { Rfu.recvBlock[i].next = 0; @@ -1052,7 +1052,7 @@ static void RfuHandleReceiveCommand(u8 unused) Rfu.blockReceived[i] = FALSE; } break; - case RFU_COMMAND_0x8900: + case RFUCMD_0x8900: if (Rfu.recvBlock[i].receiving == 1) { Rfu.recvBlock[i].next = gRecvCmds[i][0] & 0xff; @@ -1068,17 +1068,17 @@ static void RfuHandleReceiveCommand(u8 unused) } } break; - case RFU_COMMAND_SEND_BLOCK_REQ: + case RFUCMD_SEND_BLOCK_REQ: Rfu_InitBlockSend(sBlockRequests[gRecvCmds[i][1]].address, (u16)sBlockRequests[gRecvCmds[i][1]].size); break; - case RFU_COMMAND_READY_CLOSE_LINK: + case RFUCMD_READY_CLOSE_LINK: Rfu.readyCloseLink[i] = TRUE; break; - case RFU_COMMAND_READY_EXIT_STANDBY: + case RFUCMD_READY_EXIT_STANDBY: if (Rfu.unk_100 == gRecvCmds[i][1]) Rfu.readyExitStandby[i] = TRUE; break; - case RFU_COMMAND_0xED00: + case RFUCMD_0xED00: if (Rfu.parentChild == MODE_CHILD) { if (gReceivedRemoteLinkPlayers) @@ -1095,13 +1095,13 @@ static void RfuHandleReceiveCommand(u8 unused) } else { - RfuPrepareSendBuffer(RFU_COMMAND_0xEE00); + RfuPrepareSendBuffer(RFUCMD_0xEE00); gSendCmd[1] = gRecvCmds[i][1]; gSendCmd[2] = gRecvCmds[i][2]; gSendCmd[3] = gRecvCmds[i][3]; } break; - case RFU_COMMAND_0xEE00: + case RFUCMD_0xEE00: if (Rfu.parentChild == MODE_PARENT) { Rfu.unk_ce3 |= gRecvCmds[i][1]; @@ -1109,8 +1109,8 @@ static void RfuHandleReceiveCommand(u8 unused) ClearSelectedLinkPlayerIds(gRecvCmds[i][1]); } break; - case RFU_COMMAND_0x4400: - case RFU_COMMAND_0xBE00: + case RFUCMD_BLENDER_SEND_KEYS: + case RFUCMD_SEND_HELD_KEYS: gLinkPartnersHeldKeys[i] = gRecvCmds[i][1]; break; } @@ -1186,16 +1186,16 @@ static void RfuPrepareSendBuffer(u16 command) gSendCmd[0] = command; switch (command) { - case RFU_COMMAND_0x8800: + case RFUCMD_0x8800: gSendCmd[1] = Rfu.sendBlock.count; gSendCmd[2] = Rfu.sendBlock.owner + 0x80; break; - case RFU_COMMAND_SEND_BLOCK_REQ: + case RFUCMD_SEND_BLOCK_REQ: if (AreNoPlayersReceiving()) gSendCmd[1] = Rfu.blockRequestType; break; - case RFU_COMMAND_0x7700: - case RFU_COMMAND_0x7800: + case RFUCMD_0x7700: + case RFUCMD_0x7800: tmp = Rfu.unk_ce2 ^ Rfu.unk_ce3; Rfu.playerCount = sUnknown_082ED695[tmp] + 1; gSendCmd[1] = Rfu.playerCount; @@ -1203,34 +1203,34 @@ static void RfuPrepareSendBuffer(u16 command) for (i = 0; i < RFU_CHILD_MAX; i++) buff[i] = Rfu.linkPlayerIdx[i]; break; - case RFU_COMMAND_READY_EXIT_STANDBY: - case RFU_COMMAND_READY_CLOSE_LINK: + case RFUCMD_READY_EXIT_STANDBY: + case RFUCMD_READY_CLOSE_LINK: gSendCmd[1] = Rfu.unk_100; break; - case RFU_COMMAND_0x4400: + case RFUCMD_BLENDER_SEND_KEYS: gSendCmd[0] = command; gSendCmd[1] = gMain.heldKeys; break; - case RFU_COMMAND_0x2F00: - for (i = 0; i < 6; i++) - gSendCmd[1 + i] = Rfu.unk_f2[i]; + case RFUCMD_SEND_PACKET: + for (i = 0; i < RFU_PACKET_SIZE; i++) + gSendCmd[1 + i] = Rfu.packet[i]; break; - case RFU_COMMAND_0xBE00: + case RFUCMD_SEND_HELD_KEYS: gSendCmd[1] = gHeldKeyCodeToSend; break; - case RFU_COMMAND_0xEE00: + case RFUCMD_0xEE00: break; - case RFU_COMMAND_0xED00: + case RFUCMD_0xED00: break; } } -void sub_800FE50(void *a0) +void Rfu_SendPacket(void *data) { if (gSendCmd[0] == 0 && !RfuHasErrored()) { - memcpy(Rfu.unk_f2, a0, sizeof(Rfu.unk_f2)); - RfuPrepareSendBuffer(RFU_COMMAND_0x2F00); + memcpy(Rfu.packet, data, sizeof(Rfu.packet)); + RfuPrepareSendBuffer(RFUCMD_SEND_PACKET); } } @@ -1258,7 +1258,7 @@ bool32 Rfu_InitBlockSend(const u8 *src, size_t size) memcpy(gBlockSendBuffer, src, size); Rfu.sendBlock.payload = gBlockSendBuffer; } - RfuPrepareSendBuffer(RFU_COMMAND_0x8800); + RfuPrepareSendBuffer(RFUCMD_0x8800); Rfu.callback = HandleBlockSend; Rfu.unk_5b = 0; return TRUE; @@ -1268,7 +1268,7 @@ static void HandleBlockSend(void) { if (gSendCmd[0] == 0) { - RfuPrepareSendBuffer(RFU_COMMAND_0x8800); + RfuPrepareSendBuffer(RFUCMD_0x8800); if (Rfu.parentChild == MODE_PARENT) { if (++Rfu.unk_5b > 2) @@ -1276,7 +1276,7 @@ static void HandleBlockSend(void) } else { - if ((gRecvCmds[GetMultiplayerId()][0] & 0xff00) == RFU_COMMAND_0x8800) + if ((gRecvCmds[GetMultiplayerId()][0] & 0xff00) == RFUCMD_0x8800) Rfu.callback = SendNextBlock; } } @@ -1286,7 +1286,7 @@ static void SendNextBlock(void) { s32 i; const u8 *src = Rfu.sendBlock.payload; - gSendCmd[0] = RFU_COMMAND_0x8900 | Rfu.sendBlock.next; + gSendCmd[0] = RFUCMD_0x8900 | Rfu.sendBlock.next; for (i = 0; i < CMD_LENGTH - 1; i++) gSendCmd[i + 1] = (src[(i << 1) + Rfu.sendBlock.next * 12 + 1] << 8) | src[(i << 1) + Rfu.sendBlock.next * 12 + 0]; Rfu.sendBlock.next++; @@ -1304,7 +1304,7 @@ static void SendLastBlock(void) s32 i; if (Rfu.parentChild == MODE_CHILD) { - gSendCmd[0] = RFU_COMMAND_0x8900 | (Rfu.sendBlock.count - 1); + gSendCmd[0] = RFUCMD_0x8900 | (Rfu.sendBlock.count - 1); for (i = 0; i < CMD_LENGTH - 1; i++) gSendCmd[i + 1] = (src[(i << 1) + (Rfu.sendBlock.count - 1) * 12 + 1] << 8) | src[(i << 1) + (Rfu.sendBlock.count - 1) * 12 + 0]; if ((u8)gRecvCmds[mpId][0] == Rfu.sendBlock.count - 1) @@ -1325,7 +1325,7 @@ static void SendLastBlock(void) bool8 Rfu_SendBlockRequest(u8 type) { Rfu.blockRequestType = type; - RfuPrepareSendBuffer(RFU_COMMAND_SEND_BLOCK_REQ); + RfuPrepareSendBuffer(RFUCMD_SEND_BLOCK_REQ); return TRUE; } @@ -1394,7 +1394,7 @@ static void SendReadyCloseLink(void) { if (gSendCmd[0] == 0 && Rfu.unk_ce8 == 0) { - RfuPrepareSendBuffer(RFU_COMMAND_READY_CLOSE_LINK); + RfuPrepareSendBuffer(RFUCMD_READY_CLOSE_LINK); Rfu.callback = WaitAllReadyToCloseLink; } } @@ -1421,7 +1421,7 @@ static void SendReadyExitStandbyUntilAllReady(void) if (GetMultiplayerId() != 0 && Rfu.recvQueue.count == 0 && Rfu.resendExitStandbyTimer > 60) { - RfuPrepareSendBuffer(RFU_COMMAND_READY_EXIT_STANDBY); + RfuPrepareSendBuffer(RFUCMD_READY_EXIT_STANDBY); Rfu.resendExitStandbyTimer = 0; } playerCount = GetLinkPlayerCount(); @@ -1444,7 +1444,7 @@ static void LinkLeaderReadyToExitStandby(void) { if (Rfu.recvQueue.count == 0 && gSendCmd[0] == 0) { - RfuPrepareSendBuffer(RFU_COMMAND_READY_EXIT_STANDBY); + RfuPrepareSendBuffer(RFUCMD_READY_EXIT_STANDBY); Rfu.callback = SendReadyExitStandbyUntilAllReady; } } @@ -1459,7 +1459,7 @@ static void Rfu_LinkStandby(void) // Not link leader, send exit standby when ready if (Rfu.recvQueue.count == 0 && gSendCmd[0] == 0) { - RfuPrepareSendBuffer(RFU_COMMAND_READY_EXIT_STANDBY); + RfuPrepareSendBuffer(RFUCMD_READY_EXIT_STANDBY); Rfu.callback = SendReadyExitStandbyUntilAllReady; } } @@ -1476,7 +1476,7 @@ static void Rfu_LinkStandby(void) { if (Rfu.recvQueue.count == 0 && gSendCmd[0] == 0) { - RfuPrepareSendBuffer(RFU_COMMAND_READY_EXIT_STANDBY); + RfuPrepareSendBuffer(RFUCMD_READY_EXIT_STANDBY); Rfu.callback = LinkLeaderReadyToExitStandby; } } @@ -1699,9 +1699,9 @@ static void sub_801084C(u8 taskId) if (Rfu.parentChild == MODE_PARENT) { if (gReceivedRemoteLinkPlayers) - RfuPrepareSendBuffer(RFU_COMMAND_0x7800); + RfuPrepareSendBuffer(RFUCMD_0x7800); else - RfuPrepareSendBuffer(RFU_COMMAND_0x7700); + RfuPrepareSendBuffer(RFUCMD_0x7700); gTasks[taskId].data[0] = 101; } else @@ -1721,7 +1721,7 @@ static void sub_801084C(u8 taskId) if (AreNoPlayersReceiving()) { Rfu.blockRequestType = 0; - RfuPrepareSendBuffer(RFU_COMMAND_SEND_BLOCK_REQ); + RfuPrepareSendBuffer(RFUCMD_SEND_BLOCK_REQ); gTasks[taskId].data[0]++; } } @@ -1811,7 +1811,7 @@ static void Task_ExchangeLinkPlayers(u8 taskId) if (gSendCmd[0] == 0) { ResetBlockReceivedFlag(r4); - RfuPrepareSendBuffer(RFU_COMMAND_0x7800); + RfuPrepareSendBuffer(RFUCMD_0x7800); gTasks[taskId].data[0]++; } break; @@ -2624,7 +2624,7 @@ static void sub_8011E2C(u8 taskId) { if (gSendCmd[0] == 0 && Rfu.unk_ce8 == 0) { - RfuPrepareSendBuffer(RFU_COMMAND_0xED00); + RfuPrepareSendBuffer(RFUCMD_0xED00); gSendCmd[1] = gTasks[taskId].data[0]; gSendCmd[2] = gTasks[taskId].data[1]; Rfu.playerCount -= sUnknown_082ED695[gTasks[taskId].data[0]]; diff --git a/src/minigame_countdown.c b/src/minigame_countdown.c index f5ef09cac..cd5710d44 100644 --- a/src/minigame_countdown.c +++ b/src/minigame_countdown.c @@ -262,15 +262,15 @@ static void sub_802EAB0(u8 taskId) if (gReceivedRemoteLinkPlayers != 0) { - if (gRecvCmds[0][1] == 0x7FFF) + if (gRecvCmds[0][1] == LINKCMD_0x7FFF) data[11] = gRecvCmds[0][2]; if (GetMultiplayerId() == 0) { data[12]++; memset(packet, 0, sizeof(packet)); - packet[0] = 0x7FFF; + packet[0] = LINKCMD_0x7FFF; packet[1] = data[12]; - sub_800FE50(packet); + Rfu_SendPacket(packet); } } else diff --git a/src/pokeblock.c b/src/pokeblock.c index 025adf875..11fe83240 100644 --- a/src/pokeblock.c +++ b/src/pokeblock.c @@ -180,21 +180,21 @@ static const struct BgTemplate sBgTemplatesForPokeblockMenu[] = const u8 *const gPokeblockNames[] = { - NULL, - gText_RedPokeblock, - gText_BluePokeblock, - gText_PinkPokeblock, - gText_GreenPokeblock, - gText_YellowPokeblock, - gText_PurplePokeblock, - gText_IndigoPokeblock, - gText_BrownPokeblock, - gText_LiteBluePokeblock, - gText_OlivePokeblock, - gText_GrayPokeblock, - gText_BlackPokeblock, - gText_WhitePokeblock, - gText_GoldPokeblock + [PBLOCK_CLR_NONE] = NULL, + [PBLOCK_CLR_RED] = gText_RedPokeblock, + [PBLOCK_CLR_BLUE] = gText_BluePokeblock, + [PBLOCK_CLR_PINK] = gText_PinkPokeblock, + [PBLOCK_CLR_GREEN] = gText_GreenPokeblock, + [PBLOCK_CLR_YELLOW] = gText_YellowPokeblock, + [PBLOCK_CLR_PURPLE] = gText_PurplePokeblock, + [PBLOCK_CLR_INDIGO] = gText_IndigoPokeblock, + [PBLOCK_CLR_BROWN] = gText_BrownPokeblock, + [PBLOCK_CLR_LITE_BLUE] = gText_LiteBluePokeblock, + [PBLOCK_CLR_OLIVE] = gText_OlivePokeblock, + [PBLOCK_CLR_GRAY] = gText_GrayPokeblock, + [PBLOCK_CLR_BLACK] = gText_BlackPokeblock, + [PBLOCK_CLR_WHITE] = gText_WhitePokeblock, + [PBLOCK_CLR_GOLD] = gText_GoldPokeblock }; static const struct MenuAction sPokeblockMenuActions[] = @@ -726,7 +726,7 @@ static void PutPokeblockListMenuString(u8 *dst, u16 pkblId) *(txtPtr++) = EXT_CTRL_CODE_BEGIN; *(txtPtr++) = EXT_CTRL_CODE_SKIP; - *(txtPtr++) = 87; + *(txtPtr++) = CHAR_BLOCK_1; ConvertIntToDecimalStringN(gStringVar1, GetHighestPokeblocksFlavorLevel(pkblock), STR_CONV_MODE_LEFT_ALIGN, 3); StringExpandPlaceholders(txtPtr, gText_LvVar1); @@ -804,7 +804,7 @@ static void CompactPokeblockSlots(void) { for (j = i + 1; j < POKEBLOCKS_COUNT; j++) { - if (gSaveBlock1Ptr->pokeblocks[i].color == 0) + if (gSaveBlock1Ptr->pokeblocks[i].color == PBLOCK_CLR_NONE) { struct Pokeblock temp = gSaveBlock1Ptr->pokeblocks[i]; gSaveBlock1Ptr->pokeblocks[i] = gSaveBlock1Ptr->pokeblocks[j]; @@ -856,7 +856,7 @@ static void SetMenuItemsCountAndMaxShowed(void) for (sPokeblockMenu->itemsNo = 0, i = 0; i < POKEBLOCKS_COUNT; i++) { - if (gSaveBlock1Ptr->pokeblocks[i].color != 0) + if (gSaveBlock1Ptr->pokeblocks[i].color != PBLOCK_CLR_NONE) sPokeblockMenu->itemsNo++; } @@ -1322,7 +1322,7 @@ s8 GetFirstFreePokeblockSlot(void) for (i = 0; i < POKEBLOCKS_COUNT; i++) { - if (gSaveBlock1Ptr->pokeblocks[i].color == 0) + if (gSaveBlock1Ptr->pokeblocks[i].color == PBLOCK_CLR_NONE) return i; } @@ -1346,7 +1346,7 @@ bool32 AddPokeblock(const struct Pokeblock *pokeblock) bool32 TryClearPokeblock(u8 pkblId) { - if (gSaveBlock1Ptr->pokeblocks[pkblId].color == 0) + if (gSaveBlock1Ptr->pokeblocks[pkblId].color == PBLOCK_CLR_NONE) { return FALSE; } diff --git a/src/pokeblock_feed.c b/src/pokeblock_feed.c index e15a005e6..797771f80 100644 --- a/src/pokeblock_feed.c +++ b/src/pokeblock_feed.c @@ -382,22 +382,23 @@ static const struct WindowTemplate sWindowTemplates[] = DUMMY_WIN_TEMPLATE }; +// - 1 excludes PBLOCK_CLR_NONE static const u32* const sPokeblocksPals[] = { - gPokeblockRed_Pal, - gPokeblockBlue_Pal, - gPokeblockPink_Pal, - gPokeblockGreen_Pal, - gPokeblockYellow_Pal, - gPokeblockPurple_Pal, - gPokeblockIndigo_Pal, - gPokeblockBrown_Pal, - gPokeblockLiteBlue_Pal, - gPokeblockOlive_Pal, - gPokeblockGray_Pal, - gPokeblockBlack_Pal, - gPokeblockWhite_Pal, - gPokeblockGold_Pal + [PBLOCK_CLR_RED - 1] = gPokeblockRed_Pal, + [PBLOCK_CLR_BLUE - 1] = gPokeblockBlue_Pal, + [PBLOCK_CLR_PINK - 1] = gPokeblockPink_Pal, + [PBLOCK_CLR_GREEN - 1] = gPokeblockGreen_Pal, + [PBLOCK_CLR_YELLOW - 1] = gPokeblockYellow_Pal, + [PBLOCK_CLR_PURPLE - 1] = gPokeblockPurple_Pal, + [PBLOCK_CLR_INDIGO - 1] = gPokeblockIndigo_Pal, + [PBLOCK_CLR_BROWN - 1] = gPokeblockBrown_Pal, + [PBLOCK_CLR_LITE_BLUE - 1] = gPokeblockLiteBlue_Pal, + [PBLOCK_CLR_OLIVE - 1] = gPokeblockOlive_Pal, + [PBLOCK_CLR_GRAY - 1] = gPokeblockGray_Pal, + [PBLOCK_CLR_BLACK - 1] = gPokeblockBlack_Pal, + [PBLOCK_CLR_WHITE - 1] = gPokeblockWhite_Pal, + [PBLOCK_CLR_GOLD - 1] = gPokeblockGold_Pal }; static const union AffineAnimCmd sSpriteAffineAnim_84120DC[] = diff --git a/src/pokemon_jump.c b/src/pokemon_jump.c index 96774c0bb..81f3a784f 100755 --- a/src/pokemon_jump.c +++ b/src/pokemon_jump.c @@ -3684,14 +3684,14 @@ static void sub_802E0AC(struct PokemonJump1_MonInfo *arg0) packet.species = arg0->species, packet.otId = arg0->otId, packet.personality = arg0->personality, - sub_800FE50(&packet); + Rfu_SendPacket(&packet); } static bool32 sub_802E0D0(int multiplayerId, struct PokemonJump1_MonInfo *arg0) { struct MonInfoPacket packet; - if ((gRecvCmds[multiplayerId][0] & 0xFF00) != 0x2F00) + if ((gRecvCmds[multiplayerId][0] & 0xFF00) != RFUCMD_SEND_PACKET) return FALSE; memcpy(&packet, &gRecvCmds[multiplayerId][1], sizeof(packet)); @@ -3718,7 +3718,7 @@ static void sub_802E120(u32 arg0) struct UnkPacket2 packet; packet.id = 2; packet.unk4 = arg0; - sub_800FE50(&packet); + Rfu_SendPacket(&packet); } struct UnkPacket3 @@ -3746,14 +3746,14 @@ static void sub_802E138(struct PokemonJump1_82E4 *arg0, struct PokemonJump1Sub * packet.unk2 = arg0->unk10; packet.unk3_1 = arg0->unk14; packet.unk4 = arg0->unkE; - sub_800FE50(&packet); + Rfu_SendPacket(&packet); } static bool32 sub_802E1BC(struct PokemonJump1_82E4 *arg0, struct PokemonJump1Sub *arg1) { struct UnkPacket3 packet; - if ((gRecvCmds[0][0] & 0xFF00) != 0x2F00) + if ((gRecvCmds[0][0] & 0xFF00) != RFUCMD_SEND_PACKET) return FALSE; memcpy(&packet, &gRecvCmds[0][1], sizeof(packet)); @@ -3792,14 +3792,14 @@ static void sub_802E234(struct PokemonJump1_82E4 *arg0, u8 arg1, u16 arg2) packet.unk4 = arg0->unkE; packet.unk6 = arg1; packet.unk8 = arg2; - sub_800FE50(&packet); + Rfu_SendPacket(&packet); } static bool32 sub_802E264(struct PokemonJump1_82E4 *arg0, int multiplayerId, u8 *arg2, u16 *arg3) { struct UnkPacket4 packet; - if ((gRecvCmds[multiplayerId][0] & 0xFF00) != 0x2F00) + if ((gRecvCmds[multiplayerId][0] & 0xFF00) != RFUCMD_SEND_PACKET) return FALSE; memcpy(&packet, &gRecvCmds[multiplayerId][1], sizeof(packet)); @@ -3819,7 +3819,7 @@ static bool32 sub_802E2D0(struct PokemonJump1_82E4 *arg0, int multiplayerId) { struct UnkPacket4 packet; - if ((gRecvCmds[multiplayerId][0] & 0xFF00) != 0x2F00) + if ((gRecvCmds[multiplayerId][0] & 0xFF00) != RFUCMD_SEND_PACKET) return FALSE; memcpy(&packet, &gRecvCmds[multiplayerId][1], sizeof(packet)); diff --git a/src/tv.c b/src/tv.c index 37c29ed2e..3a0e78fd4 100644 --- a/src/tv.c +++ b/src/tv.c @@ -1332,7 +1332,7 @@ void PutBattleUpdateOnTheAir(u8 opponentLinkPlayerId, u16 move, u16 speciesPlaye } } -bool8 Put3CheersForPokeblocksOnTheAir(const u8 *partnersName, u8 flavor, u8 unused, u8 sheen, u8 language) +bool8 Put3CheersForPokeblocksOnTheAir(const u8 *partnersName, u8 flavor, u8 color, u8 sheen, u8 language) { TVShow *show; u8 name[32]; @@ -1355,7 +1355,7 @@ bool8 Put3CheersForPokeblocksOnTheAir(const u8 *partnersName, u8 flavor, u8 unus StripExtCtrlCodes(name); StringCopy(show->threeCheers.worstBlenderName, name); show->threeCheers.flavor = flavor; - show->threeCheers.unk_03_3 = unused; + show->threeCheers.color = color; show->threeCheers.sheen = sheen; tv_store_id_2x(show); show->threeCheers.language = gGameLanguage; diff --git a/src/union_room.c b/src/union_room.c index f79dd9cc4..1bac3678c 100644 --- a/src/union_room.c +++ b/src/union_room.c @@ -2677,7 +2677,7 @@ static void Task_RunUnionRoom(u8 taskId) if (input == -2 || input == IN_UNION_ROOM) { uroom->playerSendBuffer[0] = IN_UNION_ROOM; - sub_800FE50(uroom->playerSendBuffer); + Rfu_SendPacket(uroom->playerSendBuffer); StringCopy(gStringVar4, sIfYouWantToDoSomethingTexts[gLinkPlayers[0].gender]); uroom->state = UR_STATE_REQUEST_DECLINED; } @@ -2692,7 +2692,7 @@ static void Task_RunUnionRoom(u8 taskId) else { uroom->playerSendBuffer[0] = gPlayerCurrActivity | IN_UNION_ROOM; - sub_800FE50(uroom->playerSendBuffer); + Rfu_SendPacket(uroom->playerSendBuffer); uroom->state = UR_STATE_SEND_ACTIVITY_REQUEST; } } @@ -2721,7 +2721,7 @@ static void Task_RunUnionRoom(u8 taskId) uroom->playerSendBuffer[0] = ACTIVITY_TRADE | IN_UNION_ROOM; uroom->playerSendBuffer[1] = sUnionRoomTrade.species; uroom->playerSendBuffer[2] = sUnionRoomTrade.level; - sub_800FE50(uroom->playerSendBuffer); + Rfu_SendPacket(uroom->playerSendBuffer); uroom->state = UR_STATE_WAIT_FOR_RESPONSE_TO_REQUEST; break; case UR_STATE_WAIT_FOR_RESPONSE_TO_REQUEST: @@ -2908,32 +2908,32 @@ static void Task_RunUnionRoom(u8 taskId) if (!HasAtLeastTwoMonsOfLevel30OrLower()) { uroom->playerSendBuffer[0] = ACTIVITY_DECLINE | IN_UNION_ROOM; - sub_800FE50(uroom->playerSendBuffer); + Rfu_SendPacket(uroom->playerSendBuffer); uroom->state = UR_STATE_DECLINE_ACTIVITY_REQUEST; StringCopy(gStringVar4, sText_NeedTwoMonsOfLevel30OrLower2); } else { - sub_800FE50(uroom->playerSendBuffer); + Rfu_SendPacket(uroom->playerSendBuffer); uroom->state = UR_STATE_PRINT_START_ACTIVITY_MSG; } } else if (gPlayerCurrActivity == (ACTIVITY_CARD | IN_UNION_ROOM)) { - sub_800FE50(uroom->playerSendBuffer); + Rfu_SendPacket(uroom->playerSendBuffer); ViewURoomPartnerTrainerCard(gStringVar4, uroom, TRUE); uroom->state = UR_STATE_PRINT_CARD_INFO; } else { - sub_800FE50(uroom->playerSendBuffer); + Rfu_SendPacket(uroom->playerSendBuffer); uroom->state = UR_STATE_PRINT_START_ACTIVITY_MSG; } break; case 1: // DECLINE case -1: uroom->playerSendBuffer[0] = ACTIVITY_DECLINE | IN_UNION_ROOM; - sub_800FE50(uroom->playerSendBuffer); + Rfu_SendPacket(uroom->playerSendBuffer); uroom->state = UR_STATE_DECLINE_ACTIVITY_REQUEST; GetYouDeclinedTheOfferMessage(gStringVar4, gPlayerCurrActivity); break;