From c393f5dc07ce40ce347f3f64cd1c6ab330fe0f4b Mon Sep 17 00:00:00 2001 From: cawtds <38510667+cawtds@users.noreply.github.com> Date: Tue, 7 Jan 2025 21:52:43 +0100 Subject: [PATCH] sync battle_controllers.c --- include/battle_gfx_sfx_util.h | 1 + include/battle_message.h | 2 +- src/battle_controller_oak_old_man.c | 2 +- src/battle_controllers.c | 306 ++++++++++++++++++++++++---- src/battle_gfx_sfx_util.c | 12 ++ src/battle_message.c | 2 +- 6 files changed, 279 insertions(+), 46 deletions(-) diff --git a/include/battle_gfx_sfx_util.h b/include/battle_gfx_sfx_util.h index e11499198..1fbdd6141 100644 --- a/include/battle_gfx_sfx_util.h +++ b/include/battle_gfx_sfx_util.h @@ -5,6 +5,7 @@ void AllocateBattleSpritesData(void); void FreeBattleSpritesData(void); void SpriteCB_WaitForBattlerBallReleaseAnim(struct Sprite *sprite); void SpriteCB_TrainerSlideIn(struct Sprite *sprite); +void SpriteCB_TrainerSpawn(struct Sprite *sprite); void InitAndLaunchChosenStatusAnimation(u32 battler, bool8 isStatus2, u32 status); bool8 TryHandleLaunchBattleTableAnimation(u8 activeBattler, u8 atkBattler, u8 defBattler, u8 tableId, u16 argument); void InitAndLaunchSpecialAnimation(u8 activeBattler, u8 atkBattler, u8 defBattler, u8 tableId); diff --git a/include/battle_message.h b/include/battle_message.h index fe930a737..ec571629a 100644 --- a/include/battle_message.h +++ b/include/battle_message.h @@ -256,7 +256,7 @@ enum TRAINER_SLIDE_DYNAMAX, }; -void BufferStringBattle(u32 battler, u16 stringID); +void BufferStringBattle(u16 stringID, u32 battler); u32 BattleStringExpandPlaceholdersToDisplayedString(const u8 *src); u32 BattleStringExpandPlaceholders(const u8 *src, u8 *dst, u32 dstSize); void BattleHandleAddTextPrinter(const u8 *text, u8 arg1); diff --git a/src/battle_controller_oak_old_man.c b/src/battle_controller_oak_old_man.c index af66b3a6b..71989a1d9 100644 --- a/src/battle_controller_oak_old_man.c +++ b/src/battle_controller_oak_old_man.c @@ -699,7 +699,7 @@ static void OakOldManHandlePrintString(u32 battler) } else { - BufferStringBattle(battler, *stringId); + BufferStringBattle(*stringId, battler); if (BattleStringShouldBeColored(*stringId)) BattlePutTextOnWindow(gDisplayedStringBattle, (B_WIN_MSG | B_TEXT_FLAG_NPC_CONTEXT_FONT)); else diff --git a/src/battle_controllers.c b/src/battle_controllers.c index 581cc95f7..503ea3cec 100644 --- a/src/battle_controllers.c +++ b/src/battle_controllers.c @@ -4,6 +4,7 @@ #include "battle_ai_util.h" #include "battle_anim.h" #include "battle_controllers.h" +#include "battle_gfx_sfx_util.h" #include "battle_interface.h" #include "battle_message.h" #include "battle_setup.h" @@ -13,14 +14,13 @@ #include "link_rfu.h" #include "palette.h" #include "party_menu.h" -#include "pokeball.h" #include "recorded_battle.h" -#include "sound.h" #include "string_util.h" +#include "sound.h" #include "task.h" #include "test_runner.h" -#include "text.h" #include "util.h" +#include "text.h" #include "constants/abilities.h" #include "constants/battle_string_ids.h" #include "constants/songs.h" @@ -28,12 +28,11 @@ static EWRAM_DATA u8 sLinkSendTaskId = 0; static EWRAM_DATA u8 sLinkReceiveTaskId = 0; -static EWRAM_DATA u8 sUnused = 0; // Debug? Never read EWRAM_DATA struct UnusedControllerStruct gUnusedControllerStruct = {}; // Debug? Unused code that writes to it, never read -void (*gBattlerControllerFuncs[MAX_BATTLERS_COUNT])(u32 battler); -u8 gBattleControllerData[MAX_BATTLERS_COUNT]; -void (*gBattlerControllerEndFuncs[MAX_BATTLERS_COUNT])(u32 battler); // Controller's buffer complete function for each battler +COMMON_DATA void (*gBattlerControllerFuncs[MAX_BATTLERS_COUNT])(u32 battler) = {0}; +COMMON_DATA u8 gBattleControllerData[MAX_BATTLERS_COUNT] = {0}; // Used by the battle controllers to store misc sprite/task IDs for each battler +COMMON_DATA void (*gBattlerControllerEndFuncs[MAX_BATTLERS_COUNT])(u32 battler) = {0}; // Controller's buffer complete function for each battler static void CreateTasksForSendRecvLinkBuffers(void); static void InitLinkBtlControllers(void); @@ -103,6 +102,12 @@ void InitBattleControllers(void) for (i = 0; i < gBattlersCount; i++) BufferBattlePartyCurrentOrderBySide(i, 0); } + + // for (i = 0; i < sizeof(gBattleStruct->tvMovePoints); i++) + // *((u8 *)(&gBattleStruct->tvMovePoints) + i) = 0; + + // for (i = 0; i < sizeof(gBattleStruct->tv); i++) + // *((u8 *)(&gBattleStruct->tv) + i) = 0; } static void InitSinglePlayerBtlControllers(void) @@ -180,7 +185,7 @@ static void InitSinglePlayerBtlControllers(void) gBattlerPartyIndexes[3] = 3; } } - else if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) + else if (!IsDoubleBattle()) { gBattleMainFunc = BeginBattleIntro; @@ -422,7 +427,7 @@ static void InitLinkBtlControllers(void) s32 i; u8 multiplayerId; - if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) + if (!IsDoubleBattle()) { if (gBattleTypeFlags & BATTLE_TYPE_IS_MASTER) { @@ -447,7 +452,7 @@ static void InitLinkBtlControllers(void) gBattlersCount = 2; } } - else if (!(gBattleTypeFlags & BATTLE_TYPE_MULTI) && gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + else if (!(gBattleTypeFlags & BATTLE_TYPE_MULTI) && IsDoubleBattle()) { if (gBattleTypeFlags & BATTLE_TYPE_IS_MASTER) { @@ -484,6 +489,52 @@ static void InitLinkBtlControllers(void) gBattlersCount = MAX_BATTLERS_COUNT; } } + else if (gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER) + { + if (gBattleTypeFlags & BATTLE_TYPE_IS_MASTER) + { + gBattleMainFunc = BeginBattleIntro; + + gBattlerControllerFuncs[0] = SetControllerToPlayer; + gBattlerPositions[0] = B_POSITION_PLAYER_LEFT; + + gBattlerControllerFuncs[1] = SetControllerToOpponent; + gBattlerPositions[1] = B_POSITION_OPPONENT_LEFT; + + gBattlerControllerFuncs[2] = SetControllerToLinkPartner; + gBattlerPositions[2] = B_POSITION_PLAYER_RIGHT; + + gBattlerControllerFuncs[3] = SetControllerToOpponent; + gBattlerPositions[3] = B_POSITION_OPPONENT_RIGHT; + + gBattlersCount = MAX_BATTLERS_COUNT; + } + else + { + gBattlerControllerFuncs[0] = SetControllerToLinkPartner; + gBattlerPositions[0] = B_POSITION_PLAYER_LEFT; + + gBattlerControllerFuncs[1] = SetControllerToLinkOpponent; + gBattlerPositions[1] = B_POSITION_OPPONENT_LEFT; + + gBattlerControllerFuncs[2] = SetControllerToPlayer; + gBattlerPositions[2] = B_POSITION_PLAYER_RIGHT; + + gBattlerControllerFuncs[3] = SetControllerToLinkOpponent; + gBattlerPositions[3] = B_POSITION_OPPONENT_RIGHT; + + gBattlersCount = MAX_BATTLERS_COUNT; + } + + BufferBattlePartyCurrentOrderBySide(0, 0); + BufferBattlePartyCurrentOrderBySide(1, 0); + BufferBattlePartyCurrentOrderBySide(2, 1); + BufferBattlePartyCurrentOrderBySide(3, 1); + gBattlerPartyIndexes[0] = 0; + gBattlerPartyIndexes[1] = 0; + gBattlerPartyIndexes[2] = 3; + gBattlerPartyIndexes[3] = 3; + } else { multiplayerId = GetMultiplayerId(); @@ -513,7 +564,7 @@ static void InitLinkBtlControllers(void) case 0: case 3: gBattlerPositions[gLinkPlayers[i].id] = B_POSITION_PLAYER_LEFT; - gBattlerPartyIndexes[gLinkPlayers[i].id] = B_POSITION_PLAYER_LEFT; + gBattlerPartyIndexes[gLinkPlayers[i].id] = 0; break; case 1: case 2: @@ -533,12 +584,12 @@ static void InitLinkBtlControllers(void) case 0: case 3: gBattlerPositions[gLinkPlayers[i].id] = B_POSITION_PLAYER_LEFT; - gBattlerPartyIndexes[gLinkPlayers[i].id] = B_POSITION_PLAYER_LEFT; + gBattlerPartyIndexes[gLinkPlayers[i].id] = 0; break; case 1: case 2: gBattlerPositions[gLinkPlayers[i].id] = B_POSITION_PLAYER_RIGHT; - gBattlerPartyIndexes[gLinkPlayers[i].id] = B_POSITION_OPPONENT_RIGHT; + gBattlerPartyIndexes[gLinkPlayers[i].id] = 3; break; } } @@ -550,12 +601,12 @@ static void InitLinkBtlControllers(void) case 0: case 3: gBattlerPositions[gLinkPlayers[i].id] = B_POSITION_OPPONENT_LEFT; - gBattlerPartyIndexes[gLinkPlayers[i].id] = B_POSITION_PLAYER_LEFT; + gBattlerPartyIndexes[gLinkPlayers[i].id] = 0; break; case 1: case 2: gBattlerPositions[gLinkPlayers[i].id] = B_POSITION_OPPONENT_RIGHT; - gBattlerPartyIndexes[gLinkPlayers[i].id] = B_POSITION_OPPONENT_RIGHT; + gBattlerPartyIndexes[gLinkPlayers[i].id] = 3; break; } } @@ -569,9 +620,10 @@ static void InitLinkBtlControllers(void) bool32 IsValidForBattle(struct Pokemon *mon) { u32 species = GetMonData(mon, MON_DATA_SPECIES_OR_EGG); - return (species != SPECIES_NONE && species != SPECIES_EGG - && GetMonData(mon, MON_DATA_HP) != 0 - && GetMonData(mon, MON_DATA_IS_EGG) == FALSE); + return (species != SPECIES_NONE + && species != SPECIES_EGG + && GetMonData(mon, MON_DATA_HP) != 0 + && GetMonData(mon, MON_DATA_IS_EGG) == FALSE); } static void SetBattlePartyIds(void) @@ -674,8 +726,6 @@ static void CreateTasksForSendRecvLinkBuffers(void) gTasks[sLinkReceiveTaskId].data[13] = 0; gTasks[sLinkReceiveTaskId].data[14] = 0; gTasks[sLinkReceiveTaskId].data[15] = 0; - - sUnused = 0; } enum @@ -804,7 +854,7 @@ void TryReceiveLinkBattleData(void) DestroyTask_RfuIdle(); for (i = 0; i < GetLinkPlayerCount(); i++) { - if (GetBlockReceivedStatus() & gBitTable[i]) + if (GetBlockReceivedStatus() & (1 << (i))) { ResetBlockReceivedFlag(i); recvBuffer = (u8 *)gBlockRecvBuffer[i]; @@ -834,7 +884,7 @@ void TryReceiveLinkBattleData(void) static void Task_HandleCopyReceivedLinkBuffersData(u8 taskId) { u16 blockSize; - u8 battlerId; + u8 battler; u8 var; if (gTasks[taskId].data[15] != gTasks[taskId].data[14]) @@ -845,17 +895,17 @@ static void Task_HandleCopyReceivedLinkBuffersData(u8 taskId) gTasks[taskId].data[12] = 0; gTasks[taskId].data[15] = 0; } - battlerId = gLinkBattleRecvBuffer[gTasks[taskId].data[15] + LINK_BUFF_ACTIVE_BATTLER]; + battler = gLinkBattleRecvBuffer[gTasks[taskId].data[15] + LINK_BUFF_ACTIVE_BATTLER]; blockSize = gLinkBattleRecvBuffer[gTasks[taskId].data[15] + LINK_BUFF_SIZE_LO] | (gLinkBattleRecvBuffer[gTasks[taskId].data[15] + LINK_BUFF_SIZE_HI] << 8); switch (gLinkBattleRecvBuffer[gTasks[taskId].data[15] + 0]) { case 0: - if (gBattleControllerExecFlags & gBitTable[battlerId]) + if (gBattleControllerExecFlags & (1u << battler)) return; - memcpy(gBattleResources->bufferA[battlerId], &gLinkBattleRecvBuffer[gTasks[taskId].data[15] + LINK_BUFF_DATA], blockSize); - MarkBattlerReceivedLinkData(battlerId); + memcpy(gBattleResources->bufferA[battler], &gLinkBattleRecvBuffer[gTasks[taskId].data[15] + LINK_BUFF_DATA], blockSize); + MarkBattlerReceivedLinkData(battler); if (!(gBattleTypeFlags & BATTLE_TYPE_IS_MASTER)) { @@ -866,11 +916,11 @@ static void Task_HandleCopyReceivedLinkBuffersData(u8 taskId) } break; case 1: - memcpy(gBattleResources->bufferB[battlerId], &gLinkBattleRecvBuffer[gTasks[taskId].data[15] + LINK_BUFF_DATA], blockSize); + memcpy(gBattleResources->bufferB[battler], &gLinkBattleRecvBuffer[gTasks[taskId].data[15] + LINK_BUFF_DATA], blockSize); break; case 2: var = gLinkBattleRecvBuffer[gTasks[taskId].data[15] + LINK_BUFF_DATA]; - gBattleControllerExecFlags &= ~(gBitTable[battlerId] << (var * 4)); + gBattleControllerExecFlags &= ~(1u << (battler + var * 4)); break; } @@ -887,6 +937,15 @@ void BtlController_EmitGetMonData(u32 battler, u32 bufferId, u8 requestId, u8 mo PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, 4); } +static void UNUSED BtlController_EmitGetRawMonData(u32 battler, u32 bufferId, u8 monId, u8 bytes) +{ + gBattleResources->transferBuffer[0] = CONTROLLER_GETRAWMONDATA; + gBattleResources->transferBuffer[1] = monId; + gBattleResources->transferBuffer[2] = bytes; + gBattleResources->transferBuffer[3] = 0; + PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, 4); +} + void BtlController_EmitSetMonData(u32 battler, u32 bufferId, u8 requestId, u8 monToCheck, u8 bytes, void *data) { s32 i; @@ -899,6 +958,18 @@ void BtlController_EmitSetMonData(u32 battler, u32 bufferId, u8 requestId, u8 mo PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, 3 + bytes); } +static void UNUSED BtlController_EmitSetRawMonData(u32 battler, u32 bufferId, u8 monId, u8 bytes, void *data) +{ + s32 i; + + gBattleResources->transferBuffer[0] = CONTROLLER_SETRAWMONDATA; + gBattleResources->transferBuffer[1] = monId; + gBattleResources->transferBuffer[2] = bytes; + for (i = 0; i < bytes; i++) + gBattleResources->transferBuffer[3 + i] = *(u8 *)(data++); + PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, bytes + 3); +} + void BtlController_EmitLoadMonSprite(u32 battler, u32 bufferId) { gBattleResources->transferBuffer[0] = CONTROLLER_LOADMONSPRITE; @@ -960,6 +1031,24 @@ void BtlController_EmitFaintAnimation(u32 battler, u32 bufferId) PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, 4); } +static void UNUSED BtlController_EmitPaletteFade(u32 battler, u32 bufferId) +{ + gBattleResources->transferBuffer[0] = CONTROLLER_PALETTEFADE; + gBattleResources->transferBuffer[1] = CONTROLLER_PALETTEFADE; + gBattleResources->transferBuffer[2] = CONTROLLER_PALETTEFADE; + gBattleResources->transferBuffer[3] = CONTROLLER_PALETTEFADE; + PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, 4); +} + +static void UNUSED BtlController_EmitSuccessBallThrowAnim(u32 battler, u32 bufferId) +{ + gBattleResources->transferBuffer[0] = CONTROLLER_SUCCESSBALLTHROWANIM; + gBattleResources->transferBuffer[1] = CONTROLLER_SUCCESSBALLTHROWANIM; + gBattleResources->transferBuffer[2] = CONTROLLER_SUCCESSBALLTHROWANIM; + gBattleResources->transferBuffer[3] = CONTROLLER_SUCCESSBALLTHROWANIM; + PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, 4); +} + void BtlController_EmitBallThrowAnim(u32 battler, u32 bufferId, u8 caseId) { gBattleResources->transferBuffer[0] = CONTROLLER_BALLTHROWANIM; @@ -967,6 +1056,17 @@ void BtlController_EmitBallThrowAnim(u32 battler, u32 bufferId, u8 caseId) PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, 2); } +static void UNUSED BtlController_EmitPause(u32 battler, u32 bufferId, u8 toWait, void *data) +{ + s32 i; + + gBattleResources->transferBuffer[0] = CONTROLLER_PAUSE; + gBattleResources->transferBuffer[1] = toWait; + for (i = 0; i < toWait * 3; i++) + gBattleResources->transferBuffer[2 + i] = *(u8 *)(data++); + PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, toWait * 3 + 2); +} + void BtlController_EmitMoveAnimation(u32 battler, u32 bufferId, u16 move, u8 turnOfMove, u16 movePower, s32 dmg, u8 friendship, struct DisableStruct *disableStructPtr, u8 multihit) { gBattleResources->transferBuffer[0] = CONTROLLER_MOVEANIMATION; @@ -980,7 +1080,7 @@ void BtlController_EmitMoveAnimation(u32 battler, u32 bufferId, u16 move, u8 tur gBattleResources->transferBuffer[8] = (dmg & 0x00FF0000) >> 16; gBattleResources->transferBuffer[9] = (dmg & 0xFF000000) >> 24; gBattleResources->transferBuffer[10] = friendship; - gBattleResources->transferBuffer[11] = multihit; // multihit in pokeem + gBattleResources->transferBuffer[11] = multihit; if (WEATHER_HAS_EFFECT) { gBattleResources->transferBuffer[12] = gBattleWeather; @@ -1016,7 +1116,7 @@ void BtlController_EmitPrintString(u32 battler, u32 bufferId, u16 stringID) stringInfo->bakScriptPartyIdx = gBattleStruct->scriptPartyIdx; stringInfo->hpScale = gBattleStruct->hpScale; stringInfo->itemEffectBattler = gPotentialItemEffectBattler; - stringInfo->moveType = gMovesInfo[gCurrentMove].type; + stringInfo->moveType = GetMoveType(gCurrentMove); for (i = 0; i < MAX_BATTLERS_COUNT; i++) stringInfo->abilities[i] = gBattleMons[i].ability; @@ -1068,6 +1168,17 @@ void BtlController_EmitChooseAction(u32 battler, u32 bufferId, u8 action, u16 it PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, 4); } +// Only used by the forfeit prompt in the Battle Frontier +// For other Yes/No boxes in battle, see Cmd_yesnobox +void BtlController_EmitYesNoBox(u32 battler, u32 bufferId) +{ + gBattleResources->transferBuffer[0] = CONTROLLER_YESNOBOX; + gBattleResources->transferBuffer[1] = CONTROLLER_YESNOBOX; + gBattleResources->transferBuffer[2] = CONTROLLER_YESNOBOX; + gBattleResources->transferBuffer[3] = CONTROLLER_YESNOBOX; + PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, 4); +} + void BtlController_EmitChooseMove(u32 battler, u32 bufferId, bool8 isDoubleBattle, bool8 NoPpNumber, struct ChooseMoveStruct *movePpData) { s32 i; @@ -1102,9 +1213,19 @@ void BtlController_EmitChoosePokemon(u32 battler, u32 bufferId, u8 caseId, u8 sl gBattleResources->transferBuffer[7] = (abilityId >> 8) & 0xFF; for (i = 0; i < 3; i++) gBattleResources->transferBuffer[4 + i] = data[i]; - PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, 8); + PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, 8); // Only 7 bytes were written. } +static void UNUSED BtlController_EmitCmd23(u32 battler, u32 bufferId) +{ + gBattleResources->transferBuffer[0] = CONTROLLER_23; + gBattleResources->transferBuffer[1] = CONTROLLER_23; + gBattleResources->transferBuffer[2] = CONTROLLER_23; + gBattleResources->transferBuffer[3] = CONTROLLER_23; + PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, 4); +} + +// why is the argument u16 if it's being cast to s16 anyway? void BtlController_EmitHealthBarUpdate(u32 battler, u32 bufferId, u16 hpValue) { gBattleResources->transferBuffer[0] = CONTROLLER_HEALTHBARUPDATE; @@ -1150,6 +1271,13 @@ void BtlController_EmitStatusAnimation(u32 battler, u32 bufferId, bool8 status2, PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, 6); } +static void UNUSED BtlController_EmitStatusXor(u32 battler, u32 bufferId, u8 b) +{ + gBattleResources->transferBuffer[0] = CONTROLLER_STATUSXOR; + gBattleResources->transferBuffer[1] = b; + PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, 2); +} + void BtlController_EmitDataTransfer(u32 battler, u32 bufferId, u16 size, void *data) { s32 i; @@ -1163,14 +1291,59 @@ void BtlController_EmitDataTransfer(u32 battler, u32 bufferId, u16 size, void *d PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, size + 4); } +static void UNUSED BtlController_EmitDMA3Transfer(u32 battler, u32 bufferId, void *dst, u16 size, void *data) +{ + s32 i; + + gBattleResources->transferBuffer[0] = CONTROLLER_DMA3TRANSFER; + gBattleResources->transferBuffer[1] = (u32)(dst); + gBattleResources->transferBuffer[2] = ((u32)(dst) & 0x0000FF00) >> 8; + gBattleResources->transferBuffer[3] = ((u32)(dst) & 0x00FF0000) >> 16; + gBattleResources->transferBuffer[4] = ((u32)(dst) & 0xFF000000) >> 24; + gBattleResources->transferBuffer[5] = size; + gBattleResources->transferBuffer[6] = (size & 0xFF00) >> 8; + for (i = 0; i < size; i++) + gBattleResources->transferBuffer[7 + i] = *(u8 *)(data++); + PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, size + 7); +} + +static void UNUSED BtlController_EmitPlayBGM(u32 battler, u32 bufferId, u16 songId, void *data) +{ + s32 i; + + gBattleResources->transferBuffer[0] = CONTROLLER_PLAYBGM; + gBattleResources->transferBuffer[1] = songId; + gBattleResources->transferBuffer[2] = (songId & 0xFF00) >> 8; + + // Nonsense loop using songId as a size + // Would go out of bounds for any song id after SE_RG_BAG_POCKET (253) + for (i = 0; i < songId; i++) + gBattleResources->transferBuffer[3 + i] = *(u8 *)(data++); + PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, songId + 3); +} + +static void UNUSED BtlController_EmitCmd32(u32 battler, u32 bufferId, u16 size, void *data) +{ + s32 i; + + gBattleResources->transferBuffer[0] = CONTROLLER_32; + gBattleResources->transferBuffer[1] = size; + gBattleResources->transferBuffer[2] = (size & 0xFF00) >> 8; + for (i = 0; i < size; i++) + gBattleResources->transferBuffer[3 + i] = *(u8 *)(data++); + PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, size + 3); +} + + +//TODO: compare values to pokeemerald? void BtlController_EmitTwoReturnValues(u32 battler, u32 bufferId, u8 ret8, u32 ret32) { gBattleResources->transferBuffer[0] = CONTROLLER_TWORETURNVALUES; gBattleResources->transferBuffer[1] = ret8; gBattleResources->transferBuffer[2] = ret32; gBattleResources->transferBuffer[3] = (ret32 & 0x0000FF00) >> 8; - gBattleResources->transferBuffer[4] = (ret32 & 0x0000FF00) >> 16; - gBattleResources->transferBuffer[5] = (ret32 & 0x0000FF00) >> 24; + gBattleResources->transferBuffer[4] = (ret32 & 0x00FF0000) >> 16; + gBattleResources->transferBuffer[5] = (ret32 & 0xFF000000) >> 24; PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, 6); } @@ -1203,6 +1376,40 @@ void BtlController_EmitOneReturnValue_Duplicate(u32 battler, u32 bufferId, u16 r PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, 4); } +static void UNUSED BtlController_EmitClearUnkVar(u32 battler, u32 bufferId) +{ + gBattleResources->transferBuffer[0] = CONTROLLER_CLEARUNKVAR; + gBattleResources->transferBuffer[1] = CONTROLLER_CLEARUNKVAR; + gBattleResources->transferBuffer[2] = CONTROLLER_CLEARUNKVAR; + gBattleResources->transferBuffer[3] = CONTROLLER_CLEARUNKVAR; + PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, 4); +} + +static void UNUSED BtlController_EmitSetUnkVar(u32 battler, u32 bufferId, u8 b) +{ + gBattleResources->transferBuffer[0] = CONTROLLER_SETUNKVAR; + gBattleResources->transferBuffer[1] = b; + PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, 2); +} + +static void UNUSED BtlController_EmitClearUnkFlag(u32 battler, u32 bufferId) +{ + gBattleResources->transferBuffer[0] = CONTROLLER_CLEARUNKFLAG; + gBattleResources->transferBuffer[1] = CONTROLLER_CLEARUNKFLAG; + gBattleResources->transferBuffer[2] = CONTROLLER_CLEARUNKFLAG; + gBattleResources->transferBuffer[3] = CONTROLLER_CLEARUNKFLAG; + PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, 4); +} + +static void UNUSED BtlController_EmitToggleUnkFlag(u32 battler, u32 bufferId) +{ + gBattleResources->transferBuffer[0] = CONTROLLER_TOGGLEUNKFLAG; + gBattleResources->transferBuffer[1] = CONTROLLER_TOGGLEUNKFLAG; + gBattleResources->transferBuffer[2] = CONTROLLER_TOGGLEUNKFLAG; + gBattleResources->transferBuffer[3] = CONTROLLER_TOGGLEUNKFLAG; + PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, 4); +} + void BtlController_EmitHitAnimation(u32 battler, u32 bufferId) { gBattleResources->transferBuffer[0] = CONTROLLER_HITANIMATION; @@ -1339,6 +1546,9 @@ void BtlController_EmitEndLinkBattle(u32 battler, u32 bufferId, u8 battleOutcome { gBattleResources->transferBuffer[0] = CONTROLLER_ENDLINKBATTLE; gBattleResources->transferBuffer[1] = battleOutcome; + // gBattleResources->transferBuffer[2] = gSaveBlock2Ptr->frontier.disableRecordBattle; + // gBattleResources->transferBuffer[3] = gSaveBlock2Ptr->frontier.disableRecordBattle; + // gBattleResources->transferBuffer[5] = gBattleResources->transferBuffer[4] = RecordedBattle_BufferNewBattlerData(&gBattleResources->transferBuffer[6]); PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, 2); } @@ -1398,12 +1608,22 @@ static u32 GetBattlerMonData(u32 battler, struct Pokemon *party, u32 monId, u8 * battleMon.abilityNum = GetMonData(&party[monId], MON_DATA_ABILITY_NUM); battleMon.otId = GetMonData(&party[monId], MON_DATA_OT_ID); battleMon.metLevel = GetMonData(&party[monId], MON_DATA_MET_LEVEL); + battleMon.isShiny = GetMonData(&party[monId], MON_DATA_IS_SHINY); GetMonData(&party[monId], MON_DATA_NICKNAME, nickname); StringCopy_Nickname(battleMon.nickname, nickname); GetMonData(&party[monId], MON_DATA_OT_NAME, battleMon.otName); src = (u8 *)&battleMon; for (size = 0; size < sizeof(battleMon); size++) dst[size] = src[size]; + #if TESTING + if (gTestRunnerEnabled) + { + u32 side = GetBattlerSide(battler); + u32 partyIndex = gBattlerPartyIndexes[battler]; + if (TestRunner_Battle_GetForcedAbility(side, partyIndex)) + gBattleMons[battler].ability = gDisableStructs[battler].overwrittenAbility = TestRunner_Battle_GetForcedAbility(side, partyIndex); + } + #endif break; case REQUEST_SPECIES_BATTLE: data16 = GetMonData(&party[monId], MON_DATA_SPECIES); @@ -1890,7 +2110,7 @@ static bool8 ShouldDoSlideInAnim(void) if (gBattleTypeFlags & ( BATTLE_TYPE_LINK | BATTLE_TYPE_DOUBLE | BATTLE_TYPE_FRONTIER | BATTLE_TYPE_FIRST_BATTLE | BATTLE_TYPE_SAFARI | BATTLE_TYPE_OLD_MAN_TUTORIAL | BATTLE_TYPE_EREADER_TRAINER | BATTLE_TYPE_TWO_OPPONENTS | - BATTLE_TYPE_INGAME_PARTNER | BATTLE_TYPE_RECORDED | BATTLE_TYPE_POKEDUDE | BATTLE_TYPE_TRAINER_TOWER) + BATTLE_TYPE_INGAME_PARTNER | BATTLE_TYPE_RECORDED | BATTLE_TYPE_TRAINER_HILL | BATTLE_TYPE_POKEDUDE) ) return FALSE; return TRUE; @@ -2348,7 +2568,10 @@ void BtlController_HandleDrawTrainerPic(u32 battler, u32 trainerPicId, bool32 is gSprites[gBattlerSpriteIds[battler]].x2 = DISPLAY_WIDTH; gSprites[gBattlerSpriteIds[battler]].sSpeedX = -2; } - gSprites[gBattlerSpriteIds[battler]].callback = SpriteCB_TrainerSlideIn; + if (B_FAST_INTRO_NO_SLIDE || gTestRunnerHeadless) + gSprites[gBattlerSpriteIds[battler]].callback = SpriteCB_TrainerSpawn; + else + gSprites[gBattlerSpriteIds[battler]].callback = SpriteCB_TrainerSlideIn; gBattlerControllerFuncs[battler] = Controller_WaitForTrainerPic; } @@ -2486,7 +2709,7 @@ void BtlController_HandlePrintString(u32 battler) gBattle_BG0_X = 0; gBattle_BG0_Y = 0; stringId = (u16 *)(&gBattleResources->bufferA[battler][2]); - BufferStringBattle(battler, *stringId); + BufferStringBattle(*stringId, battler); if (gTestRunnerEnabled) { @@ -2550,7 +2773,7 @@ void DoStatusIconUpdate(u32 battler) struct Pokemon *party = GetBattlerParty(battler); UpdateHealthboxAttribute(gHealthboxSpriteIds[battler], &party[gBattlerPartyIndexes[battler]], HEALTHBOX_STATUS_ICON); - gBattleSpritesDataPtr->healthBoxesData[battler].statusAnimActive = FALSE; + gBattleSpritesDataPtr->healthBoxesData[battler].statusAnimActive = 0; gBattlerControllerFuncs[battler] = Controller_WaitForStatusAnimation; } @@ -2717,7 +2940,7 @@ void BtlController_HandleIntroTrainerBallThrow(u32 battler, u16 tagTrainerPal, c if (side == B_SIDE_PLAYER) { StoreSpriteCallbackInData6(&gSprites[gBattlerSpriteIds[battler]], SpriteCB_FreePlayerSpriteLoadMonSprite); - StartSpriteAnim(&gSprites[gBattlerSpriteIds[battler]], 1); + StartSpriteAnim(&gSprites[gBattlerSpriteIds[battler]], ShouldDoSlideInAnim() ? 2 : 1); paletteNum = AllocSpritePalette(tagTrainerPal); LoadCompressedPalette(trainerPal, OBJ_PLTT_ID(paletteNum), PLTT_SIZE_4BPP); @@ -2778,7 +3001,7 @@ static void Task_StartSendOutAnim(u8 taskId) gBattleResources->bufferA[battler][1] = gBattlerPartyIndexes[battler]; StartSendOutAnim(battler, FALSE, ShouldDoSlideInAnim()); - battlerPartner = BATTLE_PARTNER(battler); + battlerPartner = battler ^ BIT_FLANK; gBattleResources->bufferA[battlerPartner][1] = gBattlerPartyIndexes[battlerPartner]; BattleLoadMonSpriteGfx(&gPlayerParty[gBattlerPartyIndexes[battlerPartner]], battlerPartner); StartSendOutAnim(battlerPartner, FALSE, ShouldDoSlideInAnim()); @@ -2830,7 +3053,7 @@ void BtlController_HandleDrawPartyStatusSummary(u32 battler, u32 side, bool32 co } else { - gBattleSpritesDataPtr->healthBoxesData[battler].partyStatusSummaryShown = TRUE; + gBattleSpritesDataPtr->healthBoxesData[battler].partyStatusSummaryShown = 1; if (side == B_SIDE_OPPONENT && gBattleResources->bufferA[battler][2] != 0) { @@ -2878,6 +3101,3 @@ void BtlController_HandleBattleAnimation(u32 battler, bool32 ignoreSE) gBattlerControllerFuncs[battler] = Controller_WaitForBattleAnimation; } } - - - diff --git a/src/battle_gfx_sfx_util.c b/src/battle_gfx_sfx_util.c index f783e2863..a7131a727 100644 --- a/src/battle_gfx_sfx_util.c +++ b/src/battle_gfx_sfx_util.c @@ -213,6 +213,18 @@ void SpriteCB_TrainerSlideIn(struct Sprite *sprite) } } +void SpriteCB_TrainerSpawn(struct Sprite *sprite) +{ + if (!(gIntroSlideFlags & 1)) + { + sprite->x2 = 0; + if (sprite->y2 != 0) + sprite->callback = SpriteCB_TrainerSlideVertical; + else + sprite->callback = SpriteCallbackDummy; + } +} + // Slide up to 0 if necessary (used by multi battle intro) static void SpriteCB_TrainerSlideVertical(struct Sprite *sprite) { diff --git a/src/battle_message.c b/src/battle_message.c index f7c494e61..0c033b7b6 100644 --- a/src/battle_message.c +++ b/src/battle_message.c @@ -2423,7 +2423,7 @@ static const u16 sGrammarMoveUsedTable[] = static const u8 sRecordedBattleTextSpeeds[] = {8, 4, 1, 0}; -void BufferStringBattle(u32 battler, u16 stringId) +void BufferStringBattle(u16 stringId, u32 battler) { s32 i; const u8 *stringPtr = NULL;