diff options
Diffstat (limited to 'src')
36 files changed, 15316 insertions, 624 deletions
diff --git a/src/battle_anim_mon_movement.c b/src/battle_anim_mon_movement.c index 88fbce6da..21d07246f 100644 --- a/src/battle_anim_mon_movement.c +++ b/src/battle_anim_mon_movement.c @@ -92,7 +92,7 @@ const struct SpriteTemplate gUnknown_83D4EB4 = // arg 4: frame delay void AnimTask_ShakeMon(u8 taskId) { - u8 spriteId = GetAnimBankSpriteId(gBattleAnimArgs[0]); + u8 spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[0]); if (spriteId == 0xFF) DestroyAnimVisualTask(taskId); @@ -150,7 +150,7 @@ void AnimTask_ShakeMon2(u8 taskId) if (gBattleAnimArgs[0] < MAX_BATTLERS_COUNT) { - spriteId = GetAnimBankSpriteId(gBattleAnimArgs[0]); + spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[0]); if (spriteId == 0xFF) abort = TRUE; } @@ -228,7 +228,7 @@ static void AnimTask_ShakeMon2Step(u8 taskId) // arg 4: delay void AnimTask_ShakeMonInPlace(u8 taskId) { - u8 spriteId = GetAnimBankSpriteId(gBattleAnimArgs[0]); + u8 spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[0]); if (spriteId == 0xFF) DestroyAnimVisualTask(taskId); @@ -290,7 +290,7 @@ static void AnimTask_ShakeMonInPlaceStep(u8 taskId) // arg 4: duration void AnimTask_ShakeAndSinkMon(u8 taskId) { - u8 spriteId = GetAnimBankSpriteId(gBattleAnimArgs[0]); + u8 spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[0]); gSprites[spriteId].pos2.x = gBattleAnimArgs[1]; gTasks[taskId].data[0] = spriteId; @@ -331,7 +331,7 @@ void AnimTask_TranslateMonElliptical(u8 taskId) { u8 wavePeriod = 1; u8 i; - u8 spriteId = GetAnimBankSpriteId(gBattleAnimArgs[0]); + u8 spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[0]); if (gBattleAnimArgs[4] > 5) gBattleAnimArgs[4] = 5; for (i = 0; i < gBattleAnimArgs[4]; i++) @@ -414,7 +414,7 @@ static void DoVerticalDip(struct Sprite * sprite) { u8 spriteId; sprite->invisible = TRUE; - spriteId = GetAnimBankSpriteId(gBattleAnimArgs[2]); + spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[2]); sprite->data[0] = gBattleAnimArgs[0]; sprite->data[1] = 0; sprite->data[2] = gBattleAnimArgs[1]; @@ -581,7 +581,7 @@ void AnimTask_WindUpLunge(u8 taskId) gBattleAnimArgs[1] = -gBattleAnimArgs[1]; gBattleAnimArgs[5] = -gBattleAnimArgs[5]; } - gTasks[taskId].data[0] = GetAnimBankSpriteId(gBattleAnimArgs[0]); + gTasks[taskId].data[0] = GetAnimBattlerSpriteId(gBattleAnimArgs[0]); gTasks[taskId].data[1] = gBattleAnimArgs[1] * 256 / gBattleAnimArgs[3]; gTasks[taskId].data[2] = gBattleAnimArgs[2]; gTasks[taskId].data[3] = gBattleAnimArgs[3]; @@ -627,7 +627,7 @@ void sub_80995FC(u8 taskId) { case 0: case 1: - spriteId = GetAnimBankSpriteId(gBattleAnimArgs[0]); + spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[0]); break; case 2: if (!IsBattlerSpriteVisible(gBattleAnimAttacker ^ BIT_FLANK)) @@ -678,7 +678,7 @@ void AnimTask_SwayMon(u8 taskId) u8 spriteId; if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) gBattleAnimArgs[1] = -gBattleAnimArgs[1]; - spriteId = GetAnimBankSpriteId(gBattleAnimArgs[4]); + spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[4]); gTasks[taskId].data[0] = gBattleAnimArgs[0]; gTasks[taskId].data[1] = gBattleAnimArgs[1]; gTasks[taskId].data[2] = gBattleAnimArgs[2]; @@ -735,7 +735,7 @@ static void AnimTask_SwayMonStep(u8 taskId) // arg 4: sprite object mode void AnimTask_ScaleMonAndRestore(u8 taskId) { - u8 spriteId = GetAnimBankSpriteId(gBattleAnimArgs[3]); + u8 spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[3]); PrepareBattlerSpriteForRotScale(spriteId, gBattleAnimArgs[4]); gTasks[taskId].data[0] = gBattleAnimArgs[0]; gTasks[taskId].data[1] = gBattleAnimArgs[1]; @@ -773,7 +773,7 @@ static void AnimTask_ScaleMonAndRestoreStep(u8 taskId) void sub_8099980(u8 taskId) { - u8 spriteId = GetAnimBankSpriteId(gBattleAnimArgs[2]); + u8 spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[2]); PrepareBattlerSpriteForRotScale(spriteId, 0); gTasks[taskId].data[1] = 0; gTasks[taskId].data[2] = gBattleAnimArgs[0]; @@ -806,7 +806,7 @@ void sub_8099980(u8 taskId) void sub_8099A78(u8 taskId) { - u8 spriteId = GetAnimBankSpriteId(gBattleAnimArgs[2]); + u8 spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[2]); PrepareBattlerSpriteForRotScale(spriteId, 0); gTasks[taskId].data[1] = 0; gTasks[taskId].data[2] = gBattleAnimArgs[0]; @@ -844,7 +844,7 @@ static void sub_8099B54(u8 taskId) gTasks[taskId].data[3] += gTasks[taskId].data[4]; SetSpriteRotScale(gTasks[taskId].data[5], 0x100, 0x100, gTasks[taskId].data[3]); if (gTasks[taskId].data[7]) - sub_80759DC(gTasks[taskId].data[5]); + SetBattlerSpriteYOffsetFromRotation(gTasks[taskId].data[5]); if (++gTasks[taskId].data[1] >= gTasks[taskId].data[2]) { switch (gTasks[taskId].data[6]) @@ -888,7 +888,7 @@ void sub_8099BD4(u8 taskId) gTasks[taskId].data[12] = 0; gTasks[taskId].data[10] = gBattleAnimArgs[3]; gTasks[taskId].data[11] = gBattleAnimArgs[4]; - gTasks[taskId].data[7] = GetAnimBankSpriteId(1); + gTasks[taskId].data[7] = GetAnimBattlerSpriteId(1); gTasks[taskId].data[8] = gSprites[gTasks[taskId].data[7]].pos2.x; gTasks[taskId].data[9] = gSprites[gTasks[taskId].data[7]].pos2.y; gTasks[taskId].data[0] = 0; diff --git a/src/battle_anim_mons.c b/src/battle_anim_mons.c new file mode 100644 index 000000000..e871937e7 --- /dev/null +++ b/src/battle_anim_mons.c @@ -0,0 +1,2254 @@ +#include "global.h" +#include "battle_anim.h" +#include "bg.h" +#include "data.h" +#include "decompress.h" +#include "dma3.h" +#include "gpu_regs.h" +#include "malloc.h" +#include "palette.h" +#include "pokemon_icon.h" +#include "sprite.h" +#include "task.h" +#include "trig.h" +#include "util.h" +#include "constants/battle_anim.h" +#include "constants/species.h" + +#define GET_UNOWN_LETTER(personality) (( \ + (((personality & 0x03000000) >> 24) << 6) \ + | (((personality & 0x00030000) >> 16) << 4) \ + | (((personality & 0x00000300) >> 8) << 2) \ + | (((personality & 0x00000003) >> 0) << 0) \ +) % 28) + +#define IS_DOUBLE_BATTLE() (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + +static u8 GetBattlerSpriteFinal_Y(u8 battlerId, u16 species, bool8 a3); +static void sub_8075658(struct Sprite *sprite); +static void sub_80757E8(struct Sprite *sprite); +static bool8 sub_80758DC(void); +static void sub_8075EF0(struct Sprite *sprite); +static void sub_80760D0(u8 taskId); +static void AnimTask_BlendMonInAndOutSetup(struct Task *task); +static void AnimTask_BlendMonInAndOutStep(u8 taskId); +static u16 GetBattlerYDeltaFromSpriteId(u8 spriteId); +static void sub_8077118(u8 taskId); +static void sub_80771E4(struct Task *task, u8 taskId); +static void sub_8077268(struct Sprite *sprite); +static void sub_80772F4(struct Sprite *sprite); + +static EWRAM_DATA union AffineAnimCmd *sAnimTaskAffineAnim = NULL; +static EWRAM_DATA u32 gUnknown_2037F2C = 0; // not used + +static const struct UCoords8 sBattlerCoords[][4] = +{ + { + { 72, 80 }, + { 176, 40 }, + { 48, 40 }, + { 112, 80 }, + }, + { + { 32, 80 }, + { 200, 40 }, + { 90, 88 }, + { 152, 32 }, + }, +}; + +// One entry for each of the four Castform forms. +const struct MonCoords gCastformFrontSpriteCoords[] = +{ + { .size = 0x44, .y_offset = 17 }, // NORMAL + { .size = 0x66, .y_offset = 9 }, // SUN + { .size = 0x46, .y_offset = 9 }, // RAIN + { .size = 0x86, .y_offset = 8 }, // HAIL +}; + +static const u8 sCastformElevations[] = +{ + 13, // NORMAL + 14, // SUN + 13, // RAIN + 13, // HAIL +}; + +// Y position of the backsprite for each of the four Castform forms. +static const u8 sCastformBackSpriteYCoords[] = +{ + 0, // NORMAL + 0, // SUN + 0, // RAIN + 0, // HAIL +}; + +static const struct SpriteTemplate gUnknown_83AE054[] = +{ + { + .tileTag = 0xD755, + .paletteTag = 0xD755, + .oam = &gOamData_83ACA40, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy, + }, + { + .tileTag = 0xD756, + .paletteTag = 0xD756, + .oam = &gOamData_83ACA40, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy, + } +}; + +static const struct SpriteSheet gUnknown_83AE084[] = +{ + { gMiscBlank_Gfx, 0x800, 0xD755 }, + { gMiscBlank_Gfx, 0x800, 0xD756 }, +}; + +u8 GetBattlerSpriteCoord(u8 battlerId, u8 coordType) +{ + u8 retVal; + u16 species; + struct BattleSpriteInfo *spriteInfo; + + switch (coordType) + { + case BATTLER_COORD_X: + case BATTLER_COORD_X_2: + retVal = sBattlerCoords[IS_DOUBLE_BATTLE()][GetBattlerPosition(battlerId)].x; + break; + case BATTLER_COORD_Y: + retVal = sBattlerCoords[IS_DOUBLE_BATTLE()][GetBattlerPosition(battlerId)].y; + break; + case BATTLER_COORD_Y_PIC_OFFSET: + case BATTLER_COORD_Y_PIC_OFFSET_DEFAULT: + default: + if (GetBattlerSide(battlerId) != B_SIDE_PLAYER) + { + spriteInfo = gBattleSpritesDataPtr->battlerData; + if (!spriteInfo[battlerId].transformSpecies) + species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerId]], MON_DATA_SPECIES); + else + species = spriteInfo[battlerId].transformSpecies; + } + else + { + spriteInfo = gBattleSpritesDataPtr->battlerData; + if (!spriteInfo[battlerId].transformSpecies) + species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_SPECIES); + else + species = spriteInfo[battlerId].transformSpecies; + } + if (coordType == BATTLER_COORD_Y_PIC_OFFSET) + retVal = GetBattlerSpriteFinal_Y(battlerId, species, TRUE); + else + retVal = GetBattlerSpriteFinal_Y(battlerId, species, FALSE); + break; + } + return retVal; +} + +static u8 GetBattlerYDelta(u8 battlerId, u16 species) +{ + u16 letter; + u32 personality; + struct BattleSpriteInfo *spriteInfo; + u8 ret; + u16 coordSpecies; + + if (GetBattlerSide(battlerId) == B_SIDE_PLAYER) + { + if (species == SPECIES_UNOWN) + { + spriteInfo = gBattleSpritesDataPtr->battlerData; + if (!spriteInfo[battlerId].transformSpecies) + personality = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_PERSONALITY); + else + personality = gTransformedPersonalities[battlerId]; + letter = GET_UNOWN_LETTER(personality); + if (!letter) + coordSpecies = species; + else + coordSpecies = letter + SPECIES_UNOWN_B - 1; + ret = gMonBackPicCoords[coordSpecies].y_offset; + } + else if (species == SPECIES_CASTFORM) + { + ret = sCastformBackSpriteYCoords[gBattleMonForms[battlerId]]; + } + else if (species > NUM_SPECIES) + { + ret = gMonBackPicCoords[0].y_offset; + } + else + { + ret = gMonBackPicCoords[species].y_offset; + } + } + else + { + if (species == SPECIES_UNOWN) + { + spriteInfo = gBattleSpritesDataPtr->battlerData; + if (!spriteInfo[battlerId].transformSpecies) + personality = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerId]], MON_DATA_PERSONALITY); + else + personality = gTransformedPersonalities[battlerId]; + letter = GET_UNOWN_LETTER(personality); + if (!letter) + coordSpecies = species; + else + coordSpecies = letter + SPECIES_UNOWN_B - 1; + ret = gMonFrontPicCoords[coordSpecies].y_offset; + } + else if (species == SPECIES_CASTFORM) + { + ret = gCastformFrontSpriteCoords[gBattleMonForms[battlerId]].y_offset; + } + else if (species > NUM_SPECIES) + { + ret = gMonFrontPicCoords[0].y_offset; + } + else + { + ret = gMonFrontPicCoords[species].y_offset; + } + } + return ret; +} + +static u8 GetBattlerElevation(u8 battlerId, u16 species) +{ + u8 ret = 0; + + if (GetBattlerSide(battlerId) == B_SIDE_OPPONENT) + { + if (species == SPECIES_CASTFORM) + ret = sCastformElevations[gBattleMonForms[battlerId]]; + else if (species > NUM_SPECIES) + ret = gEnemyMonElevation[0]; + else + ret = gEnemyMonElevation[species]; + } + return ret; +} + +static u8 GetBattlerSpriteFinal_Y(u8 battlerId, u16 species, bool8 a3) +{ + u16 offset; + u8 y; + + if (GetBattlerSide(battlerId) == B_SIDE_PLAYER) + { + offset = GetBattlerYDelta(battlerId, species); + } + else + { + offset = GetBattlerYDelta(battlerId, species); + offset -= GetBattlerElevation(battlerId, species); + } + y = offset + sBattlerCoords[IS_DOUBLE_BATTLE()][GetBattlerPosition(battlerId)].y; + if (a3) + { + if (GetBattlerSide(battlerId) == B_SIDE_PLAYER) + y += 8; + if (y > 104) + y = 104; + } + return y; +} + +u8 GetBattlerSpriteCoord2(u8 battlerId, u8 coordType) +{ + u16 species; + struct BattleSpriteInfo *spriteInfo; + + if (coordType == BATTLER_COORD_Y_PIC_OFFSET || coordType == BATTLER_COORD_Y_PIC_OFFSET_DEFAULT) + { + spriteInfo = gBattleSpritesDataPtr->battlerData; + if (!spriteInfo[battlerId].transformSpecies) + species = gAnimBattlerSpecies[battlerId]; + else + species = spriteInfo[battlerId].transformSpecies; + if (coordType == BATTLER_COORD_Y_PIC_OFFSET) + return GetBattlerSpriteFinal_Y(battlerId, species, TRUE); + else + return GetBattlerSpriteFinal_Y(battlerId, species, FALSE); + } + else + { + return GetBattlerSpriteCoord(battlerId, coordType); + } +} + +u8 GetBattlerSpriteDefault_Y(u8 battlerId) +{ + return GetBattlerSpriteCoord(battlerId, BATTLER_COORD_Y_PIC_OFFSET_DEFAULT); +} + +u8 GetSubstituteSpriteDefault_Y(u8 battlerId) +{ + u16 y; + + if (GetBattlerSide(battlerId) != B_SIDE_PLAYER) + y = GetBattlerSpriteCoord(battlerId, BATTLER_COORD_Y) + 16; + else + y = GetBattlerSpriteCoord(battlerId, BATTLER_COORD_Y) + 17; + return y; +} + +u8 GetGhostSpriteDefault_Y(u8 battlerId) +{ + if (GetBattlerSide(battlerId) != B_SIDE_OPPONENT) + return GetBattlerSpriteCoord(battlerId, BATTLER_COORD_Y_PIC_OFFSET_DEFAULT); + else + return GetBattlerSpriteCoord(battlerId, BATTLER_COORD_Y); +} + +u8 GetBattlerYCoordWithElevation(u8 battlerId) +{ + u16 species; + u8 y; + struct BattleSpriteInfo *spriteInfo; + + y = GetBattlerSpriteCoord(battlerId, BATTLER_COORD_Y); + if (GetBattlerSide(battlerId) != B_SIDE_PLAYER) + { + spriteInfo = gBattleSpritesDataPtr->battlerData; + if (!spriteInfo[battlerId].transformSpecies) + species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerId]], MON_DATA_SPECIES); + else + species = spriteInfo[battlerId].transformSpecies; + } + else + { + spriteInfo = gBattleSpritesDataPtr->battlerData; + if (!spriteInfo[battlerId].transformSpecies) + species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_SPECIES); + else + species = spriteInfo[battlerId].transformSpecies; + } + if (GetBattlerSide(battlerId) != B_SIDE_PLAYER) + y -= GetBattlerElevation(battlerId, species); + return y; +} + +u8 GetAnimBattlerSpriteId(u8 animBattler) +{ + u8 *sprites; + + if (animBattler == ANIM_ATTACKER) + { + if (IsBattlerSpritePresent(gBattleAnimAttacker)) + { + sprites = gBattlerSpriteIds; + return sprites[gBattleAnimAttacker]; + } + else + { + return 0xFF; + } + } + else if (animBattler == ANIM_TARGET) + { + if (IsBattlerSpritePresent(gBattleAnimTarget)) + { + sprites = gBattlerSpriteIds; + return sprites[gBattleAnimTarget]; + } + else + { + return 0xFF; + } + } + else if (animBattler == ANIM_ATK_PARTNER) + { + if (!IsBattlerSpriteVisible(BATTLE_PARTNER(gBattleAnimAttacker))) + return 0xFF; + else + return gBattlerSpriteIds[BATTLE_PARTNER(gBattleAnimAttacker)]; + } + else + { + if (IsBattlerSpriteVisible(BATTLE_PARTNER(gBattleAnimTarget))) + return gBattlerSpriteIds[BATTLE_PARTNER(gBattleAnimTarget)]; + else + return 0xFF; + } +} + +void StoreSpriteCallbackInData6(struct Sprite *sprite, SpriteCallback callback) +{ + sprite->data[6] = (u32)(callback) & 0xFFFF; + sprite->data[7] = (u32)(callback) >> 16; +} + +static void SetCallbackToStoredInData6(struct Sprite *sprite) +{ + u32 callback = (u16)sprite->data[6] | (sprite->data[7] << 16); + + sprite->callback = (SpriteCallback)callback; +} + +void TranslateSpriteInCircleOverDuration(struct Sprite *sprite) +{ + if (sprite->data[3]) + { + sprite->pos2.x = Sin(sprite->data[0], sprite->data[1]); + sprite->pos2.y = Cos(sprite->data[0], sprite->data[1]); + sprite->data[0] += sprite->data[2]; + if (sprite->data[0] >= 0x100) + sprite->data[0] -= 0x100; + else if (sprite->data[0] < 0) + sprite->data[0] += 0x100; + --sprite->data[3]; + } + else + { + SetCallbackToStoredInData6(sprite); + } +} + +void TranslateSpriteInGrowingCircleOverDuration(struct Sprite *sprite) +{ + if (sprite->data[3]) + { + sprite->pos2.x = Sin(sprite->data[0], (sprite->data[5] >> 8) + sprite->data[1]); + sprite->pos2.y = Cos(sprite->data[0], (sprite->data[5] >> 8) + sprite->data[1]); + sprite->data[0] += sprite->data[2]; + sprite->data[5] += sprite->data[4]; + if (sprite->data[0] >= 0x100) + sprite->data[0] -= 0x100; + else if (sprite->data[0] < 0) + sprite->data[0] += 0x100; + --sprite->data[3]; + } + else + { + SetCallbackToStoredInData6(sprite); + } +} + +// not used +static void sub_8074B5C(struct Sprite *sprite) +{ + if (sprite->data[3]) + { + sprite->pos2.x = Sin(sprite->data[0], sprite->data[1]); + sprite->pos2.y = Cos(sprite->data[4], sprite->data[1]); + sprite->data[0] += sprite->data[2]; + sprite->data[4] += sprite->data[5]; + if (sprite->data[0] >= 0x100) + sprite->data[0] -= 0x100; + else if (sprite->data[0] < 0) + sprite->data[0] += 0x100; + if (sprite->data[4] >= 0x100) + sprite->data[4] -= 0x100; + else if (sprite->data[4] < 0) + sprite->data[4] += 0x100; + --sprite->data[3]; + } + else + { + SetCallbackToStoredInData6(sprite); + } +} + +void TranslateSpriteInEllipseOverDuration(struct Sprite *sprite) +{ + if (sprite->data[3]) + { + sprite->pos2.x = Sin(sprite->data[0], sprite->data[1]); + sprite->pos2.y = Cos(sprite->data[0], sprite->data[4]); + sprite->data[0] += sprite->data[2]; + if (sprite->data[0] >= 0x100) + sprite->data[0] -= 0x100; + else if (sprite->data[0] < 0) + sprite->data[0] += 0x100; + --sprite->data[3]; + } + else + { + SetCallbackToStoredInData6(sprite); + } +} + +// Simply waits until the sprite's data[0] hits zero. +// This is used to let sprite anims or affine anims to run for a designated +// duration. +void WaitAnimForDuration(struct Sprite *sprite) +{ + if (sprite->data[0] > 0) + --sprite->data[0]; + else + SetCallbackToStoredInData6(sprite); +} + +static void sub_8074C64(struct Sprite *sprite) +{ + sub_8074C80(sprite); + sprite->callback = TranslateSpriteLinear; + sprite->callback(sprite); +} + +void sub_8074C80(struct Sprite *sprite) +{ + s16 old; + s32 xDiff; + + if (sprite->data[1] > sprite->data[2]) + sprite->data[0] = -sprite->data[0]; + xDiff = sprite->data[2] - sprite->data[1]; + old = sprite->data[0]; + sprite->data[0] = abs(xDiff / sprite->data[0]); + sprite->data[2] = (sprite->data[4] - sprite->data[3]) / sprite->data[0]; + sprite->data[1] = old; +} + +void TranslateSpriteLinear(struct Sprite *sprite) +{ + if (sprite->data[0] > 0) + { + --sprite->data[0]; + sprite->pos2.x += sprite->data[1]; + sprite->pos2.y += sprite->data[2]; + } + else + { + SetCallbackToStoredInData6(sprite); + } +} + +void TranslateSpriteLinearFixedPoint(struct Sprite *sprite) +{ + if (sprite->data[0] > 0) + { + --sprite->data[0]; + sprite->data[3] += sprite->data[1]; + sprite->data[4] += sprite->data[2]; + sprite->pos2.x = sprite->data[3] >> 8; + sprite->pos2.y = sprite->data[4] >> 8; + } + else + { + SetCallbackToStoredInData6(sprite); + } +} + +static void TranslateSpriteLinearFixedPointIconFrame(struct Sprite *sprite) +{ + if (sprite->data[0] > 0) + { + --sprite->data[0]; + sprite->data[3] += sprite->data[1]; + sprite->data[4] += sprite->data[2]; + sprite->pos2.x = sprite->data[3] >> 8; + sprite->pos2.y = sprite->data[4] >> 8; + } + else + { + SetCallbackToStoredInData6(sprite); + } + + UpdateMonIconFrame(sprite); +} + +// not used +static void sub_8074D80(struct Sprite *sprite) +{ + sprite->data[1] = sprite->pos1.x + sprite->pos2.x; + sprite->data[3] = sprite->pos1.y + sprite->pos2.y; + sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2); + sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET); + sprite->callback = sub_8074C64; +} + +void TranslateMonSpriteLinear(struct Sprite *sprite) +{ + if (sprite->data[0] > 0) + { + --sprite->data[0]; + gSprites[sprite->data[3]].pos2.x += sprite->data[1]; + gSprites[sprite->data[3]].pos2.y += sprite->data[2]; + } + else + { + SetCallbackToStoredInData6(sprite); + } +} + +void TranslateMonSpriteLinearFixedPoint(struct Sprite *sprite) +{ + if (sprite->data[0] > 0) + { + --sprite->data[0]; + sprite->data[3] += sprite->data[1]; + sprite->data[4] += sprite->data[2]; + gSprites[sprite->data[5]].pos2.x = sprite->data[3] >> 8; + gSprites[sprite->data[5]].pos2.y = sprite->data[4] >> 8; + } + else + { + SetCallbackToStoredInData6(sprite); + } +} + +void TranslateSpriteLinearAndFlicker(struct Sprite *sprite) +{ + if (sprite->data[0] > 0) + { + --sprite->data[0]; + sprite->pos2.x = sprite->data[2] >> 8; + sprite->data[2] += sprite->data[1]; + sprite->pos2.y = sprite->data[4] >> 8; + sprite->data[4] += sprite->data[3]; + if (sprite->data[0] % sprite->data[5] == 0) + { + if (sprite->data[5]) + sprite->invisible ^= 1; + } + } + else + { + SetCallbackToStoredInData6(sprite); + } +} + +void DestroySpriteAndMatrix(struct Sprite *sprite) +{ + FreeSpriteOamMatrix(sprite); + DestroyAnimSprite(sprite); +} + +// not used +static void sub_8074EF4(struct Sprite *sprite) +{ + sprite->data[1] = sprite->pos1.x + sprite->pos2.x; + sprite->data[3] = sprite->pos1.y + sprite->pos2.y; + sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2); + sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET); + sprite->callback = sub_8074C64; +} + +// not used +static void sub_8074F38(struct Sprite *sprite) +{ + ResetPaletteStructByUid(sprite->data[5]); + DestroySpriteAndMatrix(sprite); +} + +void RunStoredCallbackWhenAffineAnimEnds(struct Sprite *sprite) +{ + if (sprite->affineAnimEnded) + SetCallbackToStoredInData6(sprite); +} + +void RunStoredCallbackWhenAnimEnds(struct Sprite *sprite) +{ + if (sprite->animEnded) + SetCallbackToStoredInData6(sprite); +} + +void DestroyAnimSpriteAndDisableBlend(struct Sprite *sprite) +{ + SetGpuReg(REG_OFFSET_BLDCNT, 0); + SetGpuReg(REG_OFFSET_BLDALPHA, 0); + DestroyAnimSprite(sprite); +} + +void DestroyAnimVisualTaskAndDisableBlend(u8 taskId) +{ + SetGpuReg(REG_OFFSET_BLDCNT, 0); + SetGpuReg(REG_OFFSET_BLDALPHA, 0); + DestroyAnimVisualTask(taskId); +} + +void SetSpriteCoordsToAnimAttackerCoords(struct Sprite *sprite) +{ + sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2); + sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET); +} + +// Sets the initial x offset of the anim sprite depending on the horizontal orientation +// of the two involved mons. +void SetAnimSpriteInitialXOffset(struct Sprite *sprite, s16 xOffset) +{ + u16 attackerX = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X); + u16 targetX = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X); + + if (attackerX > targetX) + { + sprite->pos1.x -= xOffset; + } + else if (attackerX < targetX) + { + sprite->pos1.x += xOffset; + } + else + { + if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) + sprite->pos1.x -= xOffset; + else + sprite->pos1.x += xOffset; + } +} + +void InitAnimArcTranslation(struct Sprite *sprite) +{ + sprite->data[1] = sprite->pos1.x; + sprite->data[3] = sprite->pos1.y; + InitAnimLinearTranslation(sprite); + sprite->data[6] = 0x8000 / sprite->data[0]; + sprite->data[7] = 0; +} + +bool8 TranslateAnimHorizontalArc(struct Sprite *sprite) +{ + if (AnimTranslateLinear(sprite)) + return TRUE; + sprite->data[7] += sprite->data[6]; + sprite->pos2.y += Sin((u8)(sprite->data[7] >> 8), sprite->data[5]); + return FALSE; +} + +bool8 TranslateAnimVerticalArc(struct Sprite *sprite) +{ + if (AnimTranslateLinear(sprite)) + return TRUE; + sprite->data[7] += sprite->data[6]; + sprite->pos2.x += Sin((u8)(sprite->data[7] >> 8), sprite->data[5]); + return FALSE; +} + +void SetSpritePrimaryCoordsFromSecondaryCoords(struct Sprite *sprite) +{ + sprite->pos1.x += sprite->pos2.x; + sprite->pos1.y += sprite->pos2.y; + sprite->pos2.x = 0; + sprite->pos2.y = 0; +} + +void InitSpritePosToAnimTarget(struct Sprite *sprite, bool8 respectMonPicOffsets) +{ + // Battle anim sprites are automatically created at the anim target's center, which + // is why there is no else clause for the "respectMonPicOffsets" check. + if (!respectMonPicOffsets) + { + sprite->pos1.x = GetBattlerSpriteCoord2(gBattleAnimTarget, BATTLER_COORD_X); + sprite->pos1.y = GetBattlerSpriteCoord2(gBattleAnimTarget, BATTLER_COORD_Y); + } + SetAnimSpriteInitialXOffset(sprite, gBattleAnimArgs[0]); + sprite->pos1.y += gBattleAnimArgs[1]; +} + +void InitSpritePosToAnimAttacker(struct Sprite *sprite, bool8 respectMonPicOffsets) +{ + if (!respectMonPicOffsets) + { + sprite->pos1.x = GetBattlerSpriteCoord2(gBattleAnimAttacker, BATTLER_COORD_X); + sprite->pos1.y = GetBattlerSpriteCoord2(gBattleAnimAttacker, BATTLER_COORD_Y); + } + else + { + sprite->pos1.x = GetBattlerSpriteCoord2(gBattleAnimAttacker, BATTLER_COORD_X_2); + sprite->pos1.y = GetBattlerSpriteCoord2(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET); + } + SetAnimSpriteInitialXOffset(sprite, gBattleAnimArgs[0]); + sprite->pos1.y += gBattleAnimArgs[1]; +} + +u8 GetBattlerSide(u8 battlerId) +{ + return GET_BATTLER_SIDE2(battlerId); +} + +u8 GetBattlerPosition(u8 battlerId) +{ + return GET_BATTLER_POSITION(battlerId); +} + +u8 GetBattlerAtPosition(u8 position) +{ + u8 i; + + for (i = 0; i < gBattlersCount; ++i) + if (gBattlerPositions[i] == position) + break; + return i; +} + +bool8 IsBattlerSpritePresent(u8 battlerId) +{ + if (gBattlerPositions[battlerId] == 0xFF) + { + return FALSE; + } + else if (GetBattlerSide(battlerId) != B_SIDE_PLAYER) + { + if (GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerId]], MON_DATA_HP) != 0) + return TRUE; + } + else + { + if (GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_HP) != 0) + return TRUE; + } + return FALSE; +} + +bool8 IsDoubleBattle(void) +{ + return IS_DOUBLE_BATTLE(); +} + +void sub_80752A0(struct BattleAnimBgData *animBgData) +{ + animBgData->bgTiles = gUnknown_2022BB8; + animBgData->bgTilemap = (u16 *)gUnknown_2022BBC; + animBgData->paletteId = 8; + animBgData->bgId = 1; + animBgData->tilesOffset = 0x200; + animBgData->unused = 0; +} + +void sub_80752C8(struct BattleAnimBgData *animBgData, u32 arg1) +{ + if (arg1 == 1) + { + sub_80752A0(animBgData); + } + else + { + animBgData->bgTiles = gUnknown_2022BB8; + animBgData->bgTilemap = (u16 *)gUnknown_2022BBC; + animBgData->paletteId = 9; + animBgData->bgId = 2; + animBgData->tilesOffset = 0x300; + animBgData->unused = 0; + } +} + +void sub_8075300(struct BattleAnimBgData *animBgData, u8 unused) +{ + animBgData->bgTiles = gUnknown_2022BB8; + animBgData->bgTilemap = (u16 *)gUnknown_2022BBC; + if (GetBattlerSpriteBGPriorityRank(gBattleAnimAttacker) == 1) + { + animBgData->paletteId = 8; + animBgData->bgId = 1; + animBgData->tilesOffset = 0x200; + animBgData->unused = 0; + } + else + { + animBgData->paletteId = 9; + animBgData->bgId = 2; + animBgData->tilesOffset = 0x300; + animBgData->unused = 0; + } +} + +void sub_8075358(u32 bgId) +{ + struct BattleAnimBgData animBgData; + + sub_80752C8(&animBgData, bgId); + CpuFill32(0, animBgData.bgTiles, 0x2000); + LoadBgTiles(bgId, animBgData.bgTiles, 0x2000, animBgData.tilesOffset); + FillBgTilemapBufferRect(bgId, 0, 0, 0, 32, 64, 17); + CopyBgTilemapBufferToVram(bgId); +} + +void AnimLoadCompressedBgGfx(u32 bgId, const u32 *src, u32 tilesOffset) +{ + CpuFill32(0, gUnknown_2022BB8, 0x2000); + LZDecompressWram(src, gUnknown_2022BB8); + LoadBgTiles(bgId, gUnknown_2022BB8, 0x2000, tilesOffset); +} + +void InitAnimBgTilemapBuffer(u32 bgId, const void *src) +{ + FillBgTilemapBufferRect(bgId, 0, 0, 0, 32, 64, 17); + CopyToBgTilemapBuffer(bgId, src, 0, 0); +} + +void AnimLoadCompressedBgTilemap(u32 bgId, const u32 *src) +{ + InitAnimBgTilemapBuffer(bgId, src); + CopyBgTilemapBufferToVram(bgId); +} + +u8 sub_8075454(void) +{ + return 2; +} + +void sub_8075458(bool8 arg0) +{ + if (!arg0) + { + SetAnimBgAttribute(3, BG_ANIM_SCREEN_SIZE, 0); + SetAnimBgAttribute(3, BG_ANIM_AREA_OVERFLOW_MODE, 1); + } + else + { + SetAnimBgAttribute(3, BG_ANIM_SCREEN_SIZE, 1); + SetAnimBgAttribute(3, BG_ANIM_AREA_OVERFLOW_MODE, 0); + } +} + +void sub_8075490(struct Sprite *sprite) +{ + sprite->data[1] = sprite->pos1.x; + sprite->data[3] = sprite->pos1.y; + InitSpriteDataForLinearTranslation(sprite); + sprite->callback = TranslateSpriteLinearFixedPointIconFrame; + sprite->callback(sprite); +} + +void InitSpriteDataForLinearTranslation(struct Sprite *sprite) +{ + s16 x = (sprite->data[2] - sprite->data[1]) << 8; + s16 y = (sprite->data[4] - sprite->data[3]) << 8; + + sprite->data[1] = x / sprite->data[0]; + sprite->data[2] = y / sprite->data[0]; + sprite->data[4] = 0; + sprite->data[3] = 0; +} + +void InitAnimLinearTranslation(struct Sprite *sprite) +{ + s32 x = sprite->data[2] - sprite->data[1]; + s32 y = sprite->data[4] - sprite->data[3]; + bool8 movingLeft = x < 0; + bool8 movingUp = y < 0; + u16 xDelta = abs(x) << 8; + u16 yDelta = abs(y) << 8; + + xDelta = xDelta / sprite->data[0]; + yDelta = yDelta / sprite->data[0]; + + if (movingLeft) + xDelta |= 1; + else + xDelta &= ~1; + + if (movingUp) + yDelta |= 1; + else + yDelta &= ~1; + + sprite->data[1] = xDelta; + sprite->data[2] = yDelta; + sprite->data[4] = 0; + sprite->data[3] = 0; +} + +void StartAnimLinearTranslation(struct Sprite *sprite) +{ + sprite->data[1] = sprite->pos1.x; + sprite->data[3] = sprite->pos1.y; + InitAnimLinearTranslation(sprite); + sprite->callback = sub_807563C; + sprite->callback(sprite); +} + +void sub_80755B8(struct Sprite *sprite) +{ + sprite->data[1] = sprite->pos1.x; + sprite->data[3] = sprite->pos1.y; + InitAnimLinearTranslation(sprite); + sprite->callback = sub_8075658; + sprite->callback(sprite); +} + +bool8 AnimTranslateLinear(struct Sprite *sprite) +{ + u16 v1, v2, x, y; + + if (!sprite->data[0]) + return TRUE; + v1 = sprite->data[1]; + v2 = sprite->data[2]; + x = sprite->data[3]; + y = sprite->data[4]; + x += v1; + y += v2; + if (v1 & 1) + sprite->pos2.x = -(x >> 8); + else + sprite->pos2.x = x >> 8; + + if (v2 & 1) + sprite->pos2.y = -(y >> 8); + else + sprite->pos2.y = y >> 8; + sprite->data[3] = x; + sprite->data[4] = y; + --sprite->data[0]; + return FALSE; +} + +void sub_807563C(struct Sprite *sprite) +{ + if (AnimTranslateLinear(sprite)) + SetCallbackToStoredInData6(sprite); +} + +static void sub_8075658(struct Sprite *sprite) +{ + sub_801236C(sprite); + if (AnimTranslateLinear(sprite)) + SetCallbackToStoredInData6(sprite); +} + +void sub_8075678(struct Sprite *sprite) +{ + s32 v1 = abs(sprite->data[2] - sprite->data[1]) << 8; + + sprite->data[0] = v1 / sprite->data[0]; + InitAnimLinearTranslation(sprite); +} + +void sub_80756A4(struct Sprite *sprite) +{ + sprite->data[1] = sprite->pos1.x; + sprite->data[3] = sprite->pos1.y; + sub_8075678(sprite); + sprite->callback = sub_807563C; + sprite->callback(sprite); +} + +static void InitAnimFastLinearTranslation(struct Sprite *sprite) +{ + s32 xDiff = sprite->data[2] - sprite->data[1]; + s32 yDiff = sprite->data[4] - sprite->data[3]; + bool8 xSign = xDiff < 0; + bool8 ySign = yDiff < 0; + u16 x2 = abs(xDiff) << 4; + u16 y2 = abs(yDiff) << 4; + + x2 /= sprite->data[0]; + y2 /= sprite->data[0]; + if (xSign) + x2 |= 1; + else + x2 &= ~1; + if (ySign) + y2 |= 1; + else + y2 &= ~1; + sprite->data[1] = x2; + sprite->data[2] = y2; + sprite->data[4] = 0; + sprite->data[3] = 0; +} + +void InitAndRunAnimFastLinearTranslation(struct Sprite *sprite) +{ + sprite->data[1] = sprite->pos1.x; + sprite->data[3] = sprite->pos1.y; + InitAnimFastLinearTranslation(sprite); + sprite->callback = sub_80757E8; + sprite->callback(sprite); +} + +bool8 AnimFastTranslateLinear(struct Sprite *sprite) +{ + u16 v1, v2, x, y; + + if (!sprite->data[0]) + return TRUE; + v1 = sprite->data[1]; + v2 = sprite->data[2]; + x = sprite->data[3]; + y = sprite->data[4]; + x += v1; + y += v2; + if (v1 & 1) + sprite->pos2.x = -(x >> 4); + else + sprite->pos2.x = x >> 4; + if (v2 & 1) + sprite->pos2.y = -(y >> 4); + else + sprite->pos2.y = y >> 4; + sprite->data[3] = x; + sprite->data[4] = y; + --sprite->data[0]; + return FALSE; +} + +static void sub_80757E8(struct Sprite *sprite) +{ + if (AnimFastTranslateLinear(sprite)) + SetCallbackToStoredInData6(sprite); +} + +void InitAnimFastLinearTranslationWithSpeed(struct Sprite *sprite) +{ + s32 xDiff = abs(sprite->data[2] - sprite->data[1]) << 4; + + sprite->data[0] = xDiff / sprite->data[0]; + InitAnimFastLinearTranslation(sprite); +} + +void sub_8075830(struct Sprite *sprite) +{ + sprite->data[1] = sprite->pos1.x; + sprite->data[3] = sprite->pos1.y; + InitAnimFastLinearTranslationWithSpeed(sprite); + sprite->callback = sub_80757E8; + sprite->callback(sprite); +} + +void SetSpriteRotScale(u8 spriteId, s16 xScale, s16 yScale, u16 rotation) +{ + s32 i; + struct ObjAffineSrcData src; + struct OamMatrix matrix; + + src.xScale = xScale; + src.yScale = yScale; + src.rotation = rotation; + if (sub_80758DC()) + src.xScale = -src.xScale; + i = gSprites[spriteId].oam.matrixNum; + ObjAffineSet(&src, &matrix, 1, 2); + gOamMatrices[i].a = matrix.a; + gOamMatrices[i].b = matrix.b; + gOamMatrices[i].c = matrix.c; + gOamMatrices[i].d = matrix.d; +} + +static bool8 sub_80758DC(void) +{ + return FALSE; +} + +void PrepareBattlerSpriteForRotScale(u8 spriteId, u8 objMode) +{ + u8 battlerId = gSprites[spriteId].data[0]; + + if (IsBattlerSpriteVisible(battlerId)) + gSprites[spriteId].invisible = FALSE; + gSprites[spriteId].oam.objMode = objMode; + gSprites[spriteId].affineAnimPaused = TRUE; + if (!gSprites[spriteId].oam.affineMode) + gSprites[spriteId].oam.matrixNum = gBattleSpritesDataPtr->healthBoxesData[battlerId].matrixNum; + gSprites[spriteId].oam.affineMode = ST_OAM_AFFINE_DOUBLE; + CalcCenterToCornerVec(&gSprites[spriteId], gSprites[spriteId].oam.shape, gSprites[spriteId].oam.size, gSprites[spriteId].oam.affineMode); +} + +void ResetSpriteRotScale(u8 spriteId) +{ + SetSpriteRotScale(spriteId, 0x100, 0x100, 0); + gSprites[spriteId].oam.affineMode = ST_OAM_AFFINE_NORMAL; + gSprites[spriteId].oam.objMode = 0; + gSprites[spriteId].affineAnimPaused = FALSE; + CalcCenterToCornerVec(&gSprites[spriteId], gSprites[spriteId].oam.shape, gSprites[spriteId].oam.size, gSprites[spriteId].oam.affineMode); +} + +// Sets the sprite's y offset equal to the y displacement caused by the +// matrix's rotation. +void SetBattlerSpriteYOffsetFromRotation(u8 spriteId) +{ + u16 matrixNum = gSprites[spriteId].oam.matrixNum; + // The "c" component of the battler sprite matrix contains the sine of the rotation angle divided by some scale amount. + s16 c = gOamMatrices[matrixNum].c; + + if (c < 0) + c = -c; + gSprites[spriteId].pos2.y = c >> 3; +} + +void TrySetSpriteRotScale(struct Sprite *sprite, bool8 recalcCenterVector, s16 xScale, s16 yScale, u16 rotation) +{ + s32 i; + struct ObjAffineSrcData src; + struct OamMatrix matrix; + + if (sprite->oam.affineMode & 1) + { + sprite->affineAnimPaused = TRUE; + if (recalcCenterVector) + CalcCenterToCornerVec(sprite, sprite->oam.shape, sprite->oam.size, sprite->oam.affineMode); + src.xScale = xScale; + src.yScale = yScale; + src.rotation = rotation; + if (sub_80758DC()) + src.xScale = -src.xScale; + i = sprite->oam.matrixNum; + ObjAffineSet(&src, &matrix, 1, 2); + gOamMatrices[i].a = matrix.a; + gOamMatrices[i].b = matrix.b; + gOamMatrices[i].c = matrix.c; + gOamMatrices[i].d = matrix.d; + } +} + +void sub_8075AD8(struct Sprite *sprite) +{ + TrySetSpriteRotScale(sprite, TRUE, 0x100, 0x100, 0); + sprite->affineAnimPaused = FALSE; + CalcCenterToCornerVec(sprite, sprite->oam.shape, sprite->oam.size, sprite->oam.affineMode); +} + +static u16 ArcTan2_(s16 a, s16 b) +{ + return ArcTan2(a, b); +} + +u16 ArcTan2Neg(s16 a, s16 b) +{ + u16 var = ArcTan2_(a, b); + return -var; +} + +void SetGreyscaleOrOriginalPalette(u16 paletteNum, bool8 restoreOriginalColor) +{ + s32 i; + struct PlttData *originalColor; + struct PlttData *destColor; + u16 average; + + paletteNum *= 16; + + if (!restoreOriginalColor) + { + for (i = 0; i < 16; ++i) + { + originalColor = (struct PlttData *)&gPlttBufferUnfaded[paletteNum + i]; + average = originalColor->r + originalColor->g + originalColor->b; + average /= 3; + destColor = (struct PlttData *)&gPlttBufferFaded[paletteNum + i]; + destColor->r = average; + destColor->g = average; + destColor->b = average; + } + } + else + { + CpuCopy32(&gPlttBufferUnfaded[paletteNum], &gPlttBufferFaded[paletteNum], 32); + } +} + +u32 sub_8075BE8(u8 battleBackground, u8 attacker, u8 target, u8 attackerPartner, u8 targetPartner, u8 a6, u8 a7) +{ + u32 selectedPalettes = 0; + u32 shift; + + if (battleBackground) + { + selectedPalettes = 0xe; + } + if (attacker) + { + shift = gBattleAnimAttacker + 16; + selectedPalettes |= 1 << shift; + } + if (target) + { + shift = gBattleAnimTarget + 16; + selectedPalettes |= 1 << shift; + } + if (attackerPartner) + { + if (IsBattlerSpriteVisible(BATTLE_PARTNER(gBattleAnimAttacker))) + { + shift = BATTLE_PARTNER(gBattleAnimAttacker) + 16; + selectedPalettes |= 1 << shift; + } + } + if (targetPartner) + { + if (IsBattlerSpriteVisible(BATTLE_PARTNER(gBattleAnimTarget))) + { + shift = BATTLE_PARTNER(gBattleAnimTarget) + 16; + selectedPalettes |= 1 << shift; + } + } + if (a6) + { + selectedPalettes |= 0x100; + } + if (a7) + { + selectedPalettes |= 0x200; + } + return selectedPalettes; +} + +u32 sub_8075CB8(u8 a1, u8 a2, u8 a3, u8 a4) +{ + u32 var = 0; + u32 shift; + + if (a1) + { + if (IsBattlerSpriteVisible(GetBattlerAtPosition(B_POSITION_PLAYER_LEFT))) + { + var |= 1 << (GetBattlerAtPosition(B_POSITION_PLAYER_LEFT) + 16); + } + } + if (a2) + { + if (IsBattlerSpriteVisible(GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT))) + { + shift = GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT) + 16; + var |= 1 << shift; + } + } + if (a3) + { + if (IsBattlerSpriteVisible(GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT))) + { + shift = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT) + 16; + var |= 1 << shift; + } + } + if (a4) + { + if (IsBattlerSpriteVisible(GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT))) + { + shift = GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT) + 16; + var |= 1 << shift; + } + } + return var; +} + +u8 sub_8075D80(u8 a1) +{ + return a1; +} + +// not used +static u8 GetBattlerAtPosition_(u8 position) +{ + return GetBattlerAtPosition(position); +} + +void sub_8075D9C(struct Sprite *sprite) +{ + bool8 var; + + if (!sprite->data[0]) + { + if (!gBattleAnimArgs[3]) + var = TRUE; + else + var = FALSE; + if (!gBattleAnimArgs[2]) + InitSpritePosToAnimAttacker(sprite, var); + else + InitSpritePosToAnimTarget(sprite, var); + ++sprite->data[0]; + + } + else if (sprite->animEnded || sprite->affineAnimEnded) + { + DestroySpriteAndMatrix(sprite); + } +} + +// Linearly translates a sprite to a target position on the +// other mon's sprite. +// arg 0: initial x offset +// arg 1: initial y offset +// arg 2: target x offset +// arg 3: target y offset +// arg 4: duration +// arg 5: lower 8 bits = location on attacking mon, upper 8 bits = location on target mon pick to target +void TranslateAnimSpriteToTargetMonLocation(struct Sprite *sprite) +{ + bool8 respectMonPicOffsets; + u8 coordType; + + if (!(gBattleAnimArgs[5] & 0xFF00)) + respectMonPicOffsets = TRUE; + else + respectMonPicOffsets = FALSE; + if (!(gBattleAnimArgs[5] & 0xFF)) + coordType = BATTLER_COORD_Y_PIC_OFFSET; + else + coordType = BATTLER_COORD_Y; + InitSpritePosToAnimAttacker(sprite, respectMonPicOffsets); + if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) + gBattleAnimArgs[2] = -gBattleAnimArgs[2]; + sprite->data[0] = gBattleAnimArgs[4]; + sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2) + gBattleAnimArgs[2]; + sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, coordType) + gBattleAnimArgs[3]; + sprite->callback = StartAnimLinearTranslation; + StoreSpriteCallbackInData6(sprite, DestroyAnimSprite); +} + +void sub_8075E80(struct Sprite *sprite) +{ + InitSpritePosToAnimAttacker(sprite, 1); + if (GetBattlerSide(gBattleAnimAttacker)) + gBattleAnimArgs[2] = -gBattleAnimArgs[2]; + sprite->data[0] = gBattleAnimArgs[4]; + sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2) + gBattleAnimArgs[2]; + sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET) + gBattleAnimArgs[3]; + sprite->data[5] = gBattleAnimArgs[5]; + InitAnimArcTranslation(sprite); + sprite->callback = sub_8075EF0; +} + +static void sub_8075EF0(struct Sprite *sprite) +{ + if (TranslateAnimHorizontalArc(sprite)) + DestroyAnimSprite(sprite); +} + +void sub_8075F0C(struct Sprite *sprite) +{ + bool8 r4; + u8 battlerId, coordType; + + if (!gBattleAnimArgs[6]) + { + r4 = TRUE; + coordType = BATTLER_COORD_Y_PIC_OFFSET; + } + else + { + r4 = FALSE; + coordType = BATTLER_COORD_Y; + } + if (!gBattleAnimArgs[5]) + { + InitSpritePosToAnimAttacker(sprite, r4); + battlerId = gBattleAnimAttacker; + } + else + { + InitSpritePosToAnimTarget(sprite, r4); + battlerId = gBattleAnimTarget; + } + if (GetBattlerSide(gBattleAnimAttacker)) + gBattleAnimArgs[2] = -gBattleAnimArgs[2]; + InitSpritePosToAnimTarget(sprite, r4); + sprite->data[0] = gBattleAnimArgs[4]; + sprite->data[2] = GetBattlerSpriteCoord(battlerId, BATTLER_COORD_X_2) + gBattleAnimArgs[2]; + sprite->data[4] = GetBattlerSpriteCoord(battlerId, coordType) + gBattleAnimArgs[3]; + sprite->callback = StartAnimLinearTranslation; + StoreSpriteCallbackInData6(sprite, DestroyAnimSprite); +} + +s16 CloneBattlerSpriteWithBlend(u8 animBattler) +{ + u16 i; + u8 spriteId = GetAnimBattlerSpriteId(animBattler); + + if (spriteId != 0xFF) + { + for (i = 0; i < MAX_SPRITES; ++i) + { + if (!gSprites[i].inUse) + { + gSprites[i] = gSprites[spriteId]; + gSprites[i].oam.objMode = ST_OAM_OBJ_BLEND; + gSprites[i].invisible = FALSE; + return i; + } + } + } + return -1; +} + +void obj_delete_but_dont_free_vram(struct Sprite *sprite) +{ + sprite->usingSheet = TRUE; + DestroySprite(sprite); +} + +void sub_8076048(u8 taskId) +{ + s16 v1 = 0, v2 = 0; + + if (gBattleAnimArgs[2] > gBattleAnimArgs[0]) + v2 = 1; + if (gBattleAnimArgs[2] < gBattleAnimArgs[0]) + v2 = -1; + if (gBattleAnimArgs[3] > gBattleAnimArgs[1]) + v1 = 1; + if (gBattleAnimArgs[3] < gBattleAnimArgs[1]) + v1 = -1; + gTasks[taskId].data[0] = 0; + gTasks[taskId].data[1] = gBattleAnimArgs[4]; + gTasks[taskId].data[2] = 0; + gTasks[taskId].data[3] = gBattleAnimArgs[0]; + gTasks[taskId].data[4] = gBattleAnimArgs[1]; + gTasks[taskId].data[5] = v2; + gTasks[taskId].data[6] = v1; + gTasks[taskId].data[7] = gBattleAnimArgs[2]; + gTasks[taskId].data[8] = gBattleAnimArgs[3]; + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gBattleAnimArgs[0], gBattleAnimArgs[1])); + gTasks[taskId].func = sub_80760D0; +} + +static void sub_80760D0(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + + if (++task->data[0] > task->data[1]) + { + task->data[0] = 0; + if (++task->data[2] & 1) + { + if (task->data[3] != task->data[7]) + task->data[3] += task->data[5]; + } + else + { + if (task->data[4] != task->data[8]) + task->data[4] += task->data[6]; + } + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(task->data[3], task->data[4])); + if (task->data[3] == task->data[7] && task->data[4] == task->data[8]) + { + DestroyAnimVisualTask(taskId); + return; + } + } +} + +// Linearly blends a mon's sprite colors with a target color with increasing +// strength, and then blends out to the original color. +// arg 0: anim bank +// arg 1: blend color +// arg 2: target blend coefficient +// arg 3: initial delay +// arg 4: number of times to blend in and out +void AnimTask_BlendMonInAndOut(u8 task) +{ + u8 spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[0]); + + if (spriteId == 0xFF) + { + DestroyAnimVisualTask(task); + return; + } + gTasks[task].data[0] = (gSprites[spriteId].oam.paletteNum * 0x10) + 0x101; + AnimTask_BlendMonInAndOutSetup(&gTasks[task]); +} + +static void AnimTask_BlendMonInAndOutSetup(struct Task *task) +{ + task->data[1] = gBattleAnimArgs[1]; + task->data[2] = 0; + task->data[3] = gBattleAnimArgs[2]; + task->data[4] = 0; + task->data[5] = gBattleAnimArgs[3]; + task->data[6] = 0; + task->data[7] = gBattleAnimArgs[4]; + task->func = AnimTask_BlendMonInAndOutStep; +} + +static void AnimTask_BlendMonInAndOutStep(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + + if (++task->data[4] >= task->data[5]) + { + task->data[4] = 0; + if (!task->data[6]) + { + ++task->data[2]; + BlendPalette(task->data[0], 15, task->data[2], task->data[1]); + if (task->data[2] == task->data[3]) + task->data[6] = 1; + } + else + { + --task->data[2]; + BlendPalette(task->data[0], 15, task->data[2], task->data[1]); + if (!task->data[2]) + { + if (--task->data[7]) + { + task->data[4] = 0; + task->data[6] = 0; + } + else + { + DestroyAnimVisualTask(taskId); + return; + } + } + } + } +} + +void sub_8076288(u8 taskId) +{ + u8 palette = IndexOfSpritePaletteTag(gBattleAnimArgs[0]); + + if (palette == 0xFF) + { + DestroyAnimVisualTask(taskId); + return; + } + gTasks[taskId].data[0] = (palette * 0x10) + 0x101; + AnimTask_BlendMonInAndOutSetup(&gTasks[taskId]); +} + +void PrepareAffineAnimInTaskData(struct Task *task, u8 spriteId, const union AffineAnimCmd *affineAnimCmds) +{ + task->data[7] = 0; + task->data[8] = 0; + task->data[9] = 0; + task->data[15] = spriteId; + task->data[10] = 0x100; + task->data[11] = 0x100; + task->data[12] = 0; + StorePointerInVars(&task->data[13], &task->data[14], affineAnimCmds); + PrepareBattlerSpriteForRotScale(spriteId, ST_OAM_OBJ_NORMAL); +} + +bool8 RunAffineAnimFromTaskData(struct Task *task) +{ + sAnimTaskAffineAnim = LoadPointerFromVars(task->data[13], task->data[14]) + (task->data[7] << 3); + switch (sAnimTaskAffineAnim->type) + { + default: + if (!sAnimTaskAffineAnim->frame.duration) + { + task->data[10] = sAnimTaskAffineAnim->frame.xScale; + task->data[11] = sAnimTaskAffineAnim->frame.yScale; + task->data[12] = sAnimTaskAffineAnim->frame.rotation; + ++task->data[7]; + ++sAnimTaskAffineAnim; + } + task->data[10] += sAnimTaskAffineAnim->frame.xScale; + task->data[11] += sAnimTaskAffineAnim->frame.yScale; + task->data[12] += sAnimTaskAffineAnim->frame.rotation; + SetSpriteRotScale(task->data[15], task->data[10], task->data[11], task->data[12]); + SetBattlerSpriteYOffsetFromYScale(task->data[15]); + if (++task->data[8] >= sAnimTaskAffineAnim->frame.duration) + { + task->data[8] = 0; + ++task->data[7]; + } + break; + case AFFINEANIMCMDTYPE_JUMP: + task->data[7] = sAnimTaskAffineAnim->jump.target; + break; + case AFFINEANIMCMDTYPE_LOOP: + if (sAnimTaskAffineAnim->loop.count) + { + if (task->data[9]) + { + if (!--task->data[9]) + { + ++task->data[7]; + break; + } + } + else + { + task->data[9] = sAnimTaskAffineAnim->loop.count; + } + if (!task->data[7]) + { + break; + } + while (TRUE) + { + --task->data[7]; + --sAnimTaskAffineAnim; + if (sAnimTaskAffineAnim->type == AFFINEANIMCMDTYPE_LOOP) + { + ++task->data[7]; + return TRUE; + } + if (!task->data[7]) + return TRUE; + } + } + ++task->data[7]; + break; + case AFFINEANIMCMDTYPE_END: + gSprites[task->data[15]].pos2.y = 0; + ResetSpriteRotScale(task->data[15]); + return FALSE; + } + return TRUE; +} + +// Sets the sprite's y offset equal to the y displacement caused by the +// matrix's scale in the y dimension. +void SetBattlerSpriteYOffsetFromYScale(u8 spriteId) +{ + s32 var = 64 - GetBattlerYDeltaFromSpriteId(spriteId) * 2; + u16 matrix = gSprites[spriteId].oam.matrixNum; + s32 var2 = (var << 8) / gOamMatrices[matrix].d; + + if (var2 > 128) + var2 = 128; + gSprites[spriteId].pos2.y = (var - var2) / 2; +} + +// Sets the sprite's y offset equal to the y displacement caused by another sprite +// matrix's scale in the y dimension. +void SetBattlerSpriteYOffsetFromOtherYScale(u8 spriteId, u8 otherSpriteId) +{ + s32 var = 64 - GetBattlerYDeltaFromSpriteId(otherSpriteId) * 2; + u16 matrix = gSprites[spriteId].oam.matrixNum; + s32 var2 = (var << 8) / gOamMatrices[matrix].d; + + if (var2 > 128) + var2 = 128; + gSprites[spriteId].pos2.y = (var - var2) / 2; +} + +static u16 GetBattlerYDeltaFromSpriteId(u8 spriteId) +{ + struct BattleSpriteInfo *spriteInfo; + u8 battlerId = gSprites[spriteId].data[0]; + u16 species; + u16 i; + + for (i = 0; i < MAX_BATTLERS_COUNT; ++i) + { + if (gBattlerSpriteIds[i] == spriteId) + { + if (GetBattlerSide(i) == B_SIDE_PLAYER) + { + spriteInfo = gBattleSpritesDataPtr->battlerData; + if (!spriteInfo[battlerId].transformSpecies) + species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[i]], MON_DATA_SPECIES); + else + species = spriteInfo[battlerId].transformSpecies; + return gMonBackPicCoords[species].y_offset; + } + else + { + spriteInfo = gBattleSpritesDataPtr->battlerData; + if (!spriteInfo[battlerId].transformSpecies) + species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[i]], MON_DATA_SPECIES); + else + species = spriteInfo[battlerId].transformSpecies; + return gMonFrontPicCoords[species].y_offset; + } + } + } + return 64; +} + +void StorePointerInVars(s16 *lo, s16 *hi, const void *ptr) +{ + *lo = ((intptr_t)ptr) & 0xffff; + *hi = (((intptr_t)ptr) >> 16) & 0xffff; +} + +void *LoadPointerFromVars(s16 lo, s16 hi) +{ + return (void *)((u16)lo | ((u16)hi << 16)); +} + +void sub_80765D4(struct Task *task, u8 spriteId, s16 a3, s16 a4, s16 a5, s16 a6, u16 a7) +{ + task->data[8] = a7; + task->data[15] = spriteId; + task->data[9] = a3; + task->data[10] = a4; + task->data[13] = a5; + task->data[14] = a6; + task->data[11] = (a5 - a3) / a7; + task->data[12] = (a6 - a4) / a7; +} + +u8 sub_8076640(struct Task *task) +{ + if (!task->data[8]) + return 0; + if (--task->data[8] != 0) + { + task->data[9] += task->data[11]; + task->data[10] += task->data[12]; + } + else + { + task->data[9] = task->data[13]; + task->data[10] = task->data[14]; + } + SetSpriteRotScale(task->data[15], task->data[9], task->data[10], 0); + if (task->data[8]) + SetBattlerSpriteYOffsetFromYScale(task->data[15]); + else + gSprites[task->data[15]].pos2.y = 0; + return task->data[8]; +} + +void AnimTask_GetFrustrationPowerLevel(u8 taskId) +{ + u16 powerLevel; + + if (gAnimFriendship <= 30) + powerLevel = 0; + else if (gAnimFriendship <= 100) + powerLevel = 1; + else if (gAnimFriendship <= 200) + powerLevel = 2; + else + powerLevel = 3; + gBattleAnimArgs[7] = powerLevel; + DestroyAnimVisualTask(taskId); +} + +// not used +static void sub_80766EC(u8 priority) +{ + if (IsBattlerSpriteVisible(gBattleAnimTarget)) + gSprites[gBattlerSpriteIds[gBattleAnimTarget]].oam.priority = priority; + if (IsBattlerSpriteVisible(gBattleAnimAttacker)) + gSprites[gBattlerSpriteIds[gBattleAnimAttacker]].oam.priority = priority; + if (IsBattlerSpriteVisible(BATTLE_PARTNER(gBattleAnimTarget))) + gSprites[gBattlerSpriteIds[BATTLE_PARTNER(gBattleAnimTarget)]].oam.priority = priority; + if (IsBattlerSpriteVisible(BATTLE_PARTNER(gBattleAnimAttacker))) + gSprites[gBattlerSpriteIds[BATTLE_PARTNER(gBattleAnimAttacker)]].oam.priority = priority; +} + +void sub_80767F0(void) +{ + s32 i; + + for (i = 0; i < gBattlersCount; ++i) + { + if (IsBattlerSpriteVisible(i)) + { + gSprites[gBattlerSpriteIds[i]].subpriority = GetBattlerSpriteSubpriority(i); + gSprites[gBattlerSpriteIds[i]].oam.priority = 2; + } + } +} + +u8 GetBattlerSpriteSubpriority(u8 battlerId) +{ + u8 subpriority; + u8 position = GetBattlerPosition(battlerId); + + if (position == B_POSITION_PLAYER_LEFT) + subpriority = 30; + else if (position == B_POSITION_PLAYER_RIGHT) + subpriority = 20; + else if (position == B_POSITION_OPPONENT_LEFT) + subpriority = 40; + else + subpriority = 50; + return subpriority; +} + +u8 GetBattlerSpriteBGPriority(u8 battlerId) +{ + u8 position = GetBattlerPosition(battlerId); + + if (position == B_POSITION_PLAYER_LEFT || position == B_POSITION_OPPONENT_RIGHT) + return GetAnimBgAttribute(2, BG_ANIM_PRIORITY); + else + return GetAnimBgAttribute(1, BG_ANIM_PRIORITY); +} + +u8 GetBattlerSpriteBGPriorityRank(u8 battlerId) +{ + u8 position = GetBattlerPosition(battlerId); + + if (position == B_POSITION_PLAYER_LEFT || position == B_POSITION_OPPONENT_RIGHT) + return 2; + else + return 1; +} + +u8 sub_80768D0(u16 species, bool8 isBackpic, u8 a3, s16 x, s16 y, u8 subpriority, u32 personality, u32 trainerId, u32 battlerId, u32 a10) +{ + u8 spriteId; + u16 sheet = LoadSpriteSheet(&gUnknown_83AE084[a3]); + u16 palette = AllocSpritePalette(gUnknown_83AE054[a3].paletteTag); + + if (gMonSpritesGfxPtr != NULL && gMonSpritesGfxPtr->field_17C == NULL) + gMonSpritesGfxPtr->field_17C = AllocZeroed(0x2000); + if (!isBackpic) + { + LoadCompressedPalette(GetMonSpritePalFromSpeciesAndPersonality(species, trainerId, personality), (palette * 0x10) + 0x100, 0x20); + if (a10 == 1 || sub_804455C(5, battlerId) == 1 || gBattleSpritesDataPtr->battlerData[battlerId].transformSpecies != 0) + LoadSpecialPokePic_DontHandleDeoxys(&gMonFrontPicTable[species], + gMonSpritesGfxPtr->field_17C, + species, + personality, + TRUE); + else + LoadSpecialPokePic(&gMonFrontPicTable[species], + gMonSpritesGfxPtr->field_17C, + species, + personality, + TRUE); + } + else + { + LoadCompressedPalette(GetMonSpritePalFromSpeciesAndPersonality(species, trainerId, personality), (palette * 0x10) + 0x100, 0x20); + if (a10 == 1 || sub_804455C(5, battlerId) == 1 || gBattleSpritesDataPtr->battlerData[battlerId].transformSpecies != 0) + LoadSpecialPokePic_DontHandleDeoxys(&gMonBackPicTable[species], + gMonSpritesGfxPtr->field_17C, + species, + personality, + FALSE); + else + LoadSpecialPokePic(&gMonBackPicTable[species], + gMonSpritesGfxPtr->field_17C, + species, + personality, + FALSE); + } + RequestDma3Copy(gMonSpritesGfxPtr->field_17C, (void *)(OBJ_VRAM0 + (sheet * 0x20)), 0x800, 1); + FREE_AND_SET_NULL(gMonSpritesGfxPtr->field_17C); + if (!isBackpic) + spriteId = CreateSprite(&gUnknown_83AE054[a3], x, y + gMonFrontPicCoords[species].y_offset, subpriority); + else + spriteId = CreateSprite(&gUnknown_83AE054[a3], x, y + gMonBackPicCoords[species].y_offset, subpriority); + return spriteId; +} + +void DestroySpriteAndFreeResources_(struct Sprite *sprite) +{ + DestroySpriteAndFreeResources(sprite); +} + +s16 GetBattlerSpriteCoordAttr(u8 battlerId, u8 attr) +{ + u16 species; + u32 personality; + u16 letter; + u16 unownSpecies; + s32 ret; + const struct MonCoords *coords; + struct BattleSpriteInfo *spriteInfo; + + if (GetBattlerSide(battlerId) == B_SIDE_PLAYER) + { + spriteInfo = gBattleSpritesDataPtr->battlerData; + if (!spriteInfo[battlerId].transformSpecies) + { + species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_SPECIES); + personality = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_PERSONALITY); + } + else + { + species = spriteInfo[battlerId].transformSpecies; + personality = gTransformedPersonalities[battlerId]; + } + if (species == SPECIES_UNOWN) + { + letter = GET_UNOWN_LETTER(personality); + if (!letter) + unownSpecies = SPECIES_UNOWN; + else + unownSpecies = letter + SPECIES_UNOWN_B - 1; + coords = &gMonBackPicCoords[unownSpecies]; + } + else if (species > NUM_SPECIES) + { + coords = &gMonBackPicCoords[0]; + } + else + { + coords = &gMonBackPicCoords[species]; + } + } + else + { + spriteInfo = gBattleSpritesDataPtr->battlerData; + if (!spriteInfo[battlerId].transformSpecies) + { + species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerId]], MON_DATA_SPECIES); + personality = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerId]], MON_DATA_PERSONALITY); + } + else + { + species = spriteInfo[battlerId].transformSpecies; + personality = gTransformedPersonalities[battlerId]; + } + + if (species == SPECIES_UNOWN) + { + letter = GET_UNOWN_LETTER(personality); + if (!letter) + unownSpecies = SPECIES_UNOWN; + else + unownSpecies = letter + SPECIES_UNOWN_B - 1; + coords = &gMonFrontPicCoords[unownSpecies]; + } + else if (species == SPECIES_CASTFORM) + { + coords = &gCastformFrontSpriteCoords[gBattleMonForms[battlerId]]; + } + else if (species > NUM_SPECIES) + { + coords = &gMonFrontPicCoords[0]; + } + else + { + coords = &gMonFrontPicCoords[species]; + } + } + switch (attr) + { + case BATTLER_COORD_ATTR_HEIGHT: + return (coords->size & 0xf) * 8; + case BATTLER_COORD_ATTR_WIDTH: + return (coords->size >> 4) * 8; + case BATTLER_COORD_ATTR_LEFT: + return GetBattlerSpriteCoord(battlerId, BATTLER_COORD_X_2) - ((coords->size >> 4) * 4); + case BATTLER_COORD_ATTR_RIGHT: + return GetBattlerSpriteCoord(battlerId, BATTLER_COORD_X_2) + ((coords->size >> 4) * 4); + case BATTLER_COORD_ATTR_TOP: + return GetBattlerSpriteCoord(battlerId, BATTLER_COORD_Y_PIC_OFFSET) - ((coords->size & 0xf) * 4); + case BATTLER_COORD_ATTR_BOTTOM: + return GetBattlerSpriteCoord(battlerId, BATTLER_COORD_Y_PIC_OFFSET) + ((coords->size & 0xf) * 4); + case BATTLER_COORD_ATTR_RAW_BOTTOM: + ret = GetBattlerSpriteCoord(battlerId, BATTLER_COORD_Y) + 31; + return ret - coords->y_offset; + default: + return 0; + } +} + +void SetAverageBattlerPositions(u8 battlerId, bool8 respectMonPicOffsets, s16 *x, s16 *y) +{ + u8 xCoordType, yCoordType; + s16 battlerX, battlerY; + s16 partnerX, partnerY; + + if (!respectMonPicOffsets) + { + xCoordType = BATTLER_COORD_X; + yCoordType = BATTLER_COORD_Y; + } + else + { + xCoordType = BATTLER_COORD_X_2; + yCoordType = BATTLER_COORD_Y_PIC_OFFSET; + } + battlerX = GetBattlerSpriteCoord(battlerId, xCoordType); + battlerY = GetBattlerSpriteCoord(battlerId, yCoordType); + if (IsDoubleBattle()) + { + partnerX = GetBattlerSpriteCoord(BATTLE_PARTNER(battlerId), xCoordType); + partnerY = GetBattlerSpriteCoord(BATTLE_PARTNER(battlerId), yCoordType); + } + else + { + partnerX = battlerX; + partnerY = battlerY; + } + *x = (battlerX + partnerX) / 2; + *y = (battlerY + partnerY) / 2; +} + +u8 sub_8076E34(s32 battlerId, u8 spriteId, s32 species) +{ + u8 newSpriteId = CreateInvisibleSpriteWithCallback(SpriteCallbackDummy); + + gSprites[newSpriteId] = gSprites[spriteId]; + gSprites[newSpriteId].usingSheet = TRUE; + gSprites[newSpriteId].oam.priority = 0; + gSprites[newSpriteId].oam.objMode = 2; + gSprites[newSpriteId].oam.tileNum = gSprites[spriteId].oam.tileNum; + gSprites[newSpriteId].callback = SpriteCallbackDummy; + return newSpriteId; +} + +void sub_8076ED8(struct Sprite *sprite) +{ + SetSpriteCoordsToAnimAttackerCoords(sprite); + if (GetBattlerSide(gBattleAnimAttacker)) + { + sprite->pos1.x -= gBattleAnimArgs[0]; + gBattleAnimArgs[3] = -gBattleAnimArgs[3]; + sprite->hFlip = TRUE; + } + else + { + sprite->pos1.x += gBattleAnimArgs[0]; + } + sprite->pos1.y += gBattleAnimArgs[1]; + sprite->data[0] = gBattleAnimArgs[2]; + sprite->data[1] = gBattleAnimArgs[3]; + sprite->data[3] = gBattleAnimArgs[4]; + sprite->data[5] = gBattleAnimArgs[5]; + StoreSpriteCallbackInData6(sprite, DestroySpriteAndMatrix); + sprite->callback = TranslateSpriteLinearAndFlicker; +} + +void sub_8076F58(struct Sprite *sprite) +{ + if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) + { + sprite->pos1.x -= gBattleAnimArgs[0]; + gBattleAnimArgs[3] *= -1; + } + else + { + sprite->pos1.x += gBattleAnimArgs[0]; + } + sprite->pos1.y += gBattleAnimArgs[1]; + sprite->data[0] = gBattleAnimArgs[2]; + sprite->data[1] = gBattleAnimArgs[3]; + sprite->data[3] = gBattleAnimArgs[4]; + sprite->data[5] = gBattleAnimArgs[5]; + StartSpriteAnim(sprite, gBattleAnimArgs[6]); + StoreSpriteCallbackInData6(sprite, DestroySpriteAndMatrix); + sprite->callback = TranslateSpriteLinearAndFlicker; +} + +void sub_8076FD0(struct Sprite *sprite) +{ + SetSpriteCoordsToAnimAttackerCoords(sprite); + if (GetBattlerSide(gBattleAnimAttacker)) + sprite->pos1.x -= gBattleAnimArgs[0]; + else + sprite->pos1.x += gBattleAnimArgs[0]; + sprite->pos1.y += gBattleAnimArgs[1]; + sprite->callback = RunStoredCallbackWhenAnimEnds; + StoreSpriteCallbackInData6(sprite, DestroyAnimSprite); +} + +void sub_8077030(u8 taskId) +{ + u16 src; + u16 dest; + struct Task *task = &gTasks[taskId]; + + task->data[0] = GetAnimBattlerSpriteId(ANIM_ATTACKER); + task->data[1] = ((GetBattlerSide(gBattleAnimAttacker)) != B_SIDE_PLAYER) ? -8 : 8; + task->data[2] = 0; + task->data[3] = 0; + gSprites[task->data[0]].pos2.x -= task->data[0]; + task->data[4] = AllocSpritePalette(10097); + task->data[5] = 0; + dest = (task->data[4] + 0x10) * 0x10; + src = (gSprites[task->data[0]].oam.paletteNum + 0x10) * 0x10; + task->data[6] = GetBattlerSpriteSubpriority(gBattleAnimAttacker); + if (task->data[6] == 20 || task->data[6] == 40) + task->data[6] = 2; + else + task->data[6] = 3; + CpuCopy32(&gPlttBufferUnfaded[src], &gPlttBufferFaded[dest], 0x20); + BlendPalette(dest, 16, gBattleAnimArgs[1], gBattleAnimArgs[0]); + task->func = sub_8077118; +} + +static void sub_8077118(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + switch (task->data[2]) + { + case 0: + sub_80771E4(task, taskId); + gSprites[task->data[0]].pos2.x += task->data[1]; + if (++task->data[3] == 5) + { + --task->data[3]; + ++task->data[2]; + } + break; + case 1: + sub_80771E4(task, taskId); + gSprites[task->data[0]].pos2.x -= task->data[1]; + if (--task->data[3] == 0) + { + gSprites[task->data[0]].pos2.x = 0; + ++task->data[2]; + } + break; + case 2: + if (!task->data[5]) + { + FreeSpritePaletteByTag(ANIM_TAG_BENT_SPOON); + DestroyAnimVisualTask(taskId); + } + break; + } +} + +static void sub_80771E4(struct Task *task, u8 taskId) +{ + s16 spriteId = CloneBattlerSpriteWithBlend(0); + + if (spriteId >= 0) + { + gSprites[spriteId].oam.priority = task->data[6]; + gSprites[spriteId].oam.paletteNum = task->data[4]; + gSprites[spriteId].data[0] = 8; + gSprites[spriteId].data[1] = taskId; + gSprites[spriteId].data[2] = spriteId; + gSprites[spriteId].pos2.x = gSprites[task->data[0]].pos2.x; + gSprites[spriteId].callback = sub_8077268; + ++task->data[5]; + } +} + +static void sub_8077268(struct Sprite *sprite) +{ + if (--sprite->data[0] == 0) + { + --gTasks[sprite->data[1]].data[5]; + obj_delete_but_dont_free_vram(sprite); + } +} + +void sub_807729C(struct Sprite *sprite) +{ + sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2); + sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET); + if (!GetBattlerSide(gBattleAnimAttacker)) + sprite->data[0] = 5; + else + sprite->data[0] = -10; + sprite->data[1] = -40; + sprite->callback = sub_80772F4; +} + +static void sub_80772F4(struct Sprite *sprite) +{ + sprite->data[2] += sprite->data[0]; + sprite->data[3] += sprite->data[1]; + sprite->pos2.x = sprite->data[2] / 10; + sprite->pos2.y = sprite->data[3] / 10; + if (sprite->data[1] < -20) + ++sprite->data[1]; + if (sprite->pos1.y + sprite->pos2.y < -32) + DestroyAnimSprite(sprite); +} + +void sub_8077350(struct Sprite *sprite) +{ + s32 x; + + sprite->data[0] = gBattleAnimArgs[2]; + sprite->data[2] = sprite->pos1.x + gBattleAnimArgs[4]; + sprite->data[4] = sprite->pos1.y + gBattleAnimArgs[5]; + if (!GetBattlerSide(gBattleAnimTarget)) + { + x = (u16)gBattleAnimArgs[4] + 30; + sprite->pos1.x += x; + sprite->pos1.y = gBattleAnimArgs[5] - 20; + } + else + { + x = (u16)gBattleAnimArgs[4] - 30; + sprite->pos1.x += x; + sprite->pos1.y = gBattleAnimArgs[5] - 80; + } + sprite->callback = StartAnimLinearTranslation; + StoreSpriteCallbackInData6(sprite, DestroyAnimSprite); +} diff --git a/src/battle_anim_sound_tasks.c b/src/battle_anim_sound_tasks.c new file mode 100644 index 000000000..d74b743e8 --- /dev/null +++ b/src/battle_anim_sound_tasks.c @@ -0,0 +1,313 @@ +#include "global.h" +#include "battle.h" +#include "battle_anim.h" +#include "sound.h" +#include "task.h" +#include "constants/battle_anim.h" +#include "constants/species.h" + +static void sub_80DCE78(u8 taskId); +static void sub_80DCEE4(u8 taskId); +static void sub_80DCFE8(u8 taskId); +static void sub_80DD270(u8 taskId); +static void sub_80DD390(u8 taskId); +static void sub_80DD4D4(u8 taskId); + +void sub_80DCE10(u8 taskId) +{ + s8 pan1, pan2, panIncrement; + + gTasks[taskId].data[0] = gBattleAnimArgs[0]; + gTasks[taskId].data[1] = gBattleAnimArgs[1]; + pan1 = BattleAnimAdjustPanning(SOUND_PAN_ATTACKER); + pan2 = BattleAnimAdjustPanning(SOUND_PAN_TARGET); + panIncrement = CalculatePanIncrement(pan1, pan2, 2); + gTasks[taskId].data[2] = pan1; + gTasks[taskId].data[3] = pan2; + gTasks[taskId].data[4] = panIncrement; + gTasks[taskId].data[10] = 10; + gTasks[taskId].func = sub_80DCE78; +} + +static void sub_80DCE78(u8 taskId) +{ + s16 pan = gTasks[taskId].data[2]; + s8 panIncrement = gTasks[taskId].data[4]; + + if (++gTasks[taskId].data[11] == 111) + { + gTasks[taskId].data[10] = 5; + gTasks[taskId].data[11] = 0; + gTasks[taskId].func = sub_80DCEE4; + } + else + { + if (++gTasks[taskId].data[10] == 11) + { + gTasks[taskId].data[10] = 0; + PlaySE12WithPanning(gTasks[taskId].data[0], pan); + } + pan += panIncrement; + gTasks[taskId].data[2] = KeepPanInRange(pan, panIncrement); + } +} + +static void sub_80DCEE4(u8 taskId) +{ + if (++gTasks[taskId].data[10] == 6) + { + s8 pan; + + gTasks[taskId].data[10] = 0; + pan = BattleAnimAdjustPanning(SOUND_PAN_TARGET); + PlaySE12WithPanning(gTasks[taskId].data[1], pan); + if (++gTasks[taskId].data[11] == 2) + DestroyAnimSoundTask(taskId); + } +} + +void mas_80DCF38(u8 taskId) +{ + u16 songId = gBattleAnimArgs[0]; + s8 targetPan = gBattleAnimArgs[2]; + s8 panIncrement = gBattleAnimArgs[3]; + u8 r10 = gBattleAnimArgs[4]; + u8 r7 = gBattleAnimArgs[5]; + u8 r9 = gBattleAnimArgs[6]; + s8 sourcePan = BattleAnimAdjustPanning(gBattleAnimArgs[1]); + + targetPan = BattleAnimAdjustPanning(targetPan); + panIncrement = CalculatePanIncrement(sourcePan, targetPan, panIncrement); + gTasks[taskId].data[0] = songId; + gTasks[taskId].data[1] = sourcePan; + gTasks[taskId].data[2] = targetPan; + gTasks[taskId].data[3] = panIncrement; + gTasks[taskId].data[4] = r10; + gTasks[taskId].data[5] = r7; + gTasks[taskId].data[6] = r9; + gTasks[taskId].data[10] = 0; + gTasks[taskId].data[11] = sourcePan; + gTasks[taskId].data[12] = r9; + gTasks[taskId].func = sub_80DCFE8; + sub_80DCFE8(taskId); +} + +static void sub_80DCFE8(u8 taskId) +{ + if (gTasks[taskId].data[12]++ == gTasks[taskId].data[6]) + { + gTasks[taskId].data[12] = 0; + PlaySE12WithPanning(gTasks[taskId].data[0], gTasks[taskId].data[11]); + if (--gTasks[taskId].data[4] == 0) + { + DestroyAnimSoundTask(taskId); + return; + } + } + if (gTasks[taskId].data[10]++ == gTasks[taskId].data[5]) + { + u16 dPan, oldPan; + + gTasks[taskId].data[10] = 0; + dPan = gTasks[taskId].data[3]; + oldPan = gTasks[taskId].data[11]; + gTasks[taskId].data[11] = dPan + oldPan; + gTasks[taskId].data[11] = KeepPanInRange(gTasks[taskId].data[11], oldPan); + } +} + +void sub_80DD06C(u8 taskId) +{ + u16 species = SPECIES_NONE; + u8 battlerId; + s8 pan = BattleAnimAdjustPanning(SOUND_PAN_ATTACKER); + + // Get wanted battler. + if (gBattleAnimArgs[0] == ANIM_ATTACKER) + battlerId = gBattleAnimAttacker; + else if (gBattleAnimArgs[0] == ANIM_TARGET) + battlerId = gBattleAnimTarget; + else if (gBattleAnimArgs[0] == ANIM_ATK_PARTNER) + battlerId = BATTLE_PARTNER(gBattleAnimAttacker); + else + battlerId = BATTLE_PARTNER(gBattleAnimTarget); + // Check if battler is visible. + if ((gBattleAnimArgs[0] == ANIM_TARGET || gBattleAnimArgs[0] == ANIM_DEF_PARTNER) + && !IsBattlerSpriteVisible(battlerId)) + { + DestroyAnimVisualTask(taskId); + return; + } + if (GetBattlerSide(battlerId) != B_SIDE_PLAYER) + species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerId]], MON_DATA_SPECIES); + else + species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_SPECIES); + if (species != SPECIES_NONE) + PlayCry3(species, pan, 3); + DestroyAnimVisualTask(taskId); +} + +void sub_80DD148(u8 taskId) +{ + u16 species = SPECIES_NONE; + u8 battlerId; + s8 pan = BattleAnimAdjustPanning(SOUND_PAN_ATTACKER); + + // Get wanted battler. + if (gBattleAnimArgs[0] == ANIM_ATTACKER) + battlerId = gBattleAnimAttacker; + else if (gBattleAnimArgs[0] == ANIM_TARGET) + battlerId = gBattleAnimTarget; + else if (gBattleAnimArgs[0] == ANIM_ATK_PARTNER) + battlerId = BATTLE_PARTNER(gBattleAnimAttacker); + else + battlerId = BATTLE_PARTNER(gBattleAnimTarget); + // Check if battler is visible. + if ((gBattleAnimArgs[0] == ANIM_TARGET || gBattleAnimArgs[0] == ANIM_DEF_PARTNER) + && !IsBattlerSpriteVisible(battlerId)) + { + DestroyAnimVisualTask(taskId); + return; + } + if (GetBattlerSide(battlerId) != B_SIDE_PLAYER) + species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerId]], MON_DATA_SPECIES); + else + species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_SPECIES); + gTasks[taskId].data[0] = gBattleAnimArgs[1]; + gTasks[taskId].data[1] = species; + gTasks[taskId].data[2] = pan; + if (species != SPECIES_NONE) + { + if (gBattleAnimArgs[1] == TASK_NONE) + PlayCry3(species, pan, 9); + else + PlayCry3(species, pan, 7); + gTasks[taskId].func = sub_80DD270; + } + else + { + DestroyAnimVisualTask(taskId); + } +} + +static void sub_80DD270(u8 taskId) +{ + u16 species = gTasks[taskId].data[1]; + s8 pan = gTasks[taskId].data[2]; + + if (gTasks[taskId].data[9] < 2) + { + ++gTasks[taskId].data[9]; + } + else if (gTasks[taskId].data[0] == TASK_NONE) + { + if (!IsCryPlaying()) + { + PlayCry3(species, pan, 10); + DestroyAnimVisualTask(taskId); + } + } + else if (!IsCryPlaying()) + { + PlayCry3(species, pan, 8); + DestroyAnimVisualTask(taskId); + } +} + +void sub_80DD2F4(u8 taskId) +{ + if (gTasks[taskId].data[9] < 2) + ++gTasks[taskId].data[9]; + else if (!IsCryPlaying()) + DestroyAnimVisualTask(taskId); +} + +void sub_80DD334(u8 taskId) +{ + u16 species; + s8 pan; + + pan = BattleAnimAdjustPanning(SOUND_PAN_ATTACKER); + species = gAnimBattlerSpecies[gBattleAnimAttacker]; + gTasks[taskId].data[1] = species; + gTasks[taskId].data[2] = pan; + if (species != SPECIES_NONE) + { + PlayCry3(species, pan, 4); + gTasks[taskId].func = sub_80DD390; + } + else + { + DestroyAnimVisualTask(taskId); + } +} + +static void sub_80DD390(u8 taskId) +{ + + if (gTasks[taskId].data[9] < 2) + { + ++gTasks[taskId].data[9]; + } + else if (!IsCryPlaying()) + { + u16 species = gTasks[taskId].data[1]; + s8 pan = gTasks[taskId].data[2]; + + PlayCry3(species, pan, 6); + DestroyAnimVisualTask(taskId); + } +} + +void sub_80DD3DC(u8 taskId) +{ + u16 songId = gBattleAnimArgs[0]; + s8 pan = BattleAnimAdjustPanning(gBattleAnimArgs[1]); + + PlaySE1WithPanning(songId, pan); + DestroyAnimVisualTask(taskId); +} + +void sub_80DD410(u8 taskId) +{ + u16 songId = gBattleAnimArgs[0]; + s8 pan = BattleAnimAdjustPanning(gBattleAnimArgs[1]); + + PlaySE2WithPanning(songId, pan); + DestroyAnimVisualTask(taskId); +} + +void sub_80DD444(u8 taskId) +{ + s8 targetPan = gBattleAnimArgs[1]; + s8 panIncrement = gBattleAnimArgs[2]; + u16 r9 = gBattleAnimArgs[3]; + s8 sourcePan = BattleAnimAdjustPanning(gBattleAnimArgs[0]); + + targetPan = BattleAnimAdjustPanning(targetPan); + panIncrement = CalculatePanIncrement(sourcePan, targetPan, panIncrement); + gTasks[taskId].data[1] = sourcePan; + gTasks[taskId].data[2] = targetPan; + gTasks[taskId].data[3] = panIncrement; + gTasks[taskId].data[5] = r9; + gTasks[taskId].data[10] = 0; + gTasks[taskId].data[11] = sourcePan; + gTasks[taskId].func = sub_80DD4D4; + sub_80DD4D4(taskId); +} + +static void sub_80DD4D4(u8 taskId) +{ + u16 oldPan, panIncrement = gTasks[taskId].data[3]; + + if (gTasks[taskId].data[10]++ == gTasks[taskId].data[5]) + { + gTasks[taskId].data[10] = 0; + oldPan = gTasks[taskId].data[11]; + gTasks[taskId].data[11] = panIncrement + oldPan; + gTasks[taskId].data[11] = KeepPanInRange(gTasks[taskId].data[11], oldPan); + } + gUnknown_2037F24 = gTasks[taskId].data[11]; + if (gTasks[taskId].data[11] == gTasks[taskId].data[2]) + DestroyAnimVisualTask(taskId); +} diff --git a/src/battle_anim_utility_funcs.c b/src/battle_anim_utility_funcs.c new file mode 100644 index 000000000..14c5ef6c8 --- /dev/null +++ b/src/battle_anim_utility_funcs.c @@ -0,0 +1,946 @@ +#include "global.h" +#include "battle.h" +#include "battle_anim.h" +#include "gpu_regs.h" +#include "graphics.h" +#include "malloc.h" +#include "palette.h" +#include "sound.h" +#include "sprite.h" +#include "task.h" +#include "util.h" +#include "constants/songs.h" + +struct AnimStatsChangeData +{ + u8 battler1; + u8 battler2; + u8 higherPriority; + s16 data[8]; + u16 species; +}; + +static void StartBlendAnimSpriteColor(u8 taskId, u32 selectedPalettes); +static void AnimTask_BlendSpriteColor_Step2(u8 taskId); +static void sub_80BAB78(u8 taskId); +static void sub_80BABD0(u8 taskId); +static void sub_80BACA8(struct Sprite *sprite); +static void sub_80BAF38(u8 taskId); +static void sub_80BB0D8(u8 taskId); +static void sub_80BB2A0(u8 taskId); +static void sub_80BB4B8(u8 taskId); +static void sub_80BB6CC(u8 taskId); +static void sub_80BB790(u32 selectedPalettes, u16 color); +static void sub_80BB8A4(u8 taskId); +static void sub_80BBC2C(u8 taskId); +static void sub_80BC19C(u8 taskId); + +static EWRAM_DATA struct AnimStatsChangeData *sAnimStatsChangeData = NULL; + +static const u16 gUnknown_83E7CC8[] = { RGB(31, 31, 31) }; +const u8 gUnknown_83E7CCA[] = { REG_OFFSET_BG0CNT, REG_OFFSET_BG1CNT, REG_OFFSET_BG2CNT, REG_OFFSET_BG3CNT }; +const u8 gUnknown_83E7CCE[] = { REG_OFFSET_BG0CNT, REG_OFFSET_BG1CNT, REG_OFFSET_BG2CNT, REG_OFFSET_BG3CNT }; + +void sub_80BA7F8(u8 taskId) +{ + u32 selectedPalettes = UnpackSelectedBattleAnimPalettes(gBattleAnimArgs[0]); + + selectedPalettes |= sub_8075CB8((gBattleAnimArgs[0] >> 7) & 1, + (gBattleAnimArgs[0] >> 8) & 1, + (gBattleAnimArgs[0] >> 9) & 1, + (gBattleAnimArgs[0] >> 10) & 1); + StartBlendAnimSpriteColor(taskId, selectedPalettes); +} + +void sub_80BA83C(u8 taskId) +{ + u8 battler; + u32 selectedPalettes; + u8 animBattlers[2]; + + animBattlers[1] = 0xFF; + selectedPalettes = UnpackSelectedBattleAnimPalettes(1); + switch (gBattleAnimArgs[0]) + { + case 2: + selectedPalettes = 0; + // fall through + case 0: + animBattlers[0] = gBattleAnimAttacker; + break; + case 3: + selectedPalettes = 0; + // fall through + case 1: + animBattlers[0] = gBattleAnimTarget; + break; + case 4: + animBattlers[0] = gBattleAnimAttacker; + animBattlers[1] = gBattleAnimTarget; + break; + case 5: + animBattlers[0] = 0xFF; + break; + case 6: + selectedPalettes = 0; + animBattlers[0] = BATTLE_PARTNER(gBattleAnimAttacker); + break; + case 7: + selectedPalettes = 0; + animBattlers[0] = BATTLE_PARTNER(gBattleAnimTarget); + break; + } + for (battler = 0; battler < MAX_BATTLERS_COUNT; ++battler) + { + if (battler != animBattlers[0] + && battler != animBattlers[1] + && IsBattlerSpriteVisible(battler)) + selectedPalettes |= 0x10000 << sub_8075D80(battler); + } + StartBlendAnimSpriteColor(taskId, selectedPalettes); +} + +void AnimTask_SetCamouflageBlend(u8 taskId) +{ + u32 selectedPalettes = UnpackSelectedBattleAnimPalettes(gBattleAnimArgs[0]); + + switch (gBattleTerrain) + { + case BATTLE_TERRAIN_GRASS: + gBattleAnimArgs[4] = RGB(12, 24, 2); + break; + case BATTLE_TERRAIN_LONG_GRASS: + gBattleAnimArgs[4] = RGB(0, 15, 2); + break; + case BATTLE_TERRAIN_SAND: + gBattleAnimArgs[4] = RGB(30, 24, 11); + break; + case BATTLE_TERRAIN_UNDERWATER: + gBattleAnimArgs[4] = RGB(0, 0, 18); + break; + case BATTLE_TERRAIN_WATER: + gBattleAnimArgs[4] = RGB(11, 22, 31); + break; + case BATTLE_TERRAIN_POND: + gBattleAnimArgs[4] = RGB(11, 22, 31); + break; + case BATTLE_TERRAIN_MOUNTAIN: + gBattleAnimArgs[4] = RGB(22, 16, 10); + break; + case BATTLE_TERRAIN_CAVE: + gBattleAnimArgs[4] = RGB(14, 9, 3); + break; + case BATTLE_TERRAIN_BUILDING: + gBattleAnimArgs[4] = RGB(31, 31, 31); + break; + case BATTLE_TERRAIN_PLAIN: + gBattleAnimArgs[4] = RGB(31, 31, 31); + break; + } + StartBlendAnimSpriteColor(taskId, selectedPalettes); +} + +void AnimTask_BlendParticle(u8 taskId) +{ + u8 paletteIndex = IndexOfSpritePaletteTag(gBattleAnimArgs[0]); + u32 selectedPalettes = 1 << (paletteIndex + 16); + + StartBlendAnimSpriteColor(taskId, selectedPalettes); +} + +static void StartBlendAnimSpriteColor(u8 taskId, u32 selectedPalettes) +{ + gTasks[taskId].data[0] = selectedPalettes; + gTasks[taskId].data[1] = selectedPalettes >> 16; + gTasks[taskId].data[2] = gBattleAnimArgs[1]; + gTasks[taskId].data[3] = gBattleAnimArgs[2]; + gTasks[taskId].data[4] = gBattleAnimArgs[3]; + gTasks[taskId].data[5] = gBattleAnimArgs[4]; + gTasks[taskId].data[10] = gBattleAnimArgs[2]; + gTasks[taskId].func = AnimTask_BlendSpriteColor_Step2; + gTasks[taskId].func(taskId); +} + +static void AnimTask_BlendSpriteColor_Step2(u8 taskId) +{ + u32 selectedPalettes; + u16 singlePaletteMask = 0; + + if (gTasks[taskId].data[9] == gTasks[taskId].data[2]) + { + gTasks[taskId].data[9] = 0; + selectedPalettes = gTasks[taskId].data[0] | (gTasks[taskId].data[1] << 16); + while (selectedPalettes) + { + if (selectedPalettes & 1) + BlendPalette(singlePaletteMask, 16, gTasks[taskId].data[10], gTasks[taskId].data[5]); + singlePaletteMask += 0x10; + selectedPalettes >>= 1; + } + if (gTasks[taskId].data[10] < gTasks[taskId].data[4]) + ++gTasks[taskId].data[10]; + else if (gTasks[taskId].data[10] > gTasks[taskId].data[4]) + --gTasks[taskId].data[10]; + else + DestroyAnimVisualTask(taskId); + } + else + { + ++gTasks[taskId].data[9]; + } +} + +void sub_80BAB38(u8 taskId) +{ + BeginHardwarePaletteFade(gBattleAnimArgs[0], + gBattleAnimArgs[1], + gBattleAnimArgs[2], + gBattleAnimArgs[3], + gBattleAnimArgs[4]); + gTasks[taskId].func = sub_80BAB78; +} + +static void sub_80BAB78(u8 taskId) +{ + if (!gPaletteFade.active) + DestroyAnimVisualTask(taskId); +} + +void sub_80BAB98(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + + task->data[0] = gBattleAnimArgs[0]; + task->data[1] = 0; + task->data[2] = gBattleAnimArgs[1]; + task->data[3] = gBattleAnimArgs[2]; + task->data[4] = gBattleAnimArgs[3]; + task->data[5] = 0; + task->func = sub_80BABD0; +} +static void sub_80BABD0(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + + if (task->data[4]) + { + if (task->data[1]) + { + --task->data[1]; + } + else + { + task->data[6] = CloneBattlerSpriteWithBlend(task->data[0]); + if (task->data[6] >= 0) + { + gSprites[task->data[6]].oam.priority = task->data[0] ? 1 : 2; + gSprites[task->data[6]].data[0] = task->data[3]; + gSprites[task->data[6]].data[1] = taskId; + gSprites[task->data[6]].data[2] = 5; + gSprites[task->data[6]].callback = sub_80BACA8; + ++task->data[5]; + } + --task->data[4]; + task->data[1] = task->data[2]; + } + } + else if (task->data[5] == 0) + { + DestroyAnimVisualTask(taskId); + } +} + +static void sub_80BACA8(struct Sprite *sprite) +{ + if (sprite->data[0]) + { + --sprite->data[0]; + } + else + { + --gTasks[sprite->data[1]].data[sprite->data[2]]; + obj_delete_but_dont_free_vram(sprite); + } +} + +void sub_80BACEC(u8 taskId) +{ + u16 species; + s32 newSpriteId; + u16 var0; + u16 bg1Cnt; + u8 spriteId; + struct BattleAnimBgData animBgData; + + var0 = 0; + gBattle_WIN0H = 0; + gBattle_WIN0V = 0; + SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR + | WININ_WIN1_BG_ALL | WININ_WIN1_OBJ | WININ_WIN1_CLR); + SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WIN01_BG0 | WINOUT_WIN01_BG2 | WINOUT_WIN01_BG3 | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR + | WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ | WINOUT_WINOBJ_CLR); + SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_OBJWIN_ON); + SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG1 | BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND); + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(8, 12)); + bg1Cnt = GetGpuReg(REG_OFFSET_BG1CNT); + ((struct BgCnt *)&bg1Cnt)->priority = 0; + ((struct BgCnt *)&bg1Cnt)->screenSize = 0; + SetGpuReg(REG_OFFSET_BG1CNT, bg1Cnt); + if (!IsContest()) + { + ((struct BgCnt *)&bg1Cnt)->charBaseBlock = 1; + SetGpuReg(REG_OFFSET_BG1CNT, bg1Cnt); + } + if (IsDoubleBattle() && !IsContest()) + { + if (GetBattlerPosition(gBattleAnimAttacker) == B_POSITION_OPPONENT_RIGHT + || GetBattlerPosition(gBattleAnimAttacker) == B_POSITION_PLAYER_LEFT) + { + if (IsBattlerSpriteVisible(BATTLE_PARTNER(gBattleAnimAttacker)) == TRUE) + { + gSprites[gBattlerSpriteIds[BATTLE_PARTNER(gBattleAnimAttacker)]].oam.priority -= 1; + ((struct BgCnt *)&bg1Cnt)->priority = 1; + SetGpuReg(REG_OFFSET_BG1CNT, bg1Cnt); + var0 = 1; + } + } + } + if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) + species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattleAnimAttacker]], MON_DATA_SPECIES); + else + species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattleAnimAttacker]], MON_DATA_SPECIES); + spriteId = GetAnimBattlerSpriteId(0); + newSpriteId = sub_8076E34(gBattleAnimAttacker, spriteId, species); + sub_80752A0(&animBgData); + AnimLoadCompressedBgTilemap(animBgData.bgId, gFile_graphics_battle_anims_masks_curse_tilemap); + if (IsContest()) + sub_80730C0(animBgData.paletteId, animBgData.bgTilemap, 0, 0); + AnimLoadCompressedBgGfx(animBgData.bgId, gFile_graphics_battle_anims_masks_curse_sheet, animBgData.tilesOffset); + LoadPalette(gUnknown_83E7CC8, animBgData.paletteId * 16 + 1, 2); + gBattle_BG1_X = -gSprites[spriteId].pos1.x + 32; + gBattle_BG1_Y = -gSprites[spriteId].pos1.y + 32; + gTasks[taskId].data[0] = newSpriteId; + gTasks[taskId].data[6] = var0; + gTasks[taskId].func = sub_80BAF38; +} + +static void sub_80BAF38(u8 taskId) +{ + struct BattleAnimBgData animBgData; + struct Sprite *sprite; + u16 bg1Cnt; + + gTasks[taskId].data[10] += 4; + gBattle_BG1_Y -= 4; + if (gTasks[taskId].data[10] == 64) + { + gTasks[taskId].data[10] = 0; + gBattle_BG1_Y += 64; + if (++gTasks[taskId].data[11] == 4) + { + sub_8073128(0); + gBattle_WIN0H = 0; + gBattle_WIN0V = 0; + SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR + | WININ_WIN1_BG_ALL | WININ_WIN1_OBJ | WININ_WIN1_CLR); + SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WIN01_BG_ALL | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR + | WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ | WINOUT_WINOBJ_CLR); + if (!IsContest()) + { + bg1Cnt = GetGpuReg(REG_OFFSET_BG1CNT); + ((struct BgCnt *)&bg1Cnt)->charBaseBlock = 0; + SetGpuReg(REG_OFFSET_BG1CNT, bg1Cnt); + } + SetGpuReg(REG_OFFSET_DISPCNT, GetGpuReg(REG_OFFSET_DISPCNT) ^ DISPCNT_OBJWIN_ON); + SetGpuReg(REG_OFFSET_BLDCNT, 0); + SetGpuReg(REG_OFFSET_BLDALPHA, 0); + sprite = &gSprites[GetAnimBattlerSpriteId(0)]; // unused + sprite = &gSprites[gTasks[taskId].data[0]]; + DestroySprite(sprite); + sub_80752A0(&animBgData); + sub_8075358(animBgData.bgId); + if (gTasks[taskId].data[6] == 1) + ++gSprites[gBattlerSpriteIds[BATTLE_PARTNER(gBattleAnimAttacker)]].oam.priority; + gBattle_BG1_Y = 0; + DestroyAnimVisualTask(taskId); + } + } +} + +void sub_80BB088(u8 taskId) +{ + u8 i; + + sAnimStatsChangeData = AllocZeroed(sizeof(struct AnimStatsChangeData)); + for (i = 0; i < 8; ++i) + sAnimStatsChangeData->data[i] = gBattleAnimArgs[i]; + gTasks[taskId].func = sub_80BB0D8; +} + +static void sub_80BB0D8(u8 taskId) +{ + if (sAnimStatsChangeData->data[2] == 0) + sAnimStatsChangeData->battler1 = gBattleAnimAttacker; + else + sAnimStatsChangeData->battler1 = gBattleAnimTarget; + sAnimStatsChangeData->battler2 = BATTLE_PARTNER(sAnimStatsChangeData->battler1); + if (IsContest() || (sAnimStatsChangeData->data[3] && !IsBattlerSpriteVisible(sAnimStatsChangeData->battler2))) + sAnimStatsChangeData->data[3] = 0; + gBattle_WIN0H = 0; + gBattle_WIN0V = 0; + SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR + | WININ_WIN1_BG_ALL | WININ_WIN1_OBJ | WININ_WIN1_CLR); + SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WIN01_BG0 | WINOUT_WIN01_BG2 | WINOUT_WIN01_BG3 | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR + | WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ | WINOUT_WINOBJ_CLR); + SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_OBJWIN_ON); + SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG1 | BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND); + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0, 16)); + SetAnimBgAttribute(1, BG_ANIM_PRIORITY, 0); + SetAnimBgAttribute(1, BG_ANIM_SCREEN_SIZE, 0); + if (!IsContest()) + SetAnimBgAttribute(1, BG_ANIM_CHAR_BASE_BLOCK, 1); + if (IsDoubleBattle() && sAnimStatsChangeData->data[3] == 0) + { + if (GetBattlerPosition(sAnimStatsChangeData->battler1) == B_POSITION_OPPONENT_RIGHT + || GetBattlerPosition(sAnimStatsChangeData->battler1) == B_POSITION_PLAYER_LEFT) + { + if (IsBattlerSpriteVisible(sAnimStatsChangeData->battler2) == TRUE) + { + gSprites[gBattlerSpriteIds[sAnimStatsChangeData->battler2]].oam.priority -= 1; + SetAnimBgAttribute(1, BG_ANIM_PRIORITY, 1); + sAnimStatsChangeData->higherPriority = 1; + } + } + } + if (GetBattlerSide(sAnimStatsChangeData->battler1) != B_SIDE_PLAYER) + sAnimStatsChangeData->species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[sAnimStatsChangeData->battler1]], MON_DATA_SPECIES); + else + sAnimStatsChangeData->species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[sAnimStatsChangeData->battler1]], MON_DATA_SPECIES); + gTasks[taskId].func = sub_80BB2A0; +} + +static void sub_80BB2A0(u8 taskId) +{ + struct BattleAnimBgData animBgData; + u8 spriteId, newSpriteId = 0; + u8 battlerSpriteId; + + battlerSpriteId = gBattlerSpriteIds[sAnimStatsChangeData->battler1]; + spriteId = sub_8076E34(sAnimStatsChangeData->battler1, battlerSpriteId, sAnimStatsChangeData->species); + if (sAnimStatsChangeData->data[3]) + { + battlerSpriteId = gBattlerSpriteIds[sAnimStatsChangeData->battler2]; + newSpriteId = sub_8076E34(sAnimStatsChangeData->battler2, battlerSpriteId, sAnimStatsChangeData->species); + } + sub_80752A0(&animBgData); + if (sAnimStatsChangeData->data[0] == 0) + AnimLoadCompressedBgTilemap(animBgData.bgId, gBattleStatMask1_Tilemap); + else + AnimLoadCompressedBgTilemap(animBgData.bgId, gBattleStatMask2_Tilemap); + if (IsContest()) + sub_80730C0(animBgData.paletteId, animBgData.bgTilemap, 0, 0); + AnimLoadCompressedBgGfx(animBgData.bgId, gBattleStatMask_Gfx, animBgData.tilesOffset); + switch (sAnimStatsChangeData->data[1]) + { + case 0: + LoadCompressedPalette(gBattleStatMask2_Pal, animBgData.paletteId * 16, 32); + break; + case 1: + LoadCompressedPalette(gBattleStatMask1_Pal, animBgData.paletteId * 16, 32); + break; + case 2: + LoadCompressedPalette(gBattleStatMask3_Pal, animBgData.paletteId * 16, 32); + break; + case 3: + LoadCompressedPalette(gBattleStatMask4_Pal, animBgData.paletteId * 16, 32); + break; + case 4: + LoadCompressedPalette(gBattleStatMask6_Pal, animBgData.paletteId * 16, 32); + break; + case 5: + LoadCompressedPalette(gBattleStatMask7_Pal, animBgData.paletteId * 16, 32); + break; + case 6: + LoadCompressedPalette(gBattleStatMask8_Pal, animBgData.paletteId * 16, 32); + break; + default: + LoadCompressedPalette(gBattleStatMask5_Pal, animBgData.paletteId * 16, 32); + break; + } + gBattle_BG1_X = 0; + gBattle_BG1_Y = 0; + if (sAnimStatsChangeData->data[0] == 1) + { + gBattle_BG1_X = 64; + gTasks[taskId].data[1] = -3; + } + else + { + gTasks[taskId].data[1] = 3; + } + + if (sAnimStatsChangeData->data[4] == 0) + { + gTasks[taskId].data[4] = 10; + gTasks[taskId].data[5] = 20; + } + else + { + gTasks[taskId].data[4] = 13; + gTasks[taskId].data[5] = 30; + } + gTasks[taskId].data[0] = spriteId; + gTasks[taskId].data[2] = sAnimStatsChangeData->data[3]; + gTasks[taskId].data[3] = newSpriteId; + gTasks[taskId].data[6] = sAnimStatsChangeData->higherPriority; + gTasks[taskId].data[7] = gBattlerSpriteIds[sAnimStatsChangeData->battler2]; + gTasks[taskId].func = sub_80BB4B8; + if (sAnimStatsChangeData->data[0] == 0) + PlaySE12WithPanning(SE_W287, BattleAnimAdjustPanning2(PAN_SIDE_PLAYER)); + else + PlaySE12WithPanning(SE_W287B, BattleAnimAdjustPanning2(PAN_SIDE_PLAYER)); +} + +static void sub_80BB4B8(u8 taskId) +{ + gBattle_BG1_Y += gTasks[taskId].data[1]; + switch (gTasks[taskId].data[15]) + { + case 0: + if (gTasks[taskId].data[11]++ > 0) + { + gTasks[taskId].data[11] = 0; + ++gTasks[taskId].data[12]; + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gTasks[taskId].data[12], 16 - gTasks[taskId].data[12])); + if (gTasks[taskId].data[12] == gTasks[taskId].data[4]) + ++gTasks[taskId].data[15]; + } + break; + case 1: + if (++gTasks[taskId].data[10] == gTasks[taskId].data[5]) + ++gTasks[taskId].data[15]; + break; + case 2: + if (gTasks[taskId].data[11]++ > 0) + { + gTasks[taskId].data[11] = 0; + --gTasks[taskId].data[12]; + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gTasks[taskId].data[12], 16 - gTasks[taskId].data[12])); + if (gTasks[taskId].data[12] == 0) + { + sub_8073128(0); + ++gTasks[taskId].data[15]; + } + } + break; + case 3: + gBattle_WIN0H = 0; + gBattle_WIN0V = 0; + SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR + | WININ_WIN1_BG_ALL | WININ_WIN1_OBJ | WININ_WIN1_CLR); + SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WIN01_BG_ALL | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR + | WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ | WINOUT_WINOBJ_CLR); + if (!IsContest()) + SetAnimBgAttribute(1, BG_ANIM_CHAR_BASE_BLOCK, 0); + SetGpuReg(REG_OFFSET_DISPCNT, GetGpuReg(REG_OFFSET_DISPCNT) ^ DISPCNT_OBJWIN_ON); + SetGpuReg(REG_OFFSET_BLDCNT, 0); + SetGpuReg(REG_OFFSET_BLDALPHA, 0); + DestroySprite(&gSprites[gTasks[taskId].data[0]]); + if (gTasks[taskId].data[2]) + DestroySprite(&gSprites[gTasks[taskId].data[3]]); + if (gTasks[taskId].data[6] == 1) + ++gSprites[gTasks[taskId].data[7]].oam.priority; + Free(sAnimStatsChangeData); + sAnimStatsChangeData = NULL; + DestroyAnimVisualTask(taskId); + break; + } +} + +void sub_80BB660(u8 taskId) +{ + u32 selectedPalettes = sub_8075CB8(1, 1, 1, 1); + + sub_80BB790(selectedPalettes, 0); + gTasks[taskId].data[14] = selectedPalettes >> 16; + selectedPalettes = sub_8075BE8(1, 0, 0, 0, 0, 0, 0) & 0xFFFF; + sub_80BB790(selectedPalettes, 0xFFFF); + gTasks[taskId].data[15] = selectedPalettes; + gTasks[taskId].data[0] = 0; + gTasks[taskId].data[1] = 0; + gTasks[taskId].func = sub_80BB6CC; +} + +static void sub_80BB6CC(u8 taskId) +{ + u16 i; + struct Task *task = &gTasks[taskId]; + + switch (task->data[0]) + { + case 0: + if (++task->data[1] > 6) + { + task->data[1] = 0; + task->data[2] = 16; + ++task->data[0]; + } + break; + case 1: + if (++task->data[1] > 1) + { + task->data[1] = 0; + --task->data[2]; + for (i = 0; i < 16; ++i) + { + if ((task->data[15] >> i) & 1) + { + u16 paletteOffset = i * 16; + BlendPalette(paletteOffset, 16, task->data[2], 0xFFFF); + } + + if ((task->data[14] >> i) & 1) + { + u16 paletteOffset = i * 16 + 0x100; + BlendPalette(paletteOffset, 16, task->data[2], 0); + } + } + + if (task->data[2] == 0) + ++task->data[0]; + } + break; + case 2: + DestroyAnimVisualTask(taskId); + break; + } +} + +static void sub_80BB790(u32 selectedPalettes, u16 color) +{ + u16 i, curOffset, paletteOffset; + + for (i = 0; i < 32; selectedPalettes >>= 1, ++i) + if (selectedPalettes & 1) + for (curOffset = i * 16, paletteOffset = curOffset; curOffset < paletteOffset + 16; ++curOffset) + gPlttBufferFaded[curOffset] = color; +} + +void sub_80BB7DC(u8 taskId) +{ + s32 j; + u32 battler, selectedPalettes = 0; + + for (battler = 0; battler < MAX_BATTLERS_COUNT; ++battler) + if (gBattleAnimAttacker != battler) + selectedPalettes |= 1 << (battler + 16); + for (j = 5; j != 0; --j) + gBattleAnimArgs[j] = gBattleAnimArgs[j - 1]; + StartBlendAnimSpriteColor(taskId, selectedPalettes); +} + +void sub_80BB82C(u8 taskId) +{ + u8 newTaskId; + + sub_8075458(0); + newTaskId = CreateTask(sub_80BB8A4, 5); + if (gBattleAnimArgs[2] && GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) + { + gBattleAnimArgs[0] = -gBattleAnimArgs[0]; + gBattleAnimArgs[1] = -gBattleAnimArgs[1]; + } + gTasks[newTaskId].data[1] = gBattleAnimArgs[0]; + gTasks[newTaskId].data[2] = gBattleAnimArgs[1]; + gTasks[newTaskId].data[3] = gBattleAnimArgs[3]; + ++gTasks[newTaskId].data[0]; + DestroyAnimVisualTask(taskId); +} + +static void sub_80BB8A4(u8 taskId) +{ + gTasks[taskId].data[10] += gTasks[taskId].data[1]; + gTasks[taskId].data[11] += gTasks[taskId].data[2]; + gBattle_BG3_X += gTasks[taskId].data[10] >> 8; + gBattle_BG3_Y += gTasks[taskId].data[11] >> 8; + gTasks[taskId].data[10] &= 0xFF; + gTasks[taskId].data[11] &= 0xFF; + if (gBattleAnimArgs[7] == gTasks[taskId].data[3]) + { + gBattle_BG3_X = 0; + gBattle_BG3_Y = 0; + sub_8075458(1); + DestroyTask(taskId); + } +} + +void AnimTask_GetAttackerSide(u8 taskId) +{ + gBattleAnimArgs[7] = GetBattlerSide(gBattleAnimAttacker); + DestroyAnimVisualTask(taskId); +} + +void AnimTask_GetTargetSide(u8 taskId) +{ + gBattleAnimArgs[7] = GetBattlerSide(gBattleAnimTarget); + DestroyAnimVisualTask(taskId); +} + +void AnimTask_GetTargetIsAttackerPartner(u8 taskId) +{ + gBattleAnimArgs[7] = BATTLE_PARTNER(gBattleAnimAttacker) == gBattleAnimTarget; + DestroyAnimVisualTask(taskId); +} + +void sub_80BB9B0(u8 taskId) +{ + u16 battler; + + for (battler = 0; battler < MAX_BATTLERS_COUNT; ++battler) + if (battler != gBattleAnimAttacker && IsBattlerSpriteVisible(battler)) + gSprites[gBattlerSpriteIds[battler]].invisible = gBattleAnimArgs[0]; + DestroyAnimVisualTask(taskId); +} + +void sub_80BBA20(u8 taskId, s32 unused, u16 arg2, u8 battler1, u8 arg4, u8 arg5, u8 arg6, u8 arg7, const u32 *gfx, const u32 *tilemap, const u32 *palette) +{ + u16 species; + u8 spriteId, newSpriteId = 0; + u16 bg1Cnt; + struct BattleAnimBgData animBgData; + u8 battler2 = BATTLE_PARTNER(battler1); + + if (IsContest() || (arg4 && !IsBattlerSpriteVisible(battler2))) + arg4 = 0; + gBattle_WIN0H = 0; + gBattle_WIN0V = 0; + SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR + | WININ_WIN1_BG_ALL | WININ_WIN1_OBJ | WININ_WIN1_CLR); + SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WIN01_BG0 | WINOUT_WIN01_BG2 | WINOUT_WIN01_BG3 | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR + | WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ | WINOUT_WINOBJ_CLR); + SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_OBJWIN_ON); + SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG1 | BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND); + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0, 16)); + bg1Cnt = GetGpuReg(REG_OFFSET_BG1CNT); + ((vBgCnt *)&bg1Cnt)->priority = 0; + ((vBgCnt *)&bg1Cnt)->screenSize = 0; + ((vBgCnt *)&bg1Cnt)->areaOverflowMode = 1; + if (!IsContest()) + ((vBgCnt *)&bg1Cnt)->charBaseBlock = 1; + SetGpuReg(REG_OFFSET_BG1CNT, bg1Cnt); + if (GetBattlerSide(battler1) != B_SIDE_PLAYER) + species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battler1]], MON_DATA_SPECIES); + else + species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battler1]], MON_DATA_SPECIES); + spriteId = sub_8076E34(battler1, gBattlerSpriteIds[battler1], species); + if (arg4) + newSpriteId = sub_8076E34(battler2, gBattlerSpriteIds[battler2], species); + sub_80752A0(&animBgData); + AnimLoadCompressedBgTilemap(animBgData.bgId, tilemap); + if (IsContest()) + sub_80730C0(animBgData.paletteId, animBgData.bgTilemap, 0, 0); + AnimLoadCompressedBgGfx(animBgData.bgId, gfx, animBgData.tilesOffset); + LoadCompressedPalette(palette, animBgData.paletteId * 16, 32); + gBattle_BG1_X = 0; + gBattle_BG1_Y = 0; + gTasks[taskId].data[1] = arg2; + gTasks[taskId].data[4] = arg5; + gTasks[taskId].data[5] = arg7; + gTasks[taskId].data[6] = arg6; + gTasks[taskId].data[0] = spriteId; + gTasks[taskId].data[2] = arg4; + gTasks[taskId].data[3] = newSpriteId; + gTasks[taskId].func = sub_80BBC2C; +} + +static void sub_80BBC2C(u8 taskId) +{ + gTasks[taskId].data[13] += gTasks[taskId].data[1] < 0 ? -gTasks[taskId].data[1] : gTasks[taskId].data[1]; + if (gTasks[taskId].data[1] < 0) + gBattle_BG1_Y -= gTasks[taskId].data[13] >> 8; + else + gBattle_BG1_Y += gTasks[taskId].data[13] >> 8; + gTasks[taskId].data[13] &= 0xFF; + switch (gTasks[taskId].data[15]) + { + case 0: + if (gTasks[taskId].data[11]++ >= gTasks[taskId].data[6]) + { + gTasks[taskId].data[11] = 0; + ++gTasks[taskId].data[12]; + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gTasks[taskId].data[12], 16 - gTasks[taskId].data[12])); + if (gTasks[taskId].data[12] == gTasks[taskId].data[4]) + ++gTasks[taskId].data[15]; + } + break; + case 1: + if (++gTasks[taskId].data[10] == gTasks[taskId].data[5]) + ++gTasks[taskId].data[15]; + break; + case 2: + if (gTasks[taskId].data[11]++ >= gTasks[taskId].data[6]) + { + gTasks[taskId].data[11] = 0; + --gTasks[taskId].data[12]; + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gTasks[taskId].data[12], 16 - gTasks[taskId].data[12])); + if (gTasks[taskId].data[12] == 0) + { + sub_8073128(0); + gBattle_WIN0H = 0; + gBattle_WIN0V = 0; + SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR + | WININ_WIN1_BG_ALL | WININ_WIN1_OBJ | WININ_WIN1_CLR); + SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WIN01_BG_ALL | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR + | WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ | WINOUT_WINOBJ_CLR); + if (!IsContest()) + { + u16 bg1Cnt = GetGpuReg(REG_OFFSET_BG1CNT); + ((vBgCnt *)&bg1Cnt)->charBaseBlock = 0; + SetGpuReg(REG_OFFSET_BG1CNT, bg1Cnt); + } + SetGpuReg(REG_OFFSET_DISPCNT, GetGpuReg(REG_OFFSET_DISPCNT) ^ DISPCNT_OBJWIN_ON); + SetGpuReg(REG_OFFSET_BLDCNT, 0); + SetGpuReg(REG_OFFSET_BLDALPHA, 0); + DestroySprite(&gSprites[gTasks[taskId].data[0]]); + if (gTasks[taskId].data[2]) + DestroySprite(&gSprites[gTasks[taskId].data[3]]); + DestroyAnimVisualTask(taskId); + } + } + break; + } +} + +void AnimTask_GetBattleTerrain(u8 taskId) +{ + gBattleAnimArgs[0] = gBattleTerrain; + DestroyAnimVisualTask(taskId); +} + +void sub_80BBE10(u8 taskId) +{ + gMonSpritesGfxPtr->field_17C = AllocZeroed(0x2000); + DestroyAnimVisualTask(taskId); +} + +void sub_80BBE3C(u8 taskId) +{ + FREE_AND_SET_NULL(gMonSpritesGfxPtr->field_17C); + DestroyAnimVisualTask(taskId); +} + +void sub_80BBE6C(u8 taskId) +{ + u32 selectedPalettes; + s32 paletteIndex = 0; + + if (gBattleAnimArgs[0] == 0) + for (selectedPalettes = sub_8075BE8(1, 0, 0, 0, 0, 0, 0); + (selectedPalettes & 1) == 0; + ++paletteIndex) + selectedPalettes >>= 1; + else if (gBattleAnimArgs[0] == 1) + paletteIndex = gBattleAnimAttacker + 16; + else if (gBattleAnimArgs[0] == 2) + paletteIndex = gBattleAnimTarget + 16; + memcpy(&gMonSpritesGfxPtr->field_17C[gBattleAnimArgs[1] * 16], &gPlttBufferUnfaded[paletteIndex * 16], 32); + DestroyAnimVisualTask(taskId); +} + +void sub_80BBF08(u8 taskId) +{ + u32 selectedPalettes; + s32 paletteIndex = 0; + + if (gBattleAnimArgs[0] == 0) + for (selectedPalettes = sub_8075BE8(1, 0, 0, 0, 0, 0, 0); + (selectedPalettes & 1) == 0; + ++paletteIndex) + selectedPalettes >>= 1; + else if (gBattleAnimArgs[0] == 1) + paletteIndex = gBattleAnimAttacker + 16; + else if (gBattleAnimArgs[0] == 2) + paletteIndex = gBattleAnimTarget + 16; + memcpy(&gPlttBufferUnfaded[paletteIndex * 16], &gMonSpritesGfxPtr->field_17C[gBattleAnimArgs[1] * 16], 32); + DestroyAnimVisualTask(taskId); +} + +void sub_80BBFA4(u8 taskId) +{ + u32 selectedPalettes; + s32 paletteIndex = 0; + + if (gBattleAnimArgs[0] == 0) + for (selectedPalettes = sub_8075BE8(1, 0, 0, 0, 0, 0, 0); + (selectedPalettes & 1) == 0; + ++paletteIndex) + selectedPalettes >>= 1; + else if (gBattleAnimArgs[0] == 1) + paletteIndex = gBattleAnimAttacker + 16; + else if (gBattleAnimArgs[0] == 2) + paletteIndex = gBattleAnimTarget + 16; + memcpy(&gPlttBufferUnfaded[paletteIndex * 16], &gPlttBufferFaded[paletteIndex * 16], 32); + DestroyAnimVisualTask(taskId); +} + +void AnimTask_IsContest(u8 taskId) +{ + if (IsContest()) + gBattleAnimArgs[7] = 1; + else + gBattleAnimArgs[7] = 0; + DestroyAnimVisualTask(taskId); +} + +void sub_80BC060(u8 taskId) +{ + gBattleAnimAttacker = gBattlerTarget; + gBattleAnimTarget = gEffectBattler; + DestroyAnimVisualTask(taskId); +} + +void AnimTask_IsTargetSameSide(u8 taskId) +{ + if (GetBattlerSide(gBattleAnimAttacker) == GetBattlerSide(gBattleAnimTarget)) + gBattleAnimArgs[7] = 1; + else + gBattleAnimArgs[7] = 0; + DestroyAnimVisualTask(taskId); +} + +void sub_80BC0DC(u8 taskId) +{ + gBattleAnimTarget = gBattlerTarget; + DestroyAnimVisualTask(taskId); +} + +void sub_80BC0FC(u8 taskId) +{ + gBattleAnimAttacker = gBattlerAttacker; + gBattleAnimTarget = gEffectBattler; + DestroyAnimVisualTask(taskId); +} + +void sub_80BC12C(u8 taskId) +{ + if (IsContest()) + { + DestroyAnimVisualTask(taskId); + } + else + { + gTasks[taskId].data[0] = gBattleSpritesDataPtr->battlerData[gBattleAnimAttacker].invisible; + gBattleSpritesDataPtr->battlerData[gBattleAnimAttacker].invisible = 1; + gTasks[taskId].func = sub_80BC19C; + --gAnimVisualTaskCount; + } +} + +static void sub_80BC19C(u8 taskId) +{ + if (gBattleAnimArgs[7] == 0x1000) + { + gBattleSpritesDataPtr->battlerData[gBattleAnimAttacker].invisible = (u8)gTasks[taskId].data[0] & 1; + DestroyTask(taskId); + } +} diff --git a/src/battle_controller_player.c b/src/battle_controller_player.c index 0d827c8db..a9bb5bc6e 100644 --- a/src/battle_controller_player.c +++ b/src/battle_controller_player.c @@ -1191,7 +1191,7 @@ static void sub_80303A8(u8 taskId) { s16 *data = gTasks[taskId].data; u8 battlerId = tExpTask_battler; - u16 v5 = sub_80768B0(battlerId); + u16 v5 = GetBattlerSpriteBGPriorityRank(battlerId); bool32 v6 = ((v5 ^ BIT_SIDE)) != B_SIDE_PLAYER; struct Sprite *sprite = &gSprites[gBattlerSpriteIds[battlerId]]; @@ -1222,7 +1222,7 @@ static void sub_80303A8(u8 taskId) u32 battlerIdAlt = battlerId; bool32 v6Alt = v6; - sub_8072E48(battlerIdAlt, v6Alt); + MoveBattlerSpriteToBG(battlerIdAlt, v6Alt); } ++data[15]; break; diff --git a/src/battle_intro.c b/src/battle_intro.c new file mode 100644 index 000000000..93141f2ca --- /dev/null +++ b/src/battle_intro.c @@ -0,0 +1,495 @@ +#include "global.h" +#include "battle.h" +#include "battle_anim.h" +#include "battle_setup.h" +#include "bg.h" +#include "gpu_regs.h" +#include "main.h" +#include "scanline_effect.h" +#include "task.h" +#include "trig.h" +#include "constants/trainers.h" + +static EWRAM_DATA u16 sBgCnt = 0; + +extern const u8 gUnknown_83E7CCA[]; +extern const u8 gUnknown_83E7CCE[]; + +static void BattleIntroSlide1(u8 taskId); +static void BattleIntroSlide2(u8 taskId); +static void BattleIntroSlide3(u8 taskId); +static void BattleIntroSlideLink(u8 taskId); + +static const TaskFunc sBattleIntroSlideFuncs[] = +{ + BattleIntroSlide1, // BATTLE_TERRAIN_GRASS + BattleIntroSlide1, // BATTLE_TERRAIN_LONG_GRASS + BattleIntroSlide2, // BATTLE_TERRAIN_SAND + BattleIntroSlide2, // BATTLE_TERRAIN_UNDERWATER + BattleIntroSlide2, // BATTLE_TERRAIN_WATER + BattleIntroSlide1, // BATTLE_TERRAIN_POND + BattleIntroSlide1, // BATTLE_TERRAIN_MOUNTAIN + BattleIntroSlide1, // BATTLE_TERRAIN_CAVE + BattleIntroSlide3, // BATTLE_TERRAIN_BUILDING + BattleIntroSlide3, // BATTLE_TERRAIN_PLAIN +}; + +void SetAnimBgAttribute(u8 bgId, u8 attributeId, u8 value) +{ + if (bgId < 4) + { + sBgCnt = GetGpuReg(gUnknown_83E7CCA[bgId]); + switch (attributeId) + { + case BG_ANIM_SCREEN_SIZE: + ((struct BgCnt *)&sBgCnt)->screenSize = value; + break; + case BG_ANIM_AREA_OVERFLOW_MODE: + ((struct BgCnt *)&sBgCnt)->areaOverflowMode = value; + break; + case BG_ANIM_MOSAIC: + ((struct BgCnt *)&sBgCnt)->mosaic = value; + break; + case BG_ANIM_CHAR_BASE_BLOCK: + ((struct BgCnt *)&sBgCnt)->charBaseBlock = value; + break; + case BG_ANIM_PRIORITY: + ((struct BgCnt *)&sBgCnt)->priority = value; + break; + case BG_ANIM_PALETTES_MODE: + ((struct BgCnt *)&sBgCnt)->palettes = value; + break; + case BG_ANIM_SCREEN_BASE_BLOCK: + ((struct BgCnt *)&sBgCnt)->screenBaseBlock = value; + break; + } + SetGpuReg(gUnknown_83E7CCA[bgId], sBgCnt); + } +} + +s32 GetAnimBgAttribute(u8 bgId, u8 attributeId) +{ + u16 bgCnt; + + if (bgId < 4) + { + bgCnt = GetGpuReg(gUnknown_83E7CCE[bgId]); + switch (attributeId) + { + case BG_ANIM_SCREEN_SIZE: + return ((struct BgCnt *)&bgCnt)->screenSize; + case BG_ANIM_AREA_OVERFLOW_MODE: + return ((struct BgCnt *)&bgCnt)->areaOverflowMode; + case BG_ANIM_MOSAIC: + return ((struct BgCnt *)&bgCnt)->mosaic; + case BG_ANIM_CHAR_BASE_BLOCK: + return ((struct BgCnt *)&bgCnt)->charBaseBlock; + case BG_ANIM_PRIORITY: + return ((struct BgCnt *)&bgCnt)->priority; + case BG_ANIM_PALETTES_MODE: + return ((struct BgCnt *)&bgCnt)->palettes; + case BG_ANIM_SCREEN_BASE_BLOCK: + return ((struct BgCnt *)&bgCnt)->screenBaseBlock; + } + } + return 0; +} + +void HandleIntroSlide(u8 terrain) +{ + u8 taskId; + + if (gBattleTypeFlags & BATTLE_TYPE_LINK) + { + taskId = CreateTask(BattleIntroSlideLink, 0); + } + else if ((gBattleTypeFlags & BATTLE_TYPE_KYOGRE_GROUDON) && gGameVersion != VERSION_RUBY) + { + terrain = BATTLE_TERRAIN_UNDERWATER; + taskId = CreateTask(BattleIntroSlide2, 0); + } + else + { + taskId = CreateTask(sBattleIntroSlideFuncs[terrain], 0); + } + gTasks[taskId].data[0] = 0; + gTasks[taskId].data[1] = terrain; + gTasks[taskId].data[2] = 0; + gTasks[taskId].data[3] = 0; + gTasks[taskId].data[4] = 0; + gTasks[taskId].data[5] = 0; + gTasks[taskId].data[6] = 0; +} + +void sub_80BC41C(u8 taskId) +{ + DestroyTask(taskId); + gBattle_BG1_X = 0; + gBattle_BG1_Y = 0; + gBattle_BG2_X = 0; + gBattle_BG2_Y = 0; + SetGpuReg(REG_OFFSET_BLDCNT, 0); + SetGpuReg(REG_OFFSET_BLDALPHA, 0); + SetGpuReg(REG_OFFSET_BLDY, 0); + SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR | WININ_WIN1_BG_ALL | WININ_WIN1_OBJ | WININ_WIN1_CLR); + SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WIN01_BG_ALL | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR | WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ | WINOUT_WINOBJ_CLR); +} + +static void BattleIntroSlide1(u8 taskId) +{ + s32 i; + + gBattle_BG1_X += 6; + switch (gTasks[taskId].data[0]) + { + case 0: + if (gBattleTypeFlags & BATTLE_TYPE_LINK) + { + gTasks[taskId].data[2] = 16; + ++gTasks[taskId].data[0]; + } + else + { + gTasks[taskId].data[2] = 1; + ++gTasks[taskId].data[0]; + } + break; + case 1: + if (--gTasks[taskId].data[2] == 0) + { + ++gTasks[taskId].data[0]; + SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR); + } + break; + case 2: + gBattle_WIN0V -= 0xFF; + if ((gBattle_WIN0V & 0xFF00) == 0x3000) + { + ++gTasks[taskId].data[0]; + gTasks[taskId].data[2] = 240; + gTasks[taskId].data[3] = 32; + gIntroSlideFlags &= ~1; + } + break; + case 3: + if (gTasks[taskId].data[3]) + { + --gTasks[taskId].data[3]; + } + else + { + if (gTasks[taskId].data[1] == 1) + { + if (gBattle_BG1_Y != 0xFFB0) + gBattle_BG1_Y -= 2; + } + else if (gBattle_BG1_Y != 0xFFC8) + { + gBattle_BG1_Y -= 1; + } + } + if (gBattle_WIN0V & 0xFF00) + gBattle_WIN0V -= 0x3FC; + if (gTasks[taskId].data[2]) + gTasks[taskId].data[2] -= 2; + // Scanline settings have already been set in CB2_InitBattleInternal + for (i = 0; i < 80; ++i) + gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer][i] = gTasks[taskId].data[2]; + while (i < 160) + gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer][i++] = -gTasks[taskId].data[2]; + if (!gTasks[taskId].data[2]) + { + gScanlineEffect.state = 3; + ++gTasks[taskId].data[0]; + CpuFill32(0, (void *)BG_SCREEN_ADDR(28), BG_SCREEN_SIZE); + SetBgAttribute(1, BG_ATTR_CHARBASEINDEX, 0); + SetBgAttribute(2, BG_ATTR_CHARBASEINDEX, 0); + SetGpuReg(REG_OFFSET_BG1CNT, BGCNT_PRIORITY(0) | BGCNT_CHARBASE(0) | BGCNT_16COLOR | BGCNT_SCREENBASE(28) | BGCNT_TXT256x512); + SetGpuReg(REG_OFFSET_BG2CNT, BGCNT_PRIORITY(0) | BGCNT_CHARBASE(0) | BGCNT_16COLOR | BGCNT_SCREENBASE(30) | BGCNT_TXT512x256); + } + break; + case 4: + sub_80BC41C(taskId); + break; + } +} + +static void BattleIntroSlide2(u8 taskId) +{ + s32 i; + + switch (gTasks[taskId].data[1]) + { + case 2: + case 4: + gBattle_BG1_X += 8; + break; + case 3: + gBattle_BG1_X += 6; + break; + } + if (gTasks[taskId].data[1] == 4) + { + gBattle_BG1_Y = Cos2(gTasks[taskId].data[6]) / 512 - 8; + if (gTasks[taskId].data[6] < 180) + gTasks[taskId].data[6] += 4; + else + gTasks[taskId].data[6] += 6; + if (gTasks[taskId].data[6] == 360) + gTasks[taskId].data[6] = 0; + } + switch (gTasks[taskId].data[0]) + { + case 0: + gTasks[taskId].data[4] = 16; + if (gBattleTypeFlags & BATTLE_TYPE_LINK) + { + gTasks[taskId].data[2] = 16; + ++gTasks[taskId].data[0]; + } + else + { + gTasks[taskId].data[2] = 1; + ++gTasks[taskId].data[0]; + } + break; + case 1: + if (--gTasks[taskId].data[2] == 0) + { + ++gTasks[taskId].data[0]; + SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR); + } + break; + case 2: + gBattle_WIN0V -= 0xFF; + if ((gBattle_WIN0V & 0xFF00) == 0x3000) + { + ++gTasks[taskId].data[0]; + gTasks[taskId].data[2] = 240; + gTasks[taskId].data[3] = 32; + gTasks[taskId].data[5] = 1; + gIntroSlideFlags &= ~1; + } + break; + case 3: + if (gTasks[taskId].data[3]) + { + if (--gTasks[taskId].data[3] == 0) + { + SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG1 | BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_BG3 | BLDCNT_TGT2_OBJ); + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(15, 0)); + SetGpuReg(REG_OFFSET_BLDY, 0); + } + } + else if ((gTasks[taskId].data[4] & 0x1F) && --gTasks[taskId].data[5] == 0) + { + gTasks[taskId].data[4] += 0xFF; + gTasks[taskId].data[5] = 4; + } + if (gBattle_WIN0V & 0xFF00) + gBattle_WIN0V -= 0x3FC; + + if (gTasks[taskId].data[2]) + gTasks[taskId].data[2] -= 2; + // Scanline settings have already been set in CB2_InitBattleInternal() + for (i = 0; i < 80; ++i) + gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer][i] = gTasks[taskId].data[2]; + while (i < 160) + gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer][i++] = -gTasks[taskId].data[2]; + if (!gTasks[taskId].data[2]) + { + gScanlineEffect.state = 3; + ++gTasks[taskId].data[0]; + CpuFill32(0, (void *)BG_SCREEN_ADDR(28), BG_SCREEN_SIZE); + SetBgAttribute(1, BG_ATTR_CHARBASEINDEX, 0); + SetBgAttribute(2, BG_ATTR_CHARBASEINDEX, 0); + SetGpuReg(REG_OFFSET_BG1CNT, BGCNT_PRIORITY(0) | BGCNT_CHARBASE(0) | BGCNT_16COLOR | BGCNT_SCREENBASE(28) | BGCNT_TXT256x512); + SetGpuReg(REG_OFFSET_BG2CNT, BGCNT_PRIORITY(0) | BGCNT_CHARBASE(0) | BGCNT_16COLOR | BGCNT_SCREENBASE(30) | BGCNT_TXT512x256); + } + break; + case 4: + sub_80BC41C(taskId); + break; + } + if (gTasks[taskId].data[0] != 4) + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gTasks[taskId].data[4], 0)); +} + +static void BattleIntroSlide3(u8 taskId) +{ + s32 i; + + gBattle_BG1_X += 8; + switch (gTasks[taskId].data[0]) + { + case 0: + SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG1 | BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_BG3 | BLDCNT_TGT2_OBJ); + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(8, 8)); + SetGpuReg(REG_OFFSET_BLDY, 0); + gTasks[taskId].data[4] = BLDALPHA_BLEND(8, 8); + if (gBattleTypeFlags & BATTLE_TYPE_LINK) + { + gTasks[taskId].data[2] = 16; + ++gTasks[taskId].data[0]; + } + else + { + gTasks[taskId].data[2] = 1; + ++gTasks[taskId].data[0]; + } + break; + case 1: + if (--gTasks[taskId].data[2] == 0) + { + ++gTasks[taskId].data[0]; + SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR); + } + break; + case 2: + gBattle_WIN0V -= 0xFF; + if ((gBattle_WIN0V & 0xFF00) == 0x3000) + { + ++gTasks[taskId].data[0]; + gTasks[taskId].data[2] = 240; + gTasks[taskId].data[3] = 32; + gTasks[taskId].data[5] = 1; + gIntroSlideFlags &= ~1; + } + break; + case 3: + if (gTasks[taskId].data[3]) + { + --gTasks[taskId].data[3]; + } + else if ((gTasks[taskId].data[4] & 0xF) && --gTasks[taskId].data[5] == 0) + { + gTasks[taskId].data[4] += 0xFF; + gTasks[taskId].data[5] = 6; + } + if (gBattle_WIN0V & 0xFF00) + gBattle_WIN0V -= 0x3FC; + if (gTasks[taskId].data[2]) + gTasks[taskId].data[2] -= 2; + // Scanline settings have already been set in CB2_InitBattleInternal() + for (i = 0; i < 80; ++i) + gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer][i] = gTasks[taskId].data[2]; + while (i < 160) + gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer][i++] = -gTasks[taskId].data[2]; + if (!gTasks[taskId].data[2]) + { + gScanlineEffect.state = 3; + ++gTasks[taskId].data[0]; + CpuFill32(0, (void *)BG_SCREEN_ADDR(28), BG_SCREEN_SIZE); + SetBgAttribute(1, BG_ATTR_CHARBASEINDEX, 0); + SetBgAttribute(2, BG_ATTR_CHARBASEINDEX, 0); + SetGpuReg(REG_OFFSET_BG1CNT, BGCNT_PRIORITY(0) | BGCNT_CHARBASE(0) | BGCNT_16COLOR | BGCNT_SCREENBASE(28) | BGCNT_TXT256x512); + SetGpuReg(REG_OFFSET_BG2CNT, BGCNT_PRIORITY(0) | BGCNT_CHARBASE(0) | BGCNT_16COLOR | BGCNT_SCREENBASE(30) | BGCNT_TXT512x256); + } + break; + case 4: + sub_80BC41C(taskId); + break; + } + if (gTasks[taskId].data[0] != 4) + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gTasks[taskId].data[4], 0)); +} + +static void BattleIntroSlideLink(u8 taskId) +{ + s32 i; + + if (gTasks[taskId].data[0] > 1 && !gTasks[taskId].data[4]) + { + u16 var0 = gBattle_BG1_X & 0x8000; + + if (var0 || gBattle_BG1_X < 80) + { + gBattle_BG1_X += 3; + gBattle_BG2_X -= 3; + } + else + { + CpuFill32(0, (void *)BG_SCREEN_ADDR(28), BG_SCREEN_SIZE); + CpuFill32(0, (void *)BG_SCREEN_ADDR(30), BG_SCREEN_SIZE); + gTasks[taskId].data[4] = 1; + } + } + switch (gTasks[taskId].data[0]) + { + case 0: + gTasks[taskId].data[2] = 32; + ++gTasks[taskId].data[0]; + break; + case 1: + if (--gTasks[taskId].data[2] == 0) + { + ++gTasks[taskId].data[0]; + gSprites[gBattleStruct->linkBattleVsSpriteId_V].oam.objMode = ST_OAM_OBJ_WINDOW; + gSprites[gBattleStruct->linkBattleVsSpriteId_V].callback = sub_801182C; + gSprites[gBattleStruct->linkBattleVsSpriteId_S].oam.objMode = ST_OAM_OBJ_WINDOW; + gSprites[gBattleStruct->linkBattleVsSpriteId_S].callback = sub_801182C; + SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR); + SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ | WINOUT_WINOBJ_CLR | WINOUT_WIN01_BG1 | WINOUT_WIN01_BG2); + } + break; + case 2: + gBattle_WIN0V -= 0xFF; + if ((gBattle_WIN0V & 0xFF00) == 0x3000) + { + ++gTasks[taskId].data[0]; + gTasks[taskId].data[2] = 240; + gTasks[taskId].data[3] = 32; + gIntroSlideFlags &= ~1; + } + break; + case 3: + if (gBattle_WIN0V & 0xFF00) + gBattle_WIN0V -= 0x3FC; + if (gTasks[taskId].data[2]) + gTasks[taskId].data[2] -= 2; + // Scanline settings have already been set in CB2_InitBattleInternal() + for (i = 0; i < 80; ++i) + gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer][i] = gTasks[taskId].data[2]; + while (i < 160) + gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer][i++] = -gTasks[taskId].data[2]; + if (!gTasks[taskId].data[2]) + { + gScanlineEffect.state = 3; + ++gTasks[taskId].data[0]; + SetBgAttribute(1, BG_ATTR_CHARBASEINDEX, 0); + SetBgAttribute(2, BG_ATTR_CHARBASEINDEX, 0); + SetGpuReg(REG_OFFSET_BG1CNT, BGCNT_PRIORITY(0) | BGCNT_CHARBASE(0) | BGCNT_16COLOR | BGCNT_SCREENBASE(28) | BGCNT_TXT256x512); + SetGpuReg(REG_OFFSET_BG2CNT, BGCNT_PRIORITY(0) | BGCNT_CHARBASE(0) | BGCNT_16COLOR | BGCNT_SCREENBASE(30) | BGCNT_TXT512x256); + } + break; + case 4: + sub_80BC41C(taskId); + break; + } +} + +void sub_80BCEF4(s32 bgId, u8 arg1, u8 arg2, u8 battlerPosition, u8 arg4, u8 *arg5, u16 *arg6, u16 tilesOffset) +{ + s32 i, j; + u8 battler = GetBattlerAtPosition(battlerPosition); + s32 offset = tilesOffset; + + CpuCopy16(gMonSpritesGfxPtr->sprites[battlerPosition] + BG_SCREEN_SIZE * gBattleMonForms[battler], arg5, BG_SCREEN_SIZE); + LoadBgTiles(bgId, arg5, 0x1000, tilesOffset); + for (i = arg2; i < arg2 + 8; ++i) + for (j = arg1; j < arg1 + 8; ++j) + arg6[i * 32 + j] = offset++ | (arg4 << 12); + LoadBgTilemap(bgId, arg6, BG_SCREEN_SIZE, 0); +} + +// not used +static void sub_80BCFCC(u8 arg0, u8 arg1, u8 battlerPosition, u8 arg3, u8 arg4, u16 arg5, u8 arg6, u8 arg7) +{ + s32 i, j, offset; + + DmaCopy16(3, gMonSpritesGfxPtr->sprites[battlerPosition] + BG_SCREEN_SIZE * arg3, (void *)BG_SCREEN_ADDR(0) + arg5, BG_SCREEN_SIZE); + offset = (arg5 >> 5) - (arg7 << 9); + for (i = arg1; i < arg1 + 8; ++i) + for (j = arg0; j < arg0 + 8; ++j) + *((u16 *)(BG_VRAM) + (i * 32) + (j + (arg6 << 10))) = offset++ | (arg4 << 12); +} diff --git a/src/battle_transition.c b/src/battle_transition.c index d391b3ed4..19d76fed1 100644 --- a/src/battle_transition.c +++ b/src/battle_transition.c @@ -857,14 +857,14 @@ static bool8 BT_Phase2BigPokeball_Init(struct Task *task) task->tEva = 0; task-> tTheta = 0; task-> tAmplitude = 0x4000; - sTransitionStructPtr->winIn = 0x3F; + sTransitionStructPtr->winIn = WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR; sTransitionStructPtr->winOut = 0; - sTransitionStructPtr->win0H = 240; - sTransitionStructPtr->win0V = 160; + sTransitionStructPtr->win0H = WIN_RANGE(0, 0xF0); + sTransitionStructPtr->win0V = WIN_RANGE(0, 0xA0); sTransitionStructPtr->bldCnt = BLDCNT_TGT1_BG0 | BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_BG0 | BLDCNT_TGT2_BG1 | BLDCNT_TGT2_BG2 | BLDCNT_TGT2_BG3 | BLDCNT_TGT2_OBJ | BLDCNT_TGT2_BD; sTransitionStructPtr->bldAlpha = (task->tEvb << 8) | task->tEva; for (i = 0; i < 160; ++i) - gScanlineEffectRegBuffers[1][i] = 240; + gScanlineEffectRegBuffers[1][i] = 0xF0; SetVBlankCallback(VBCB_BT_Phase2BigPokeball1); BT_GetBg0TilemapAndTilesetBase(&tilemapAddr, &tilesetAddr); CpuFill16(0, tilemapAddr, 0x800); @@ -897,7 +897,7 @@ static bool8 BT_Phase2BigPokeball_UpdateWave1IncEva(struct Task *task) ++task->tEva; task->tInterval = 1; // Broken logic. This makes the condition always TRUE. } - sTransitionStructPtr->bldAlpha = (task->tEvb << 8) | task->tEva; + sTransitionStructPtr->bldAlpha = BLDALPHA_BLEND(task->tEva, task->tEvb); // Increment eva until it reaches 50% coeff if (task->tEva > 15) ++task->tState; @@ -1148,13 +1148,11 @@ static bool8 BT_Phase2ClockwiseBlackFade_Init(struct Task *task) BT_InitCtrlBlk(); ScanlineEffect_Clear(); sTransitionStructPtr->winIn = 0; - sTransitionStructPtr->winOut = 0x3F; - sTransitionStructPtr->win0H = 0xF0F1; - sTransitionStructPtr->win0V = 0x00A0; + sTransitionStructPtr->winOut = WINOUT_WIN01_BG_ALL | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR; + sTransitionStructPtr->win0H = WIN_RANGE(0xF0, 0xF1); + sTransitionStructPtr->win0V = WIN_RANGE(0, 0xA0); for (i = 0; i < 160; ++i) - { - gScanlineEffectRegBuffers[1][i] = 0xF3F4; - } + gScanlineEffectRegBuffers[1][i] = WIN_RANGE(0xF3, 0xF4); SetVBlankCallback(VBCB_BT_Phase2ClockwiseBlackFade); sTransitionStructPtr->trEndPtX = 120; ++task->tState; @@ -1167,7 +1165,7 @@ static bool8 BT_Phase2ClockwiseBlackFade_Step1(struct Task *task) BT_DiagonalSegment_InitParams(sTransitionStructPtr->data, 120, 80, sTransitionStructPtr->trEndPtX, -1, 1, 1); do { - gScanlineEffectRegBuffers[0][sTransitionStructPtr->trCurrentPtY] = (sTransitionStructPtr->trCurrentPtX + 1) | 0x7800; + gScanlineEffectRegBuffers[0][sTransitionStructPtr->trCurrentPtY] = WIN_RANGE(0x78, sTransitionStructPtr->trCurrentPtX + 1); } while (!BT_DiagonalSegment_ComputePointOnSegment(sTransitionStructPtr->data, TRUE, TRUE)); @@ -1197,7 +1195,7 @@ static bool8 BT_Phase2ClockwiseBlackFade_Step2(struct Task *task) left = sTransitionStructPtr->trCurrentPtX; right = 240; } - gScanlineEffectRegBuffers[0][sTransitionStructPtr->trCurrentPtY] = right | (left << 8); + gScanlineEffectRegBuffers[0][sTransitionStructPtr->trCurrentPtY] = WIN_RANGE2(left, right); if (finished) break; finished = BT_DiagonalSegment_ComputePointOnSegment(sTransitionStructPtr->data, TRUE, TRUE); @@ -1211,7 +1209,7 @@ static bool8 BT_Phase2ClockwiseBlackFade_Step2(struct Task *task) else { while (sTransitionStructPtr->trCurrentPtY < sTransitionStructPtr->trEndPtY) - gScanlineEffectRegBuffers[0][++sTransitionStructPtr->trCurrentPtY] = right | (left << 8); + gScanlineEffectRegBuffers[0][++sTransitionStructPtr->trCurrentPtY] = WIN_RANGE2(left, right); } ++sTransitionStructPtr->vblankDma; return FALSE; @@ -1265,7 +1263,7 @@ static bool8 BT_Phase2ClockwiseBlackFade_Step4(struct Task *task) left = 120; right = sTransitionStructPtr->trCurrentPtX; } - win0H = right | (left << 8); + win0H = WIN_RANGE2(left, right); gScanlineEffectRegBuffers[0][sTransitionStructPtr->trCurrentPtY] = win0H; if (finished) break; @@ -1280,7 +1278,7 @@ static bool8 BT_Phase2ClockwiseBlackFade_Step4(struct Task *task) else { while (sTransitionStructPtr->trCurrentPtY > sTransitionStructPtr->trEndPtY) - gScanlineEffectRegBuffers[0][--sTransitionStructPtr->trCurrentPtY] = right | (left << 8); + gScanlineEffectRegBuffers[0][--sTransitionStructPtr->trCurrentPtY] = WIN_RANGE2(left, right); } ++sTransitionStructPtr->vblankDma; return FALSE; @@ -1301,7 +1299,7 @@ static bool8 BT_Phase2ClockwiseBlackFade_Step5(struct Task *task) left = 0; right = 240; } - gScanlineEffectRegBuffers[0][sTransitionStructPtr->trCurrentPtY] = right | (left << 8); + gScanlineEffectRegBuffers[0][sTransitionStructPtr->trCurrentPtY] = WIN_RANGE2(left, right); } while (!BT_DiagonalSegment_ComputePointOnSegment(sTransitionStructPtr->data, TRUE, TRUE)); sTransitionStructPtr->trEndPtX += 32; @@ -1431,12 +1429,12 @@ static bool8 BT_Phase2BlackWaveToRight_Init(struct Task *task) BT_InitCtrlBlk(); ScanlineEffect_Clear(); - sTransitionStructPtr->winIn = 0x3F; + sTransitionStructPtr->winIn = WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR; sTransitionStructPtr->winOut = 0; - sTransitionStructPtr->win0H = 240; - sTransitionStructPtr->win0V = 160; + sTransitionStructPtr->win0H = WIN_RANGE(0, 0xF0); + sTransitionStructPtr->win0V = WIN_RANGE(0, 0xA0); for (i = 0; i < 160; ++i) - gScanlineEffectRegBuffers[1][i] = 242; + gScanlineEffectRegBuffers[1][i] = WIN_RANGE(0, 0xF2); SetVBlankCallback(VBCB_BT_Phase2BlackWaveToRight); ++task->tState; return TRUE; @@ -1460,7 +1458,7 @@ static bool8 BT_Phase2BlackWaveToRight_UpdateWave(struct Task *task) left = 0; if (left > 240) left = 240; - *winVal = (left << 8) | (0xF1); + *winVal = WIN_RANGE(left, 0xF1); if (left < 240) nextFunc = FALSE; } @@ -2529,10 +2527,10 @@ static bool8 BT_Phase2AntiClockwiseSpiral_Init(struct Task *task) BT_InitCtrlBlk(); ScanlineEffect_Clear(); sTransitionStructPtr->winIn = 0; - sTransitionStructPtr->winOut = 0x3F; - sTransitionStructPtr->win0H = 0x7878; - sTransitionStructPtr->win0V = 0x3070; - sTransitionStructPtr->win1V = 0x1090; + sTransitionStructPtr->winOut = WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR; + sTransitionStructPtr->win0H = WIN_RANGE(0x78, 0x78); + sTransitionStructPtr->win0V = WIN_RANGE(0x30, 0x70); + sTransitionStructPtr->win1V = WIN_RANGE(0x10, 0x90); sTransitionStructPtr->counter = 0; sub_80D1F64(0, 0, FALSE); sub_80D1F64(0, 0, TRUE); @@ -2665,11 +2663,11 @@ static bool8 BT_Phase2Mugshot_Init(struct Task *task) task->tTheta = 0; task->tbg0HOfsOpponent = 1; task->tbg0HOfsPlayer = 239; - sTransitionStructPtr->winIn = 0x3F; - sTransitionStructPtr->winOut = 0x3E; - sTransitionStructPtr->win0V = 160; + sTransitionStructPtr->winIn = WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR; + sTransitionStructPtr->winOut = WININ_WIN0_BG1 | WININ_WIN0_BG2 | WININ_WIN0_BG3 | WININ_WIN0_OBJ | WININ_WIN0_CLR; + sTransitionStructPtr->win0V = WIN_RANGE(0, 0xA0); for (i = 0; i < 160; ++i) - gScanlineEffectRegBuffers[1][i] = 0xF0F1; + gScanlineEffectRegBuffers[1][i] = WIN_RANGE(0xF0, 0xF1); SetVBlankCallback(VBCB_BT_Phase2Mugshot1_Slide); ++task->tState; return FALSE; @@ -2784,7 +2782,7 @@ static bool8 BT_Phase2Mugshot_WaitForPlayerInPlace(struct Task *task) DmaStop(0); memset(gScanlineEffectRegBuffers[0], 0, 320); memset(gScanlineEffectRegBuffers[1], 0, 320); - SetGpuReg(REG_OFFSET_WIN0H, 0xF0); + SetGpuReg(REG_OFFSET_WIN0H, WIN_RANGE(0, 0xF0)); SetGpuReg(REG_OFFSET_BLDY, 0); ++task->tState; task->tCounter = 0; @@ -3026,9 +3024,9 @@ static bool8 BT_Phase2SlicedScreen_Init(struct Task *task) ScanlineEffect_Clear(); task->tAcc = 256; task->tJerk = 1; - sTransitionStructPtr->winIn = 0x3F; + sTransitionStructPtr->winIn = WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR; sTransitionStructPtr->winOut = 0; - sTransitionStructPtr->win0V = 160; + sTransitionStructPtr->win0V = WIN_RANGE(0, 0xA0); for (i = 0; i < 160; ++i) { gScanlineEffectRegBuffers[1][i] = sTransitionStructPtr->bg123HOfs; @@ -3065,7 +3063,7 @@ static bool8 BT_Phase2SlicedScreen_UpdateOffsets(struct Task *task) else { *ofsBuffer = sTransitionStructPtr->bg123HOfs - task->tSpeed; - *win0HBuffer = (task->tSpeed << 8) | 0xF1; + *win0HBuffer = WIN_RANGE(task->tSpeed, 0xF1); } } if (task->tSpeed > 0xEF) @@ -3126,9 +3124,9 @@ static bool8 BT_Phase2WhiteFadeInStripes_Init(struct Task *task) ScanlineEffect_Clear(); sTransitionStructPtr->bldCnt = BLDCNT_TGT1_BG0 | BLDCNT_TGT1_BG1 | BLDCNT_TGT1_BG2 | BLDCNT_TGT1_BG3 | BLDCNT_TGT1_OBJ | BLDCNT_TGT1_BD | BLDCNT_EFFECT_LIGHTEN; sTransitionStructPtr->bldY = 0; - sTransitionStructPtr->winIn = 0x1E; - sTransitionStructPtr->winOut = 0x3F; - sTransitionStructPtr->win0V = 160; + sTransitionStructPtr->winIn = WINOUT_WIN01_BG1 | WINOUT_WIN01_BG2 | WINOUT_WIN01_BG3 | WINOUT_WIN01_OBJ; + sTransitionStructPtr->winOut = WINOUT_WIN01_BG_ALL | WINOUT_WIN01_OBJ | WININ_WIN0_CLR; + sTransitionStructPtr->win0V = WIN_RANGE(0, 0xA0); for (i = 0; i < 160; ++i) { gScanlineEffectRegBuffers[1][i] = 0; @@ -3180,7 +3178,7 @@ static bool8 BT_Phase2WhiteFadeInStripes_Stop(struct Task *task) sTransitionStructPtr->win0H = 240; sTransitionStructPtr->bldY = 0; sTransitionStructPtr->bldCnt = BLDCNT_TGT1_BG0 | BLDCNT_TGT1_BG1 | BLDCNT_TGT1_BG2 | BLDCNT_TGT1_BG3 | BLDCNT_TGT1_OBJ | BLDCNT_TGT1_BD | BLDCNT_EFFECT_DARKEN; - sTransitionStructPtr->winIn = 0x3F; + sTransitionStructPtr->winIn = WINOUT_WIN01_BG_ALL | WINOUT_WIN01_OBJ | WININ_WIN0_CLR; sTransitionStructPtr->counter = 0; SetVBlankCallback(VBCB_BT_Phase2WhiteFadeInStripes2); ++task->tState; @@ -3351,11 +3349,11 @@ static bool8 BT_Phase2BlackDoodles_Init(struct Task *task) BT_InitCtrlBlk(); ScanlineEffect_Clear(); - sTransitionStructPtr->winIn = 0x3F; + sTransitionStructPtr->winIn = WINOUT_WIN01_BG_ALL | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR; sTransitionStructPtr->winOut = 0; - sTransitionStructPtr->win0V = 0xA0; + sTransitionStructPtr->win0V = WIN_RANGE(0, 0xA0); for (i = 0; i < 160; ++i) - gScanlineEffectRegBuffers[0][i] = 0x00F0; + gScanlineEffectRegBuffers[0][i] = WIN_RANGE(0, 0xF0); CpuSet(gScanlineEffectRegBuffers[0], gScanlineEffectRegBuffers[1], 160); SetVBlankCallback(VBCB_BT_Phase2BlackDoodles); ++task->tState; @@ -3394,7 +3392,7 @@ static bool8 BT_Phase2BlackDoodles_DrawSingleBrush(struct Task *task) if (right <= left) right = left; } - gScanlineEffectRegBuffers[0][sTransitionStructPtr->trCurrentPtY] = right | (left << 8); + gScanlineEffectRegBuffers[0][sTransitionStructPtr->trCurrentPtY] = WIN_RANGE2(left, right); if (nextFunc) { ++task->tState; @@ -356,7 +356,6 @@ void ResetBgsAndClearDma3BusyFlags(bool32 enableWindowTileAutoAlloc) } } -#ifdef NONMATCHING void InitBgsFromTemplates(u8 bgMode, const struct BgTemplate *templates, u8 numTemplates) { int i; @@ -390,121 +389,6 @@ void InitBgsFromTemplates(u8 bgMode, const struct BgTemplate *templates, u8 numT } } } -#else -NAKED -void InitBgsFromTemplates(u8 bgMode, const struct BgTemplate *templates, u8 numTemplates) -{ - asm(".syntax unified\n\ - push {r4-r7,lr}\n\ - mov r7, r10\n\ - mov r6, r9\n\ - mov r5, r8\n\ - push {r5-r7}\n\ - sub sp, 0x10\n\ - adds r5, r1, 0\n\ - lsls r0, 24\n\ - lsrs r0, 24\n\ - lsls r2, 24\n\ - lsrs r4, r2, 24\n\ - bl SetBgModeInternal\n\ - bl ResetBgControlStructs\n\ - cmp r4, 0\n\ - beq _08001712\n\ - movs r7, 0\n\ - ldr r0, _08001724 @ =sGpuBgConfigs2\n\ - mov r9, r0\n\ - adds r6, r5, 0\n\ - ldr r2, _08001728 @ =gpu_tile_allocation_map_bg\n\ - mov r10, r2\n\ - mov r8, r4\n\ -_08001688:\n\ - ldr r4, [r6]\n\ - lsls r0, r4, 30\n\ - lsrs r5, r0, 30\n\ - cmp r5, 0x3\n\ - bhi _08001704\n\ - lsls r1, r4, 28\n\ - lsrs r1, 30\n\ - lsls r2, r4, 23\n\ - lsrs r2, 27\n\ - lsls r3, r4, 21\n\ - lsrs r3, 30\n\ - lsls r0, r4, 20\n\ - lsrs r0, 31\n\ - str r0, [sp]\n\ - lsls r0, r4, 18\n\ - lsrs r0, 30\n\ - str r0, [sp, 0x4]\n\ - str r7, [sp, 0x8]\n\ - str r7, [sp, 0xC]\n\ - adds r0, r5, 0\n\ - bl SetBgControlAttributes\n\ - lsls r4, r5, 4\n\ - mov r5, r9\n\ - adds r3, r4, r5\n\ - ldr r2, [r6]\n\ - lsls r2, 8\n\ - lsrs r2, 22\n\ - ldrh r0, [r3]\n\ - ldr r5, _0800172C @ =0xfffffc00\n\ - adds r1, r5, 0\n\ - ands r0, r1\n\ - orrs r0, r2\n\ - strh r0, [r3]\n\ - ldrb r0, [r3, 0x1]\n\ - movs r2, 0x3D\n\ - negs r2, r2\n\ - adds r1, r2, 0\n\ - ands r0, r1\n\ - strb r0, [r3, 0x1]\n\ - ldr r0, [r3]\n\ - ldr r1, _08001730 @ =0x00003fff\n\ - ands r0, r1\n\ - str r0, [r3]\n\ - mov r0, r9\n\ - adds r0, 0x4\n\ - adds r0, r4, r0\n\ - str r7, [r0]\n\ - mov r0, r9\n\ - adds r0, 0x8\n\ - adds r0, r4, r0\n\ - str r7, [r0]\n\ - ldr r5, _08001734 @ =sGpuBgConfigs2 + 0xC\n\ - adds r4, r5\n\ - str r7, [r4]\n\ - ldr r0, [r6]\n\ - lsls r0, 28\n\ - lsrs r0, 30\n\ - lsls r0, 6\n\ - add r0, r10\n\ - movs r1, 0x1\n\ - strb r1, [r0]\n\ -_08001704:\n\ - adds r6, 0x4\n\ - movs r0, 0x1\n\ - negs r0, r0\n\ - add r8, r0\n\ - mov r2, r8\n\ - cmp r2, 0\n\ - bne _08001688\n\ -_08001712:\n\ - add sp, 0x10\n\ - pop {r3-r5}\n\ - mov r8, r3\n\ - mov r9, r4\n\ - mov r10, r5\n\ - pop {r4-r7}\n\ - pop {r0}\n\ - bx r0\n\ - .align 2, 0\n\ -_08001724: .4byte sGpuBgConfigs2\n\ -_08001728: .4byte gpu_tile_allocation_map_bg\n\ -_0800172C: .4byte 0xfffffc00\n\ -_08001730: .4byte 0x00003fff\n\ -_08001734: .4byte sGpuBgConfigs2 + 0xC\n\ -.syntax divided"); -} -#endif // NONMATCHING void InitBgFromTemplate(const struct BgTemplate *template) { diff --git a/src/bug.c b/src/bug.c new file mode 100644 index 000000000..9b8935744 --- /dev/null +++ b/src/bug.c @@ -0,0 +1,462 @@ +#include "global.h" +#include "battle_anim.h" +#include "gpu_regs.h" +#include "trig.h" + +static void sub_80B3FAC(struct Sprite *sprite); +static void sub_80B407C(struct Sprite *sprite); +static void AnimTranslateWebThread(struct Sprite *sprite); +static void sub_80B41F8(struct Sprite *sprite); +static void sub_80B42C0(struct Sprite *sprite); +static void AnimTranslateStinger(struct Sprite *sprite); +static void AnimMissileArc(struct Sprite *sprite); +static void sub_80B45D8(struct Sprite *sprite); +static void sub_80B41C0(struct Sprite *sprite); +static void sub_80B4274(struct Sprite *sprite); +static void sub_80B42E8(struct Sprite *sprite); +static void sub_80B4344(struct Sprite *sprite); +static void AnimMissileArcStep(struct Sprite *sprite); + +static const union AffineAnimCmd gUnknown_83E71E8[] = +{ + AFFINEANIMCMD_FRAME(0x100, 0x100, 30, 0), + AFFINEANIMCMD_END, +}; + +static const union AffineAnimCmd gUnknown_83E71F8[] = +{ + AFFINEANIMCMD_FRAME(0x100, 0x100, -99, 0), + AFFINEANIMCMD_END, +}; + +static const union AffineAnimCmd gUnknown_83E7208[] = +{ + AFFINEANIMCMD_FRAME(0x100, 0x100, 94, 0), + AFFINEANIMCMD_END, +}; + +static const union AffineAnimCmd *const gUnknown_83E7218[] = +{ + gUnknown_83E71E8, + gUnknown_83E71F8, + gUnknown_83E7208, +}; + +const struct SpriteTemplate gUnknown_83E7224 = +{ + .tileTag = ANIM_TAG_HORN_HIT_2, + .paletteTag = ANIM_TAG_HORN_HIT_2, + .oam = &gOamData_83ACAB8, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gUnknown_83E7218, + .callback = sub_80B3FAC, +}; + +static const union AffineAnimCmd gUnknown_83E723C[] = +{ + AFFINEANIMCMD_FRAME(0x0, 0x0, -33, 1), + AFFINEANIMCMD_END, +}; + +static const union AffineAnimCmd gUnknown_83E724C[] = +{ + AFFINEANIMCMD_FRAME(0x0, 0x0, 96, 1), + AFFINEANIMCMD_END, +}; + +static const union AffineAnimCmd gUnknown_83E725C[] = +{ + AFFINEANIMCMD_FRAME(0x0, 0x0, -96, 1), + AFFINEANIMCMD_END, +}; + +static const union AffineAnimCmd *const gUnknown_83E726C[] = +{ + gUnknown_83E723C, + gUnknown_83E724C, + gUnknown_83E725C, +}; + +const struct SpriteTemplate gUnknown_83E7278 = +{ + .tileTag = ANIM_TAG_NEEDLE, + .paletteTag = ANIM_TAG_NEEDLE, + .oam = &gOamData_83ACA30, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gUnknown_83E726C, + .callback = sub_80B407C, +}; + +const struct SpriteTemplate gWebThreadSpriteTemplate = +{ + .tileTag = ANIM_TAG_WEB_THREAD, + .paletteTag = ANIM_TAG_WEB_THREAD, + .oam = &gOamData_83AC9C8, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimTranslateWebThread, +}; + +const struct SpriteTemplate gUnknown_83E72A8 = +{ + .tileTag = ANIM_TAG_STRING, + .paletteTag = ANIM_TAG_STRING, + .oam = &gOamData_83ACA00, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_80B41F8, +}; + +static const union AffineAnimCmd gUnknown_83E72C0[] = +{ + AFFINEANIMCMD_FRAME(0x10, 0x10, 0, 0), + AFFINEANIMCMD_FRAME(0x6, 0x6, 0, 1), + AFFINEANIMCMD_JUMP(1), +}; + +static const union AffineAnimCmd *const gUnknown_83E72D8[] = +{ + gUnknown_83E72C0, +}; + +const struct SpriteTemplate gSpiderWebSpriteTemplate = +{ + .tileTag = ANIM_TAG_SPIDER_WEB, + .paletteTag = ANIM_TAG_SPIDER_WEB, + .oam = &gOamData_83ACBC0, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gUnknown_83E72D8, + .callback = sub_80B42C0, +}; + +const struct SpriteTemplate gLinearStingerSpriteTemplate = +{ + .tileTag = ANIM_TAG_NEEDLE, + .paletteTag = ANIM_TAG_NEEDLE, + .oam = &gOamData_83ACA30, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimTranslateStinger, +}; + +const struct SpriteTemplate gPinMissileSpriteTemplate = +{ + .tileTag = ANIM_TAG_NEEDLE, + .paletteTag = ANIM_TAG_NEEDLE, + .oam = &gOamData_83ACA30, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimMissileArc, +}; + +const struct SpriteTemplate gIcicleSpearSpriteTemplate = +{ + .tileTag = ANIM_TAG_ICICLE_SPEAR, + .paletteTag = ANIM_TAG_ICICLE_SPEAR, + .oam = &gOamData_83ACA38, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimMissileArc, +}; + +static const union AffineAnimCmd gUnknown_83E733C[] = +{ + AFFINEANIMCMD_FRAME(0x10, 0x10, 0, 0), + AFFINEANIMCMD_FRAME(0x8, 0x8, 0, 18), + AFFINEANIMCMD_LOOP(0), + AFFINEANIMCMD_FRAME(0xFFFB, 0xFFFB, 0, 8), + AFFINEANIMCMD_FRAME(0x5, 0x5, 0, 8), + AFFINEANIMCMD_LOOP(5), + AFFINEANIMCMD_END, +}; + +static const union AffineAnimCmd *const gUnknown_83E7374[] = +{ + gUnknown_83E733C, +}; + +const struct SpriteTemplate gUnknown_83E7378 = +{ + .tileTag = ANIM_TAG_CIRCLE_OF_LIGHT, + .paletteTag = ANIM_TAG_CIRCLE_OF_LIGHT, + .oam = &gOamData_83ACB60, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gUnknown_83E7374, + .callback = sub_80B45D8, +}; + +static void sub_80B3FAC(struct Sprite *sprite) +{ + if (IsContest()) + { + StartSpriteAffineAnim(sprite, 2); + gBattleAnimArgs[2] = -gBattleAnimArgs[2]; + gBattleAnimArgs[0] = -gBattleAnimArgs[0]; + } + else if (!GetBattlerSide(gBattleAnimTarget)) + { + StartSpriteAffineAnim(sprite, 1); + gBattleAnimArgs[1] = -gBattleAnimArgs[1]; + gBattleAnimArgs[2] = -gBattleAnimArgs[2]; + gBattleAnimArgs[3] = -gBattleAnimArgs[3]; + gBattleAnimArgs[0] = -gBattleAnimArgs[0]; + } + sprite->pos1.x = GetBattlerSpriteCoord2(gBattleAnimTarget, 2) + gBattleAnimArgs[0]; + sprite->pos1.y = GetBattlerSpriteCoord2(gBattleAnimTarget, 3) + gBattleAnimArgs[1]; + sprite->data[0] = gBattleAnimArgs[4]; + sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, 2) + gBattleAnimArgs[2]; + sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, 3) + gBattleAnimArgs[3]; + sprite->callback = StartAnimLinearTranslation; + StoreSpriteCallbackInData6(sprite, DestroyAnimSprite); +} + +static void sub_80B407C(struct Sprite *sprite) +{ + if (IsContest()) + { + gBattleAnimArgs[0] = -gBattleAnimArgs[0]; + StartSpriteAffineAnim(sprite, 2); + } + else if (!GetBattlerSide(gBattleAnimTarget)) + { + gBattleAnimArgs[1] = -gBattleAnimArgs[1]; + gBattleAnimArgs[0] = -gBattleAnimArgs[0]; + } + sprite->pos1.x = GetBattlerSpriteCoord2(gBattleAnimTarget, 2) + gBattleAnimArgs[0]; + sprite->pos1.y = GetBattlerSpriteCoord2(gBattleAnimTarget, 3) + gBattleAnimArgs[1]; + sprite->data[0] = gBattleAnimArgs[2]; + sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, 2); + sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, 3); + sprite->callback = StartAnimLinearTranslation; + StoreSpriteCallbackInData6(sprite, DestroyAnimSprite); +} + +// Creates a single web thread that travels from attacker to target. +// Used by MOVE_STRING_SHOT and MOVE_SPIDER_WEB in their first move phase. +// arg 0: x +// arg 1: y +// arg 2: controls the left-to-right movement +// arg 3: amplitude +// arg 4: if targets both opponents +static void AnimTranslateWebThread(struct Sprite *sprite) +{ + if (IsContest()) + gBattleAnimArgs[2] /= 2; + InitSpritePosToAnimAttacker(sprite, TRUE); + sprite->data[0] = gBattleAnimArgs[2]; + sprite->data[1] = sprite->pos1.x; + sprite->data[3] = sprite->pos1.y; + if (!gBattleAnimArgs[4]) + { + sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, 2); + sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, 3); + } + else + { + SetAverageBattlerPositions(gBattleAnimTarget, 1, &sprite->data[2], &sprite->data[4]); + } + sub_8075678(sprite); + sprite->data[5] = gBattleAnimArgs[3]; + sprite->callback = sub_80B41C0; +} + +static void sub_80B41C0(struct Sprite *sprite) +{ + if (AnimTranslateLinear(sprite)) + { + DestroyAnimSprite(sprite); + return; + } + sprite->pos2.x += Sin(sprite->data[6], sprite->data[5]); + sprite->data[6] = (sprite->data[6] + 13) & 0xFF; +} + +static void sub_80B41F8(struct Sprite *sprite) +{ + SetAverageBattlerPositions(gBattleAnimTarget, 0, &sprite->pos1.x, &sprite->pos1.y); + if (GetBattlerSide(gBattleAnimAttacker)) + sprite->pos1.x -= gBattleAnimArgs[0]; + else + sprite->pos1.x += gBattleAnimArgs[0]; + sprite->pos1.y += gBattleAnimArgs[1]; + if (!GetBattlerSide(gBattleAnimTarget)) + sprite->pos1.y += 8; + sprite->callback = sub_80B4274; +} + +static void sub_80B4274(struct Sprite *sprite) +{ + if (++sprite->data[0] == 3) + { + sprite->data[0] = 0; + sprite->invisible ^= 1; + } + if (++sprite->data[1] == 51) + { + DestroyAnimSprite(sprite); + } +} + +static void sub_80B42C0(struct Sprite *sprite) +{ + SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND); + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(16, 0)); + sprite->data[0] = 16; + sprite->callback = sub_80B42E8; +} + +static void sub_80B42E8(struct Sprite *sprite) +{ + if (sprite->data[2] < 20) + { + ++sprite->data[2]; + } + else if (sprite->data[1]++ & 1) + { + --sprite->data[0]; + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(sprite->data[0], 16 - sprite->data[0])); + + if (sprite->data[0] == 0) + { + sprite->invisible = TRUE; + sprite->callback = sub_80B4344; + } + } +} + +static void sub_80B4344(struct Sprite *sprite) +{ + SetGpuReg(REG_OFFSET_BLDCNT, 0); + SetGpuReg(REG_OFFSET_BLDALPHA, 0); + DestroyAnimSprite(sprite); +} + +// Translates a stinger sprite linearly to a destination location. The sprite is +// initially rotated so that it appears to be traveling in a straight line. +// arg 0: initial x pixel offset +// arg 1: initial y pixel offset +// arg 2: target x pixel offset +// arg 3: target y pixel offset +// arg 4: duration +static void AnimTranslateStinger(struct Sprite *sprite) +{ + s16 lVarX, lVarY; + u16 rot; + + if (IsContest()) + { + gBattleAnimArgs[2] = -gBattleAnimArgs[2]; + } + else if (GetBattlerSide(gBattleAnimAttacker)) + { + gBattleAnimArgs[2] = -gBattleAnimArgs[2]; + gBattleAnimArgs[1] = -gBattleAnimArgs[1]; + gBattleAnimArgs[3] = -gBattleAnimArgs[3]; + } + if (!IsContest() && GetBattlerSide(gBattleAnimAttacker) == GetBattlerSide(gBattleAnimTarget)) + { + if (GetBattlerPosition(gBattleAnimTarget) == B_POSITION_PLAYER_LEFT + || GetBattlerPosition(gBattleAnimTarget) == B_POSITION_OPPONENT_LEFT) + { + s16 temp1, temp2; + + temp1 = gBattleAnimArgs[2]; + gBattleAnimArgs[2] = -temp1; + + temp2 = gBattleAnimArgs[0]; + gBattleAnimArgs[0] = -temp2; + } + } + InitSpritePosToAnimAttacker(sprite, 1); + lVarX = GetBattlerSpriteCoord(gBattleAnimTarget, 2) + gBattleAnimArgs[2]; + lVarY = GetBattlerSpriteCoord(gBattleAnimTarget, 3) + gBattleAnimArgs[3]; + rot = ArcTan2Neg(lVarX - sprite->pos1.x, lVarY - sprite->pos1.y); + rot += 0xC000; + TrySetSpriteRotScale(sprite, FALSE, 0x100, 0x100, rot); + sprite->data[0] = gBattleAnimArgs[4]; + sprite->data[2] = lVarX; + sprite->data[4] = lVarY; + sprite->callback = StartAnimLinearTranslation; + StoreSpriteCallbackInData6(sprite, DestroyAnimSprite); +} + +// Rotates sprite and moves it in an arc, so that it appears like a missle or arrow traveling. +// arg 0: initial x pixel offset +// arg 1: initial y pixel offset +// arg 2: target x pixel offset +// arg 3: target y pixel offset +// arg 4: duration +// arg 5: wave amplitude +static void AnimMissileArc(struct Sprite *sprite) +{ + InitSpritePosToAnimAttacker(sprite, 1); + if (GetBattlerSide(gBattleAnimAttacker)) + gBattleAnimArgs[2] = -gBattleAnimArgs[2]; + sprite->data[0] = gBattleAnimArgs[4]; + sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, 2) + gBattleAnimArgs[2]; + sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, 3) + gBattleAnimArgs[3]; + sprite->data[5] = gBattleAnimArgs[5]; + InitAnimArcTranslation(sprite); + sprite->callback = AnimMissileArcStep; + sprite->invisible = TRUE; +} + +static void AnimMissileArcStep(struct Sprite *sprite) +{ + sprite->invisible = FALSE; + + if (TranslateAnimHorizontalArc(sprite)) + { + DestroyAnimSprite(sprite); + } + else + { + s16 tempData[8]; + u16 *data = sprite->data; + u16 x1 = sprite->pos1.x; + s16 x2 = sprite->pos2.x; + u16 y1 = sprite->pos1.y; + s16 y2 = sprite->pos2.y; + s32 i; + + for (i = 0; i < 8; ++i) + tempData[i] = data[i]; + x2 += x1; + y2 += y1; + if (!TranslateAnimHorizontalArc(sprite)) + { + u16 rotation = ArcTan2Neg(sprite->pos1.x + sprite->pos2.x - x2, + sprite->pos1.y + sprite->pos2.y - y2); + + rotation += 0xC000; + TrySetSpriteRotScale(sprite, FALSE, 0x100, 0x100, rotation); + for (i = 0; i < 8; ++i) + data[i] = tempData[i]; + } + } +} + +static void sub_80B45D8(struct Sprite *sprite) +{ + if (gBattleAnimArgs[0] == 0) + { + sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 2); + sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, 3) + 18; + } + else + { + sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimTarget, 2); + sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimTarget, 3) + 18; + } + StoreSpriteCallbackInData6(sprite, DestroySpriteAndMatrix); + sprite->callback = RunStoredCallbackWhenAffineAnimEnds; +} diff --git a/src/dark.c b/src/dark.c new file mode 100644 index 000000000..cb34b991e --- /dev/null +++ b/src/dark.c @@ -0,0 +1,921 @@ +#include "global.h" +#include "battle_anim.h" +#include "gpu_regs.h" +#include "graphics.h" +#include "palette.h" +#include "scanline_effect.h" +#include "trig.h" +#include "util.h" + +static void sub_80B7ACC(struct Sprite *sprite); +static void sub_80B7BD4(struct Sprite *sprite); +static void sub_80B7C88(struct Sprite *sprite); +static void sub_80B86B0(struct Sprite *sprite); +static void sub_80B7954(u8 taskId); +static void sub_80B7A14(u8 taskId); +static void sub_80B7B48(struct Sprite *sprite); +static void sub_80B7C10(struct Sprite *sprite); +static void sub_80B7C50(struct Sprite *sprite); +static void sub_80B7D88(struct Sprite *sprite); +static void sub_80B856C(u8 priority); +static void sub_80B7F58(u8 taskId); +static void sub_80B843C(struct Task *task); +static void sub_80B82C0(u8 taskId); +static void sub_80B8920(u8 taskId); + +const struct SpriteTemplate gUnknown_83E7878 = +{ + .tileTag = ANIM_TAG_TIED_BAG, + .paletteTag = ANIM_TAG_TIED_BAG, + .oam = &gOamData_83AC9D0, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_80B7ACC, +}; + +static const union AffineAnimCmd gUnknown_83E7890[] = +{ + AFFINEANIMCMD_FRAME(0x0, 0x0, 0, 1), + AFFINEANIMCMD_END, +}; + +static const union AffineAnimCmd gUnknown_83E78A0[] = +{ + AFFINEANIMCMD_FRAME(0x0, 0x0, 32, 1), + AFFINEANIMCMD_END, +}; + +static const union AffineAnimCmd gUnknown_83E78B0[] = +{ + AFFINEANIMCMD_FRAME(0x0, 0x0, 64, 1), + AFFINEANIMCMD_END, +}; + +static const union AffineAnimCmd gUnknown_83E78C0[] = +{ + AFFINEANIMCMD_FRAME(0x0, 0x0, 96, 1), + AFFINEANIMCMD_END, +}; + +static const union AffineAnimCmd gUnknown_83E78D0[] = +{ + AFFINEANIMCMD_FRAME(0x0, 0x0, -128, 1), + AFFINEANIMCMD_END, +}; + +static const union AffineAnimCmd gUnknown_83E78E0[] = +{ + AFFINEANIMCMD_FRAME(0x0, 0x0, -96, 1), + AFFINEANIMCMD_END, +}; + +static const union AffineAnimCmd gUnknown_83E78F0[] = +{ + AFFINEANIMCMD_FRAME(0x0, 0x0, -64, 1), + AFFINEANIMCMD_END, +}; + +static const union AffineAnimCmd gUnknown_83E7900[] = +{ + AFFINEANIMCMD_FRAME(0x0, 0x0, -32, 1), + AFFINEANIMCMD_END, +}; + +static const union AffineAnimCmd *const gUnknown_83E7910[] = +{ + gUnknown_83E7890, + gUnknown_83E78A0, + gUnknown_83E78B0, + gUnknown_83E78C0, + gUnknown_83E78D0, + gUnknown_83E78E0, + gUnknown_83E78F0, + gUnknown_83E7900, +}; + +const struct SpriteTemplate gUnknown_83E7930 = +{ + .tileTag = ANIM_TAG_SHARP_TEETH, + .paletteTag = ANIM_TAG_SHARP_TEETH, + .oam = &gOamData_83ACB60, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gUnknown_83E7910, + .callback = sub_80B7BD4, +}; + +const struct SpriteTemplate gUnknown_83E7948 = +{ + .tileTag = ANIM_TAG_CLAMP, + .paletteTag = ANIM_TAG_CLAMP, + .oam = &gOamData_83ACB60, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gUnknown_83E7910, + .callback = sub_80B7BD4, +}; + +static const union AffineAnimCmd gUnknown_83E7960[] = +{ + AFFINEANIMCMD_FRAME(0xC0, 0xC0, 80, 0), + AFFINEANIMCMD_FRAME(0x0, 0x0, -2, 8), + AFFINEANIMCMD_END, +}; + +static const union AffineAnimCmd gUnknown_83E7978[] = +{ + AFFINEANIMCMD_FRAME(0xC0, 0xC0, -80, 0), + AFFINEANIMCMD_FRAME(0x0, 0x0, 2, 8), + AFFINEANIMCMD_END, +}; + +static const union AffineAnimCmd *const gUnknown_83E7990[] = +{ + gUnknown_83E7960, + gUnknown_83E7978, +}; + +const struct SpriteTemplate gUnknown_83E7998 = +{ + .tileTag = ANIM_TAG_SMALL_BUBBLES, + .paletteTag = ANIM_TAG_SMALL_BUBBLES, + .oam = &gOamData_83ACA30, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gUnknown_83E7990, + .callback = sub_80B7C88, +}; + +static const union AnimCmd gUnknown_83E79B0[] = +{ + ANIMCMD_FRAME(0, 4), + ANIMCMD_FRAME(16, 4), + ANIMCMD_FRAME(32, 4), + ANIMCMD_FRAME(48, 4), + ANIMCMD_FRAME(64, 4), + ANIMCMD_END, +}; + +static const union AnimCmd gUnknown_83E79C8[] = +{ + ANIMCMD_FRAME(0, 4, .hFlip = TRUE), + ANIMCMD_FRAME(16, 4, .hFlip = TRUE), + ANIMCMD_FRAME(32, 4, .hFlip = TRUE), + ANIMCMD_FRAME(48, 4, .hFlip = TRUE), + ANIMCMD_FRAME(64, 4, .hFlip = TRUE), + ANIMCMD_END, +}; + +static const union AnimCmd *const gUnknown_83E79E0[] = +{ + gUnknown_83E79B0, + gUnknown_83E79C8, +}; + +const struct SpriteTemplate gUnknown_83E79E8 = +{ + .tileTag = ANIM_TAG_CLAW_SLASH, + .paletteTag = ANIM_TAG_CLAW_SLASH, + .oam = &gOamData_83AC9D8, + .anims = gUnknown_83E79E0, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_80B86B0, +}; + +void sub_80B78E0(u8 taskId) +{ + s32 battler; + + gTasks[taskId].data[0] = gBattleAnimArgs[0]; + battler = gBattleAnimAttacker; + gTasks[taskId].data[1] = 16; + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(16, 0)); + if (GetBattlerSpriteBGPriorityRank(battler) == 1) + SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND | BLDCNT_TGT1_BG1); + else + SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND | BLDCNT_TGT1_BG2); + gTasks[taskId].func = sub_80B7954; +} + +static void sub_80B7954(u8 taskId) +{ + u8 blendA = gTasks[taskId].data[1] >> 8; + u8 blendB = gTasks[taskId].data[1]; + + if (gTasks[taskId].data[2] == (u8)gTasks[taskId].data[0]) + { + ++blendA; + --blendB; + gTasks[taskId].data[1] = BLDALPHA_BLEND(blendB, blendA); + SetGpuReg(REG_OFFSET_BLDALPHA, gTasks[taskId].data[1]); + gTasks[taskId].data[2] = 0; + if (blendA == 16) + { + gSprites[gBattlerSpriteIds[gBattleAnimAttacker]].invisible = TRUE; + DestroyAnimVisualTask(taskId); + } + } + else + { + ++gTasks[taskId].data[2]; + } +} + +void sub_80B79DC(u8 taskId) +{ + gTasks[taskId].data[0] = gBattleAnimArgs[0]; + gTasks[taskId].data[1] = BLDALPHA_BLEND(0, 16); + gTasks[taskId].func = sub_80B7A14; + SetGpuReg(REG_OFFSET_BLDALPHA, gTasks[taskId].data[1]); +} + +static void sub_80B7A14(u8 taskId) +{ + u8 blendA = gTasks[taskId].data[1] >> 8; + u8 blendB = gTasks[taskId].data[1]; + + if (gTasks[taskId].data[2] == (u8)gTasks[taskId].data[0]) + { + --blendA; + ++blendB; + gTasks[taskId].data[1] = (blendA << 8) | blendB; + SetGpuReg(REG_OFFSET_BLDALPHA, gTasks[taskId].data[1]); + gTasks[taskId].data[2] = 0; + if (blendA == 0) + { + SetGpuReg(REG_OFFSET_BLDCNT, 0); + SetGpuReg(REG_OFFSET_BLDALPHA, 0); + DestroyAnimVisualTask(taskId); + } + } + else + { + ++gTasks[taskId].data[2]; + } +} + +void sub_80B7A80(u8 taskId) +{ + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0, 16)); + if (GetBattlerSpriteBGPriorityRank(gBattleAnimAttacker) == 1) + SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND | BLDCNT_TGT1_BG1); + else + SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND | BLDCNT_TGT1_BG2); + DestroyAnimVisualTask(taskId); +} + +static void sub_80B7ACC(struct Sprite *sprite) +{ + sprite->data[1] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2); + sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2); + sprite->data[3] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET); + sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET); + sprite->data[0] = 0x7E; + InitSpriteDataForLinearTranslation(sprite); + sprite->data[3] = -sprite->data[1]; + sprite->data[4] = -sprite->data[2]; + sprite->data[6] = 0xFFD8; + sprite->callback = sub_80B7B48; + sprite->callback(sprite); +} + +static void sub_80B7B48(struct Sprite *sprite) +{ + sprite->data[3] += sprite->data[1]; + sprite->data[4] += sprite->data[2]; + sprite->pos2.x = sprite->data[3] >> 8; + sprite->pos2.y = sprite->data[4] >> 8; + if (sprite->data[7] == 0) + { + sprite->data[3] += sprite->data[1]; + sprite->data[4] += sprite->data[2]; + sprite->pos2.x = sprite->data[3] >> 8; + sprite->pos2.y = sprite->data[4] >> 8; + --sprite->data[0]; + } + sprite->pos2.y += Sin(sprite->data[5], sprite->data[6]); + sprite->data[5] = (sprite->data[5] + 3) & 0xFF; + if (sprite->data[5] > 0x7F) + { + sprite->data[5] = 0; + sprite->data[6] += 20; + ++sprite->data[7]; + } + if (--sprite->data[0] == 0) + DestroyAnimSprite(sprite); +} + +static void sub_80B7BD4(struct Sprite *sprite) +{ + sprite->pos1.x += gBattleAnimArgs[0]; + sprite->pos1.y += gBattleAnimArgs[1]; + StartSpriteAffineAnim(sprite, gBattleAnimArgs[2]); + sprite->data[0] = gBattleAnimArgs[3]; + sprite->data[1] = gBattleAnimArgs[4]; + sprite->data[2] = gBattleAnimArgs[5]; + sprite->callback = sub_80B7C10; +} + +static void sub_80B7C10(struct Sprite *sprite) +{ + sprite->data[4] += sprite->data[0]; + sprite->data[5] += sprite->data[1]; + sprite->pos2.x = sprite->data[4] >> 8; + sprite->pos2.y = sprite->data[5] >> 8; + if (++sprite->data[3] == sprite->data[2]) + sprite->callback = sub_80B7C50; +} + +static void sub_80B7C50(struct Sprite *sprite) +{ + sprite->data[4] -= sprite->data[0]; + sprite->data[5] -= sprite->data[1]; + sprite->pos2.x = sprite->data[4] >> 8; + sprite->pos2.y = sprite->data[5] >> 8; + if (--sprite->data[3] == 0) + DestroySpriteAndMatrix(sprite); +} + +static void sub_80B7C88(struct Sprite *sprite) +{ + u8 battler; + s8 xOffset; + + if (gBattleAnimArgs[0] == 0) + battler = gBattleAnimAttacker; + else + battler = gBattleAnimTarget; + xOffset = 20; + sprite->oam.tileNum += 4; + switch (gBattleAnimArgs[1]) + { + case 0: + sprite->pos1.x = GetBattlerSpriteCoordAttr(battler, BATTLER_COORD_ATTR_RIGHT) - 8; + sprite->pos1.y = GetBattlerSpriteCoordAttr(battler, BATTLER_COORD_ATTR_TOP) + 8; + break; + case 1: + sprite->pos1.x = GetBattlerSpriteCoordAttr(battler, BATTLER_COORD_ATTR_RIGHT) - 14; + sprite->pos1.y = GetBattlerSpriteCoordAttr(battler, BATTLER_COORD_ATTR_TOP) + 16; + break; + case 2: + sprite->pos1.x = GetBattlerSpriteCoordAttr(battler, BATTLER_COORD_ATTR_LEFT) + 8; + sprite->pos1.y = GetBattlerSpriteCoordAttr(battler, BATTLER_COORD_ATTR_TOP) + 8; + StartSpriteAffineAnim(sprite, 1); + xOffset = -20; + break; + case 3: + sprite->pos1.x = GetBattlerSpriteCoordAttr(battler, BATTLER_COORD_ATTR_LEFT) + 14; + sprite->pos1.y = GetBattlerSpriteCoordAttr(battler, BATTLER_COORD_ATTR_TOP) + 16; + StartSpriteAffineAnim(sprite, 1); + xOffset = -20; + break; + } + sprite->data[0] = 32; + sprite->data[2] = sprite->pos1.x + xOffset; + sprite->data[4] = sprite->pos1.y + 12; + sprite->data[5] = -12; + InitAnimArcTranslation(sprite); + sprite->callback = sub_80B7D88; +} + +static void sub_80B7D88(struct Sprite *sprite) +{ + if (TranslateAnimHorizontalArc(sprite)) + DestroySpriteAndMatrix(sprite); +} + +void sub_80B7DA4(u8 taskId) +{ + struct ScanlineEffectParams scanlineParams; + struct BattleAnimBgData animBg; + u16 i; + u8 pos; + s32 var0; + struct Task *task = &gTasks[taskId]; + + task->data[7] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y) + 31; + task->data[6] = GetBattlerSpriteCoordAttr(gBattleAnimAttacker, BATTLER_COORD_ATTR_TOP) - 7; + task->data[5] = task->data[7]; + task->data[4] = task->data[6]; + task->data[13] = (task->data[7] - task->data[6]) << 8; + pos = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X); + task->data[14] = pos - 32; + task->data[15] = pos + 32; + if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER) + task->data[8] = -12; + else + task->data[8] = -64; + task->data[3] = GetBattlerSpriteBGPriorityRank(gBattleAnimAttacker); + if (task->data[3] == 1) + { + sub_80752A0(&animBg); + task->data[10] = gBattle_BG1_Y; + SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND | BLDCNT_TGT1_BG1); + FillPalette(0, animBg.paletteId * 16, 32); + scanlineParams.dmaDest = ®_BG1VOFS; + var0 = WINOUT_WIN01_BG1; + if (!IsContest()) + gBattle_BG2_X += 240; + } + else + { + task->data[10] = gBattle_BG2_Y; + SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND | BLDCNT_TGT1_BG2); + FillPalette(0, 144, 32); + scanlineParams.dmaDest = ®_BG2VOFS; + var0 = WINOUT_WIN01_BG2; + if (!IsContest()) + gBattle_BG1_X += 240; + } + scanlineParams.dmaControl = SCANLINE_EFFECT_DMACNT_16BIT; + scanlineParams.initState = 1; + scanlineParams.unused9 = 0; + task->data[11] = 0; + task->data[12] = 16; + task->data[0] = 0; + task->data[1] = 0; + task->data[2] = 0; + sub_80B856C(3); + for (i = 0; i < 112; ++i) + { + gScanlineEffectRegBuffers[0][i] = task->data[10]; + gScanlineEffectRegBuffers[1][i] = task->data[10]; + } + ScanlineEffect_SetParams(scanlineParams); + SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ | WINOUT_WINOBJ_CLR | (var0 ^ (WINOUT_WIN01_BG_ALL | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR))); + SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR | WININ_WIN1_BG_ALL | WININ_WIN1_OBJ | WININ_WIN1_CLR); + gBattle_WIN0H = (task->data[14] << 8) | task->data[15]; + gBattle_WIN0V = 160; + + task->func = sub_80B7F58; +} + +static void sub_80B7F58(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + + switch (task->data[0]) + { + case 0: + if (++task->data[1] > 1) + { + task->data[1] = 0; + if (++task->data[2] & 1) + { + if (task->data[11] != 12) + ++task->data[11]; + } + else if (task->data[12] != 8) + { + --task->data[12]; + } + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(task->data[11], task->data[12])); + if (task->data[11] == 12 && task->data[12] == 8) + ++task->data[0]; + } + break; + case 1: + task->data[4] -= 8; + sub_80B843C(task); + if (task->data[4] < task->data[8]) + ++task->data[0]; + break; + case 2: + task->data[4] -= 8; + sub_80B843C(task); + task->data[14] += 4; + task->data[15] -= 4; + if (task->data[14] >= task->data[15]) + task->data[14] = task->data[15]; + gBattle_WIN0H = (task->data[14] << 8) | task->data[15]; + if (task->data[14] == task->data[15]) + ++task->data[0]; + break; + case 3: + gScanlineEffect.state = 3; + ++task->data[0]; + break; + case 4: + DestroyAnimVisualTask(taskId); + break; + } +} + +void sub_80B8070(u8 taskId) +{ + struct BattleAnimBgData animBg; + struct ScanlineEffectParams scanlineParams; + u8 x; + u16 i; + struct Task *task = &gTasks[taskId]; + + switch (task->data[0]) + { + case 0: + if (IsContest() == TRUE) + { + gBattle_WIN0H = 0; + gBattle_WIN0V = 0; + SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR | WININ_WIN1_BG_ALL | WININ_WIN1_OBJ | WININ_WIN1_CLR); + SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ | WINOUT_WINOBJ_CLR | WINOUT_WIN01_BG_ALL | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR); + DestroyAnimVisualTask(taskId); + } + else + { + task->data[3] = GetBattlerSpriteBGPriorityRank(gBattleAnimTarget); + if (task->data[3] == 1) + { + SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND | BLDCNT_TGT1_BG1); + gBattle_BG2_X += 240; + } + else + { + SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND | BLDCNT_TGT1_BG2); + gBattle_BG1_X += 240; + } + ++task->data[0]; + } + break; + case 1: + if (task->data[3] == 1) + { + sub_80752A0(&animBg); + task->data[10] = gBattle_BG1_Y; + FillPalette(0, animBg.paletteId * 16, 32); + } + else + { + task->data[10] = gBattle_BG2_Y; + FillPalette(0, 9 * 16, 32); + } + sub_80B856C(3); + ++task->data[0]; + break; + case 2: + task->data[7] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y) + 31; + task->data[6] = GetBattlerSpriteCoordAttr(gBattleAnimTarget, BATTLER_COORD_ATTR_TOP) - 7; + task->data[13] = (task->data[7] - task->data[6]) << 8; + x = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X); + task->data[14] = x - 4; + task->data[15] = x + 4; + if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER) + task->data[8] = -12; + else + task->data[8] = -64; + task->data[4] = task->data[8]; + task->data[5] = task->data[8]; + task->data[11] = 12; + task->data[12] = 8; + ++task->data[0]; + break; + case 3: + if (task->data[3] == 1) + scanlineParams.dmaDest = ®_BG1VOFS; + else + scanlineParams.dmaDest = ®_BG2VOFS; + for (i = 0; i < 112; ++i) + { + gScanlineEffectRegBuffers[0][i] = task->data[10] + (159 - i); + gScanlineEffectRegBuffers[1][i] = task->data[10] + (159 - i); + } + scanlineParams.dmaControl = SCANLINE_EFFECT_DMACNT_16BIT; + scanlineParams.initState = 1; + scanlineParams.unused9 = 0; + ScanlineEffect_SetParams(scanlineParams); + ++task->data[0]; + break; + case 4: + if (task->data[3] == 1) + SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ | WINOUT_WINOBJ_CLR | WINOUT_WIN01_BG0 | WINOUT_WIN01_BG2 | WINOUT_WIN01_BG3 | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR); + else + SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ | WINOUT_WINOBJ_CLR | WINOUT_WIN01_BG0 | WINOUT_WIN01_BG1 | WINOUT_WIN01_BG3 | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR); + SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR | WININ_WIN1_BG_ALL | WININ_WIN1_OBJ | WININ_WIN1_CLR); + gBattle_WIN0H = (task->data[14] << 8) | task->data[15]; + gBattle_WIN0V = 160; + task->data[0] = 0; + task->data[1] = 0; + task->data[2] = 0; + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(12, 8)); + task->func = sub_80B82C0; + break; + } +} + +static void sub_80B82C0(u8 taskId) +{ + u8 pos; + u16 i; + struct Task *task = &gTasks[taskId]; + + switch (task->data[0]) + { + case 0: + task->data[5] += 8; + if (task->data[5] >= task->data[7]) + task->data[5] = task->data[7]; + sub_80B843C(task); + if (task->data[5] == task->data[7]) + ++task->data[0]; + break; + case 1: + if (task->data[15] - task->data[14] < 0x40) + { + task->data[14] -= 4; + task->data[15] += 4; + } + else + { + task->data[1] = 1; + } + gBattle_WIN0H = (task->data[14] << 8) | task->data[15]; + task->data[4] += 8; + if (task->data[4] >= task->data[6]) + task->data[4] = task->data[6]; + sub_80B843C(task); + if (task->data[4] == task->data[6] && task->data[1]) + { + task->data[1] = 0; + ++task->data[0]; + } + break; + case 2: + if (++task->data[1] > 1) + { + task->data[1] = 0; + ++task->data[2]; + if (task->data[2] & 1) + { + if (task->data[11]) + --task->data[11]; + } + else if (task->data[12] < 16) + { + ++task->data[12]; + } + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(task->data[11], task->data[12])); + if (task->data[11] == 0 && task->data[12] == 16) + ++task->data[0]; + } + break; + case 3: + gScanlineEffect.state = 3; + ++task->data[0]; + break; + case 4: + gBattle_WIN0H = 0; + gBattle_WIN0V = 0; + SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR | WININ_WIN1_BG_ALL | WININ_WIN1_OBJ | WININ_WIN1_CLR); + SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ | WINOUT_WINOBJ_CLR | WINOUT_WIN01_BG_ALL | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR); + DestroyAnimVisualTask(taskId); + break; + } +} + +static void sub_80B843C(struct Task *task) +{ + s32 var0, var1, var4; + s16 var2, i; + + var2 = task->data[5] - task->data[4]; + if (var2 != 0) + { + var0 = task->data[13] / var2; + var1 = task->data[6] << 8; + for (i = 0; i < task->data[4]; ++i) + gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer][i] = task->data[10] - (i - 159); + for (i = task->data[4]; i <= task->data[5]; ++i) + { + if (i >= 0) + { + s16 var3 = (var1 >> 8) - i; + + gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer][i] = var3 + task->data[10]; + } + var1 += var0; + } + var4 = task->data[10] - (i - 159); + for (; i < task->data[7]; ++i) + if (i >= 0) + gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer][i] = var4--; + } + else + { + var4 = task->data[10] + 159; + for (i = 0; i < 112; ++i) + { + gScanlineEffectRegBuffers[0][i] = var4; + gScanlineEffectRegBuffers[1][i] = var4; + --var4; + } + } +} + +static void sub_80B856C(u8 priority) +{ + u16 i; + + for (i = 0; i < MAX_BATTLERS_COUNT; ++i) + { + u8 spriteId = GetAnimBattlerSpriteId(i); + + if (spriteId != 0xFF) + gSprites[spriteId].oam.priority = priority; + } +} + +void sub_80B85B8(u8 taskId) +{ + bool8 toBG2 = GetBattlerSpriteBGPriorityRank(gBattleAnimAttacker) ^ 1 ? TRUE : FALSE; + + MoveBattlerSpriteToBG(gBattleAnimAttacker, toBG2); + gSprites[gBattlerSpriteIds[gBattleAnimAttacker]].invisible = FALSE; + if (IsBattlerSpriteVisible(BATTLE_PARTNER(gBattleAnimAttacker))) + { + MoveBattlerSpriteToBG(gBattleAnimAttacker ^ 2, toBG2 ^ 1); + gSprites[gBattlerSpriteIds[gBattleAnimAttacker ^ 2]].invisible = FALSE; + } + DestroyAnimVisualTask(taskId); +} + +void sub_80B8664(u8 taskId) +{ + bool8 toBG2 = GetBattlerSpriteBGPriorityRank(gBattleAnimAttacker) ^ 1 ? TRUE : FALSE; + + sub_8073128(toBG2); + if (IsBattlerSpriteVisible(BATTLE_PARTNER(gBattleAnimAttacker))) + sub_8073128(toBG2 ^ 1); + DestroyAnimVisualTask(taskId); +} + +static void sub_80B86B0(struct Sprite *sprite) +{ + sprite->pos1.x += gBattleAnimArgs[0]; + sprite->pos1.y += gBattleAnimArgs[1]; + StartSpriteAnim(sprite, gBattleAnimArgs[2]); + sprite->callback = RunStoredCallbackWhenAnimEnds; + StoreSpriteCallbackInData6(sprite, DestroyAnimSprite); +} + +// Makes the attacker metallic and shining. +// Used by MOVE_HARDEN and MOVE_IRON_DEFENSE. +// arg0: if true won't change battler's palette back +// arg1: if true, use custom color +// arg2: custom color +// Custom color argument is used in MOVE_POISON_TAIL to make the mon turn purplish/pinkish as if became cloaked in poison. +void AnimTask_MetallicShine(u8 taskId) +{ + u16 species; + u8 spriteId, newSpriteId; + u16 paletteNum; + struct BattleAnimBgData animBg; + bool32 priorityChanged = FALSE; + + gBattle_WIN0H = 0; + gBattle_WIN0V = 0; + SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR | WININ_WIN1_BG_ALL | WININ_WIN1_OBJ | WININ_WIN1_CLR); + SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ | WINOUT_WINOBJ_CLR | WINOUT_WIN01_BG0 | WINOUT_WIN01_BG2 | WINOUT_WIN01_BG3 | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR); + SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_OBJWIN_ON); + SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND | BLDCNT_TGT1_BG1); + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(8, 12)); + SetAnimBgAttribute(1, BG_ANIM_PRIORITY, 0); + SetAnimBgAttribute(1, BG_ANIM_SCREEN_SIZE, 0); + if (!IsContest()) + SetAnimBgAttribute(1, BG_ANIM_CHAR_BASE_BLOCK, 1); + if (IsDoubleBattle() && !IsContest()) + { + if (GetBattlerPosition(gBattleAnimAttacker) == B_POSITION_OPPONENT_RIGHT || GetBattlerPosition(gBattleAnimAttacker) == B_POSITION_PLAYER_LEFT) + { + if (IsBattlerSpriteVisible(BATTLE_PARTNER(gBattleAnimAttacker)) == TRUE) + { + gSprites[gBattlerSpriteIds[BATTLE_PARTNER(gBattleAnimAttacker)]].oam.priority--; + SetAnimBgAttribute(1, BG_ANIM_PRIORITY, 1); + priorityChanged = TRUE; + } + } + } + if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) + species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattleAnimAttacker]], MON_DATA_SPECIES); + else + species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattleAnimAttacker]], MON_DATA_SPECIES); + spriteId = GetAnimBattlerSpriteId(ANIM_ATTACKER); + newSpriteId = sub_8076E34(gBattleAnimAttacker, spriteId, species); + sub_80752A0(&animBg); + AnimLoadCompressedBgTilemap(animBg.bgId, gMetalShineTilemap); + AnimLoadCompressedBgGfx(animBg.bgId, gMetalShineGfx, animBg.tilesOffset); + LoadCompressedPalette(gMetalShinePalette, animBg.paletteId * 16, 32); + gBattle_BG1_X = -gSprites[spriteId].pos1.x + 96; + gBattle_BG1_Y = -gSprites[spriteId].pos1.y + 32; + paletteNum = 16 + gSprites[spriteId].oam.paletteNum; + if (gBattleAnimArgs[1] == 0) + SetGreyscaleOrOriginalPalette(paletteNum, FALSE); + else + BlendPalette(paletteNum * 16, 16, 11, gBattleAnimArgs[2]); + gTasks[taskId].data[0] = newSpriteId; + gTasks[taskId].data[1] = gBattleAnimArgs[0]; + gTasks[taskId].data[2] = gBattleAnimArgs[1]; + gTasks[taskId].data[3] = gBattleAnimArgs[2]; + gTasks[taskId].data[6] = priorityChanged; + gTasks[taskId].func = sub_80B8920; +} + +static void sub_80B8920(u8 taskId) +{ + struct BattleAnimBgData animBg; + u16 paletteNum; + u8 spriteId; + + gTasks[taskId].data[10] += 4; + gBattle_BG1_X -= 4; + if (gTasks[taskId].data[10] == 128) + { + gTasks[taskId].data[10] = 0; + gBattle_BG1_X += 128; + gTasks[taskId].data[11]++; + if (gTasks[taskId].data[11] == 2) + { + spriteId = GetAnimBattlerSpriteId(ANIM_ATTACKER); + paletteNum = 16 + gSprites[spriteId].oam.paletteNum; + if (gTasks[taskId].data[1] == 0) + SetGreyscaleOrOriginalPalette(paletteNum, 1); + DestroySprite(&gSprites[gTasks[taskId].data[0]]); + sub_80752A0(&animBg); + sub_8075358(animBg.bgId); + if (gTasks[taskId].data[6] == 1) + gSprites[gBattlerSpriteIds[BATTLE_PARTNER(gBattleAnimAttacker)]].oam.priority++; + } + else if (gTasks[taskId].data[11] == 3) + { + gBattle_WIN0H = 0; + gBattle_WIN0V = 0; + SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR | WININ_WIN1_BG_ALL | WININ_WIN1_OBJ | WININ_WIN1_CLR); + SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ | WINOUT_WINOBJ_CLR | WINOUT_WIN01_BG_ALL | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR); + if (!IsContest()) + SetAnimBgAttribute(1, BG_ANIM_CHAR_BASE_BLOCK, 0); + SetGpuReg(REG_OFFSET_DISPCNT, GetGpuReg(REG_OFFSET_DISPCNT) ^ DISPCNT_OBJWIN_ON); + SetGpuReg(REG_OFFSET_BLDCNT, 0); + SetGpuReg(REG_OFFSET_BLDALPHA, 0); + DestroyAnimVisualTask(taskId); + } + } +} + +// Changes battler's palette to either greyscale or original. +// arg0: which battler +// arg1: 0 grayscale, 1 original +void AnimTask_SetGreyscaleOrOriginalPal(u8 taskId) +{ + u8 spriteId, battler; + bool8 calcSpriteId = FALSE; + u8 position = B_POSITION_PLAYER_LEFT; + + switch (gBattleAnimArgs[0]) + { + case 0: + case 1: + case 2: + case 3: + spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[0]); + break; + case 4: + position = B_POSITION_PLAYER_LEFT; + calcSpriteId = TRUE; + break; + case 5: + position = B_POSITION_PLAYER_RIGHT; + calcSpriteId = TRUE; + break; + case 6: + position = B_POSITION_OPPONENT_LEFT; + calcSpriteId = TRUE; + break; + case 7: + position = B_POSITION_OPPONENT_RIGHT; + calcSpriteId = TRUE; + break; + default: + spriteId = 0xFF; + break; + } + if (calcSpriteId) + { + battler = GetBattlerAtPosition(position); + if (IsBattlerSpriteVisible(battler)) + spriteId = gBattlerSpriteIds[battler]; + else + spriteId = 0xFF; + } + if (spriteId != 0xFF) + SetGreyscaleOrOriginalPalette(gSprites[spriteId].oam.paletteNum + 16, gBattleAnimArgs[1]); + DestroyAnimVisualTask(taskId); +} + +void sub_80B8B38(u8 taskId) +{ + if (gAnimMoveTurn < 2) + gBattleAnimArgs[7] = 0; + if (gAnimMoveTurn == 2) + gBattleAnimArgs[7] = 1; + DestroyAnimVisualTask(taskId); +} diff --git a/src/daycare.c b/src/daycare.c index 837a2c4e6..fede86156 100644 --- a/src/daycare.c +++ b/src/daycare.c @@ -2087,7 +2087,7 @@ struct UnkStruct_82349CC u8 field_3; }; -extern const struct UnkStruct_82349CC gUnknown_82349CC[NUM_SPECIES]; +extern const struct UnkStruct_82349CC gMonFrontPicCoords[NUM_SPECIES]; static void SpriteCB_Egg_2(struct Sprite* sprite) { @@ -2101,7 +2101,7 @@ static void SpriteCB_Egg_2(struct Sprite* sprite) sprite->data[0] = 0; species = GetMonData(&gPlayerParty[sEggHatchData->eggPartyID], MON_DATA_SPECIES); gSprites[sEggHatchData->pokeSpriteID].pos2.x = 0; - gSprites[sEggHatchData->pokeSpriteID].pos2.y = gUnknown_82349CC[species].field_1; + gSprites[sEggHatchData->pokeSpriteID].pos2.y = gMonFrontPicCoords[species].field_1; } else { diff --git a/src/dragon.c b/src/dragon.c new file mode 100644 index 000000000..34f97ba74 --- /dev/null +++ b/src/dragon.c @@ -0,0 +1,431 @@ +#include "global.h" +#include "battle_anim.h" +#include "scanline_effect.h" +#include "task.h" +#include "trig.h" + +static void sub_80B725C(struct Sprite *sprite); +static void sub_80B741C(struct Sprite *sprite); +static void sub_80B73AC(struct Sprite *sprite); +static void sub_80B7448(struct Sprite *sprite); +static void sub_80B77E4(struct Sprite *sprite); +static void sub_80B74D8(struct Sprite *sprite); +static void sub_80B76B0(u8 taskId); +static void sub_80B776C(struct Task *task); +static void sub_80B7894(struct Sprite *sprite); + +static EWRAM_DATA u16 gUnknown_20399A4[7] = {0}; + +static const union AnimCmd gUnknown_83E7710[] = +{ + ANIMCMD_FRAME(0, 4), + ANIMCMD_FRAME(16, 4), + ANIMCMD_FRAME(32, 4), + ANIMCMD_FRAME(48, 4), + ANIMCMD_FRAME(64, 4), + ANIMCMD_JUMP(0), +}; + +static const union AnimCmd *const gUnknown_83E7728[] = +{ + gUnknown_83E7710, +}; + +const struct SpriteTemplate gUnknown_83E772C = +{ + .tileTag = ANIM_TAG_SMALL_EMBER, + .paletteTag = ANIM_TAG_SMALL_EMBER, + .oam = &gOamData_83AC9D8, + .anims = gUnknown_83E7728, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_80B725C, +}; + +static const union AnimCmd gUnknown_83E7744[] = +{ + ANIMCMD_FRAME(16, 3), + ANIMCMD_FRAME(32, 3), + ANIMCMD_FRAME(48, 3), + ANIMCMD_JUMP(0), +}; + +static const union AnimCmd gUnknown_83E7754[] = +{ + ANIMCMD_FRAME(16, 3, .vFlip = TRUE, .hFlip = TRUE), + ANIMCMD_FRAME(32, 3, .vFlip = TRUE, .hFlip = TRUE), + ANIMCMD_FRAME(48, 3, .vFlip = TRUE, .hFlip = TRUE), + ANIMCMD_JUMP(0), +}; + +static const union AnimCmd *const gUnknown_83E7764[] = +{ + gUnknown_83E7744, + gUnknown_83E7754, +}; + +static const union AffineAnimCmd gUnknown_83E776C[] = +{ + AFFINEANIMCMD_FRAME(0x50, 0x50, 127, 0), + AFFINEANIMCMD_FRAME(0xD, 0xD, 0, 100), + AFFINEANIMCMD_END, +}; + +static const union AffineAnimCmd gUnknown_83E7784[] = +{ + AFFINEANIMCMD_FRAME(0x50, 0x50, 0, 0), + AFFINEANIMCMD_FRAME(0xD, 0xD, 0, 100), + AFFINEANIMCMD_END, +}; + +static const union AffineAnimCmd *const gUnknown_83E779C[] = +{ + gUnknown_83E776C, + gUnknown_83E7784, +}; + +const struct SpriteTemplate gUnknown_83E77A4 = +{ + .tileTag = ANIM_TAG_SMALL_EMBER, + .paletteTag = ANIM_TAG_SMALL_EMBER, + .oam = &gOamData_83ACA98, + .anims = gUnknown_83E7764, + .images = NULL, + .affineAnims = gUnknown_83E779C, + .callback = sub_80B741C, +}; + +const union AnimCmd gUnknown_83E77BC[] = +{ + ANIMCMD_FRAME(0, 5), + ANIMCMD_FRAME(16, 5), + ANIMCMD_FRAME(32, 5), + ANIMCMD_FRAME(48, 5), + ANIMCMD_FRAME(64, 5), + ANIMCMD_END, +}; + +static const union AnimCmd *const gUnknown_83E77D4[] = +{ + gUnknown_83E77BC, +}; + +const struct SpriteTemplate gUnknown_83E77D8 = +{ + .tileTag = ANIM_TAG_FIRE_PLUME, + .paletteTag = ANIM_TAG_FIRE_PLUME, + .oam = &gOamData_83AC9D8, + .anims = gUnknown_83E77D4, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_80B73AC, +}; + +static const union AnimCmd gUnknown_83E77F0[] = +{ + ANIMCMD_FRAME(16, 3), + ANIMCMD_FRAME(32, 3), + ANIMCMD_FRAME(48, 3), + ANIMCMD_JUMP(0), +}; + +static const union AnimCmd *const gUnknown_83E7800[] = +{ + gUnknown_83E77F0, + gUnknown_83E77F0, +}; + +static const union AffineAnimCmd gUnknown_83E7808[] = +{ + AFFINEANIMCMD_FRAME(0x64, 0x64, 127, 1), + AFFINEANIMCMD_END, +}; + +static const union AffineAnimCmd gUnknown_83E7818[] = +{ + AFFINEANIMCMD_FRAME(0x64, 0x64, 0, 1), + AFFINEANIMCMD_END, +}; + +static const union AffineAnimCmd *const gUnknown_83E7828[] = +{ + gUnknown_83E7808, + gUnknown_83E7818, +}; + +const struct SpriteTemplate gUnknown_83E7830 = +{ + .tileTag = ANIM_TAG_SMALL_EMBER, + .paletteTag = ANIM_TAG_SMALL_EMBER, + .oam = &gOamData_83ACA98, + .anims = gUnknown_83E7800, + .images = NULL, + .affineAnims = gUnknown_83E7828, + .callback = sub_80B741C, +}; + +const struct SpriteTemplate gUnknown_83E7848 = +{ + .tileTag = ANIM_TAG_HOLLOW_ORB, + .paletteTag = ANIM_TAG_HOLLOW_ORB, + .oam = &gOamData_83AC9D0, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_80B7448, +}; + +const struct SpriteTemplate gUnknown_83E7860 = +{ + .tileTag = ANIM_TAG_SMALL_EMBER, + .paletteTag = ANIM_TAG_SMALL_EMBER, + .oam = &gOamData_83AC9D8, + .anims = gUnknown_83E7728, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_80B77E4, +}; + +static void sub_80B725C(struct Sprite *sprite) +{ + sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 2); + sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, 3); + if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) + { + sprite->pos1.x -= gBattleAnimArgs[0]; + gBattleAnimArgs[3] = -gBattleAnimArgs[3]; + gBattleAnimArgs[4] = -gBattleAnimArgs[4]; + } + else + { + sprite->pos1.x += gBattleAnimArgs[0]; + } + sprite->pos1.y += gBattleAnimArgs[1]; + sprite->data[0] = gBattleAnimArgs[2]; + sprite->data[1] = gBattleAnimArgs[3]; + sprite->data[3] = gBattleAnimArgs[4]; + sprite->data[5] = gBattleAnimArgs[5]; + sprite->invisible = TRUE; + StoreSpriteCallbackInData6(sprite, DestroySpriteAndMatrix); + sprite->callback = TranslateSpriteLinearAndFlicker; +} + +static void sub_80B72F8(struct Sprite *sprite) +{ + SetSpriteCoordsToAnimAttackerCoords(sprite); + sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, 2); + sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, 3); + if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) + { + sprite->pos1.x -= gBattleAnimArgs[1]; + sprite->pos1.y += gBattleAnimArgs[1]; + sprite->data[2] -= gBattleAnimArgs[2]; + sprite->data[4] += gBattleAnimArgs[3]; + } + else + { + sprite->pos1.x += gBattleAnimArgs[0]; + sprite->pos1.y += gBattleAnimArgs[1]; + sprite->data[2] += gBattleAnimArgs[2]; + sprite->data[4] += gBattleAnimArgs[3]; + StartSpriteAnim(sprite, 1); + } + sprite->data[0] = gBattleAnimArgs[4]; + sprite->callback = StartAnimLinearTranslation; + StoreSpriteCallbackInData6(sprite, DestroySpriteAndMatrix); +} + +static void sub_80B73AC(struct Sprite *sprite) +{ + if (gBattleAnimArgs[0] == 0) + { + sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 0); + sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, 1); + } + else + { + sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimTarget, 0); + sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimTarget, 1); + } + SetAnimSpriteInitialXOffset(sprite, gBattleAnimArgs[1]); + sprite->pos1.y += gBattleAnimArgs[2]; + sprite->callback = RunStoredCallbackWhenAnimEnds; + StoreSpriteCallbackInData6(sprite, DestroySpriteAndMatrix); +} + +static void sub_80B741C(struct Sprite *sprite) +{ + if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) + StartSpriteAffineAnim(sprite, 1); + sub_80B72F8(sprite); +} + +static void sub_80B7448(struct Sprite *sprite) +{ + u16 r5; + u16 r0; + + sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 2); + sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, 3); + sprite->data[4] = 0; + sprite->data[5] = 1; + sprite->data[6] = gBattleAnimArgs[0]; + r5 = GetBattlerSpriteCoordAttr(gBattlerAttacker, BATTLER_COORD_ATTR_HEIGHT); + r0 = GetBattlerSpriteCoordAttr(gBattlerAttacker, BATTLER_COORD_ATTR_WIDTH); + if (r5 > r0) + sprite->data[7] = r5 / 2; + else + sprite->data[7] = r0 / 2; + sprite->pos2.x = Cos(sprite->data[6], sprite->data[7]); + sprite->pos2.y = Sin(sprite->data[6], sprite->data[7]); + sprite->callback = sub_80B74D8; +} + +static void sub_80B74D8(struct Sprite *sprite) +{ + switch (sprite->data[0]) + { + case 0: + sprite->data[6] = (sprite->data[6] - sprite->data[5]) & 0xFF; + sprite->pos2.x = Cos(sprite->data[6], sprite->data[7]); + sprite->pos2.y = Sin(sprite->data[6], sprite->data[7]); + if (++sprite->data[4] > 5) + { + sprite->data[4] = 0; + if (sprite->data[5] <= 15 && ++sprite->data[5] > 15) + sprite->data[5] = 16; + } + if (++sprite->data[3] > 0x3C) + { + sprite->data[3] = 0; + ++sprite->data[0]; + } + break; + case 1: + sprite->data[6] = (sprite->data[6] - sprite->data[5]) & 0xFF; + if (sprite->data[7] <= 0x95 && (sprite->data[7] += 8) > 0x95) + sprite->data[7] = 0x96; + sprite->pos2.x = Cos(sprite->data[6], sprite->data[7]); + sprite->pos2.y = Sin(sprite->data[6], sprite->data[7]); + if (++sprite->data[4] > 5) + { + sprite->data[4] = 0; + if (sprite->data[5] <= 15 && ++sprite->data[5] > 15) + sprite->data[5] = 16; + } + if (++sprite->data[3] > 20) + DestroyAnimSprite(sprite); + break; + } +} + +void sub_80B75E0(u8 taskId) +{ + struct ScanlineEffectParams sp; + struct Task *task = &gTasks[taskId]; + u16 i; + u8 r1; + + if (GetBattlerSpriteBGPriorityRank(gBattleAnimAttacker) == 1) + { + sp.dmaDest = ®_BG1HOFS; + task->data[2] = gBattle_BG1_X; + } + else + { + sp.dmaDest = ®_BG2HOFS; + task->data[2] = gBattle_BG2_X; + } + sp.dmaControl = 0xA2600001; + sp.initState = 1; + sp.unused9 = 0; + r1 = GetBattlerYCoordWithElevation(gBattleAnimAttacker); + task->data[3] = r1 - 32; + task->data[4] = r1 + 32; + if (task->data[3] < 0) + task->data[3] = 0; + for (i = task->data[3]; i <= task->data[4]; ++i) + { + gScanlineEffectRegBuffers[0][i] = task->data[2]; + gScanlineEffectRegBuffers[1][i] = task->data[2]; + } + ScanlineEffect_SetParams(sp); + task->func = sub_80B76B0; +} + +static void sub_80B76B0(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + + switch (task->data[0]) + { + case 0: + if (++task->data[7] > 1) + { + task->data[7] = 0; + if (++task->data[6] == 3) + ++task->data[0]; + } + sub_80B776C(task); + break; + case 1: + if (++task->data[1] > 0x3C) + ++task->data[0]; + sub_80B776C(task); + break; + case 2: + if (++task->data[7] > 1) + { + task->data[7] = 0; + if (--task->data[6] == 0) + ++task->data[0]; + } + sub_80B776C(task); + break; + case 3: + gScanlineEffect.state = 3; + ++task->data[0]; + break; + case 4: + DestroyAnimVisualTask(taskId); + break; + } +} + +static void sub_80B776C(struct Task *task) +{ + u16 i, r3 = task->data[5]; + + for (i = task->data[3]; i <= task->data[4]; ++i) + { + gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer][i] = ((gSineTable[r3] * task->data[6]) >> 7) + task->data[2]; + r3 = (r3 + 8) & 0xFF; + } + task->data[5] = (task->data[5] + 9) & 0xFF; +} + +static void sub_80B77E4(struct Sprite *sprite) +{ + s32 i, r6 = (gBattleAnimArgs[2] * 3) / 5; + + sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 2); + sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, 3) + gBattleAnimArgs[4]; + sprite->data[1] = Cos(gBattleAnimArgs[1], gBattleAnimArgs[2]); + sprite->data[2] = Sin(gBattleAnimArgs[1], r6); + sprite->pos1.x += sprite->data[1] * gBattleAnimArgs[0]; + sprite->pos1.y += sprite->data[2] * gBattleAnimArgs[0]; + sprite->data[3] = gBattleAnimArgs[3]; + sprite->callback = sub_80B7894; + for (i = 0; i < 7; ++i) + gUnknown_20399A4[i] = sprite->data[i]; +} + +static void sub_80B7894(struct Sprite *sprite) +{ + sprite->data[4] += sprite->data[1]; + sprite->data[5] += sprite->data[2]; + sprite->pos2.x = sprite->data[4] / 10; + sprite->pos2.y = sprite->data[5] / 10; + if (++sprite->data[0] > sprite->data[3]) + DestroyAnimSprite(sprite); +} diff --git a/src/fame_checker.c b/src/fame_checker.c index 0278fda18..e803a9700 100644 --- a/src/fame_checker.c +++ b/src/fame_checker.c @@ -552,7 +552,7 @@ static void Task_TopMenuHandleInput(u8 taskId) if (FindTaskIdByFunc(Task_FCOpenOrCloseInfoBox) == 0xFF) { RunTextPrinters(); - if ((JOY_NEW(SELECT_BUTTON)) && !sFameCheckerData->inPickMode && sFameCheckerData->savedCallback != ReturnToBagFromKeyItem) + if ((JOY_NEW(SELECT_BUTTON)) && !sFameCheckerData->inPickMode && sFameCheckerData->savedCallback != CB2_BagMenuFromStartMenu) task->func = Task_StartToCloseFameChecker; else if (JOY_NEW(START_BUTTON)) { @@ -802,7 +802,7 @@ static void WipeMsgBoxAndTransfer(void) static void Setup_DrawMsgAndListBoxes(void) { - sub_80F6E9C(); + LoadStdWindowFrameGfx(); DrawDialogueFrame(FCWINDOWID_MSGBOX, TRUE); FC_PutWindowTilemapAndCopyWindowToVramMode3(FCWINDOWID_MSGBOX); FC_PutWindowTilemapAndCopyWindowToVramMode3(FCWINDOWID_LIST); diff --git a/src/field_fadetransition.c b/src/field_fadetransition.c index 62254a559..6a539b60e 100644 --- a/src/field_fadetransition.c +++ b/src/field_fadetransition.c @@ -475,25 +475,25 @@ static void sub_807E31C(u8 taskId) } } -static void sub_807E378(u8 taskId) +static void Task_WaitFadeAndCreateStartMenuTask(u8 taskId) { if (sub_807E418() == TRUE) { DestroyTask(taskId); - CreateTask(sub_806F1F0, 80); + CreateTask(Task_StartMenuHandleInput, 80); } } -void sub_807E3A0(void) +void FadeTransition_FadeInOnReturnToStartMenu(void) { sub_807DC00(); - CreateTask(sub_807E378, 80); + CreateTask(Task_WaitFadeAndCreateStartMenuTask, 80); ScriptContext2_Enable(); } -bool32 sub_807E3BC(void) +bool8 FieldCB2_ReturnToStartMenuInit(void) { - sub_806F1D4(); + SetUpReturnToStartMenu(); return FALSE; } @@ -522,7 +522,7 @@ static bool32 sub_807E40C(void) bool32 sub_807E418(void) { - if (sub_807AA70() == TRUE && sub_80F83B0()) + if (field_weather_is_fade_finished() == TRUE && sub_80F83B0()) return TRUE; else return FALSE; diff --git a/src/flying.c b/src/flying.c new file mode 100644 index 000000000..8c3ccb52a --- /dev/null +++ b/src/flying.c @@ -0,0 +1,1289 @@ +#include "global.h" +#include "battle_anim.h" +#include "palette.h" +#include "trig.h" +#include "constants/battle_anim.h" +#include "random.h" + +static void sub_80B18E4(struct Sprite *sprite); +static void sub_80B1A1C(struct Sprite *sprite); +static void sub_80B1AB8(struct Sprite *sprite); +static void sub_80B1BB0(struct Sprite *sprite); +static void sub_80B1C3C(struct Sprite *sprite); +static void sub_80B1D88(struct Sprite *sprite); +static void sub_80B24C0(struct Sprite *sprite); +static void sub_80B2514(struct Sprite *sprite); +static void sub_80B2780(struct Sprite *sprite); +static void sub_80B2914(struct Sprite *sprite); +static void sub_80B2974(struct Sprite *sprite); +static void sub_80B2A08(struct Sprite *sprite); +static void sub_80B2AF4(struct Sprite *sprite); +static void sub_80B2BD8(struct Sprite *sprite); +static void sub_80B2CE4(struct Sprite *sprite); +static void sub_80B2D64(struct Sprite *sprite); +static void sub_80B190C(struct Sprite *sprite); +static void sub_80B198C(u8 taskId); +static void sub_80B1A9C(struct Sprite *sprite); +static void sub_80B1BF8(struct Sprite *sprite); +static void sub_80B1CC0(struct Sprite *sprite); +static void sub_80B1F94(struct Sprite *sprite); +static void sub_80B268C(struct Sprite *sprite); +static void sub_80B2820(struct Sprite *sprite); +static void sub_80B2A50(struct Sprite *sprite); +static void sub_80B2AB0(struct Sprite *sprite); +static void sub_80B2C88(struct Sprite *sprite); +static void sub_80B2CF8(struct Sprite *sprite); +static void sub_80B2E20(struct Sprite *sprite); + +const struct SpriteTemplate gUnknown_83E6AE8 = +{ + .tileTag = ANIM_TAG_GUST, + .paletteTag = ANIM_TAG_GUST, + .oam = &gOamData_83ACA20, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_80B18E4, +}; + +static const union AffineAnimCmd gUnknown_83E6B00[] = +{ + AFFINEANIMCMD_FRAME(0x10, 0x100, 0, 0), + AFFINEANIMCMD_FRAME(0xA, 0x0, 0, 24), + AFFINEANIMCMD_END, +}; + +static const union AffineAnimCmd *const gUnknown_83E6B18[] = +{ + gUnknown_83E6B00, +}; + +const struct SpriteTemplate gUnknown_83E6B1C = +{ + .tileTag = ANIM_TAG_GUST, + .paletteTag = ANIM_TAG_GUST, + .oam = &gOamData_83ACA80, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gUnknown_83E6B18, + .callback = sub_80B1A1C, +}; + +static const union AnimCmd gUnknown_83E6B34[] = +{ + ANIMCMD_FRAME(0, 3), + ANIMCMD_FRAME(0, 3, .hFlip = TRUE), + ANIMCMD_FRAME(0, 3, .vFlip = TRUE), + ANIMCMD_FRAME(0, 3, .vFlip = TRUE, .hFlip = TRUE), + ANIMCMD_JUMP(0), +}; + +static const union AnimCmd *const gUnknown_83E6B48[] = +{ + gUnknown_83E6B34, +}; + +const struct SpriteTemplate gUnknown_83E6B4C = +{ + .tileTag = ANIM_TAG_AIR_WAVE_2, + .paletteTag = ANIM_TAG_AIR_WAVE_2, + .oam = &gOamData_83AC9F8, + .anims = gUnknown_83E6B48, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_80B1AB8, +}; + +static const union AffineAnimCmd gUnknown_83E6B64[] = +{ + AFFINEANIMCMD_FRAME(0x10, 0x100, 0, 0), + AFFINEANIMCMD_FRAME(0x28, 0x0, 0, 6), + AFFINEANIMCMD_FRAME(0x0, 0xFFE0, 0, 5), + AFFINEANIMCMD_FRAME(0xFFF0, 0x20, 0, 10), + AFFINEANIMCMD_END, +}; + +static const union AffineAnimCmd *const gUnknown_83E6B8C[] = +{ + gUnknown_83E6B64, +}; + +static const union AffineAnimCmd gUnknown_83E6B90[] = +{ + AFFINEANIMCMD_FRAME(0x0, 0x0, 50, 1), + AFFINEANIMCMD_END, +}; + +static const union AffineAnimCmd gUnknown_83E6B9C[] = +{ + AFFINEANIMCMD_FRAME(0x0, 0x0, -40, 1), + AFFINEANIMCMD_END, +}; + +static const union AffineAnimCmd *const gUnknown_83E6BB0[] = +{ + gUnknown_83E6B90, + gUnknown_83E6B9C, +}; + +const struct SpriteTemplate gUnknown_83E6BB8 = +{ + .tileTag = ANIM_TAG_ROUND_SHADOW, + .paletteTag = ANIM_TAG_ROUND_SHADOW, + .oam = &gOamData_83ACAA0, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gUnknown_83E6B8C, + .callback = sub_80B1BB0, +}; + +const struct SpriteTemplate gUnknown_83E6BD0 = +{ + .tileTag = ANIM_TAG_ROUND_SHADOW, + .paletteTag = ANIM_TAG_ROUND_SHADOW, + .oam = &gOamData_83ACA40, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gUnknown_83E6BB0, + .callback = sub_80B1C3C, +}; + +static const union AnimCmd gUnknown_83E6BE8[] = +{ + ANIMCMD_FRAME(0, 0), + ANIMCMD_END, +}; + +static const union AnimCmd gUnknown_83E6BF0[] = +{ + ANIMCMD_FRAME(16, 0, .hFlip = TRUE), + ANIMCMD_END, +}; + +static const union AnimCmd *const gUnknown_83E6BF8[] = +{ + gUnknown_83E6BE8, + gUnknown_83E6BF0, +}; + +const struct SpriteTemplate gUnknown_83E6C00 = +{ + .tileTag = ANIM_TAG_WHITE_FEATHER, + .paletteTag = ANIM_TAG_WHITE_FEATHER, + .oam = &gOamData_83ACA38, + .anims = gUnknown_83E6BF8, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_80B1D88, +}; + +// not used +static const u16 gUnknown_83E6C18[] = INCBIN_U16("graphics/battle_anims/sprites/unk_83E6C18.gbapal"); + +const struct SpriteTemplate gUnknown_83E6C38 = +{ + .tileTag = ANIM_TAG_SMALL_BUBBLES, + .paletteTag = ANIM_TAG_SMALL_BUBBLES, + .oam = &gOamData_83AC9D0, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_80B24C0, +}; + +const struct SpriteTemplate gUnknown_83E6C50 = +{ + .tileTag = ANIM_TAG_WHITE_FEATHER, + .paletteTag = ANIM_TAG_WHITE_FEATHER, + .oam = &gOamData_83ACA38, + .anims = gUnknown_83E6BF8, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_80B2514, +}; + +static const union AnimCmd gUnknown_83E6C68[] = +{ + ANIMCMD_FRAME(0, 1), + ANIMCMD_FRAME(8, 1), + ANIMCMD_FRAME(16, 1), + ANIMCMD_FRAME(8, 1, .hFlip = TRUE), + ANIMCMD_FRAME(0, 1, .hFlip = TRUE), + ANIMCMD_END, +}; + +static const union AnimCmd *const gUnknown_83E6C80[] = +{ + gUnknown_83E6C68, +}; + +const struct SpriteTemplate gUnknown_83E6C84 = +{ + .tileTag = ANIM_TAG_WHIRLWIND_LINES, + .paletteTag = ANIM_TAG_WHIRLWIND_LINES, + .oam = &gOamData_83AC9F8, + .anims = gUnknown_83E6C80, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_80B2780, +}; + +static const union AffineAnimCmd gUnknown_83E6C9C[] = +{ + AFFINEANIMCMD_FRAME(0x10, 0x100, 0, 0), + AFFINEANIMCMD_FRAME(0x28, 0x0, 0, 6), + AFFINEANIMCMD_FRAME(0x0, 0xFFE0, 0, 5), + AFFINEANIMCMD_FRAME(0xFFEC, 0x0, 0, 7), + AFFINEANIMCMD_FRAME(0xFFEC, 0xFFEC, 0, 5), + AFFINEANIMCMD_END, +}; + +static const union AffineAnimCmd *const gUnknown_83E6CCC[] = +{ + gUnknown_83E6C9C, +}; + +const struct SpriteTemplate gUnknown_83E6CD0 = +{ + .tileTag = ANIM_TAG_ROUND_SHADOW, + .paletteTag = ANIM_TAG_ROUND_SHADOW, + .oam = &gOamData_83ACAA0, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gUnknown_83E6CCC, + .callback = sub_80B2914, +}; + +static const union AffineAnimCmd gUnknown_83E6CE8[] = +{ + AFFINEANIMCMD_FRAME(0xA0, 0x100, 0, 0), + AFFINEANIMCMD_END, +}; + +static const union AffineAnimCmd *const gUnknown_83E6CF8[] = +{ + gUnknown_83E6CE8, +}; + +const struct SpriteTemplate gUnknown_83E6CFC = +{ + .tileTag = ANIM_TAG_ROUND_SHADOW, + .paletteTag = ANIM_TAG_ROUND_SHADOW, + .oam = &gOamData_83ACAA0, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gUnknown_83E6CF8, + .callback = sub_80B2974, +}; + +static const union AffineAnimCmd gUnknown_83E6D14[] = +{ + AFFINEANIMCMD_FRAME(0x10, 0x100, 0, 0), + AFFINEANIMCMD_FRAME(0x28, 0x0, 0, 6), + AFFINEANIMCMD_FRAME(0x0, 0xFFE0, 0, 5), + AFFINEANIMCMD_FRAME(0xFFF0, 0x20, 0, 10), + AFFINEANIMCMD_END, +}; + +static const union AffineAnimCmd *const gUnknown_83E6D3C[] = +{ + gUnknown_83E6D14, +}; + +const struct SpriteTemplate gUnknown_83E6D40 = +{ + .tileTag = ANIM_TAG_ROUND_SHADOW, + .paletteTag = ANIM_TAG_ROUND_SHADOW, + .oam = &gOamData_83ACAA0, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gUnknown_83E6D3C, + .callback = sub_80B2A08, +}; + +// not used +static const union AffineAnimCmd gUnknown_83E6D58[] = +{ + AFFINEANIMCMD_FRAME(0x100, 0x0, 0, 0), + AFFINEANIMCMD_FRAME(0x0, 0x20, 0, 12), + AFFINEANIMCMD_FRAME(0x0, 0xFFE0, 0, 11), + AFFINEANIMCMD_END, +}; + +// not used +static const union AffineAnimCmd *const gUnknown_83E6D80[] = +{ + gUnknown_83E6D58, +}; + +const struct SpriteTemplate gUnknown_83E6D7C = +{ + .tileTag = ANIM_TAG_SPLASH, + .paletteTag = ANIM_TAG_SPLASH, + .oam = &gOamData_83ACAA0, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_80B2AF4, +}; + +const struct SpriteTemplate gUnknown_83E6D94 = +{ + .tileTag = ANIM_TAG_SWEAT_BEAD, + .paletteTag = ANIM_TAG_SWEAT_BEAD, + .oam = &gOamData_83AC9C8, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_80B2BD8, +}; + +const struct SpriteTemplate gUnknown_83E6DAC = +{ + .tileTag = ANIM_TAG_CIRCLE_OF_LIGHT, + .paletteTag = ANIM_TAG_CIRCLE_OF_LIGHT, + .oam = &gOamData_83ACB00, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_80B2CE4, +}; + +const struct SpriteTemplate gUnknown_83E6DB4 = +{ + .tileTag = ANIM_TAG_BIRD, + .paletteTag = ANIM_TAG_BIRD, + .oam = &gOamData_83ACAA0, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_80B2D64, +}; + +static void sub_80B18E4(struct Sprite *sprite) +{ + InitSpritePosToAnimTarget(sprite, FALSE); + sprite->pos1.y += 20; + sprite->data[1] = 191; + sprite->callback = sub_80B190C; + sprite->callback(sprite); +} + +static void sub_80B190C(struct Sprite *sprite) +{ + sprite->pos2.x = Sin(sprite->data[1], 32); + sprite->pos2.y = Cos(sprite->data[1], 8); + sprite->data[1] += 5; + sprite->data[1] &= 0xFF; + if (++sprite->data[0] == 71) + DestroyAnimSprite(sprite); +} + +void sub_80B194C(u8 taskId) +{ + gTasks[taskId].data[0] = gBattleAnimArgs[1]; + gTasks[taskId].data[1] = gBattleAnimArgs[0]; + gTasks[taskId].data[2] = IndexOfSpritePaletteTag(ANIM_TAG_GUST); + gTasks[taskId].func = sub_80B198C; +} + +static void sub_80B198C(u8 taskId) +{ + u8 data2; + u16 temp; + s32 i, base; + + if (gTasks[taskId].data[10]++ == gTasks[taskId].data[1]) + { + gTasks[taskId].data[10] = 0; + data2 = gTasks[taskId].data[2]; + temp = gPlttBufferFaded[16 * data2 + 0x108]; + i = 7; + base = data2 * 16; + do + { + gPlttBufferFaded[base + 0x101 + i] = gPlttBufferFaded[base + 0x100 + i]; + } while (--i > 0); + + gPlttBufferFaded[base + 0x101] = temp; + } + if (--gTasks[taskId].data[0] == 0) + DestroyAnimVisualTask(taskId); +} + +static void sub_80B1A1C(struct Sprite *sprite) +{ + InitSpritePosToAnimAttacker(sprite, TRUE); + if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) + gBattleAnimArgs[2] = -gBattleAnimArgs[2]; + sprite->data[0] = gBattleAnimArgs[4]; + sprite->data[1] = sprite->pos1.x; + sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2) + gBattleAnimArgs[2]; + sprite->data[3] = sprite->pos1.y; + sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET) + gBattleAnimArgs[3]; + InitAnimLinearTranslation(sprite); + sprite->callback = RunStoredCallbackWhenAffineAnimEnds; + StoreSpriteCallbackInData6(sprite, sub_80B1A9C); +} + +static void sub_80B1A9C(struct Sprite *sprite) +{ + if (AnimTranslateLinear(sprite)) + DestroyAnimSprite(sprite); +} + +static void sub_80B1AB8(struct Sprite *sprite) +{ + if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) + { + gBattleAnimArgs[0] = -gBattleAnimArgs[0]; + gBattleAnimArgs[1] = -gBattleAnimArgs[1]; + gBattleAnimArgs[2] = -gBattleAnimArgs[2]; + gBattleAnimArgs[3] = -gBattleAnimArgs[3]; + } + if (IsContest()) + { + gBattleAnimArgs[1] = -gBattleAnimArgs[1]; + gBattleAnimArgs[3] = -gBattleAnimArgs[3]; + } + sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2); + sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET); + sprite->pos1.x += gBattleAnimArgs[0]; + sprite->pos1.y += gBattleAnimArgs[1]; + sprite->data[0] = gBattleAnimArgs[4]; + if (gBattleAnimArgs[6] == 0) + { + sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2); + sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET); + } + else + { + SetAverageBattlerPositions(gBattleAnimTarget, 1, &sprite->data[2], &sprite->data[4]); + } + sprite->data[2] = sprite->data[2] + gBattleAnimArgs[2]; + sprite->data[4] = sprite->data[4] + gBattleAnimArgs[3]; + sprite->callback = StartAnimLinearTranslation; + StoreSpriteCallbackInData6(sprite, DestroyAnimSprite); + SeekSpriteAnim(sprite, gBattleAnimArgs[5]); +} + +static void sub_80B1BB0(struct Sprite *sprite) +{ + InitSpritePosToAnimAttacker(sprite, TRUE); + sprite->data[0] = gBattleAnimArgs[2]; + sprite->data[1] = gBattleAnimArgs[3]; + sprite->callback = sub_80B1BF8; + gSprites[GetAnimBattlerSpriteId(ANIM_ATTACKER)].invisible = TRUE; +} + +static void sub_80B1BF8(struct Sprite *sprite) +{ + if (sprite->data[0] > 0) + { + --sprite->data[0]; + } + else + { + sprite->data[2] += sprite->data[1]; + sprite->pos2.y -= (sprite->data[2] >> 8); + } + if (sprite->pos1.y + sprite->pos2.y < -32) + DestroyAnimSprite(sprite); +} + +static void sub_80B1C3C(struct Sprite *sprite) +{ + if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) + { + sprite->pos1.x = 272; + sprite->pos1.y = -32; + StartSpriteAffineAnim(sprite, 1); + } + else + { + sprite->pos1.x = -32; + sprite->pos1.y = -32; + } + sprite->data[0] = gBattleAnimArgs[0]; + sprite->data[1] = sprite->pos1.x; + sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2); + sprite->data[3] = sprite->pos1.y; + sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET); + InitAnimLinearTranslation(sprite); + sprite->callback = sub_80B1CC0; +} + +static void sub_80B1CC0(struct Sprite *sprite) +{ + sprite->data[0] = 1; + AnimTranslateLinear(sprite); + if (((u16)sprite->data[3] >> 8) > 200) + { + sprite->pos1.x += sprite->pos2.x; + sprite->pos2.x = 0; + sprite->data[3] &= 0xFF; + } + if (sprite->pos1.x + sprite->pos2.x < -32 + || sprite->pos1.x + sprite->pos2.x > 272 + || sprite->pos1.y + sprite->pos2.y > 160) + { + gSprites[GetAnimBattlerSpriteId(ANIM_ATTACKER)].invisible = FALSE; + DestroyAnimSprite(sprite); + } +} + +void sub_80B1D3C(struct Sprite *sprite) +{ + if (sprite->data[0]-- <= 0) + { + if (sprite->oam.affineMode & ST_OAM_AFFINE_ON_MASK) + { + FreeOamMatrix(sprite->oam.matrixNum); + sprite->oam.affineMode = 0; + } + DestroySprite(sprite); + --gAnimVisualTaskCount; + } +} + +struct FeatherDanceData +{ + u16 unk0_0a:1; + u16 unk0_0b:1; + u16 unk0_0c:1; + u16 unk0_0d:1; + u16 unk0_1:4; + u16 unk1:8; + u16 unk2; + s16 unk4; + u16 unk6; + u16 unk8; + u16 unkA; + u8 unkC[2]; + u16 unkE_0:1; + u16 unkE_1:15; +}; + +static void sub_80B1D88(struct Sprite *sprite) +{ + u8 battler, matrixNum, sinIndex; + s16 spriteCoord, sinVal; + struct FeatherDanceData *data = (struct FeatherDanceData *)sprite->data; + + if (gBattleAnimArgs[7] & 0x100) + battler = gBattleAnimAttacker; + else + battler = gBattleAnimTarget; + if (GetBattlerSide(battler) == B_SIDE_PLAYER) + gBattleAnimArgs[0] = -gBattleAnimArgs[0]; + sprite->pos1.x = GetBattlerSpriteCoord(battler, BATTLER_COORD_ATTR_HEIGHT) + gBattleAnimArgs[0]; + spriteCoord = GetBattlerSpriteCoord(battler, BATTLER_COORD_ATTR_WIDTH); + sprite->pos1.y = spriteCoord + gBattleAnimArgs[1]; + data->unk8 = sprite->pos1.y << 8; + data->unkE_1 = spriteCoord + gBattleAnimArgs[6]; + data->unk0_0c = 1; + data->unk2 = gBattleAnimArgs[2] & 0xFF; + data->unkA = (gBattleAnimArgs[2] >> 8) & 0xFF; + data->unk4 = gBattleAnimArgs[3]; + data->unk6 = gBattleAnimArgs[4]; + *(u16 *)(data->unkC) = gBattleAnimArgs[5]; + if (data->unk2 >= 64 && data->unk2 <= 191) + { + if (!IsContest()) + sprite->oam.priority = GetBattlerSpriteBGPriority(battler) + 1; + else + sprite->oam.priority = GetBattlerSpriteBGPriority(battler); + data->unkE_0 = 0; + if (!(data->unk4 & 0x8000)) + { + sprite->hFlip ^= 1; + sprite->animNum = sprite->hFlip; + sprite->animBeginning = TRUE; + sprite->animEnded = FALSE; + } + } + else + { + sprite->oam.priority = GetBattlerSpriteBGPriority(battler); + data->unkE_0 = 1; + if (data->unk4 & 0x8000) + { + sprite->hFlip ^= 1; + sprite->animNum = sprite->hFlip; + + sprite->animBeginning = TRUE; + sprite->animEnded = FALSE; + } + } + data->unk0_1 = data->unk2 >> 6; + sprite->pos2.x = (gSineTable[data->unk2] * data->unkC[0]) >> 8; + matrixNum = sprite->oam.matrixNum; + sinIndex = (-sprite->pos2.x >> 1) + data->unkA; + sinVal = gSineTable[sinIndex]; + gOamMatrices[matrixNum].a = gOamMatrices[matrixNum].d = gSineTable[sinIndex + 64]; + if (sprite) + { + gOamMatrices[matrixNum].b = sinVal; + gOamMatrices[matrixNum].c = -sinVal; + } + else // pointless, exactly the same + { + gOamMatrices[matrixNum].b = sinVal; + gOamMatrices[matrixNum].c = -sinVal; + } + sprite->callback = sub_80B1F94; +} + +static void sub_80B1F94(struct Sprite *sprite) +{ + u8 matrixNum, sinIndex; + s16 sinVal = 0; + struct FeatherDanceData *data = (struct FeatherDanceData *)sprite->data; + + if (data->unk0_0a) + { + if (data->unk1-- % 256 == 0) + { + data->unk0_0a = 0; + data->unk1 = 0; + } + } + else + { + switch (data->unk2 / 64) + { + case 0: + if (data->unk0_1 << 24 >> 24 == 1) // the shifts have to be here + { + data->unk0_0d = 1; + data->unk0_0a = 1; + data->unk1 = 0; + } + else if (data->unk0_1 << 24 >> 24 == 3) + { + data->unk0_0b ^= 1; + data->unk0_0a = 1; + data->unk1 = 0; + } + else if (data->unk0_0d) + { + sprite->hFlip ^= 1; + sprite->animNum = sprite->hFlip; + sprite->animBeginning = TRUE; + sprite->animEnded = FALSE; + if (data->unk0_0c) + { + if (!IsContest()) + { + if (!data->unkE_0) + { + --sprite->oam.priority; + data->unkE_0 ^= 1; + } + else + { + ++sprite->oam.priority; + data->unkE_0 ^= 1; + } + } + else + { + if (!data->unkE_0) + { + sprite->subpriority -= 12; + data->unkE_0 ^= 1; + } + else + { + sprite->subpriority += 12; + data->unkE_0 ^= 1; + } + } + } + data->unk0_0d = 0; + data->unk2; + } + data->unk0_1 = 0; + break; + case 1: + if (data->unk0_1 << 24 >> 24 == 0) + { + data->unk0_0d = 1; + data->unk0_0a = 1; + data->unk1 = 0; + } + else if (data->unk0_1 << 24 >> 24 == 2) + { + data->unk0_0a = 1; + data->unk1 = 0; + } + else if (data->unk0_0d) + { + sprite->hFlip ^= 1; + sprite->animNum = sprite->hFlip; + sprite->animBeginning = TRUE; + sprite->animEnded = FALSE; + if (data->unk0_0c) + { + if (!IsContest()) + { + if (!data->unkE_0) + { + --sprite->oam.priority; + data->unkE_0 ^= 1; + } + else + { + ++sprite->oam.priority; + data->unkE_0 ^= 1; + } + } + else + { + if (!data->unkE_0) + { + sprite->subpriority -= 12; + data->unkE_0 ^= 1; + } + else + { + sprite->subpriority += 12; + data->unkE_0 ^= 1; + } + } + } + data->unk0_0d = 0; + } + data->unk0_1 = 1; + break; + case 2: + if (data->unk0_1 << 24 >> 24 == 3) + { + data->unk0_0d = 1; + data->unk0_0a = 1; + data->unk1 = 0; + } + else if (data->unk0_1 << 24 >> 24 == 1) + { + data->unk0_0a = 1; + data->unk1 = 0; + } + else if (data->unk0_0d) + { + sprite->hFlip ^= 1; + sprite->animNum = sprite->hFlip; + sprite->animBeginning = TRUE; + sprite->animEnded = FALSE; + if (data->unk0_0c) + { + if (!IsContest()) + { + if (!data->unkE_0) + { + --sprite->oam.priority; + data->unkE_0 ^= 1; + } + else + { + ++sprite->oam.priority; + data->unkE_0 ^= 1; + } + } + else + { + if (!data->unkE_0) + { + sprite->subpriority -= 12; + data->unkE_0 ^= 1; + } + else + { + sprite->subpriority += 12; + data->unkE_0 ^= 1; + } + } + } + data->unk0_0d = 0; + } + data->unk0_1 = 2; + break; + case 3: + if (data->unk0_1 << 24 >> 24 == 2) + { + data->unk0_0d = 1; + } + else if (data->unk0_1 << 24 >> 24 == 0) + { + data->unk0_0b ^= 1; + data->unk0_0a = 1; + data->unk1 = 0; + } + else if (data->unk0_0d) + { + sprite->hFlip ^= 1; + sprite->animNum = sprite->hFlip; + sprite->animBeginning = TRUE; + sprite->animEnded = FALSE; + if (data->unk0_0c) + { + if (!IsContest()) + { + if (!data->unkE_0) + { + --sprite->oam.priority; + data->unkE_0 ^= 1; + } + else + { + ++sprite->oam.priority; + data->unkE_0 ^= 1; + } + } + else + { + if (!data->unkE_0) + { + sprite->subpriority -= 12; + data->unkE_0 ^= 1; + } + else + { + sprite->subpriority += 12; + data->unkE_0 ^= 1; + } + } + } + data->unk0_0d = 0; + } + data->unk0_1 = 3; + break; + } + #ifndef NONMATCHING + asm("":::"r8"); + #endif + sprite->pos2.x = (data->unkC[data->unk0_0b] * gSineTable[data->unk2]) >> 8; + matrixNum = sprite->oam.matrixNum; + sinIndex = (-sprite->pos2.x >> 1) + data->unkA; + sinVal = gSineTable[sinIndex]; + gOamMatrices[matrixNum].a = gOamMatrices[matrixNum].d = gSineTable[sinIndex + 64]; + gOamMatrices[matrixNum].b = sinVal; + gOamMatrices[matrixNum].c = -sinVal; + data->unk8 += data->unk6; + sprite->pos1.y = data->unk8 >> 8; + if (data->unk4 & 0x8000) + data->unk2 = (data->unk2 - (data->unk4 & 0x7FFF)) & 0xFF; + else + data->unk2 = (data->unk2 + (data->unk4 & 0x7FFF)) & 0xFF; + if (sprite->pos1.y + sprite->pos2.y >= data->unkE_1) + { + sprite->data[0] = 0; + sprite->callback = sub_80B1D3C; + } + } +} + +static void sub_80B24C0(struct Sprite *sprite) +{ + sprite->oam.priority = GetBattlerSpriteBGPriority(gBattleAnimTarget); + sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 2); + sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, 3); + sprite->callback = TranslateAnimSpriteToTargetMonLocation; +} + +static void sub_80B2514(struct Sprite *sprite) +{ + u8 matrixNum; + s16 rn, sinVal; + + sprite->data[1] = gBattleAnimArgs[0]; + sprite->data[2] = gBattleAnimArgs[1]; + sprite->data[3] = gBattleAnimArgs[2]; + if (!IsContest()) + { + if (gBattlerPositions[gBattleAnimTarget] & B_POSITION_OPPONENT_LEFT) + sprite->data[7] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_ATTR_WIDTH) + gBattleAnimArgs[3]; + else + sprite->data[7] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_ATTR_WIDTH) + 40; + if (gBattleAnimArgs[4]) + sprite->oam.priority = GetBattlerSpriteBGPriority(gBattleAnimTarget) + 1; + else + sprite->oam.priority = GetBattlerSpriteBGPriority(gBattleAnimTarget); + } + else + { + sprite->data[7] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_ATTR_WIDTH) + gBattleAnimArgs[3]; + } + sprite->data[4] = gSineTable[sprite->data[1] & 0xFF]; + sprite->data[5] = -gSineTable[(sprite->data[1] & 0xFF) + 64]; + sprite->data[6] = 0; + sprite->pos2.y = 0; + sprite->pos2.x = 0; + matrixNum = sprite->oam.matrixNum; + sprite->data[1] = (u16)sprite->data[1] >> 8; + rn = Random(); + if (rn & 0x8000) + sprite->data[1] = 0xFF - sprite->data[1]; + sinVal = gSineTable[sprite->data[1]]; + gOamMatrices[matrixNum].a = gOamMatrices[matrixNum].d = gSineTable[sprite->data[1] + 64]; + gOamMatrices[matrixNum].b = sinVal; + gOamMatrices[matrixNum].c = -sinVal; + sprite->animBeginning = TRUE; + sprite->animEnded = FALSE; + if (rn & 1) + { + sprite->animNum = 1; + sprite->hFlip = TRUE; + } + sprite->callback = sub_80B268C; +} + +static void sub_80B268C(struct Sprite *sprite) +{ + struct FeatherDanceData fData; + struct FeatherDanceData *tData = (struct FeatherDanceData *)sprite->data; + u8 item; + u32 x, y; + + ++sprite->data[0]; + if (sprite->data[0] <= 4) + return; + sprite->pos2.x = (sprite->data[4] * sprite->data[6]) >> 8; + sprite->pos2.y = (sprite->data[5] * sprite->data[6]) >> 8; + sprite->data[6] += sprite->data[3] & 0xFF; + if (sprite->data[6] < (sprite->data[2] & 0xFF)) + return; + sprite->pos1.x += sprite->pos2.x; + sprite->pos1.y += sprite->pos2.y; + sprite->pos2.x = 0; + sprite->pos2.y = 0; + memcpy(&fData, tData, sizeof(struct FeatherDanceData)); + memset(tData, 0, sizeof(struct FeatherDanceData)); + tData->unk8 = sprite->pos1.y << 8; + tData->unk6 = fData.unk6 >> 8; + tData->unk2 = 0; + tData->unkA = fData.unk2; + if (sprite->animNum != 0) + { + if (tData->unk6 & 8) + tData->unk4 = 0x8001; + else + tData->unk4 = 0x8002; + } + else if (tData->unk6 & 8) + { + tData->unk4 = 1; + } + else + { + tData->unk4 = 2; + } + item = fData.unk4 >> 8; + tData->unkC[0] = item; + tData->unkC[1] = item - 2; + x = (((u16 *)&fData)[7] << 1); + y = (((u16 *)tData)[7] & 1); + ((u16 *)tData)[7] = y | x; + sprite->callback = sub_80B1F94; +} + +static void sub_80B2780(struct Sprite *sprite) +{ + u16 arg; + u8 mult; + + if (!gBattleAnimArgs[2]) + InitSpritePosToAnimAttacker(sprite, 0); + else + InitSpritePosToAnimTarget(sprite, FALSE); + if ((!gBattleAnimArgs[2] && !GetBattlerSide(gBattleAnimAttacker)) + || (gBattleAnimArgs[2] == 1 && !GetBattlerSide(gBattleAnimTarget))) + sprite->pos1.x += 8; + SeekSpriteAnim(sprite, gBattleAnimArgs[4]); + sprite->pos1.x -= 32; + sprite->data[1] = 0x0ccc; + arg = gBattleAnimArgs[4]; + mult = 12; + sprite->pos2.x += mult * arg; + sprite->data[0] = arg; + sprite->data[7] = gBattleAnimArgs[3]; + sprite->callback = sub_80B2820; +} + +static void sub_80B2820(struct Sprite *sprite) +{ + sprite->pos2.x += sprite->data[1] >> 8; + if (++sprite->data[0] == 6) + { + sprite->data[0] = 0; + sprite->pos2.x = 0; + StartSpriteAnim(sprite, 0); + } + + if (--sprite->data[7] == -1) + DestroyAnimSprite(sprite); +} + +void sub_80B2868(u8 taskId) +{ + if (!(gTasks[taskId].data[0] % 32)) + { + ++gAnimVisualTaskCount; + gBattleAnimArgs[0] = Sin(gTasks[taskId].data[0], -13); + gBattleAnimArgs[1] = Cos(gTasks[taskId].data[0], -13); + gBattleAnimArgs[2] = 1; + gBattleAnimArgs[3] = 3; + CreateSpriteAndAnimate(&gUnknown_83E7C98, + GetBattlerSpriteCoord(gBattleAnimTarget, 2), + GetBattlerSpriteCoord(gBattleAnimTarget, 3), + 3); + } + gTasks[taskId].data[0] += 8; + if (gTasks[taskId].data[0] > 255) + DestroyAnimVisualTask(taskId); +} + +static void sub_80B2914(struct Sprite *sprite) +{ + switch (sprite->data[0]) + { + case 0: + InitSpritePosToAnimAttacker(sprite, 1); + gSprites[GetAnimBattlerSpriteId(0)].invisible = TRUE; + ++sprite->data[0]; + break; + case 1: + if (sprite->affineAnimEnded) + DestroyAnimSprite(sprite); + break; + } +} + +static void sub_80B2974(struct Sprite *sprite) +{ + switch (sprite->data[0]) + { + case 0: + sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimTarget, 1); + sprite->pos2.y = -sprite->pos1.y - 32; + ++sprite->data[0]; + break; + case 1: + sprite->pos2.y += 10; + if (sprite->pos2.y >= 0) + ++sprite->data[0]; + break; + case 2: + sprite->pos2.y -= 10; + if (sprite->pos1.y + sprite->pos2.y < -32) + { + gSprites[GetAnimBattlerSpriteId(0)].invisible = FALSE; + DestroyAnimSprite(sprite); + } + break; + } +} + +static void sub_80B2A08(struct Sprite *sprite) +{ + InitSpritePosToAnimAttacker(sprite, 1); + sprite->data[0] = gBattleAnimArgs[2]; + sprite->data[1] = gBattleAnimArgs[3]; + sprite->callback = sub_80B2A50; + gSprites[GetAnimBattlerSpriteId(0)].invisible = TRUE; +} + +static void sub_80B2A50(struct Sprite *sprite) +{ + if (sprite->data[0] > 0) + { + --sprite->data[0]; + } + else if (sprite->pos1.y + sprite->pos2.y > -32) + { + sprite->data[2] += sprite->data[1]; + sprite->pos2.y -= (sprite->data[2] >> 8); + } + else + { + sprite->invisible = TRUE; + if (sprite->data[3]++ > 20) + sprite->callback = sub_80B2AB0; + } +} + +static void sub_80B2AB0(struct Sprite *sprite) +{ + sprite->pos2.y += sprite->data[2] >> 8; + if (sprite->pos1.y + sprite->pos2.y > -32) + sprite->invisible = FALSE; + if (sprite->pos2.y > 0) + DestroyAnimSprite(sprite); +} + +static void sub_80B2AF4(struct Sprite *sprite) +{ + u32 matrixNum; + s32 t1, t2; + + switch (sprite->data[0]) + { + case 0: + if (!gBattleAnimArgs[0]) + { + sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 0); + sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, 1); + } + else + { + sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimTarget, 0); + sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimTarget, 1); + } + sprite->data[1] = 512; + TrySetSpriteRotScale(sprite, 0, 256, sprite->data[1], 0); + ++sprite->data[0]; + break; + case 1: + if (sprite->data[2] <= 11) + sprite->data[1] -= 40; + else + sprite->data[1] += 40; + ++sprite->data[2]; + TrySetSpriteRotScale(sprite, 0, 256, sprite->data[1], 0); + matrixNum = sprite->oam.matrixNum; + t1 = 15616; + t2 = t1 / gOamMatrices[matrixNum].d + 1; + if (t2 > 128) + t2 = 128; + t2 = (64 - t2) / 2; + sprite->pos2.y = t2; + if (sprite->data[2] == 24) + { + sub_8075AD8(sprite); + DestroyAnimSprite(sprite); + } + break; + } +} + +static void sub_80B2BD8(struct Sprite *sprite) +{ + s32 v1 = 0x1FF & Random(); + s32 v2 = 0x7F & Random(); + + if (v1 % 2) + sprite->data[0] = 736 + v1; + else + sprite->data[0] = 736 - v1; + + if (v2 % 2) + sprite->data[1] = 896 + v2; + else + sprite->data[1] = 896 - v2; + sprite->data[2] = gBattleAnimArgs[0]; + if (sprite->data[2]) + sprite->oam.matrixNum = ST_OAM_HFLIP; + if (gBattleAnimArgs[1] == 0) + { + sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 0); + sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, 1) + 32; + } + else + { + sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimTarget, 0); + sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimTarget, 1) + 32; + } + sprite->callback = sub_80B2C88; +} + +static void sub_80B2C88(struct Sprite *sprite) +{ + if (sprite->data[2] == 0) + { + sprite->pos2.x += sprite->data[0] >> 8; + sprite->pos2.y -= sprite->data[1] >> 8; + } + else + { + sprite->pos2.x -= sprite->data[0] >> 8; + sprite->pos2.y -= sprite->data[1] >> 8; + } + sprite->data[0] = sprite->data[0]; + sprite->data[1] -= 32; + if (sprite->data[0] < 0) + sprite->data[0] = 0; + if (++sprite->data[3] == 31) + DestroyAnimSprite(sprite); +} + +static void sub_80B2CE4(struct Sprite *sprite) +{ + sprite->data[6] = 0; + sprite->data[7] = 64; + sprite->callback = sub_80B2CF8; +} + +static void sub_80B2CF8(struct Sprite *sprite) +{ + switch (sprite->data[0]) + { + case 0: + if (++sprite->data[1] > 8) + { + sprite->data[1] = 0; + sprite->invisible ^= 1; + if (++sprite->data[2] > 5 && sprite->invisible != FALSE) + ++sprite->data[0]; + } + break; + case 1: + DestroyAnimSprite(sprite); + break; + } +} + +static void sub_80B2D64(struct Sprite *sprite) +{ + u16 rotation; + s16 posx = sprite->pos1.x; + s16 posy = sprite->pos1.y; + + sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 2); + sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, 3); + sprite->data[4] = sprite->pos1.x << 4; + sprite->data[5] = sprite->pos1.y << 4; + sprite->data[6] = ((posx - sprite->pos1.x) << 4) / 12; + sprite->data[7] = ((posy - sprite->pos1.y) << 4) / 12; + rotation = ArcTan2Neg(posx - sprite->pos1.x, posy - sprite->pos1.y); + rotation += 49152; + TrySetSpriteRotScale(sprite, 1, 0x100, 0x100, rotation); + sprite->callback = sub_80B2E20; +} + +static void sub_80B2E20(struct Sprite *sprite) +{ + sprite->data[4] += sprite->data[6]; + sprite->data[5] += sprite->data[7]; + sprite->pos1.x = sprite->data[4] >> 4; + sprite->pos1.y = sprite->data[5] >> 4; + if (sprite->pos1.x > 285 || sprite->pos1.x < -45 + || sprite->pos1.y > 157 || sprite->pos1.y < -45) + DestroySpriteAndMatrix(sprite); +} + +// not used +static void sub_80B2E64(u8 taskId) +{ + if (gBattleAnimArgs[0] == 0) + { + u8 spriteId = GetAnimBattlerSpriteId(0); + + gSprites[spriteId].invisible = TRUE; + } + else + { + u8 spriteId = GetAnimBattlerSpriteId(0); + + gSprites[spriteId].invisible = FALSE; + } + DestroyAnimVisualTask(taskId); +} diff --git a/src/ghost.c b/src/ghost.c new file mode 100644 index 000000000..fbf452af6 --- /dev/null +++ b/src/ghost.c @@ -0,0 +1,1484 @@ +#include "global.h" +#include "battle_anim.h" +#include "bg.h" +#include "gpu_regs.h" +#include "palette.h" +#include "scanline_effect.h" +#include "malloc.h" +#include "graphics.h" +#include "sound.h" +#include "trig.h" +#include "util.h" +#include "decompress.h" +#include "constants/songs.h" + +static void sub_80B5268(struct Sprite *sprite); +static void sub_80B52D0(struct Sprite *sprite); +static void sub_80B5344(struct Sprite *sprite); +static void sub_80B53C0(struct Sprite *sprite); +static void sub_80B5450(struct Sprite *sprite); +static void sub_80B5470(struct Sprite *sprite); +static void sub_80B5570(u8 taskId); +static void sub_80B55C8(u8 taskId); +static void InitAnimShadowBall(struct Sprite *sprite); +static void AnimShadowBallStep(struct Sprite *sprite); +static void sub_80B57F8(struct Sprite *sprite); +static void sub_80B5810(struct Sprite *sprite); +static void sub_80B59D4(u8 taskId); +static void sub_80B5AD4(u8 taskId); +static void sub_80B5D38(u8 taskId); +static void sub_80B5DCC(u8 taskId); +static void sub_80B5EC0(struct Sprite *sprite); +static void sub_80B5FE0(struct Sprite *sprite); +static void sub_80B623C(u8 taskId); +static void sub_80B6468(u8 taskId); +static void sub_80B65F0(u8 taskId); +static void sub_80B664C(struct Sprite *sprite); +static void sub_80B66A8(struct Sprite *sprite); +static void sub_80B6728(struct Sprite *sprite); +static void sub_80B67A0(struct Sprite *sprite); +static void sub_80B67D4(struct Sprite *sprite); +static void sub_80B68A8(struct Sprite *sprite); +static void sub_80B696C(u8 taskId); +static void sub_80B6AF8(struct Sprite *sprite); +static void sub_80B7158(struct Sprite *sprite); +static void sub_80B6BE4(u8 taskId); +static void sub_80B6F30(u8 taskId); +static void sub_80B6FC4(u8 taskId); +static void sub_80B71B0(struct Sprite *sprite); + +static const union AffineAnimCmd gUnknown_83E75A8[] = +{ + AFFINEANIMCMD_FRAME(0x1E, 0x1E, 10, 5), + AFFINEANIMCMD_FRAME(0xFFE2, 0xFFE2, 10, 5), + AFFINEANIMCMD_JUMP(0), +}; + +static const union AffineAnimCmd *const gUnknown_83E75C0[] = +{ + gUnknown_83E75A8, +}; + +const struct SpriteTemplate gUnknown_83E75C4 = +{ + .tileTag = ANIM_TAG_YELLOW_BALL, + .paletteTag = ANIM_TAG_YELLOW_BALL, + .oam = &gOamData_83ACA90, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gUnknown_83E75C0, + .callback = sub_80B5268, +}; + +const struct SpriteTemplate gUnknown_83E75DC = +{ + .tileTag = ANIM_TAG_YELLOW_BALL, + .paletteTag = ANIM_TAG_YELLOW_BALL, + .oam = &gOamData_83ACAF0, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_80B5450, +}; + +static const union AffineAnimCmd gUnknown_83E75F4[] = +{ + AFFINEANIMCMD_FRAME(0x0, 0x0, 10, 1), + AFFINEANIMCMD_JUMP(0), +}; + +static const union AffineAnimCmd *const gUnknown_83E7604[] = +{ + gUnknown_83E75F4, +}; + +const struct SpriteTemplate gShadowBallSpriteTemplate = +{ + .tileTag = ANIM_TAG_SHADOW_BALL, + .paletteTag = ANIM_TAG_SHADOW_BALL, + .oam = &gOamData_83ACA38, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gUnknown_83E7604, + .callback = InitAnimShadowBall, +}; + +const union AnimCmd gUnknown_83E7620[] = +{ + ANIMCMD_FRAME(0, 2), + ANIMCMD_FRAME(8, 2), + ANIMCMD_FRAME(16, 2), + ANIMCMD_FRAME(24, 2), + ANIMCMD_FRAME(32, 2), + ANIMCMD_END, +}; + +static const union AnimCmd *const gUnknown_83E7638[] = +{ + gUnknown_83E7620, +}; + +const struct SpriteTemplate gUnknown_83E763C = +{ + .tileTag = ANIM_TAG_LICK, + .paletteTag = ANIM_TAG_LICK, + .oam = &gOamData_83ACA18, + .anims = gUnknown_83E7638, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_80B57F8, +}; + +// not used +static const union AffineAnimCmd gUnknown_83E7654[] = +{ + AFFINEANIMCMD_FRAME(0x200, 0x200, 0, 0), + AFFINEANIMCMD_END, +}; + +// not used +static const union AffineAnimCmd *const gUnknown_83E7664[] = +{ + gUnknown_83E7654, +}; + +const struct SpriteTemplate gUnknown_83E7668 = +{ + .tileTag = ANIM_TAG_WHITE_SHADOW, + .paletteTag = ANIM_TAG_WHITE_SHADOW, + .oam = &gOamData_83ACB20, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_80B5EC0, +}; + +const struct SpriteTemplate gUnknown_83E7680 = +{ + .tileTag = ANIM_TAG_NAIL, + .paletteTag = ANIM_TAG_NAIL, + .oam = &gOamData_83ACB18, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_80B664C, +}; + +const struct SpriteTemplate gUnknown_83E7698 = +{ + .tileTag = ANIM_TAG_GHOSTLY_SPIRIT, + .paletteTag = ANIM_TAG_GHOSTLY_SPIRIT, + .oam = &gOamData_83ACAF8, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_80B67D4, +}; + +const struct SpriteTemplate gUnknown_83E76B0 = +{ + .tileTag = ANIM_TAG_DEVIL, + .paletteTag = ANIM_TAG_DEVIL, + .oam = &gOamData_83ACAF8, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_80B67D4, +}; + +static const union AnimCmd gUnknown_83E76C8[] = +{ + ANIMCMD_FRAME(0, 4), + ANIMCMD_FRAME(8, 4), + ANIMCMD_FRAME(16, 4), + ANIMCMD_FRAME(24, 4), + ANIMCMD_JUMP(0), +}; + +static const union AnimCmd *const gUnknown_83E76DC[] = +{ + gUnknown_83E76C8, +}; + +const struct SpriteTemplate gUnknown_83E76E0 = +{ + .tileTag = ANIM_TAG_PURPLE_FLAME, + .paletteTag = ANIM_TAG_PURPLE_FLAME, + .oam = &gOamData_83ACB38, + .anims = gUnknown_83E76DC, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_80B6AF8, +}; + +const struct SpriteTemplate gUnknown_83E76F8 = +{ + .tileTag = 0, + .paletteTag = 0, + .oam = &gDummyOamData, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_80B7158, +}; + +static void sub_80B5268(struct Sprite *sprite) +{ + InitSpritePosToAnimAttacker(sprite, 1); + sprite->data[0] = gBattleAnimArgs[2]; + sprite->data[1] = sprite->pos1.x; + sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, 2); + sprite->data[3] = sprite->pos1.y; + sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, 3); + sub_8075678(sprite); + sprite->callback = sub_80B52D0; + sprite->data[6] = 16; + SetGpuReg(REG_OFFSET_BLDCNT, (BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_ALL)); + SetGpuReg(REG_OFFSET_BLDALPHA, sprite->data[6]); +} + +static void sub_80B52D0(struct Sprite *sprite) +{ + s16 r0, r2; + + sub_80B53C0(sprite); + if (AnimTranslateLinear(sprite)) + { + sprite->callback = sub_80B5344; + return; + } + sprite->pos2.x += Sin(sprite->data[5], 10); + sprite->pos2.y += Cos(sprite->data[5], 15); + r2 = sprite->data[5]; + sprite->data[5] = (sprite->data[5] + 5) & 0xFF; + r0 = sprite->data[5]; + if (r2 != 0 && r2 <= 196) + return; + if (r0 <= 0) + return; + PlaySE12WithPanning(SE_W109, gUnknown_2037F24); +} + +static void sub_80B5344(struct Sprite *sprite) +{ + s16 r2, r0; + + sprite->data[0] = 1; + AnimTranslateLinear(sprite); + sprite->pos2.x += Sin(sprite->data[5], 10); + sprite->pos2.y += Cos(sprite->data[5], 15); + r2 = sprite->data[5]; + sprite->data[5] = (sprite->data[5] + 5) & 0xFF; + r0 = sprite->data[5]; + if ((r2 == 0 || r2 > 196) && r0 > 0) + PlaySE(SE_W109); + if (sprite->data[6] == 0) + { + sprite->invisible = TRUE; + sprite->callback = DestroyAnimSpriteAndDisableBlend; + } + else + { + sub_80B53C0(sprite); + } +} + +static void sub_80B53C0(struct Sprite *sprite) +{ + s16 r0; + + if (sprite->data[6] > 0xFF) + { + if (++sprite->data[6] == 0x10d) + sprite->data[6] = 0; + return; + } + r0 = sprite->data[7]; + ++sprite->data[7]; + if ((r0 & 0xFF) == 0) + { + sprite->data[7] &= 0xff00; + if ((sprite->data[7] & 0x100) != 0) + ++sprite->data[6]; + else + --sprite->data[6]; + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(sprite->data[6], 16 - sprite->data[6])); + if (sprite->data[6] == 0 || sprite->data[6] == 16) + sprite->data[7] ^= 0x100; + if (sprite->data[6] == 0) + sprite->data[6] = 0x100; + } +} + +static void sub_80B5450(struct Sprite *sprite) +{ + InitSpritePosToAnimTarget(sprite, TRUE); + sprite->callback = sub_80B5470; + sprite->callback(sprite); +} + +static void sub_80B5470(struct Sprite *sprite) +{ + u16 temp1; + + sprite->pos2.x = Sin(sprite->data[0], 32); + sprite->pos2.y = Cos(sprite->data[0], 8); + temp1 = sprite->data[0] - 65; + if (temp1 <= 130) + sprite->oam.priority = 2; + else + sprite->oam.priority = 1; + sprite->data[0] = (sprite->data[0] + 19) & 0xFF; + sprite->data[2] += 80; + sprite->pos2.y += sprite->data[2] >> 8; + sprite->data[7] += 1; + if (sprite->data[7] == 61) + DestroyAnimSprite(sprite); +} + +void sub_80B54E8(u8 taskId) +{ + u8 spriteId; + + SetGpuReg(REG_OFFSET_BLDCNT, (BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_ALL)); + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0, 0x10)); + spriteId = GetAnimBattlerSpriteId(0); + PrepareBattlerSpriteForRotScale(spriteId, ST_OAM_OBJ_BLEND); + SetSpriteRotScale(spriteId, 128, 128, 0); + gSprites[spriteId].invisible = FALSE; + gTasks[taskId].data[0] = 128; + gTasks[taskId].data[1] = *gBattleAnimArgs; + gTasks[taskId].data[2] = 0; + gTasks[taskId].data[3] = 16; + gTasks[taskId].func = sub_80B5570; +} + +static void sub_80B5570(u8 taskId) +{ + gTasks[taskId].data[10] += 1; + if (gTasks[taskId].data[10] == 3) + { + gTasks[taskId].data[10] = 0; + gTasks[taskId].data[2] += 1; + gTasks[taskId].data[3] -= 1; + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gTasks[taskId].data[2], gTasks[taskId].data[3])); + if (gTasks[taskId].data[2] != 9) + return; + gTasks[taskId].func = sub_80B55C8; + } +} + +static void sub_80B55C8(u8 taskId) +{ + u8 spriteId; + + if (gTasks[taskId].data[1] > 0) + { + gTasks[taskId].data[1] -= 1; + return; + } + spriteId = GetAnimBattlerSpriteId(0); + gTasks[taskId].data[0] += 8; + if (gTasks[taskId].data[0] <= 0xFF) + { + SetSpriteRotScale(spriteId, gTasks[taskId].data[0], gTasks[taskId].data[0], 0); + } + else + { + ResetSpriteRotScale(spriteId); + DestroyAnimVisualTask(taskId); + SetGpuReg(REG_OFFSET_BLDCNT, 0); + SetGpuReg(REG_OFFSET_BLDALPHA, 0); + } +} + +// Spins a sprite towards the target, pausing in the middle. +// Used in Shadow Ball. +// arg 0: duration step 1 (attacker -> center) +// arg 1: duration step 2 (spin center) +// arg 2: duration step 3 (center -> target) +static void InitAnimShadowBall(struct Sprite *sprite) +{ + s16 oldPosX = sprite->pos1.x; + s16 oldPosY = sprite->pos1.y; + + sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 2); + sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, 3); + sprite->data[0] = 0; + sprite->data[1] = gBattleAnimArgs[0]; + sprite->data[2] = gBattleAnimArgs[1]; + sprite->data[3] = gBattleAnimArgs[2]; + sprite->data[4] = sprite->pos1.x << 4; + sprite->data[5] = sprite->pos1.y << 4; + sprite->data[6] = ((oldPosX - sprite->pos1.x) << 4) / (gBattleAnimArgs[0] << 1); + sprite->data[7] = ((oldPosY - sprite->pos1.y) << 4) / (gBattleAnimArgs[0] << 1); + sprite->callback = AnimShadowBallStep; +} + +static void AnimShadowBallStep(struct Sprite *sprite) +{ + switch (sprite->data[0]) + { + case 0: + sprite->data[4] += sprite->data[6]; + sprite->data[5] += sprite->data[7]; + sprite->pos1.x = sprite->data[4] >> 4; + sprite->pos1.y = sprite->data[5] >> 4; + sprite->data[1] -= 1; + if (sprite->data[1] > 0) + break; + sprite->data[0] += 1; + break; + case 1: + sprite->data[2] -= 1; + if (sprite->data[2] > 0) + break; + sprite->data[1] = GetBattlerSpriteCoord(gBattleAnimTarget, 2); + sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, 3); + sprite->data[4] = sprite->pos1.x << 4; + sprite->data[5] = sprite->pos1.y << 4; + sprite->data[6] = ((sprite->data[1] - sprite->pos1.x) << 4) / sprite->data[3]; + sprite->data[7] = ((sprite->data[2] - sprite->pos1.y) << 4) / sprite->data[3]; + sprite->data[0] += 1; + break; + case 2: + sprite->data[4] += sprite->data[6]; + sprite->data[5] += sprite->data[7]; + sprite->pos1.x = sprite->data[4] >> 4; + sprite->pos1.y = sprite->data[5] >> 4; + sprite->data[3] -= 1; + if (sprite->data[3] > 0) + break; + sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimTarget, 2); + sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimTarget, 3); + sprite->data[0] += 1; + break; + case 3: + DestroySpriteAndMatrix(sprite); + break; + } +} + +static void sub_80B57F8(struct Sprite *sprite) +{ + InitSpritePosToAnimTarget(sprite, TRUE); + sprite->callback = sub_80B5810; +} + +static void sub_80B5810(struct Sprite *sprite) +{ + bool8 r5 = FALSE; + bool8 r6 = FALSE; + + if (sprite->animEnded) + { + if (!sprite->invisible) + sprite->invisible = TRUE; + + switch (sprite->data[0]) + { + default: + r6 = TRUE; + break; + case 0: + if (sprite->data[1] == 2) + r5 = TRUE; + break; + case 1: + if (sprite->data[1] == 4) + r5 = TRUE; + break; + } + if (r5) + { + sprite->invisible ^= 1; + ++sprite->data[2]; + sprite->data[1] = 0; + if (sprite->data[2] == 5) + { + sprite->data[2] = 0; + ++sprite->data[0]; + } + } + else if (r6) + { + DestroyAnimSprite(sprite); + } + else + { + ++sprite->data[1]; + } + } +} + +void sub_80B58AC(u8 taskId) +{ + struct Task *task; + + task = &gTasks[taskId]; + task->data[0] = CloneBattlerSpriteWithBlend(1); + if (task->data[0] < 0) + { + DestroyAnimVisualTask(taskId); + return; + } + task->data[1] = 0; + task->data[2] = 15; + task->data[3] = 2; + task->data[4] = 0; + SetGpuReg(REG_OFFSET_BLDCNT, (BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_ALL)); + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(task->data[2], task->data[3])); + gSprites[task->data[0]].data[0] = 80; + if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER) + { + gSprites[task->data[0]].data[1] = -144; + gSprites[task->data[0]].data[2] = 112; + } + else + { + gSprites[task->data[0]].data[1] = 144; + gSprites[task->data[0]].data[2] = -112; + } + gSprites[task->data[0]].data[3] = 0; + gSprites[task->data[0]].data[4] = 0; + StoreSpriteCallbackInData6(&gSprites[task->data[0]], SpriteCallbackDummy); + gSprites[task->data[0]].callback = TranslateSpriteLinearFixedPoint; + task->func = sub_80B59D4; +} + +static void sub_80B59D4(u8 taskId) +{ + struct Task *task; + + task = &gTasks[taskId]; + switch (task->data[4]) + { + case 0: + task->data[1] += 1; + task->data[5] = task->data[1] & 3; + if (task->data[5] == 1) + if (task->data[2] > 0) + task->data[2] -= 1; + if (task->data[5] == 3) + if (task->data[3] <= 15) + task->data[3] += 1; + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(task->data[2], task->data[3])); + if (task->data[3] != 16 || task->data[2] != 0) + break; + if (task->data[1] <= 80) + break; + obj_delete_but_dont_free_vram(&gSprites[task->data[0]]); + task->data[4] = 1; + break; + case 1: + if (++task->data[6] <= 1) + break; + SetGpuReg(REG_OFFSET_BLDCNT, 0); + SetGpuReg(REG_OFFSET_BLDALPHA, 0); + task->data[4] += 1; + break; + case 2: + DestroyAnimVisualTask(taskId); + break; + } +} + +void sub_80B5AAC(u8 taskId) +{ + struct Task *task; + + task = &gTasks[taskId]; + task->data[15] = 0; + task->func = sub_80B5AD4; + task->func(taskId); +} + +static void sub_80B5AD4(u8 taskId) +{ + s16 startLine; + struct Task *task = &gTasks[taskId]; + u8 position = GetBattlerSpriteBGPriorityRank(gBattleAnimTarget); + + switch (task->data[15]) + { + case 0: + task->data[14] = AllocSpritePalette(ANIM_TAG_BENT_SPOON); + if (task->data[14] == 0xFF || task->data[14] == 0xF) + { + DestroyAnimVisualTask(taskId); + } + else + { + task->data[0] = CloneBattlerSpriteWithBlend(1); + if (task->data[0] < 0) + { + FreeSpritePaletteByTag(ANIM_TAG_BENT_SPOON); + DestroyAnimVisualTask(taskId); + } + else + { + s16 mask2; + + gSprites[task->data[0]].oam.paletteNum = task->data[14]; + gSprites[task->data[0]].oam.objMode = ST_OAM_OBJ_NORMAL; + gSprites[task->data[0]].oam.priority = 3; + gSprites[task->data[0]].invisible = (gBattleSpritesDataPtr->battlerData[gBattleAnimTarget].invisible); + task->data[1] = 0; + task->data[2] = 0; + task->data[3] = 16; + task->data[13] = GetAnimBattlerSpriteId(1); + task->data[4] = (gSprites[task->data[13]].oam.paletteNum + 16) * 16; + if (position == 1) + { + u16 mask = DISPCNT_BG1_ON; + + mask2 = mask; + } + else + { + u16 mask = DISPCNT_BG2_ON; + + mask2 = mask; + } + ClearGpuRegBits(REG_OFFSET_DISPCNT, mask2); + ++task->data[15]; + } + } + break; + case 1: + task->data[14] = (task->data[14] + 16) * 16; + CpuSet(&gPlttBufferUnfaded[task->data[4]], &gPlttBufferFaded[task->data[14]], 0x4000008); + BlendPalette(task->data[4], 16, 10, RGB(13, 0, 15)); + ++task->data[15]; + break; + case 2: + startLine = gSprites[task->data[13]].pos1.y + gSprites[task->data[13]].pos2.y - 32; + if (startLine < 0) + startLine = 0; + if (position == 1) + task->data[10] = ScanlineEffect_InitWave(startLine, startLine + 64, 2, 6, 0, 4, 1); + else + task->data[10] = ScanlineEffect_InitWave(startLine, startLine + 64, 2, 6, 0, 8, 1); + ++task->data[15]; + break; + case 3: + if (position == 1) + SetGpuReg(REG_OFFSET_BLDCNT, (BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_ALL | BLDCNT_TGT1_BG1)); + else + SetGpuReg(REG_OFFSET_BLDCNT, (BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_ALL | BLDCNT_TGT1_BG2)); + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0, 0x10)); + ++task->data[15]; + break; + case 4: + if (position == 1) + SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_BG1_ON); + else + SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_BG2_ON); + task->func = sub_80B5D38; + ++task->data[15]; + break; + default: + ++task->data[15]; + break; + } +} + +static void sub_80B5D38(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + + ++task->data[1]; + task->data[5] = task->data[1] & 1; + if (task->data[5] == 0) + task->data[2] = gSineTable[task->data[1]] / 18; + if (task->data[5] == 1) + task->data[3] = 16 - (gSineTable[task->data[1]] / 18); + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(task->data[2], task->data[3])); + if (task->data[1] == 128) + { + task->data[15] = 0; + task->func = sub_80B5DCC; + task->func(taskId); + } +} + +static void sub_80B5DCC(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + u8 rank = GetBattlerSpriteBGPriorityRank(gBattleAnimTarget); + + switch (task->data[15]) + { + case 0: + gScanlineEffect.state = 3; + task->data[14] = GetAnimBattlerSpriteId(1); + if (rank == 1) + ClearGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_BG1_ON); + else + ClearGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_BG2_ON); + break; + case 1: + BlendPalette(task->data[4], 16, 0, RGB(13, 0, 15)); + break; + case 2: + gSprites[task->data[14]].invisible = TRUE; + obj_delete_but_dont_free_vram(&gSprites[task->data[0]]); + FreeSpritePaletteByTag(ANIM_TAG_BENT_SPOON); + SetGpuReg(REG_OFFSET_BLDCNT, 0); + SetGpuReg(REG_OFFSET_BLDALPHA, 0); + if (rank == 1) + SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_BG1_ON); + else + SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_BG2_ON); + DestroyAnimVisualTask(taskId); + break; + } + ++task->data[15]; +} + +static void sub_80B5EC0(struct Sprite *sprite) +{ + s16 battler1X, battler1Y; + s16 battler2X, battler2Y; + s16 yDiff; + + if (gBattleAnimArgs[0] == 0) + { + battler1X = GetBattlerSpriteCoord(gBattleAnimAttacker, 0); + battler1Y = GetBattlerSpriteCoord(gBattleAnimAttacker, 1) + 28; + battler2X = GetBattlerSpriteCoord(gBattleAnimTarget, 0); + battler2Y = GetBattlerSpriteCoord(gBattleAnimTarget, 1) + 28; + } + else + { + battler1X = GetBattlerSpriteCoord(gBattleAnimTarget, 0); + battler1Y = GetBattlerSpriteCoord(gBattleAnimTarget, 1) + 28; + battler2X = GetBattlerSpriteCoord(gBattleAnimAttacker, 0); + battler2Y = GetBattlerSpriteCoord(gBattleAnimAttacker, 1) + 28; + } + yDiff = battler2Y - battler1Y; + sprite->data[0] = battler1X * 16; + sprite->data[1] = battler1Y * 16; + sprite->data[2] = ((battler2X - battler1X) * 16) / gBattleAnimArgs[1]; + sprite->data[3] = (yDiff * 16) / gBattleAnimArgs[1]; + sprite->data[4] = gBattleAnimArgs[1]; + sprite->data[5] = battler2X; + sprite->data[6] = battler2Y; + sprite->data[7] = sprite->data[4] / 2; + sprite->oam.priority = 2; + sprite->pos1.x = battler1X; + sprite->pos1.y = battler1Y; + sprite->callback = sub_80B5FE0; + sprite->invisible = TRUE; +} + +static void sub_80B5FE0(struct Sprite *sprite) +{ + if (sprite->data[4]) + { + sprite->data[0] += sprite->data[2]; + sprite->data[1] += sprite->data[3]; + sprite->pos1.x = sprite->data[0] >> 4; + sprite->pos1.y = sprite->data[1] >> 4; + if (--sprite->data[4] == 0) + sprite->data[0] = 0; + } +} + +void sub_80B6020(u8 taskId) +{ + struct Task *task; + s16 battler; + u8 spriteId; + s16 baseX, baseY; + s16 x, y; + + task = &gTasks[taskId]; + SetGpuReg(REG_OFFSET_BLDCNT, (BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_ALL)); + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0, 0x10)); + task->data[5] = 0; + task->data[6] = 0; + task->data[7] = 0; + task->data[8] = 0; + task->data[9] = 16; + task->data[10] = gBattleAnimArgs[0]; + baseX = GetBattlerSpriteCoord(gBattleAnimAttacker, 2); + baseY = GetBattlerSpriteCoordAttr(gBattleAnimAttacker, BATTLER_COORD_ATTR_BOTTOM); + if (!IsContest()) + { + for (battler = 0; battler < 4; ++battler) + { + if (battler != gBattleAnimAttacker + && battler != (gBattleAnimAttacker ^ 2) + && IsBattlerSpriteVisible(battler)) + { + spriteId = CreateSprite(&gUnknown_83E7668, baseX, baseY, 55); + if (spriteId != MAX_SPRITES) + { + x = GetBattlerSpriteCoord(battler, 2); + y = GetBattlerSpriteCoordAttr(battler, BATTLER_COORD_ATTR_BOTTOM); + gSprites[spriteId].data[0] = baseX << 4; + gSprites[spriteId].data[1] = baseY << 4; + gSprites[spriteId].data[2] = ((x - baseX) << 4) / gBattleAnimArgs[1]; + gSprites[spriteId].data[3] = ((y - baseY) << 4) / gBattleAnimArgs[1]; + gSprites[spriteId].data[4] = gBattleAnimArgs[1]; + gSprites[spriteId].data[5] = x; + gSprites[spriteId].data[6] = y; + gSprites[spriteId].callback = sub_80B5FE0; + task->data[task->data[12] + 13] = spriteId; + ++task->data[12]; + } + } + } + } + else + { + spriteId = CreateSprite(&gUnknown_83E7668, baseX, baseY, 55); + if (spriteId != MAX_SPRITES) + { + x = 48; + y = 40; + gSprites[spriteId].data[0] = baseX << 4; + gSprites[spriteId].data[1] = baseY << 4; + gSprites[spriteId].data[2] = ((x - baseX) << 4) / gBattleAnimArgs[1]; + gSprites[spriteId].data[3] = ((y - baseY) << 4) / gBattleAnimArgs[1]; + gSprites[spriteId].data[4] = gBattleAnimArgs[1]; + gSprites[spriteId].data[5] = x; + gSprites[spriteId].data[6] = y; + gSprites[spriteId].callback = sub_80B5FE0; + task->data[13] = spriteId; + task->data[12] = 1; + } + } + task->func = sub_80B623C; +} + +static void sub_80B623C(u8 taskId) +{ + u16 i; + struct Task *task = &gTasks[taskId]; + + switch (task->data[0]) + { + case 0: + if (task->data[6] == 0) + { + if (++task->data[5] > 1) + { + task->data[5] = 0; + ++task->data[7]; + if (task->data[7] & 1) + { + if (task->data[8] < 16) + ++task->data[8]; + } + else + { + if (task->data[9]) + --task->data[9]; + } + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(task->data[8], task->data[9])); + if (task->data[7] >= 24) + { + task->data[7] = 0; + task->data[6] = 1; + } + } + } + if (task->data[10]) + --task->data[10]; + else if (task->data[6]) + ++task->data[0]; + break; + case 1: + if (++task->data[5] > 1) + { + task->data[5] = 0; + ++task->data[7]; + if (task->data[7] & 1) + { + if (task->data[8]) + --task->data[8]; + } + else if (task->data[9] < 16) + { + ++task->data[9]; + } + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(task->data[8], task->data[9])); + if (task->data[8] == 0 && task->data[9] == 16) + { + for (i = 0; i < task->data[12]; ++i) + DestroySprite(&gSprites[task->data[i + 13]]); + ++task->data[0]; + } + } + break; + case 2: + if (++task->data[5] > 0) + ++task->data[0]; + break; + case 3: + SetGpuReg(REG_OFFSET_BLDCNT, 0); + SetGpuReg(REG_OFFSET_BLDALPHA, 0); + DestroyAnimVisualTask(taskId); + break; + } +} + +void sub_80B63B4(u8 taskId) +{ + s16 startX, startY; + s16 leftDistance, topDistance, bottomDistance, rightDistance; + + gBattle_WIN0H = 0; + gBattle_WIN0V = 0; + SetGpuReg(REG_OFFSET_WININ, ((WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR) | + (WININ_WIN1_BG_ALL | WININ_WIN1_OBJ | WININ_WIN1_CLR))); + SetGpuReg(REG_OFFSET_WINOUT, ((WINOUT_WIN01_BG_ALL | WINOUT_WIN01_OBJ) | + (WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ | WINOUT_WINOBJ_CLR))); + SetGpuReg(REG_OFFSET_BLDCNT, (BLDCNT_TGT1_BG3 | BLDCNT_EFFECT_DARKEN)); + SetGpuReg(REG_OFFSET_BLDY, 0x10); + if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER || IsContest()) + startX = 40; + else + startX = 200; + gBattle_WIN0H = WIN_RANGE(startX, startX); + startY = 40; + gBattle_WIN0V = WIN_RANGE(startY, startY); + leftDistance = startX; + rightDistance = 240 - startX; + topDistance = startY; + bottomDistance = 72; + gTasks[taskId].data[1] = leftDistance; + gTasks[taskId].data[2] = rightDistance; + gTasks[taskId].data[3] = topDistance; + gTasks[taskId].data[4] = bottomDistance; + gTasks[taskId].data[5] = startX; + gTasks[taskId].data[6] = startY; + gTasks[taskId].func = sub_80B6468; +} + +static void sub_80B6468(u8 taskId) +{ + s16 step, leftDistance, rightDistance, topDistance, bottomDistance, startX, startY; + u16 left, right, top, bottom, selectedPalettes; + + step = gTasks[taskId].data[0]; + ++gTasks[taskId].data[0]; + leftDistance = gTasks[taskId].data[1]; + rightDistance = gTasks[taskId].data[2]; + topDistance = gTasks[taskId].data[3]; + bottomDistance = gTasks[taskId].data[4]; + startX = gTasks[taskId].data[5]; + startY = gTasks[taskId].data[6]; + if (step < 16) + { + left = startX - (leftDistance * 0.0625) * step; + right = startX + (rightDistance * 0.0625) * step; + top = startY - (topDistance * 0.0625) * step; + bottom = startY + (bottomDistance * 0.0625) * step; + } + else + { + left = 0; + right = 240; + top = 0; + bottom = 112; + selectedPalettes = sub_8075BE8(1, 0, 0, 0, 0, 0, 0); + BeginNormalPaletteFade(selectedPalettes, 0, 16, 16, RGB(0, 0, 0)); + gTasks[taskId].func = sub_80B65F0; + } + gBattle_WIN0H = WIN_RANGE(left, right); + gBattle_WIN0V = WIN_RANGE(top, bottom); +} + +static void sub_80B65F0(u8 taskId) +{ + if (!gPaletteFade.active) + { + gBattle_WIN0H = 0; + gBattle_WIN0V = 0; + SetGpuReg(REG_OFFSET_WININ, ((WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR) | + (WININ_WIN1_BG_ALL | WININ_WIN1_OBJ | WININ_WIN1_CLR))); + SetGpuReg(REG_OFFSET_WINOUT, ((WINOUT_WIN01_BG_ALL | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR) | + (WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ | WINOUT_WINOBJ_CLR))); + SetGpuReg(REG_OFFSET_BLDCNT, 0); + SetGpuReg(REG_OFFSET_BLDY, 0); + DestroyAnimVisualTask(taskId); + } +} + +static void sub_80B664C(struct Sprite *sprite) +{ + s16 xDelta, xDelta2; + + InitSpritePosToAnimAttacker(sprite, 1); + if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER) + { + xDelta = 24; + xDelta2 = -2; + sprite->oam.matrixNum = ST_OAM_HFLIP; + } + else + { + xDelta = -24; + xDelta2 = 2; + } + sprite->pos1.x += xDelta; + sprite->data[1] = xDelta2; + sprite->data[0] = 60; + sprite->callback = sub_80B66A8; +} + +static void sub_80B66A8(struct Sprite *sprite) +{ + u16 var0; + + if (sprite->data[0] > 0) + { + --sprite->data[0]; + } + else + { + sprite->pos2.x += sprite->data[1]; + var0 = sprite->pos2.x + 7; + if (var0 > 14) + { + sprite->pos1.x += sprite->pos2.x; + sprite->pos2.x = 0; + sprite->oam.tileNum += 8; + if (++sprite->data[2] == 3) + { + sprite->data[0] = 30; + sprite->callback = WaitAnimForDuration; + StoreSpriteCallbackInData6(sprite, sub_80B6728); + } + else + { + sprite->data[0] = 40; + } + } + } +} + +static void sub_80B6728(struct Sprite *sprite) +{ + if (sprite->data[0] == 0) + { + SetGpuReg(REG_OFFSET_BLDCNT, (BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_ALL)); + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(16, 0)); + ++sprite->data[0]; + sprite->data[1] = 0; + sprite->data[2] = 0; + } + else if (sprite->data[1] < 2) + { + ++sprite->data[1]; + } + else + { + sprite->data[1] = 0; + ++sprite->data[2]; + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND2(16 - sprite->data[2], sprite->data[2])); + if (sprite->data[2] == 16) + { + sprite->invisible = TRUE; + sprite->callback = sub_80B67A0; + } + } +} + +static void sub_80B67A0(struct Sprite *sprite) +{ + SetGpuReg(REG_OFFSET_BLDCNT, 0); + SetGpuReg(REG_OFFSET_BLDALPHA, 0); + gBattle_WIN0H = 0; + gBattle_WIN0V = 0; + DestroyAnimSprite(sprite); +} + +static void sub_80B67D4(struct Sprite *sprite) +{ + u16 coeffB, coeffA; + + sprite->pos2.x = Sin(sprite->data[0], 12); + if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) + sprite->pos2.x = -sprite->pos2.x; + sprite->data[0] = (sprite->data[0] + 6) & 0xFF; + sprite->data[1] += 0x100; + sprite->pos2.y = -(sprite->data[1] >> 8); + ++sprite->data[7]; + if (sprite->data[7] == 1) + { + sprite->data[6] = 0x050B; + SetGpuReg(REG_OFFSET_BLDCNT, (BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_ALL)); + SetGpuReg(REG_OFFSET_BLDALPHA, sprite->data[6]); + } + else if (sprite->data[7] > 30) + { + ++sprite->data[2]; + coeffB = sprite->data[6] >> 8; + coeffA = sprite->data[6] & 0xFF; + if (++coeffB > 16) + coeffB = 16; + --coeffA; + if ((s16)coeffA < 0) + coeffA = 0; + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(coeffA, coeffB)); + sprite->data[6] = BLDALPHA_BLEND(coeffA, coeffB); + if (coeffB == 16 && coeffA == 0) + { + sprite->invisible = TRUE; + sprite->callback = sub_80B68A8; + } + } +} + +static void sub_80B68A8(struct Sprite *sprite) +{ + SetGpuReg(REG_OFFSET_BLDCNT, 0); + SetGpuReg(REG_OFFSET_BLDALPHA, 0); + DestroyAnimSprite(sprite); +} + +void sub_80B68C8(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + + task->data[0] = 0; + task->data[1] = 16; + task->data[9] = GetBattlerSpriteCoord(gBattleAnimAttacker, 2); + task->data[10] = GetBattlerYCoordWithElevation(gBattleAnimAttacker); + task->data[11] = (GetBattlerSpriteCoordAttr(gBattleAnimAttacker, BATTLER_COORD_ATTR_WIDTH) / 2) + 8; + task->data[7] = 0; + task->data[5] = GetBattlerSpriteBGPriority(gBattleAnimAttacker); + task->data[6] = GetBattlerSpriteSubpriority(gBattleAnimAttacker) - 2; + task->data[3] = 0; + task->data[4] = 16; + SetGpuReg(REG_OFFSET_BLDCNT, (BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_ALL)); + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0, 0x10)); + task->data[8] = 0; + task->func = sub_80B696C; +} + +static void sub_80B696C(u8 taskId) +{ + u16 i; + u8 spriteId; + struct Task *task = &gTasks[taskId]; + + switch (task->data[0]) + { + case 0: + for (i = 0; i < 6; ++i) + { + spriteId = CreateSprite(&gUnknown_83E76E0, task->data[9], task->data[10], task->data[6]); + if (spriteId != MAX_SPRITES) + { + gSprites[spriteId].data[0] = taskId; + gSprites[spriteId].data[1] = GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER; + gSprites[spriteId].data[2] = (i * 42) & 0xFF; + gSprites[spriteId].data[3] = task->data[11]; + gSprites[spriteId].data[5] = i * 6; + ++task->data[7]; + } + } + ++task->data[0]; + break; + case 1: + if (++task->data[1] & 1) + { + if (task->data[3] < 14) + ++task->data[3]; + } + else if (task->data[4] > 4) + { + --task->data[4]; + } + if (task->data[3] == 14 && task->data[4] == 4) + { + task->data[1] = 0; + ++task->data[0]; + } + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(task->data[3], task->data[4])); + break; + case 2: + if (++task->data[1] > 30) + { + task->data[1] = 0; + ++task->data[0]; + } + break; + case 3: + if (++task->data[1] & 1) + { + if (task->data[3] > 0) + --task->data[3]; + } + else if (task->data[4] < 16) + { + ++task->data[4]; + } + + if (task->data[3] == 0 && task->data[4] == 16) + { + task->data[8] = 1; + ++task->data[0]; + } + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(task->data[3], task->data[4])); + break; + case 4: + if (task->data[7] == 0) + ++task->data[0]; + break; + case 5: + SetGpuReg(REG_OFFSET_BLDCNT, 0); + SetGpuReg(REG_OFFSET_BLDALPHA, 0); + DestroyAnimVisualTask(taskId); + break; + } +} + +static void sub_80B6AF8(struct Sprite *sprite) +{ + u16 index; + + if (sprite->data[1] == 0) + sprite->data[2] += 2; + else + sprite->data[2] -= 2; + sprite->data[2] &= 0xFF; + sprite->pos2.x = Sin(sprite->data[2], sprite->data[3]); + index = sprite->data[2] - 65; + if (index < 127) + sprite->oam.priority = gTasks[sprite->data[0]].data[5] + 1; + else + sprite->oam.priority = gTasks[sprite->data[0]].data[5]; + ++sprite->data[5]; + sprite->data[6] = (sprite->data[5] * 8) & 0xFF; + sprite->pos2.y = Sin(sprite->data[6], 7); + if (gTasks[sprite->data[0]].data[8]) + { + --gTasks[sprite->data[0]].data[7]; + DestroySprite(sprite); + } +} + +void sub_80B6BBC(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + + task->data[15] = 0; + task->func = sub_80B6BE4; + sub_80B6BE4(taskId); +} + +static void sub_80B6BE4(u8 taskId) +{ + s16 y; + struct BattleAnimBgData animBgData; + struct Task *task = &gTasks[taskId]; + u8 rank = GetBattlerSpriteBGPriorityRank(gBattleAnimAttacker); + + switch (task->data[15]) + { + case 0: + SetAnimBgAttribute(1, BG_ANIM_PRIORITY, 2); + SetAnimBgAttribute(2, BG_ANIM_PRIORITY, 1); + task->data[1] = 0; + task->data[2] = 0; + task->data[3] = 16; + task->data[4] = GetAnimBattlerSpriteId(0); + task->data[5] = gSprites[task->data[4]].oam.priority; + task->data[6] = (gSprites[task->data[4]].oam.paletteNum + 16) << 4; + gSprites[task->data[4]].oam.objMode = ST_OAM_OBJ_BLEND; + gSprites[task->data[4]].oam.priority = 3; + task->data[7] = 128; + break; + case 1: + ++task->data[1]; + if (task->data[1] & 1) + return; + BlendPalette(task->data[6], 0x10, task->data[2], RGB(0, 23, 25)); + BlendPalette(task->data[7], 0x10, task->data[2], RGB(0, 23, 25)); + if (task->data[2] <= 11) + { + ++task->data[2]; + return; + } + task->data[1] = 0; + task->data[2] = 0; + SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG2 | BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_ALL); + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0, 0x10)); + break; + case 2: + SetAnimBgAttribute(2, BG_ANIM_CHAR_BASE_BLOCK, 1); + SetAnimBgAttribute(2, BG_ANIM_SCREEN_SIZE, 0); + gBattle_BG2_X = 0; + gBattle_BG2_Y = 0; + SetGpuReg(REG_OFFSET_BG2HOFS, gBattle_BG2_X); + SetGpuReg(REG_OFFSET_BG2VOFS, gBattle_BG2_Y); + sub_80752C8(&animBgData, 2); + AnimLoadCompressedBgGfx(animBgData.bgId, gFile_graphics_battle_anims_backgrounds_scary_face_sheet, animBgData.tilesOffset); + LoadCompressedPalette(gFile_graphics_battle_anims_backgrounds_scary_face_palette, 16 * animBgData.paletteId, 0x20); + break; + case 3: + sub_80752C8(&animBgData, 2); + gMonSpritesGfxPtr->field_17C = AllocZeroed(0x2000); + LZDecompressWram(gFile_graphics_battle_anims_backgrounds_scary_face_player_tilemap, gMonSpritesGfxPtr->field_17C); + sub_80730C0(animBgData.paletteId, gMonSpritesGfxPtr->field_17C, 256, 0); + CopyToBgTilemapBufferRect_ChangePalette(animBgData.bgId, gMonSpritesGfxPtr->field_17C, 0, 0, 0x20, 0x20, 0x11); + CopyBgTilemapBufferToVram(2); + FREE_AND_SET_NULL(gMonSpritesGfxPtr->field_17C); + break; + case 4: + ++task->data[1]; + if (task->data[1] & 1) + return; + ++task->data[2]; + --task->data[3]; + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(task->data[2], task->data[3])); + if (task->data[3]) + return; + task->data[1] = 0; + task->data[2] = 0; + task->data[3] = 16; + SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG1 | BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_ALL); + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0, 0x10)); + SetAnimBgAttribute(1, BG_ANIM_PRIORITY, 1); + SetAnimBgAttribute(2, BG_ANIM_PRIORITY, 2); + break; + case 5: + if (rank == 1) + ClearGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_BG1_ON); + else + ClearGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_BG2_ON); + break; + case 6: + y = gSprites[task->data[4]].pos1.y + gSprites[task->data[4]].pos2.y - 0x20; + if (y < 0) + y = 0; + if (rank == 1) + task->data[10] = ScanlineEffect_InitWave(y, y + 0x40, 4, 8, 0, 4, 1); + else + task->data[10] = ScanlineEffect_InitWave(y, y + 0x40, 4, 8, 0, 8, 1); + break; + case 7: + BlendPalette(task->data[7], 0x10, 0xC, RGB(31, 31, 29)); + if (rank == 1) + SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_BG1_ON); + else + SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_BG2_ON); + task->func = sub_80B6F30; + task->data[15] = 0; + break; + } + ++task->data[15]; +} + +static void sub_80B6F30(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + + ++task->data[1]; + task->data[8] = task->data[1] & 1; + if (!task->data[8]) + task->data[2] = gSineTable[task->data[1]] / 18; + if (task->data[8] == 1) + task->data[3] = 16 - gSineTable[task->data[1]] / 18; + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(task->data[2], task->data[3])); + if (task->data[1] == 128) + { + task->data[15] = 0; + task->func = sub_80B6FC4; + sub_80B6FC4(taskId); + } +} + +static void sub_80B6FC4(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + + switch (task->data[15]) + { + case 0: + gScanlineEffect.state = 3; + BlendPalette(task->data[7], 0x10, 0xC, RGB(0, 23, 25)); + break; + case 1: + SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG2 | BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_ALL); + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0x10, 0)); + task->data[2] = 16; + task->data[3] = 0; + break; + case 2: + --task->data[2]; + ++task->data[3]; + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(task->data[2], task->data[3])); + if (task->data[3] <= 15) + return; + SetAnimBgAttribute(1, BG_ANIM_PRIORITY, 2); + SetAnimBgAttribute(2, BG_ANIM_PRIORITY, 2); + break; + case 3: + sub_8075358(2); + FillPalette(0, 0x90, 0x20); + SetAnimBgAttribute(2, BG_ANIM_CHAR_BASE_BLOCK, 0); + task->data[1] = 12; + break; + case 4: + BlendPalette(task->data[6], 0x10, task->data[1], RGB(0, 23, 25)); + BlendPalette(task->data[7], 0x10, task->data[1], RGB(0, 23, 25)); + if ( task->data[1] ) + { + --task->data[1]; + return; + } + task->data[1] = 0; + SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG2 | BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_ALL); + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0, 0x10)); + break; + case 5: + gSprites[task->data[4]].oam.priority = task->data[5]; + gSprites[task->data[4]].oam.objMode = ST_OAM_OBJ_NORMAL; + SetAnimBgAttribute(1, BG_ANIM_PRIORITY, 1); + SetAnimBgAttribute(2, BG_ANIM_PRIORITY, 1); + SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_EFFECT_NONE); + SetGpuReg(REG_OFFSET_BLDALPHA, 0); + DestroyAnimVisualTask(taskId); + break; + } + ++task->data[15]; +} + +static void sub_80B7158(struct Sprite *sprite) +{ + sprite->invisible = TRUE; + sprite->data[5] = gBattlerSpriteIds[gBattleAnimAttacker]; + sprite->data[0] = 128; + sprite->data[1] = 10; + sprite->data[2] = gBattleAnimArgs[0]; + sprite->data[3] = gBattleAnimArgs[1]; + sprite->callback = sub_80B71B0; + gSprites[sprite->data[5]].pos1.y += 8; +} + +static void sub_80B71B0(struct Sprite *sprite) +{ + if (sprite->data[3]) + { + --sprite->data[3]; + gSprites[sprite->data[5]].pos2.x = Sin(sprite->data[0], sprite->data[1]); + gSprites[sprite->data[5]].pos2.y = Cos(sprite->data[0], sprite->data[1]); + sprite->data[0] += sprite->data[2]; + if (sprite->data[0] > 255) + sprite->data[0] -= 256; + } + else + { + gSprites[sprite->data[5]].pos2.x = 0; + gSprites[sprite->data[5]].pos2.y = 0; + gSprites[sprite->data[5]].pos1.y -= 8; + sprite->callback = DestroySpriteAndMatrix; + } +} diff --git a/src/ground.c b/src/ground.c new file mode 100644 index 000000000..4ae4d8370 --- /dev/null +++ b/src/ground.c @@ -0,0 +1,724 @@ +#include "global.h" +#include "battle_anim.h" +#include "random.h" +#include "scanline_effect.h" +#include "task.h" +#include "trig.h" + +static void AnimBonemerangProjectile(struct Sprite *sprite); +static void AnimBoneHitProjectile(struct Sprite *sprite); +static void AnimDirtScatter(struct Sprite *sprite); +static void AnimMudSportDirt(struct Sprite *sprite); +static void AnimFissureDirtPlumeParticle(struct Sprite *sprite); +static void AnimDigDirtMound(struct Sprite *sprite); +static void AnimBonemerangProjectileStep(struct Sprite *sprite); +static void AnimBonemerangProjectileEnd(struct Sprite *sprite); +static void AnimMudSportDirtRising(struct Sprite *sprite); +static void AnimMudSportDirtFalling(struct Sprite *sprite); +static void sub_80B8ED4(u8 taskId); +static void sub_80B908C(u8 taskId); +static void sub_80B92B8(u8 useBg1, s16 y, s16 endY); +static void sub_80B912C(u8 taskId); +static void sub_80B91B0(u8 taskId); +static void AnimFissureDirtPlumeParticleStep(struct Sprite *sprite); +static void sub_80B9584(u8 taskId); +static void sub_80B967C(u8 taskId); +static void sub_80B9760(struct Task *task); +static void sub_80B98A8(u8 taskId); + +static const union AffineAnimCmd gUnknown_83E7A00[] = +{ + AFFINEANIMCMD_FRAME(0x0, 0x0, 15, 1), + AFFINEANIMCMD_JUMP(0), +}; + +static const union AffineAnimCmd gUnknown_83E7A10[] = +{ + AFFINEANIMCMD_FRAME(0x0, 0x0, 20, 1), + AFFINEANIMCMD_JUMP(0), +}; + +static const union AffineAnimCmd *const gUnknown_83E7A20[] = +{ + gUnknown_83E7A00, +}; + +static const union AffineAnimCmd *const gUnknown_83E7A24[] = +{ + gUnknown_83E7A10, +}; + +const struct SpriteTemplate gUnknown_83E7A28 = +{ + .tileTag = ANIM_TAG_BONE, + .paletteTag = ANIM_TAG_BONE, + .oam = &gOamData_83ACA38, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gUnknown_83E7A20, + .callback = AnimBonemerangProjectile, +}; + +const struct SpriteTemplate gUnknown_83E7A40 = +{ + .tileTag = ANIM_TAG_BONE, + .paletteTag = ANIM_TAG_BONE, + .oam = &gOamData_83ACA38, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gUnknown_83E7A24, + .callback = AnimBoneHitProjectile, +}; + +const struct SpriteTemplate gUnknown_83E7A58 = +{ + .tileTag = ANIM_TAG_MUD_SAND, + .paletteTag = ANIM_TAG_MUD_SAND, + .oam = &gOamData_83AC9C8, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimDirtScatter, +}; + +static const union AnimCmd gUnknown_83E7A70[] = +{ + ANIMCMD_FRAME(1, 1), + ANIMCMD_END, +}; + +static const union AnimCmd *const gUnknown_83E7A78[] = +{ + gUnknown_83E7A70, +}; + +const struct SpriteTemplate gUnknown_83E7A7C = +{ + .tileTag = ANIM_TAG_MUD_SAND, + .paletteTag = ANIM_TAG_MUD_SAND, + .oam = &gOamData_83AC9D0, + .anims = gUnknown_83E7A78, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimDirtScatter, +}; + +const struct SpriteTemplate gUnknown_83E7A94 = +{ + .tileTag = ANIM_TAG_MUD_SAND, + .paletteTag = ANIM_TAG_MUD_SAND, + .oam = &gOamData_83AC9D0, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimMudSportDirt, +}; + +const struct SpriteTemplate gUnknown_83E7AAC = +{ + .tileTag = ANIM_TAG_MUD_SAND, + .paletteTag = ANIM_TAG_MUD_SAND, + .oam = &gOamData_83AC9C8, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimFissureDirtPlumeParticle, +}; + +const struct SpriteTemplate gUnknown_83E7AC4 = +{ + .tileTag = ANIM_TAG_DIRT_MOUND, + .paletteTag = ANIM_TAG_DIRT_MOUND, + .oam = &gOamData_83AC9F8, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimDigDirtMound, +}; + +// Moves a bone projectile towards the target mon, which moves like +// a boomerang. After hitting the target mon, it comes back to the user. +static void AnimBonemerangProjectile(struct Sprite *sprite) +{ + sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 2); + sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, 3); + sprite->data[0] = 20; + sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, 2); + sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, 3); + sprite->data[5] = -40; + InitAnimArcTranslation(sprite); + sprite->callback = AnimBonemerangProjectileStep; +} + +static void AnimBonemerangProjectileStep(struct Sprite *sprite) +{ + if (TranslateAnimHorizontalArc(sprite)) + { + sprite->pos1.x += sprite->pos2.x; + sprite->pos1.y += sprite->pos2.y; + sprite->pos2.y = 0; + sprite->pos2.x = 0; + sprite->data[0] = 20; + sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimAttacker, 2); + sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimAttacker, 3); + sprite->data[5] = 40; + InitAnimArcTranslation(sprite); + sprite->callback = AnimBonemerangProjectileEnd; + } +} + +static void AnimBonemerangProjectileEnd(struct Sprite *sprite) +{ + if (TranslateAnimHorizontalArc(sprite)) + DestroyAnimSprite(sprite); +} + +// Moves a bone projectile towards the target mon, starting right next to +// the target mon. +// arg 0: initial x pixel offset +// arg 1: initial y pixel offset +// arg 2: target x pixel offset +// arg 3: target y pixel offset +// arg 4: duration +static void AnimBoneHitProjectile(struct Sprite *sprite) +{ + InitSpritePosToAnimTarget(sprite, TRUE); + if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) + gBattleAnimArgs[2] = -gBattleAnimArgs[2]; + sprite->data[0] = gBattleAnimArgs[4]; + sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, 2) + gBattleAnimArgs[2]; + sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, 3) + gBattleAnimArgs[3]; + sprite->callback = StartAnimLinearTranslation; + StoreSpriteCallbackInData6(sprite, DestroyAnimSprite); +} + +// Moves a small dirt projectile towards the target mon. +// arg 0: initial x pixel offset +// arg 1: initial y pixel offset +// arg 2: duration +// arg 3: target x pixel offset +// arg 4: target y pixel offset +static void AnimDirtScatter(struct Sprite *sprite) +{ + u8 targetXPos, targetYPos; + s16 xOffset, yOffset; + + InitSpritePosToAnimAttacker(sprite, 1); + targetXPos = GetBattlerSpriteCoord2(gBattleAnimTarget, 2); + targetYPos = GetBattlerSpriteCoord2(gBattleAnimTarget, 3); + xOffset = Random() & 0x1F; + yOffset = Random() & 0x1F; + if (xOffset > 16) + xOffset = 16 - xOffset; + if (yOffset > 16) + yOffset = 16 - yOffset; + sprite->data[0] = gBattleAnimArgs[2]; + sprite->data[2] = targetXPos + xOffset; + sprite->data[4] = targetYPos + yOffset; + sprite->callback = StartAnimLinearTranslation; + StoreSpriteCallbackInData6(sprite, DestroySpriteAndMatrix); +} + +// Moves a particle of dirt in the Mud Sport animation. +// The dirt can either be rising upward, or falling down. +// arg 0: 0 = dirt is rising into the air, 1 = dirt is falling down +// arg 1: initial x pixel offset +// arg 2: initial y pixel offset +static void AnimMudSportDirt(struct Sprite *sprite) +{ + ++sprite->oam.tileNum; + if (gBattleAnimArgs[0] == 0) + { + sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 2) + gBattleAnimArgs[1]; + sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, 3) + gBattleAnimArgs[2]; + sprite->data[0] = gBattleAnimArgs[1] > 0 ? 1 : -1; + sprite->callback = AnimMudSportDirtRising; + } + else + { + sprite->pos1.x = gBattleAnimArgs[1]; + sprite->pos1.y = gBattleAnimArgs[2]; + sprite->pos2.y = -gBattleAnimArgs[2]; + sprite->callback = AnimMudSportDirtFalling; + } +} + +static void AnimMudSportDirtRising(struct Sprite *sprite) +{ + if (++sprite->data[1] > 1) + { + sprite->data[1] = 0; + sprite->pos1.x += sprite->data[0]; + } + sprite->pos1.y -= 4; + if (sprite->pos1.y < -4) + DestroyAnimSprite(sprite); +} + +static void AnimMudSportDirtFalling(struct Sprite *sprite) +{ + switch (sprite->data[0]) + { + case 0: + sprite->pos2.y += 4; + if (sprite->pos2.y >= 0) + { + sprite->pos2.y = 0; + ++sprite->data[0]; + } + break; + case 1: + if (++sprite->data[1] > 0) + { + sprite->data[1] = 0; + sprite->invisible ^= 1; + if (++sprite->data[2] == 10) + DestroyAnimSprite(sprite); + } + break; + } +} + +void sub_80B8E94(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + + if (gBattleAnimArgs[0] == 0) + task->func = sub_80B8ED4; + else + task->func = sub_80B908C; + task->func(taskId); +} + +static void sub_80B8ED4(u8 taskId) +{ + u8 var0; + struct Task *task = &gTasks[taskId]; + + switch (task->data[0]) + { + case 0: + task->data[10] = GetAnimBattlerSpriteId(0); + task->data[11] = GetBattlerSpriteBGPriorityRank(gBattleAnimAttacker); + if (task->data[11] == 1) + { + task->data[12] = gBattle_BG1_X; + task->data[13] = gBattle_BG1_Y; + } + else + { + task->data[12] = gBattle_BG2_X; + task->data[13] = gBattle_BG2_Y; + } + var0 = GetBattlerYCoordWithElevation(gBattleAnimAttacker); + task->data[14] = var0 - 32; + task->data[15] = var0 + 32; + if (task->data[14] < 0) + task->data[14] = 0; + gSprites[task->data[10]].invisible = TRUE; + ++task->data[0]; + break; + case 1: + sub_80B92B8(task->data[11], task->data[14], task->data[15]); + ++task->data[0]; + break; + case 2: + task->data[2] = (task->data[2] + 6) & 0x7F; + if (++task->data[4] > 2) + { + task->data[4] = 0; + ++task->data[3]; + } + task->data[5] = task->data[3] + (gSineTable[task->data[2]] >> 4); + if (task->data[11] == 1) + gBattle_BG1_Y = task->data[13] - task->data[5]; + else + gBattle_BG2_Y = task->data[13] - task->data[5]; + + if (task->data[5] > 63) + { + task->data[5] = 120 - task->data[14]; + if (task->data[11] == 1) + gBattle_BG1_Y = task->data[13] - task->data[5]; + else + gBattle_BG2_Y = task->data[13] - task->data[5]; + + gSprites[task->data[10]].pos2.x = 272 - gSprites[task->data[10]].pos1.x; + ++task->data[0]; + } + break; + case 3: + gScanlineEffect.state = 3; + ++task->data[0]; + break; + case 4: + DestroyAnimVisualTask(taskId); + gSprites[task->data[10]].invisible = TRUE; + break; + } +} + +static void sub_80B908C(u8 taskId) +{ + u8 spriteId = GetAnimBattlerSpriteId(0); + + gSprites[spriteId].invisible = TRUE; + gSprites[spriteId].pos2.x = 0; + gSprites[spriteId].pos2.y = 0; + if (GetBattlerSpriteBGPriorityRank(gBattleAnimAttacker) == 1) + gBattle_BG1_Y = 0; + else + gBattle_BG2_Y = 0; + DestroyAnimVisualTask(taskId); +} + +void sub_80B90EC(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + + if (gBattleAnimArgs[0] == 0) + task->func = sub_80B912C; + else + task->func = sub_80B91B0; + + task->func(taskId); +} + +static void sub_80B912C(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + + switch (task->data[0]) + { + case 0: + task->data[10] = GetAnimBattlerSpriteId(0); + gSprites[task->data[10]].invisible = FALSE; + gSprites[task->data[10]].pos2.x = 0; + gSprites[task->data[10]].pos2.y = 160 - gSprites[task->data[10]].pos1.y; + ++task->data[0]; + break; + case 1: + DestroyAnimVisualTask(taskId); + } +} + +static void sub_80B91B0(u8 taskId) +{ + u8 var0; + struct Task *task = &gTasks[taskId]; + + switch (task->data[0]) + { + case 0: + task->data[10] = GetAnimBattlerSpriteId(0); + task->data[11] = GetBattlerSpriteBGPriorityRank(gBattleAnimAttacker); + if (task->data[11] == 1) + task->data[12] = gBattle_BG1_X; + else + task->data[12] = gBattle_BG2_X; + + var0 = GetBattlerYCoordWithElevation(gBattleAnimAttacker); + task->data[14] = var0 - 32; + task->data[15] = var0 + 32; + ++task->data[0]; + break; + case 1: + sub_80B92B8(task->data[11], 0, task->data[15]); + ++task->data[0]; + break; + case 2: + gSprites[task->data[10]].pos2.y = 96; + ++task->data[0]; + break; + case 3: + gSprites[task->data[10]].pos2.y -= 8; + if (gSprites[task->data[10]].pos2.y == 0) + { + gScanlineEffect.state = 3; + ++task->data[0]; + } + break; + case 4: + DestroyAnimVisualTask(taskId); + break; + } +} + +static void sub_80B92B8(u8 useBG1, s16 y, s16 endY) +{ + s16 bgX; + struct ScanlineEffectParams scanlineParams; + + if (useBG1 == 1) + { + bgX = gBattle_BG1_X; + scanlineParams.dmaDest = ®_BG1HOFS; + } + else + { + bgX = gBattle_BG2_X; + scanlineParams.dmaDest = ®_BG2HOFS; + } + if (y < 0) + y = 0; + while (y < endY) + { + gScanlineEffectRegBuffers[0][y] = bgX; + gScanlineEffectRegBuffers[1][y] = bgX; + ++y; + } + while (y < 160) + { + gScanlineEffectRegBuffers[0][y] = bgX + 240; + gScanlineEffectRegBuffers[1][y] = bgX + 240; + ++y; + } + scanlineParams.dmaControl = SCANLINE_EFFECT_DMACNT_16BIT; + scanlineParams.initState = 1; + scanlineParams.unused9 = 0; + ScanlineEffect_SetParams(scanlineParams); +} + +// Moves a particle of dirt in a plume of dirt. Used in Fissure and Dig. +// arg 0: which mon (0 = attacker, 1 = target) +// arg 1: which side of mon (0 = left, 1 = right) +// arg 2: target x offset +// arg 3: target y offset +// arg 4: wave amplitude +// arg 5: duration +static void AnimFissureDirtPlumeParticle(struct Sprite *sprite) +{ + s8 battler; + s16 xOffset; + + if (gBattleAnimArgs[0] == 0) + battler = gBattleAnimAttacker; + else + battler = gBattleAnimTarget; + xOffset = 24; + if (gBattleAnimArgs[1] == 1) + { + xOffset *= -1; + gBattleAnimArgs[2] *= -1; + } + sprite->pos1.x = GetBattlerSpriteCoord(battler, 2) + xOffset; + sprite->pos1.y = GetBattlerYCoordWithElevation(battler) + 30; + sprite->data[0] = gBattleAnimArgs[5]; + sprite->data[2] = sprite->pos1.x + gBattleAnimArgs[2]; + sprite->data[4] = sprite->pos1.y + gBattleAnimArgs[3]; + sprite->data[5] = gBattleAnimArgs[4]; + InitAnimArcTranslation(sprite); + sprite->callback = AnimFissureDirtPlumeParticleStep; +} + +static void AnimFissureDirtPlumeParticleStep(struct Sprite *sprite) +{ + if (TranslateAnimHorizontalArc(sprite)) + DestroyAnimSprite(sprite); +} + +// Displays the dirt mound seen in the move Dig for set duration. +// The dirt mound image is too large for a single sprite, so two +// sprites are lined up next to each other. +// arg 0: which mon (0 = attacker, 1 = target) +// arg 1: oam tile num (0 = left half of image, 1 = right half of image) +// arg 2: duration +static void AnimDigDirtMound(struct Sprite *sprite) +{ + s8 battler; + + if (gBattleAnimArgs[0] == 0) + battler = gBattleAnimAttacker; + else + battler = gBattleAnimTarget; + sprite->pos1.x = GetBattlerSpriteCoord(battler, 0) - 16 + (gBattleAnimArgs[1] * 32); + sprite->pos1.y = GetBattlerYCoordWithElevation(battler) + 32; + sprite->oam.tileNum += gBattleAnimArgs[1] * 8; + StoreSpriteCallbackInData6(sprite, DestroyAnimSprite); + sprite->data[0] = gBattleAnimArgs[2]; + sprite->callback = WaitAnimForDuration; +} + +void sub_80B94B4(u8 taskId) +{ + u16 i; + struct Task *task = &gTasks[taskId]; + + if (gBattleAnimArgs[1]) + task->data[14] = task->data[15] = gBattleAnimArgs[1] + 3; + else + task->data[14] = task->data[15] = (gAnimMovePower / 10) + 3; + + task->data[3] = gBattleAnimArgs[2]; + switch (gBattleAnimArgs[0]) + { + case 5: + task->data[13] = gBattle_BG3_X; + task->func = sub_80B9584; + break; + case 4: + task->data[13] = 0; + for (i = 0; i < MAX_BATTLERS_COUNT; ++i) + { + if (IsBattlerSpriteVisible(i)) + { + task->data[task->data[13] + 9] = gBattlerSpriteIds[i]; + ++task->data[13]; + } + } + task->func = sub_80B967C; + break; + default: + task->data[9] = GetAnimBattlerSpriteId(gBattleAnimArgs[0]); + if (task->data[9] == 0xFF) + { + DestroyAnimVisualTask(taskId); + } + else + { + task->data[13] = 1; + task->func = sub_80B967C; + } + + break; + } +} + +static void sub_80B9584(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + + switch (task->data[0]) + { + case 0: + if (++task->data[1] > 1) + { + task->data[1] = 0; + if ((task->data[2] & 1) == 0) + gBattle_BG3_X = task->data[13] + task->data[15]; + else + gBattle_BG3_X = task->data[13] - task->data[15]; + + if (++task->data[2] == task->data[3]) + { + task->data[2] = 0; + --task->data[14]; + ++task->data[0]; + } + } + break; + case 1: + if (++task->data[1] > 1) + { + task->data[1] = 0; + if ((task->data[2] & 1) == 0) + gBattle_BG3_X = task->data[13] + task->data[14]; + else + gBattle_BG3_X = task->data[13] - task->data[14]; + + if (++task->data[2] == 4) + { + task->data[2] = 0; + if (--task->data[14] == 0) + ++task->data[0]; + } + } + break; + case 2: + gBattle_BG3_X = task->data[13]; + DestroyAnimVisualTask(taskId); + break; + } +} + +static void sub_80B967C(u8 taskId) +{ + u16 i; + struct Task *task = &gTasks[taskId]; + + switch (task->data[0]) + { + case 0: + if (++task->data[1] > 1) + { + task->data[1] = 0; + sub_80B9760(task); + if (++task->data[2] == task->data[3]) + { + task->data[2] = 0; + --task->data[14]; + ++task->data[0]; + } + } + break; + case 1: + if (++task->data[1] > 1) + { + task->data[1] = 0; + sub_80B9760(task); + if (++task->data[2] == 4) + { + task->data[2] = 0; + if (--task->data[14] == 0) + ++task->data[0]; + } + } + break; + case 2: + for (i = 0; i < task->data[13]; ++i) + gSprites[task->data[9 + i]].pos2.x = 0; + DestroyAnimVisualTask(taskId); + break; + } +} + +static void sub_80B9760(struct Task *task) +{ + u16 i, xOffset; + + if ((task->data[2] & 1) == 0) + xOffset = (task->data[14] / 2) + (task->data[14] & 1); + else + xOffset = -(task->data[14] / 2); + for (i = 0; i < task->data[13]; ++i) + gSprites[task->data[9 + i]].pos2.x = xOffset; +} + +void AnimTask_IsPowerOver99(u8 taskId) +{ + gBattleAnimArgs[15] = gAnimMovePower > 99; + DestroyAnimVisualTask(taskId); +} + +void sub_80B9800(u8 taskId) +{ + struct Task *newTask; + u8 battler = (gBattleAnimArgs[0] & 1) ? gBattleAnimTarget : gBattleAnimAttacker; + + if (gBattleAnimArgs[0] > 1) + battler ^= BIT_FLANK; + newTask = &gTasks[CreateTask(sub_80B98A8, gBattleAnimArgs[1])]; + newTask->data[1] = (32 - GetBattlerSpriteCoord(battler, 2)) & 0x1FF; + newTask->data[2] = (64 - GetBattlerSpriteCoord(battler, 3)) & 0xFF; + gBattle_BG3_X = newTask->data[1]; + gBattle_BG3_Y = newTask->data[2]; + newTask->data[3] = gBattleAnimArgs[2]; + DestroyAnimVisualTask(taskId); +} + +static void sub_80B98A8(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + + if (gBattleAnimArgs[7] == task->data[3]) + { + gBattle_BG3_X = 0; + gBattle_BG3_Y = 0; + DestroyTask(taskId); + } + else + { + gBattle_BG3_X = task->data[1]; + gBattle_BG3_Y = task->data[2]; + } +} diff --git a/src/help_system_812B1E0.c b/src/help_system_812B1E0.c index a527525f8..afb792072 100644 --- a/src/help_system_812B1E0.c +++ b/src/help_system_812B1E0.c @@ -16,13 +16,13 @@ #include "constants/maps.h" #include "constants/songs.h" -static EWRAM_DATA u16 gUnknown_203B0EC = 0; +static EWRAM_DATA u16 sSomeVariable = 0; static EWRAM_DATA u8 gUnknown_203B0EE = 0; u8 gUnknown_3005E9C[4]; -u16 gUnknown_3005EA0; +u16 gSomeVariableBackup; -static bool32 sub_812B27C(const u16 * mapIdxs); +static bool32 IsCurrentMapInArray(const u16 * mapIdxs); static void sub_812B520(struct HelpSystemListMenu * a0, struct ListMenuItem * a1); static void sub_812B614(struct HelpSystemListMenu * a0, struct ListMenuItem * a1); static bool8 sub_812B754(void); @@ -824,7 +824,7 @@ static const u8 gUnknown_845C4B6[][6] = { {0, 0, 0, 0, 0, 0} }; -static const u16 gUnknown_845C594[] = { +static const u16 sMartMaps[] = { MAP_VIRIDIAN_CITY_MART, MAP_PEWTER_CITY_MART, MAP_CERULEAN_CITY_MART, @@ -847,7 +847,7 @@ static const u16 gUnknown_845C594[] = { MAP_UNDEFINED }; -static const u16 gUnknown_845C5BC[] = { +static const u16 sGymMaps[] = { MAP_PEWTER_CITY_GYM, MAP_CERULEAN_CITY_GYM, MAP_VERMILION_CITY_GYM, @@ -859,7 +859,7 @@ static const u16 gUnknown_845C5BC[] = { MAP_UNDEFINED }; -static const u8 gUnknown_845C5CE[][3] = { +static const u8 sDungeonMaps[][3] = { { MAP_GROUP(VIRIDIAN_FOREST), MAP_NUM(VIRIDIAN_FOREST), 1 }, { MAP_GROUP(MT_MOON_1F), MAP_NUM(MT_MOON_1F), 3 }, { MAP_GROUP(ROCK_TUNNEL_1F), MAP_NUM(ROCK_TUNNEL_1F), 2 }, @@ -878,14 +878,14 @@ static const u8 gUnknown_845C5CE[][3] = { { MAP_GROUP(SEVEN_ISLAND_TANOBY_RUINS_MONEAN_CHAMBER), MAP_NUM(SEVEN_ISLAND_TANOBY_RUINS_MONEAN_CHAMBER), 7 } }; -void sub_812B1E0(u8 a0) +void HelpSystem_SetSomeVariable(u8 a0) { - gUnknown_203B0EC = a0; + sSomeVariable = a0; } void HelpSystem_SetSomeVariable2(u8 a0) { - switch (gUnknown_203B0EC) + switch (sSomeVariable) { case 23: case 24: @@ -895,37 +895,37 @@ void HelpSystem_SetSomeVariable2(u8 a0) break; // fallthrough default: - gUnknown_203B0EC = a0; + sSomeVariable = a0; break; } } -void sub_812B220(void) +void Special_SetSomeVariable(void) { - gUnknown_203B0EC = gSpecialVar_0x8004; + sSomeVariable = gSpecialVar_0x8004; } -void sub_812B234(void) +void HelpSystem_BackupSomeVariable(void) { - gUnknown_3005EA0 = gUnknown_203B0EC; + gSomeVariableBackup = sSomeVariable; } -void sub_812B248(void) +void HelpSystem_RestoreSomeVariable(void) { - gUnknown_203B0EC = gUnknown_3005EA0; + sSomeVariable = gSomeVariableBackup; } -static bool32 sub_812B25C(void) +static bool32 IsInMartMap(void) { - return sub_812B27C(gUnknown_845C594); + return IsCurrentMapInArray(sMartMaps); } -static bool32 sub_812B26C(void) +static bool32 IsInGymMap(void) { - return sub_812B27C(gUnknown_845C5BC); + return IsCurrentMapInArray(sGymMaps); } -static bool32 sub_812B27C(const u16 * mapIdxs) +static bool32 IsCurrentMapInArray(const u16 * mapIdxs) { u16 mapIdx = (gSaveBlock1Ptr->location.mapGroup << 8) + gSaveBlock1Ptr->location.mapNum; s32 i; @@ -939,18 +939,18 @@ static bool32 sub_812B27C(const u16 * mapIdxs) return FALSE; } -static bool8 sub_812B2C4(void) +static bool8 IsInDungeonMap(void) { u8 i, j; for (i = 0; i < 16; i++) { - for (j = 0; j < gUnknown_845C5CE[i][2]; j++) + for (j = 0; j < sDungeonMaps[i][2]; j++) { if ( - gUnknown_845C5CE[i][0] == gSaveBlock1Ptr->location.mapGroup - && gUnknown_845C5CE[i][1] + j == gSaveBlock1Ptr->location.mapNum - && (i != 15 || FlagGet(FLAG_0x849) == TRUE) + sDungeonMaps[i][0] == gSaveBlock1Ptr->location.mapGroup + && sDungeonMaps[i][1] + j == gSaveBlock1Ptr->location.mapNum + && (i != 15 /* TANOBY */ || FlagGet(FLAG_0x849) == TRUE) ) return TRUE; } @@ -964,7 +964,7 @@ void sub_812B35C(void) sub_812B4B8(); if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_SURFING)) HelpSystem_SetSomeVariable2(0x16); - else if (sub_812B2C4()) + else if (IsInDungeonMap()) HelpSystem_SetSomeVariable2(0x15); else if (is_light_level_8_or_9(gMapHeader.mapType)) { @@ -974,9 +974,9 @@ void sub_812B35C(void) HelpSystem_SetSomeVariable2(0x0F); else if (IsCurMapPokeCenter() == TRUE) HelpSystem_SetSomeVariable2(0x10); - else if (sub_812B25C() == TRUE) + else if (IsInMartMap() == TRUE) HelpSystem_SetSomeVariable2(0x11); - else if (sub_812B26C() == TRUE) + else if (IsInGymMap() == TRUE) HelpSystem_SetSomeVariable2(0x12); else HelpSystem_SetSomeVariable2(0x13); @@ -1055,7 +1055,7 @@ static void sub_812B520(struct HelpSystemListMenu * a0, struct ListMenuItem * a1 u8 r4 = 0; for (i = 0; i < 6; i++) { - if (gUnknown_845C4B6[gUnknown_203B0EC][gUnknown_845C4B0[i]] == 1) + if (gUnknown_845C4B6[sSomeVariable][gUnknown_845C4B0[i]] == 1) { a1[r4].label = gUnknown_845B080[gUnknown_845C4B0[i]]; a1[r4].index = gUnknown_845C4B0[i]; @@ -1085,7 +1085,7 @@ static void sub_812B5A8(struct HelpSystemListMenu * a0, struct ListMenuItem * a1 static void sub_812B614(struct HelpSystemListMenu * a0, struct ListMenuItem * a1) { u8 r6 = 0; - const u8 * r3 = gUnknown_845B9E0[gUnknown_203B0EC * 5 + gUnknown_3005E9C[1]]; + const u8 * r3 = gUnknown_845B9E0[sSomeVariable * 5 + gUnknown_3005E9C[1]]; u8 i; for (i = 0; r3[i] != 0xFF; i++) { diff --git a/src/item_use.c b/src/item_use.c index f8a99cb1d..3a189d84a 100644 --- a/src/item_use.c +++ b/src/item_use.c @@ -117,7 +117,7 @@ void sub_80A1084(void) void sub_80A109C(u8 taskId) { - if (sub_807AA70() == TRUE) + if (field_weather_is_fade_finished() == TRUE) { sItemUseOnFieldCB(taskId); } @@ -172,7 +172,7 @@ bool8 sub_80A1194(void) void sub_80A11C0(u8 taskId) { - if (sub_807AA70() == TRUE) + if (field_weather_is_fade_finished() == TRUE) { UnfreezeMapObjects(); ScriptContext2_Disable(); @@ -191,7 +191,7 @@ void sub_80A1208(void) struct MailStruct mail; mail.itemId = gSpecialVar_ItemId; - sub_80BEBEC(&mail, ReturnToBagFromKeyItem, 0); + sub_80BEBEC(&mail, CB2_BagMenuFromStartMenu, 0); } void FieldUseFunc_MachBike(u8 taskId) @@ -404,7 +404,7 @@ void FieldUseFunc_TmCase(u8 taskId) void InitTMCaseFromBag(void) { - InitTMCase(0, ReturnToBagFromKeyItem, 0); + InitTMCase(0, CB2_BagMenuFromStartMenu, 0); } void Task_InitTMCaseFromField(u8 taskId) @@ -435,7 +435,7 @@ void FieldUseFunc_BerryPouch(u8 taskId) void InitBerryPouchFromBag(void) { - InitBerryPouch(BERRYPOUCH_FROMFIELD, ReturnToBagFromKeyItem, 0); + InitBerryPouch(BERRYPOUCH_FROMFIELD, CB2_BagMenuFromStartMenu, 0); } void Task_InitBerryPouchFromField(u8 taskId) @@ -478,7 +478,7 @@ void FieldUseFunc_TeachyTv(u8 taskId) void InitTeachyTvFromBag(void) { - InitTeachyTvController(0, ReturnToBagFromKeyItem); + InitTeachyTvController(0, CB2_BagMenuFromStartMenu); } void Task_InitTeachyTvFromField(u8 taskId) @@ -608,7 +608,7 @@ void FieldUseFunc_TownMap(u8 taskId) void sub_80A1CAC(void) { - sub_80BFF50(0, ReturnToBagFromKeyItem); + sub_80BFF50(0, CB2_BagMenuFromStartMenu); } void sub_80A1CC0(u8 taskId) @@ -640,7 +640,7 @@ void FieldUseFunc_FameChecker(u8 taskId) void sub_80A1D58(void) { - UseFameChecker(ReturnToBagFromKeyItem); + UseFameChecker(CB2_BagMenuFromStartMenu); } void sub_80A1D68(u8 taskId) diff --git a/src/mailbox_pc.c b/src/mailbox_pc.c index 0ebffc67e..0a4535271 100644 --- a/src/mailbox_pc.c +++ b/src/mailbox_pc.c @@ -94,10 +94,10 @@ static void ItemPrintFunc(u8 windowId, s32 itemId, u8 y) } } -u8 MailboxPC_InitListMenu(struct PlayerPC_Unk_203AAC4 * playerPcStruct) +u8 MailboxPC_InitListMenu(struct PlayerPCItemPageStruct * playerPcStruct) { u16 i; - for (i = 0; i < playerPcStruct->unk_5; i++) + for (i = 0; i < playerPcStruct->count; i++) { sListMenuItems[i].label = sString_Dummy; sListMenuItems[i].index = i; @@ -106,7 +106,7 @@ u8 MailboxPC_InitListMenu(struct PlayerPC_Unk_203AAC4 * playerPcStruct) sListMenuItems[i].index = -2; gMultiuseListMenuTemplate.items = sListMenuItems; - gMultiuseListMenuTemplate.totalItems = playerPcStruct->unk_5 + 1; + gMultiuseListMenuTemplate.totalItems = playerPcStruct->count + 1; gMultiuseListMenuTemplate.windowId = sWindowIds[1]; gMultiuseListMenuTemplate.header_X = 0; gMultiuseListMenuTemplate.item_X = GetMenuCursorDimensionByFont(2, 0); @@ -132,9 +132,9 @@ static void MoveCursorFunc(s32 itemIndex, bool8 onInit, struct ListMenu * list) PlaySE(SE_SELECT); } -void MailboxPC_AddScrollIndicatorArrows(struct PlayerPC_Unk_203AAC4 * playerPcStruct) +void MailboxPC_AddScrollIndicatorArrows(struct PlayerPCItemPageStruct * playerPcStruct) { - playerPcStruct->unk_A = AddScrollIndicatorArrowPairParameterized(2, 0xC2, 0xC, 0x94, playerPcStruct->unk_5 - playerPcStruct->unk_4 + 1, 110, 110, &playerPcStruct->scrollOffset); + playerPcStruct->scrollIndicatorId = AddScrollIndicatorArrowPairParameterized(2, 0xC2, 0xC, 0x94, playerPcStruct->count - playerPcStruct->pageItems + 1, 110, 110, &playerPcStruct->scrollOffset); } void MailboxPC_DestroyListMenuBuffer(void) diff --git a/src/map_preview_screen.c b/src/map_preview_screen.c index 7d9fa935e..c465a5683 100644 --- a/src/map_preview_screen.c +++ b/src/map_preview_screen.c @@ -495,7 +495,7 @@ static void sub_80F83D0(u8 taskId) } break; case 2: - if (sub_807AA70()) + if (field_weather_is_fade_finished()) { Overworld_PlaySpecialMapMusic(); data[0]++; diff --git a/src/menu2.c b/src/menu2.c index c6d5ab094..221f84318 100644 --- a/src/menu2.c +++ b/src/menu2.c @@ -485,7 +485,7 @@ void AddTextPrinterParameterized5(u8 windowId, u8 fontId, const u8 *str, u8 x, u AddTextPrinter(&printer, speed, callback); } -void sub_812E6DC(u8 windowId, const u8 * src, u16 x, u16 y) +void Menu_PrintFormatIntlPlayerName(u8 windowId, const u8 * src, u16 x, u16 y) { s32 i; diff --git a/src/mystery_event_script.c b/src/mystery_event_script.c index 89df1ee34..26cbdb145 100644 --- a/src/mystery_event_script.c +++ b/src/mystery_event_script.c @@ -247,7 +247,7 @@ bool8 MEScrCmd_givepokemon(struct ScriptContext *ctx) if (species == SPECIES_EGG) StringCopyN(gStringVar1, gText_EggNickname, POKEMON_NAME_LENGTH + 1); else - StringCopyN(gStringVar1, gText_Pokemon, POKEMON_NAME_LENGTH + 1); + StringCopyN(gStringVar1, gStartMenuText_Pokemon, POKEMON_NAME_LENGTH + 1); if (gPlayerPartyCount == PARTY_SIZE) { diff --git a/src/new_menu_helpers.c b/src/new_menu_helpers.c index 9d2a5c883..f82dbe9c6 100644 --- a/src/new_menu_helpers.c +++ b/src/new_menu_helpers.c @@ -395,7 +395,7 @@ void ResetBg0(void) ChangeBgX(0, 0, 0); ChangeBgY(0, 0, 0); DeactivateAllTextPrinters(); - sub_80F6E9C(); + LoadStdWindowFrameGfx(); } u16 RunTextPrinters_CheckPrinter0Active(void) @@ -452,7 +452,7 @@ void AddTextPrinterWithCustomSpeedForMessage(bool8 allowSkippingDelayWithButtonP AddTextPrinterParameterized2(0, 2, gStringVar4, speed, NULL, 2, 1, 3); } -void sub_80F6E9C(void) +void LoadStdWindowFrameGfx(void) { if (gUnknown_203ADFA == 2) { @@ -644,7 +644,7 @@ static u16 GetStdPalColor(u8 colorNum) void DisplayItemMessageOnField(u8 taskId, u8 bgId, const u8 *string, TaskFunc callback) { - sub_80F6E9C(); + LoadStdWindowFrameGfx(); DisplayMessageAndContinueTask(taskId, 0, DLG_WINDOW_BASE_TILE_NUM, DLG_WINDOW_PALETTE_NUM, bgId, GetTextSpeedSetting(), string, callback); CopyWindowToVram(0, 3); } @@ -667,7 +667,7 @@ u8 GetTextSpeedSetting(void) return gUnknown_841F428[gSaveBlock2Ptr->optionsTextSpeed]; } -u8 sub_80F78E0(u8 height) +u8 CreateStartMenuWindow(u8 height) { if (sStartMenuWindowId == 0xFF) { @@ -702,15 +702,15 @@ u16 GetStdWindowBaseTileNum(void) return STD_WINDOW_BASE_TILE_NUM; } -void sub_80F7974(const u8 * text) +void DrawHelpMessageWindowWithText(const u8 * text) { - sub_814FE6C(sub_8112EB4(), DLG_WINDOW_BASE_TILE_NUM, 0x10 * DLG_WINDOW_PALETTE_NUM); - sub_8113018(text, 2); + sub_814FE6C(CreateHelpMessageWindow(), DLG_WINDOW_BASE_TILE_NUM, 0x10 * DLG_WINDOW_PALETTE_NUM); + PrintTextOnHelpMessageWindow(text, 2); } -void sub_80F7998(void) +void DestroyHelpMessageWindow_(void) { - sub_8112EDC(2); + DestroyHelpMessageWindow(2); } void sub_80F79A4(void) diff --git a/src/normal.c b/src/normal.c new file mode 100644 index 000000000..4d86b55a6 --- /dev/null +++ b/src/normal.c @@ -0,0 +1,916 @@ +#include "global.h" +#include "battle_anim.h" +#include "palette.h" +#include "random.h" +#include "task.h" +#include "trig.h" + +static void AnimConfusionDuck(struct Sprite *sprite); +static void AnimSimplePaletteBlend(struct Sprite *sprite); +static void sub_80B9A7C(struct Sprite *sprite); +static void sub_80B9B8C(struct Sprite *sprite); +static void sub_80BA27C(struct Sprite *sprite); +static void sub_80BA560(struct Sprite *sprite); +static void sub_80BA5F8(struct Sprite *sprite); +static void sub_80BA630(struct Sprite *sprite); +static void sub_80BA6C8(struct Sprite *sprite); +static void sub_80BA738(struct Sprite *sprite); +static void sub_80BA780(struct Sprite *sprite); +static void sub_80BA5A8(struct Sprite *sprite); +static void AnimConfusionDuckStep(struct Sprite *sprite); +static void AnimSimplePaletteBlendStep(struct Sprite *sprite); +static void sub_80B9AD0(struct Sprite *sprite); +static void sub_80B9B5C(struct Sprite *sprite); +static void sub_80B9C2C(u8 taskId, u8 initialBlendAmount, u8 targetBlendAmount); +static void sub_80B9C7C(u8 taskId); +static void sub_80B9DA0(u8 taskId, u8 initialBlendAmount, u8 targetBlendAmount); +static void sub_80B9DF0(u8 taskId); +static void sub_80B9EA8(u8 taskId, u8 initialBlendAmount, u8 targetBlendAmount); +static void sub_80B9F04(u8 taskId); +static void sub_80B9FD8(u8 taskId); +static void sub_80BA090(u8 taskId); +static void sub_80BA3CC(void); +static void sub_80BA320(struct Sprite *sprite); +static void sub_80BA4D0(u8 taskId); +static void sub_80BA7BC(struct Sprite *sprite); + + +static const union AnimCmd gUnknown_83E7ADC[] = +{ + ANIMCMD_FRAME(0, 8), + ANIMCMD_FRAME(4, 8), + ANIMCMD_FRAME(0, 8, .hFlip = TRUE), + ANIMCMD_FRAME(8, 8), + ANIMCMD_JUMP(0), +}; + +static const union AnimCmd gUnknown_83E7AF0[] = +{ + ANIMCMD_FRAME(0, 8, .hFlip = TRUE), + ANIMCMD_FRAME(4, 8), + ANIMCMD_FRAME(0, 8), + ANIMCMD_FRAME(8, 8), + ANIMCMD_JUMP(0), +}; + +static const union AnimCmd *const gUnknown_83E7B04[] = +{ + gUnknown_83E7ADC, + gUnknown_83E7AF0, +}; + +const struct SpriteTemplate gConfusionDuckSpriteTemplate = +{ + .tileTag = ANIM_TAG_DUCK, + .paletteTag = ANIM_TAG_DUCK, + .oam = &gOamData_83AC9D0, + .anims = gUnknown_83E7B04, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimConfusionDuck, +}; + +const struct SpriteTemplate gSimplePaletteBlendSpriteTemplate = +{ + .tileTag = 0, + .paletteTag = 0, + .oam = &gDummyOamData, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimSimplePaletteBlend, +}; + +const struct SpriteTemplate gComplexPaletteBlendSpriteTemplate = +{ + .tileTag = 0, + .paletteTag = 0, + .oam = &gDummyOamData, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_80B9A7C, +}; + +static const union AnimCmd gUnknown_83E7B54[] = +{ + ANIMCMD_FRAME(0, 3), + ANIMCMD_FRAME(16, 3), + ANIMCMD_FRAME(32, 3), + ANIMCMD_FRAME(48, 3), + ANIMCMD_FRAME(64, 3), + ANIMCMD_JUMP(0), +}; + +static const union AnimCmd *const gUnknown_83E7B6C[] = +{ + gUnknown_83E7B54, +}; + +const struct SpriteTemplate gUnknown_83E7B70 = +{ + .tileTag = ANIM_TAG_SPARKLE_4, + .paletteTag = ANIM_TAG_SPARKLE_4, + .oam = &gOamData_83AC9D8, + .anims = gUnknown_83E7B6C, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_80B9B8C, +}; + +const struct SpriteTemplate gUnknown_83E7B88 = +{ + .tileTag = 0, + .paletteTag = 0, + .oam = &gDummyOamData, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_80BA27C, +}; + +static const union AffineAnimCmd gUnknown_83E7BA0[] = +{ + AFFINEANIMCMD_FRAME(0x0, 0x0, 0, 8), + AFFINEANIMCMD_END, +}; + +static const union AffineAnimCmd gUnknown_83E7BB0[] = +{ + AFFINEANIMCMD_FRAME(0xD8, 0xD8, 0, 0), + AFFINEANIMCMD_FRAME(0x0, 0x0, 0, 8), + AFFINEANIMCMD_END, +}; + +static const union AffineAnimCmd gUnknown_83E7BC8[] = +{ + AFFINEANIMCMD_FRAME(0xB0, 0xB0, 0, 0), + AFFINEANIMCMD_FRAME(0x0, 0x0, 0, 8), + AFFINEANIMCMD_END, +}; + +static const union AffineAnimCmd gUnknown_83E7BE0[] = +{ + AFFINEANIMCMD_FRAME(0x80, 0x80, 0, 0), + AFFINEANIMCMD_FRAME(0x0, 0x0, 0, 8), + AFFINEANIMCMD_END, +}; + +static const union AffineAnimCmd *const gUnknown_83E7BF8[] = +{ + gUnknown_83E7BA0, + gUnknown_83E7BB0, + gUnknown_83E7BC8, + gUnknown_83E7BE0, +}; + +const struct SpriteTemplate gBasicHitSplatSpriteTemplate = +{ + .tileTag = ANIM_TAG_IMPACT, + .paletteTag = ANIM_TAG_IMPACT, + .oam = &gOamData_83ACB58, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gUnknown_83E7BF8, + .callback = sub_80BA560, +}; + +const struct SpriteTemplate gUnknown_83E7C20 = +{ + .tileTag = ANIM_TAG_IMPACT, + .paletteTag = ANIM_TAG_IMPACT, + .oam = &gOamData_83ACB58, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gUnknown_83E7BF8, + .callback = sub_80BA5F8, +}; + +const struct SpriteTemplate gUnknown_83E7C38 = +{ + .tileTag = ANIM_TAG_WATER_IMPACT, + .paletteTag = ANIM_TAG_WATER_IMPACT, + .oam = &gOamData_83ACB58, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gUnknown_83E7BF8, + .callback = sub_80BA560, +}; + +const struct SpriteTemplate gUnknown_83E7C50 = +{ + .tileTag = ANIM_TAG_IMPACT, + .paletteTag = ANIM_TAG_IMPACT, + .oam = &gOamData_83ACB58, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gUnknown_83E7BF8, + .callback = sub_80BA630, +}; + +const struct SpriteTemplate gUnknown_83E7C68 = +{ + .tileTag = ANIM_TAG_IMPACT, + .paletteTag = ANIM_TAG_IMPACT, + .oam = &gOamData_83ACB58, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gUnknown_83E7BF8, + .callback = sub_80BA6C8, +}; + +const struct SpriteTemplate gUnknown_83E7C80 = +{ + .tileTag = ANIM_TAG_CROSS_IMPACT, + .paletteTag = ANIM_TAG_CROSS_IMPACT, + .oam = &gOamData_83ACAF8, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_80BA738, +}; + +const struct SpriteTemplate gUnknown_83E7C98 = +{ + .tileTag = ANIM_TAG_IMPACT, + .paletteTag = ANIM_TAG_IMPACT, + .oam = &gOamData_83ACA38, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gUnknown_83E7BF8, + .callback = sub_80BA780, +}; + +const struct SpriteTemplate gUnknown_83E7CB0 = +{ + .tileTag = ANIM_TAG_IMPACT, + .paletteTag = ANIM_TAG_IMPACT, + .oam = &gOamData_83ACB58, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gUnknown_83E7BF8, + .callback = sub_80BA5A8, +}; + +// Moves a spinning duck around the mon's head. +// arg 0: initial x pixel offset +// arg 1: initial y pixel offset +// arg 2: initial wave offset +// arg 3: wave period (higher means faster wave) +// arg 4: duration +static void AnimConfusionDuck(struct Sprite *sprite) +{ + sprite->pos1.x += gBattleAnimArgs[0]; + sprite->pos1.y += gBattleAnimArgs[1]; + sprite->data[0] = gBattleAnimArgs[2]; + if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) + { + sprite->data[1] = -gBattleAnimArgs[3]; + sprite->data[4] = 1; + } + else + { + sprite->data[1] = gBattleAnimArgs[3]; + sprite->data[4] = 0; + StartSpriteAnim(sprite, 1); + } + sprite->data[3] = gBattleAnimArgs[4]; + sprite->callback = AnimConfusionDuckStep; + sprite->callback(sprite); +} + +static void AnimConfusionDuckStep(struct Sprite *sprite) +{ + sprite->pos2.x = Cos(sprite->data[0], 30); + sprite->pos2.y = Sin(sprite->data[0], 10); + if ((u16)sprite->data[0] < 128) + sprite->oam.priority = 1; + else + sprite->oam.priority = 3; + sprite->data[0] = (sprite->data[0] + sprite->data[1]) & 0xFF; + if (++sprite->data[2] == sprite->data[3]) + DestroyAnimSprite(sprite); +} + +// Performs a simple color blend on a specified sprite. +// arg 0: palette selector +// arg 1: delay +// arg 2: start blend amount +// arg 3: end blend amount +// arg 4: blend color +static void AnimSimplePaletteBlend(struct Sprite *sprite) +{ + u32 selectedPalettes = UnpackSelectedBattleAnimPalettes(gBattleAnimArgs[0]); + + BeginNormalPaletteFade(selectedPalettes, gBattleAnimArgs[1], gBattleAnimArgs[2], gBattleAnimArgs[3], gBattleAnimArgs[4]); + sprite->invisible = TRUE; + sprite->callback = AnimSimplePaletteBlendStep; +} + +// Unpacks a bitfield and returns a bitmask of its selected palettes. +// Bits 0-6 of the selector parameter result in the following palettes being selected: +// 0: battle background palettes (BG palettes 1, 2, and 3) +// 1: gBattleAnimAttacker OBJ palette +// 2: gBattleAnimTarget OBJ palette +// 3: gBattleAnimAttacker partner OBJ palette +// 4: gBattleAnimTarget partner OBJ palette +// 5: BG palette 4 +// 6: BG palette 5 +u32 UnpackSelectedBattleAnimPalettes(s16 selector) +{ + u8 battleBackground = selector & 1; + u8 attacker = (selector >> 1) & 1; + u8 target = (selector >> 2) & 1; + u8 attackerPartner = (selector >> 3) & 1; + u8 targetPartner = (selector >> 4) & 1; + u8 arg5 = (selector >> 5) & 1; + u8 arg6 = (selector >> 6) & 1; + + return sub_8075BE8(battleBackground, attacker, target, attackerPartner, targetPartner, arg5, arg6); +} + +static void AnimSimplePaletteBlendStep(struct Sprite *sprite) +{ + if (!gPaletteFade.active) + DestroyAnimSprite(sprite); +} + +static void sub_80B9A7C(struct Sprite *sprite) +{ + u32 selectedPalettes; + + sprite->data[0] = gBattleAnimArgs[1]; + sprite->data[1] = gBattleAnimArgs[1]; + sprite->data[2] = gBattleAnimArgs[2]; + sprite->data[3] = gBattleAnimArgs[3]; + sprite->data[4] = gBattleAnimArgs[4]; + sprite->data[5] = gBattleAnimArgs[5]; + sprite->data[6] = gBattleAnimArgs[6]; + sprite->data[7] = gBattleAnimArgs[0]; + selectedPalettes = UnpackSelectedBattleAnimPalettes(sprite->data[7]); + BlendPalettes(selectedPalettes, gBattleAnimArgs[4], gBattleAnimArgs[3]); + sprite->invisible = TRUE; + sprite->callback = sub_80B9AD0; +} + +static void sub_80B9AD0(struct Sprite *sprite) +{ + u32 selectedPalettes; + + if (sprite->data[0] > 0) + { + --sprite->data[0]; + return; + } + if (gPaletteFade.active) + return; + if (sprite->data[2] == 0) + { + sprite->callback = sub_80B9B5C; + return; + } + selectedPalettes = UnpackSelectedBattleAnimPalettes(sprite->data[7]); + if (sprite->data[1] & 0x100) + BlendPalettes(selectedPalettes, sprite->data[4], sprite->data[3]); + else + BlendPalettes(selectedPalettes, sprite->data[6], sprite->data[5]); + sprite->data[1] ^= 0x100; + sprite->data[0] = sprite->data[1] & 0xFF; + --sprite->data[2]; +} + +static void sub_80B9B5C(struct Sprite *sprite) +{ + u32 selectedPalettes; + + if (!gPaletteFade.active) + { + selectedPalettes = UnpackSelectedBattleAnimPalettes(sprite->data[7]); + BlendPalettes(selectedPalettes, 0, 0); + DestroyAnimSprite(sprite); + } +} + +static void sub_80B9B8C(struct Sprite *sprite) +{ + sprite->pos1.x += gBattleAnimArgs[0]; + sprite->pos1.y += gBattleAnimArgs[1]; + sprite->data[0] = 0; + sprite->data[1] = 10; + sprite->data[2] = 8; + sprite->data[3] = 40; + sprite->data[4] = 112; + sprite->data[5] = 0; + StoreSpriteCallbackInData6(sprite, DestroySpriteAndMatrix); + sprite->callback = TranslateSpriteInGrowingCircleOverDuration; + sprite->callback(sprite); +} + +void sub_80B9BDC(u8 taskId) +{ + gTasks[taskId].data[0] = gBattleAnimArgs[0]; + gTasks[taskId].data[1] = gBattleAnimArgs[1]; + gTasks[taskId].data[2] = gBattleAnimArgs[2]; + gTasks[taskId].data[3] = gBattleAnimArgs[3]; + gTasks[taskId].data[4] = gBattleAnimArgs[4]; + gTasks[taskId].data[5] = gBattleAnimArgs[5]; + gTasks[taskId].data[8] = 0; + sub_80B9C2C(taskId, 0, gTasks[taskId].data[4]); + gTasks[taskId].func = sub_80B9C7C; +} + +static void sub_80B9C2C(u8 taskId, u8 initialBlendAmount, u8 targetBlendAmount) +{ + u32 selectedPalettes = UnpackSelectedBattleAnimPalettes(gTasks[taskId].data[0]); + + BeginNormalPaletteFade(selectedPalettes, + gTasks[taskId].data[1], + initialBlendAmount, + targetBlendAmount, + gTasks[taskId].data[5]); + --gTasks[taskId].data[2]; + gTasks[taskId].data[8] ^= 1; +} + +static void sub_80B9C7C(u8 taskId) +{ + u8 initialBlendAmount, targetBlendAmount; + + if (!gPaletteFade.active) + { + if (gTasks[taskId].data[2] > 0) + { + if (gTasks[taskId].data[8] == 0) + { + initialBlendAmount = gTasks[taskId].data[3]; + targetBlendAmount = gTasks[taskId].data[4]; + } + else + { + initialBlendAmount = gTasks[taskId].data[4]; + targetBlendAmount = gTasks[taskId].data[3]; + } + if (gTasks[taskId].data[2] == 1) + targetBlendAmount = 0; + sub_80B9C2C(taskId, initialBlendAmount, targetBlendAmount); + } + else + { + DestroyAnimVisualTask(taskId); + } + } +} + +void sub_80B9CE4(u8 taskId) +{ + s32 battler; + u32 selectedPalettes = 0; + + gTasks[taskId].data[0] = gBattleAnimArgs[0]; + gTasks[taskId].data[1] = gBattleAnimArgs[1]; + gTasks[taskId].data[2] = gBattleAnimArgs[2]; + gTasks[taskId].data[3] = gBattleAnimArgs[3]; + gTasks[taskId].data[4] = gBattleAnimArgs[4]; + gTasks[taskId].data[5] = gBattleAnimArgs[5]; + gTasks[taskId].data[8] = 0; + for (battler = 0; battler < gBattlersCount; ++battler) + if (battler != gBattleAnimAttacker && battler != gBattleAnimTarget) + selectedPalettes |= 1 << (battler + 16); + if (gBattleAnimArgs[0] == 1) + selectedPalettes |= 0xE; + gTasks[taskId].data[9] = selectedPalettes >> 16; + gTasks[taskId].data[10] = selectedPalettes & 0xFF; + sub_80B9DA0(taskId, 0, gTasks[taskId].data[4]); + gTasks[taskId].func = sub_80B9DF0; +} + +static void sub_80B9DA0(u8 taskId, u8 initialBlendAmount, u8 targetBlendAmount) +{ + u32 selectedPalettes = ((u16)gTasks[taskId].data[9] << 16) | (u16)gTasks[taskId].data[10]; + + BeginNormalPaletteFade(selectedPalettes, + gTasks[taskId].data[1], + initialBlendAmount, + targetBlendAmount, + gTasks[taskId].data[5]); + --gTasks[taskId].data[2]; + gTasks[taskId].data[8] ^= 1; +} + +static void sub_80B9DF0(u8 taskId) +{ + u8 initialBlendAmount, targetBlendAmount; + + if (!gPaletteFade.active) + { + if (gTasks[taskId].data[2] > 0) + { + if (gTasks[taskId].data[8] == 0) + { + initialBlendAmount = gTasks[taskId].data[3]; + targetBlendAmount = gTasks[taskId].data[4]; + } + else + { + initialBlendAmount = gTasks[taskId].data[4]; + targetBlendAmount = gTasks[taskId].data[3]; + } + + if (gTasks[taskId].data[2] == 1) + targetBlendAmount = 0; + sub_80B9DA0(taskId, initialBlendAmount, targetBlendAmount); + } + else + { + DestroyAnimVisualTask(taskId); + } + } +} + +void sub_80B9E58(u8 taskId) +{ + u8 paletteIndex; + + gTasks[taskId].data[0] = gBattleAnimArgs[0]; + gTasks[taskId].data[1] = gBattleAnimArgs[1]; + gTasks[taskId].data[2] = gBattleAnimArgs[2]; + gTasks[taskId].data[3] = gBattleAnimArgs[3]; + gTasks[taskId].data[4] = gBattleAnimArgs[4]; + gTasks[taskId].data[5] = gBattleAnimArgs[5]; + gTasks[taskId].data[8] = 0; + sub_80B9EA8(taskId, 0, gTasks[taskId].data[4]); + gTasks[taskId].func = sub_80B9F04; +} + +static void sub_80B9EA8(u8 taskId, u8 initialBlendAmount, u8 targetBlendAmount) +{ + u8 paletteIndex = IndexOfSpritePaletteTag(gTasks[taskId].data[0]); + + BeginNormalPaletteFade(1 << (paletteIndex + 16), + gTasks[taskId].data[1], + initialBlendAmount, + targetBlendAmount, + gTasks[taskId].data[5]); + --gTasks[taskId].data[2]; + gTasks[taskId].data[8] ^= 1; +} + +static void sub_80B9F04(u8 taskId) +{ + u8 initialBlendAmount, targetBlendAmount; + + if (!gPaletteFade.active) + { + if (gTasks[taskId].data[2] > 0) + { + if (gTasks[taskId].data[8] == 0) + { + initialBlendAmount = gTasks[taskId].data[3]; + targetBlendAmount = gTasks[taskId].data[4]; + } + else + { + initialBlendAmount = gTasks[taskId].data[4]; + targetBlendAmount = gTasks[taskId].data[3]; + } + + if (gTasks[taskId].data[2] == 1) + targetBlendAmount = 0; + sub_80B9EA8(taskId, initialBlendAmount, targetBlendAmount); + } + else + { + DestroyAnimVisualTask(taskId); + } + } +} + +void sub_80B9F6C(u8 taskId) +{ + u8 paletteIndex; + + gTasks[taskId].data[0] = gBattleAnimArgs[1]; + gTasks[taskId].data[1] = gBattleAnimArgs[1]; + gTasks[taskId].data[2] = gBattleAnimArgs[2]; + gTasks[taskId].data[3] = gBattleAnimArgs[3]; + gTasks[taskId].data[4] = gBattleAnimArgs[4]; + gTasks[taskId].data[5] = gBattleAnimArgs[5]; + gTasks[taskId].data[6] = gBattleAnimArgs[6]; + gTasks[taskId].data[7] = gBattleAnimArgs[0]; + paletteIndex = IndexOfSpritePaletteTag(gBattleAnimArgs[0]); + BeginNormalPaletteFade(1 << (paletteIndex + 16), + 0, + gBattleAnimArgs[4], + gBattleAnimArgs[4], + gBattleAnimArgs[3]); + gTasks[taskId].func = sub_80B9FD8; +} + +static void sub_80B9FD8(u8 taskId) +{ + u32 selectedPalettes; + + if (gTasks[taskId].data[0] > 0) + { + --gTasks[taskId].data[0]; + return; + } + if (gPaletteFade.active) + return; + if (gTasks[taskId].data[2] == 0) + { + gTasks[taskId].func = sub_80BA090; + return; + } + selectedPalettes = 1 << (IndexOfSpritePaletteTag(gTasks[taskId].data[7]) + 16); + if (gTasks[taskId].data[1] & 0x100) + BeginNormalPaletteFade(selectedPalettes, + 0, + gTasks[taskId].data[4], + gTasks[taskId].data[4], + gTasks[taskId].data[3]); + else + BeginNormalPaletteFade(selectedPalettes, + 0, + gTasks[taskId].data[6], + gTasks[taskId].data[6], + gTasks[taskId].data[5]); + gTasks[taskId].data[1] ^= 0x100; + gTasks[taskId].data[0] = gTasks[taskId].data[1] & 0xFF; + --gTasks[taskId].data[2]; +} + +static void sub_80BA090(u8 taskId) +{ + u32 selectedPalettes; + + if (!gPaletteFade.active) + { + selectedPalettes = 1 << (IndexOfSpritePaletteTag(gTasks[taskId].data[7]) + 16); + BeginNormalPaletteFade(selectedPalettes, 0, 0, 0, RGB(0, 0, 0)); + DestroyAnimVisualTask(taskId); + } +} + +void sub_80BA0E8(u8 taskId) +{ + u32 selectedPalettes = 0; + u8 attackerBattler = gBattleAnimAttacker; + u8 targetBattler = gBattleAnimTarget; + + if (gBattleAnimArgs[0] & 0x100) + selectedPalettes = sub_8075BE8(1, 0, 0, 0, 0, 0, 0); + if (gBattleAnimArgs[1] & 0x100) + selectedPalettes |= (0x10000 << attackerBattler); + if (gBattleAnimArgs[2] & 0x100) + selectedPalettes |= (0x10000 << targetBattler); + InvertPlttBuffer(selectedPalettes); + DestroyAnimVisualTask(taskId); +} + +// not used +static void sub_80BA16C(u8 taskId) +{ + u8 attackerBattler; + u8 targetBattler; + u8 paletteIndex; + u32 selectedPalettes = 0; + + if (gTasks[taskId].data[0] == 0) + { + gTasks[taskId].data[2] = gBattleAnimArgs[0]; + gTasks[taskId].data[3] = gBattleAnimArgs[1]; + gTasks[taskId].data[4] = gBattleAnimArgs[2]; + gTasks[taskId].data[1] = gBattleAnimArgs[3]; + gTasks[taskId].data[5] = gBattleAnimArgs[4]; + gTasks[taskId].data[6] = gBattleAnimArgs[5]; + gTasks[taskId].data[7] = gBattleAnimArgs[6]; + } + ++gTasks[taskId].data[0]; + attackerBattler = gBattleAnimAttacker; + targetBattler = gBattleAnimTarget; + if (gTasks[taskId].data[2] & 0x100) + selectedPalettes = 0x0000FFFF; + if (gTasks[taskId].data[2] & 0x1) + { + paletteIndex = IndexOfSpritePaletteTag(gSprites[gHealthboxSpriteIds[attackerBattler]].template->paletteTag); + selectedPalettes |= (1 << paletteIndex) << 16; + } + if (gTasks[taskId].data[3] & 0x100) + selectedPalettes |= (1 << attackerBattler) << 16; + if (gTasks[taskId].data[4] & 0x100) + selectedPalettes |= (1 << targetBattler) << 16; + TintPlttBuffer(selectedPalettes, gTasks[taskId].data[5], gTasks[taskId].data[6], gTasks[taskId].data[7]); + if (gTasks[taskId].data[0] == gTasks[taskId].data[1]) + { + UnfadePlttBuffer(selectedPalettes); + DestroyAnimVisualTask(taskId); + } +} + +static void sub_80BA27C(struct Sprite *sprite) +{ + u16 var0; + + sprite->invisible = TRUE; + sprite->data[0] = -gBattleAnimArgs[0]; + sprite->data[1] = gBattleAnimArgs[1]; + sprite->data[2] = gBattleAnimArgs[1]; + sprite->data[3] = gBattleAnimArgs[2]; + + switch (gBattleAnimArgs[3]) + { + case 0: + StoreSpriteCallbackInData6(sprite, (void *)&gBattle_BG3_X); + break; + case 1: + StoreSpriteCallbackInData6(sprite, (void *)&gBattle_BG3_Y); + break; + case 2: + StoreSpriteCallbackInData6(sprite, (void *)&gSpriteCoordOffsetX); + break; + default: + StoreSpriteCallbackInData6(sprite, (void *)&gSpriteCoordOffsetY); + break; + } + sprite->data[4] = *(u16 *)(sprite->data[6] | (sprite->data[7] << 16)); + sprite->data[5] = gBattleAnimArgs[3]; + var0 = sprite->data[5] - 2; + if (var0 < 2) + sub_80BA3CC(); + sprite->callback = sub_80BA320; +} + +static void sub_80BA320(struct Sprite *sprite) +{ + u8 i; + u16 var0; + + if (sprite->data[3] > 0) + { + --sprite->data[3]; + if (sprite->data[1] > 0) + { + --sprite->data[1]; + } + else + { + sprite->data[1] = sprite->data[2]; + *(u16 *)(sprite->data[6] | (sprite->data[7] << 16)) += sprite->data[0]; + sprite->data[0] = -sprite->data[0]; + } + } + else + { + *(u16 *)(sprite->data[6] | (sprite->data[7] << 16)) = sprite->data[4]; + var0 = sprite->data[5] - 2; + if (var0 < 2) + for (i = 0; i < gBattlersCount; ++i) + gSprites[gBattlerSpriteIds[i]].coordOffsetEnabled = 0; + DestroyAnimSprite(sprite); + } +} + +static void sub_80BA3CC(void) +{ + gSprites[gBattlerSpriteIds[gBattleAnimAttacker]].coordOffsetEnabled = 0; + gSprites[gBattlerSpriteIds[gBattleAnimTarget]].coordOffsetEnabled = 0; + if (gBattleAnimArgs[4] == 2) + { + gSprites[gBattlerSpriteIds[gBattleAnimAttacker]].coordOffsetEnabled = 1; + gSprites[gBattlerSpriteIds[gBattleAnimTarget]].coordOffsetEnabled = 1; + } + else + { + if (gBattleAnimArgs[4] == 0) + gSprites[gBattlerSpriteIds[gBattleAnimAttacker]].coordOffsetEnabled = 1; + else + gSprites[gBattlerSpriteIds[gBattleAnimTarget]].coordOffsetEnabled = 1; + } +} + +void sub_80BA47C(u8 taskId) +{ + gTasks[taskId].data[0] = gBattleAnimArgs[0]; + gTasks[taskId].data[1] = gBattleAnimArgs[1]; + gTasks[taskId].data[2] = gBattleAnimArgs[2]; + gTasks[taskId].data[3] = gBattleAnimArgs[3]; + gTasks[taskId].data[8] = gBattleAnimArgs[3]; + gBattle_BG3_X = gBattleAnimArgs[0]; + gBattle_BG3_Y = gBattleAnimArgs[1]; + gTasks[taskId].func = sub_80BA4D0; + gTasks[taskId].func(taskId); +} + +static void sub_80BA4D0(u8 taskId) +{ + if (gTasks[taskId].data[3] == 0) + { + if (gBattle_BG3_X == gTasks[taskId].data[0]) + gBattle_BG3_X = -gTasks[taskId].data[0]; + else + gBattle_BG3_X = gTasks[taskId].data[0]; + + if (gBattle_BG3_Y == -gTasks[taskId].data[1]) + gBattle_BG3_Y = 0; + else + gBattle_BG3_Y = -gTasks[taskId].data[1]; + + gTasks[taskId].data[3] = gTasks[taskId].data[8]; + if (--gTasks[taskId].data[2] == 0) + { + gBattle_BG3_X = 0; + gBattle_BG3_Y = 0; + DestroyAnimVisualTask(taskId); + } + } + else + { + --gTasks[taskId].data[3]; + } +} + +static void sub_80BA560(struct Sprite *sprite) +{ + StartSpriteAffineAnim(sprite, gBattleAnimArgs[3]); + if (gBattleAnimArgs[2] == 0) + InitSpritePosToAnimAttacker(sprite, 1); + else + InitSpritePosToAnimTarget(sprite, TRUE); + sprite->callback = RunStoredCallbackWhenAffineAnimEnds; + StoreSpriteCallbackInData6(sprite, DestroyAnimSprite); +} + +static void sub_80BA5A8(struct Sprite *sprite) +{ + StartSpriteAffineAnim(sprite, gBattleAnimArgs[3]); + if (gBattleAnimArgs[2] == 0) + InitSpritePosToAnimAttacker(sprite, 1); + else + InitSpritePosToAnimTarget(sprite, TRUE); + sprite->data[0] = gBattleAnimArgs[4]; + sprite->callback = RunStoredCallbackWhenAffineAnimEnds; + StoreSpriteCallbackInData6(sprite, sub_80B1D3C); +} + +static void sub_80BA5F8(struct Sprite *sprite) +{ + if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER && !IsContest()) + gBattleAnimArgs[1] = -gBattleAnimArgs[1]; + sub_80BA560(sprite); +} + +static void sub_80BA630(struct Sprite *sprite) +{ + if (gBattleAnimArgs[1] == -1) + gBattleAnimArgs[1] = Random() & 3; + StartSpriteAffineAnim(sprite, gBattleAnimArgs[1]); + if (gBattleAnimArgs[0] == 0) + InitSpritePosToAnimAttacker(sprite, 0); + else + InitSpritePosToAnimTarget(sprite, FALSE); + sprite->pos2.x += (Random() % 48) - 24; + sprite->pos2.y += (Random() % 24) - 12; + StoreSpriteCallbackInData6(sprite, DestroySpriteAndMatrix); + sprite->callback = RunStoredCallbackWhenAffineAnimEnds; +} + +static void sub_80BA6C8(struct Sprite *sprite) +{ + sprite->data[0] = GetAnimBattlerSpriteId(gBattleAnimArgs[0]); + sprite->pos1.x = gSprites[sprite->data[0]].pos1.x + gSprites[sprite->data[0]].pos2.x; + sprite->pos1.y = gSprites[sprite->data[0]].pos1.y + gSprites[sprite->data[0]].pos2.y; + sprite->pos2.x = gBattleAnimArgs[1]; + sprite->pos2.y = gBattleAnimArgs[2]; + StartSpriteAffineAnim(sprite, gBattleAnimArgs[3]); + StoreSpriteCallbackInData6(sprite, DestroySpriteAndMatrix); + sprite->callback = RunStoredCallbackWhenAffineAnimEnds; +} + +static void sub_80BA738(struct Sprite *sprite) +{ + if (gBattleAnimArgs[2] == 0) + InitSpritePosToAnimAttacker(sprite, 1); + else + InitSpritePosToAnimTarget(sprite, TRUE); + sprite->data[0] = gBattleAnimArgs[3]; + StoreSpriteCallbackInData6(sprite, DestroyAnimSprite); + sprite->callback = WaitAnimForDuration; +} + +static void sub_80BA780(struct Sprite *sprite) +{ + StartSpriteAffineAnim(sprite, gBattleAnimArgs[3]); + if (gBattleAnimArgs[2] == 0) + InitSpritePosToAnimAttacker(sprite, 1); + else + InitSpritePosToAnimTarget(sprite, TRUE); + sprite->callback = sub_80BA7BC; +} + +static void sub_80BA7BC(struct Sprite *sprite) +{ + sprite->invisible ^= 1; + if (sprite->data[0]++ > 12) + DestroyAnimSprite(sprite); +} diff --git a/src/player_pc.c b/src/player_pc.c new file mode 100644 index 000000000..b1929b9ed --- /dev/null +++ b/src/player_pc.c @@ -0,0 +1,741 @@ +#include "global.h" +#include "palette.h" +#include "item.h" +#include "task.h" +#include "menu_indicators.h" +#include "new_menu_helpers.h" +#include "strings.h" +#include "menu.h" +#include "mail.h" +#include "mail_data.h" +#include "help_system.h" +#include "sound.h" +#include "overworld.h" +#include "script.h" +#include "mailbox_pc.h" +#include "player_pc.h" +#include "field_weather.h" +#include "event_scripts.h" +#include "field_fadetransition.h" +#include "string_util.h" +#include "item_menu.h" +#include "item_pc.h" +#include "party_menu.h" +#include "constants/items.h" +#include "constants/songs.h" + +#define PC_ITEM_ID 0 +#define PC_QUANTITY 1 +#define NEW_GAME_PC_ITEMS(i, type) (((u16 *)gNewGamePCItems + type)[i * 2]) + +#define tCount data[2] +#define tPageItems data[4] +#define tItemPcParam data[6] +#define tWindowId data[10] +#define tListMenuTaskId data[11] + +static EWRAM_DATA const u8 *sItemOrder = NULL; +static EWRAM_DATA u8 sTopMenuItemCount = 0; +EWRAM_DATA struct PlayerPCItemPageStruct gPlayerPcMenuManager = {}; + +#define SELECTED_MAIL (gSaveBlock1Ptr->mail[PC_MAIL_NUM(gPlayerPcMenuManager.scrollOffset) + gPlayerPcMenuManager.selectedRow]) + +static void Task_DrawPlayerPcTopMenu(u8 taskId); +static void Task_TopMenuHandleInput(u8 taskId); +static void Task_PlayerPcItemStorage(u8 taskId); +static void Task_PlayerPcMailbox(u8 taskId); +static void Task_PlayerPcTurnOff(u8 taskId); +static void Task_CreateItemStorageSubmenu(u8 taskId, u8 cursorPos); +static void PrintStringOnWindow0WithDialogueFrame(const u8 *str); +static void Task_TopMenu_ItemStorageSubmenu_HandleInput(u8 taskId); +static void Task_PlayerPcDepositItem(u8 taskId); +static void Task_DepositItem_WaitFadeAndGoToBag(u8 taskId); +static void CB2_ReturnFromDepositMenu(void); +static void Task_PlayerPcWithdrawItem(u8 taskId); +static void CB2_ReturnFromWithdrawMenu(void); +static void Task_WithdrawItemBeginFade(u8 taskId); +static void Task_PlayerPcCancel(u8 taskId); +static void Task_SetPageItemVars(u8 taskId); +static u8 CountPCMail(void); +static void PCMailCompaction(void); +static void Task_DrawMailboxPcMenu(u8 taskId); +static void Task_MailboxPcHandleInput(u8 taskId); +static void Task_PrintWhatToDoWithSelectedMail(u8 taskId); +static void Task_DestroyMailboxPcViewAndCancel(u8 taskId); +static void Task_DrawMailSubmenu(u8 taskId); +static void Task_MailSubmenuHandleInput(u8 taskId); +static void Task_PlayerPcReadMail(u8 taskId); +static void Task_WaitFadeAndReadSelectedMail(u8 taskId); +static void CB2_SetCbToReturnToMailbox(void); +static void Task_PlayerPcMoveMailToBag(u8 taskId); +static void Task_DrawYesNoMenuToConfirmMoveToBag(u8 taskId); +static void Task_MoveToBagYesNoMenuHandleInput(u8 taskId); +static void Task_TryPutMailInBag_DestroyMsgIfSuccessful(u8 taskId); +static void Task_DeclinedMoveMailToBag(u8 taskId); +static void Task_PlayerPcGiveMailToMon(u8 taskId); +static void Task_WaitFadeAndGoToPartyMenu(u8 taskId); +static void Task_Error_NoPokemon(u8 taskId); +static void Task_PlayerPcExitMailSubmenu(u8 taskId); + +static const u8 *const sItemStorageActionDescriptionPtrs[] = { + gText_TakeOutItemsFromThePC, + gText_StoreItemsInThePC, + gText_GoBackToThePreviousMenu +}; + +static const struct MenuAction sMenuActions_TopMenu[] = { + {gText_ItemStorage, Task_PlayerPcItemStorage}, + {gText_Mailbox, Task_PlayerPcMailbox}, + {gText_TurnOff, Task_PlayerPcTurnOff} +}; + +static const u8 gUnknown_8402200[] = { 0, 1, 2 }; +static const u8 gUnknown_8402203[] = { 0, 1, 2 }; + +static const struct MenuAction sMenuActions_ItemPc[] = { + {gText_WithdrawItem2, Task_PlayerPcWithdrawItem}, + {gText_DepositItem2, Task_PlayerPcDepositItem}, + {gFameCheckerText_Cancel, Task_PlayerPcCancel} +}; + +static const struct ItemSlot gNewGamePCItems[] = { + { ITEM_POTION, 1 }, + { ITEM_NONE, 0 } +}; + +static const struct MenuAction sMenuActions_MailSubmenu[] = { + {gOtherText_Read, Task_PlayerPcReadMail}, + {gOtherText_MoveToBag, Task_PlayerPcMoveMailToBag}, + {gOtherText_Give2, Task_PlayerPcGiveMailToMon}, + {gOtherText_Exit, Task_PlayerPcExitMailSubmenu} +}; + +static const struct WindowTemplate sWindowTemplate_TopMenu_3Items = { + .bg = 0, + .tilemapLeft = 1, + .tilemapTop = 1, + .width = 13, + .height = 6, + .paletteNum = 15, + .baseBlock = 0x008 +}; + +static const struct WindowTemplate sWindowTemplate_TopMenu_4Items = { + .bg = 0, + .tilemapLeft = 1, + .tilemapTop = 1, + .width = 13, + .height = 8, + .paletteNum = 15, + .baseBlock = 0x008 +}; + +static const struct WindowTemplate sWindowTemplate_ItemStorageSubmenu = { + .bg = 0, + .tilemapLeft = 1, + .tilemapTop = 1, + .width = 14, + .height = 6, + .paletteNum = 15, + .baseBlock = 0x008 +}; + +void NewGameInitPCItems(void) +{ + u8 i; + + for (i = 0, ClearPCItemSlots(); NEW_GAME_PC_ITEMS(i, PC_ITEM_ID) && NEW_GAME_PC_ITEMS(i, PC_QUANTITY) && + AddPCItem(NEW_GAME_PC_ITEMS(i, PC_ITEM_ID), NEW_GAME_PC_ITEMS(i, PC_QUANTITY)) == TRUE; i++) + ; +} + +void sub_80EB6AC(void) +{ + u8 taskId; + + gPlayerPcMenuManager.unk_9 = 0; + HelpSystem_BackupSomeVariable(); + sItemOrder = gUnknown_8402200; + sTopMenuItemCount = 3; + taskId = CreateTask(TaskDummy, 0); + DisplayItemMessageOnField(taskId, 2, gText_WhatWouldYouLikeToDo, Task_DrawPlayerPcTopMenu); +} + +void sub_80EB6FC(void) +{ + u8 taskId; + + gPlayerPcMenuManager.unk_9 = 1; + HelpSystem_BackupSomeVariable(); + sItemOrder = gUnknown_8402203; + sTopMenuItemCount = 3; + taskId = CreateTask(TaskDummy, 0); + DisplayItemMessageOnField(taskId, 2, gText_WhatWouldYouLikeToDo, Task_DrawPlayerPcTopMenu); +} + +static void Task_DrawPlayerPcTopMenu(u8 taskId) +{ + s16 *data = gTasks[taskId].data; + if (sTopMenuItemCount == 3) + tWindowId = AddWindow(&sWindowTemplate_TopMenu_3Items); + else + tWindowId = AddWindow(&sWindowTemplate_TopMenu_4Items); + SetStdWindowBorderStyle(tWindowId, 0); + AddItemMenuActionTextPrinters(tWindowId, 2, GetMenuCursorDimensionByFont(2, 0), 2, GetFontAttribute(2, FONTATTR_LETTER_SPACING), 16, sTopMenuItemCount, sMenuActions_TopMenu, sItemOrder); + Menu_InitCursor(tWindowId, 2, 0, 2, 16, sTopMenuItemCount, 0); + ScheduleBgCopyTilemapToVram(0); + gTasks[taskId].func = Task_TopMenuHandleInput; +} + +static void Task_TopMenuHandleInput(u8 taskId) +{ + s16 *data = gTasks[taskId].data; + s8 input = Menu_ProcessInputNoWrapAround(); + switch (input) + { + case -2: + break; + case -1: + PlaySE(SE_SELECT); + ClearStdWindowAndFrameToTransparent(tWindowId, FALSE); + ClearWindowTilemap(tWindowId); + RemoveWindow(tWindowId); + ScheduleBgCopyTilemapToVram(0); + gTasks[taskId].func = Task_PlayerPcTurnOff; + break; + default: + ClearStdWindowAndFrameToTransparent(tWindowId, FALSE); + ClearWindowTilemap(tWindowId); + RemoveWindow(tWindowId); + ScheduleBgCopyTilemapToVram(0); + gTasks[taskId].func = sMenuActions_TopMenu[sItemOrder[input]].func.void_u8; + break; + } +} + +static void Task_ReturnToTopMenu(u8 taskId) +{ + HelpSystem_RestoreSomeVariable(); + DisplayItemMessageOnField(taskId, 2, gText_WhatWouldYouLikeToDo, Task_DrawPlayerPcTopMenu); +} + +static void Task_PlayerPcItemStorage(u8 taskId) +{ + Task_CreateItemStorageSubmenu(taskId, FALSE); + gTasks[taskId].func = Task_TopMenu_ItemStorageSubmenu_HandleInput; +} + +static void Task_PlayerPcMailbox(u8 taskId) +{ + gPlayerPcMenuManager.count = CountPCMail(); + if (gPlayerPcMenuManager.count == 0) + { + DisplayItemMessageOnField(taskId, 2, gText_TheresNoMailHere, Task_ReturnToTopMenu); + } + else + { + gPlayerPcMenuManager.selectedRow = 0; + gPlayerPcMenuManager.scrollOffset = 0; + PCMailCompaction(); + Task_SetPageItemVars(taskId); + if (gPlayerPcMenuManager.unk_9 == 0) + HelpSystem_SetSomeVariable2(34); + else + HelpSystem_SetSomeVariable2(30); + if (MailboxPC_InitBuffers(gPlayerPcMenuManager.count) == TRUE) + { + ClearDialogWindowAndFrame(0, FALSE); + Task_DrawMailboxPcMenu(taskId); + gTasks[taskId].func = Task_MailboxPcHandleInput; + } + else + { + DisplayItemMessageOnField(taskId, 2, gText_TheresNoMailHere, Task_ReturnToTopMenu); + } + } +} + +static void Task_PlayerPcTurnOff(u8 taskId) +{ + if (gPlayerPcMenuManager.unk_9 == 0) + ScriptContext1_SetupScript(EventScript_PalletTown_PlayersHouse_2F_ShutDownPC); + else + EnableBothScriptContexts(); + DestroyTask(taskId); +} + +static void Task_CreateItemStorageSubmenu(u8 taskId, u8 cursorPos) +{ + s16 *data = gTasks[taskId].data; + if (gPlayerPcMenuManager.unk_9 == 0) + HelpSystem_SetSomeVariable2(33); + else + HelpSystem_SetSomeVariable2(29); + tWindowId = AddWindow(&sWindowTemplate_ItemStorageSubmenu); + SetStdWindowBorderStyle(tWindowId, FALSE); + PrintTextArray(tWindowId, 2, GetMenuCursorDimensionByFont(2, 0), 2, 16, 3, sMenuActions_ItemPc); + Menu_InitCursor(tWindowId, 2, 0, 2, 16, 3, cursorPos); + ScheduleBgCopyTilemapToVram(0); + PrintStringOnWindow0WithDialogueFrame(sItemStorageActionDescriptionPtrs[cursorPos]); +} + +static void PrintStringOnWindow0WithDialogueFrame(const u8 *str) +{ + DrawDialogueFrame(0, FALSE); + AddTextPrinterParameterized(0, 2, str, 0, 1, 0, NULL); +} + +static void Task_TopMenu_ItemStorageSubmenu_HandleInput(u8 taskId) +{ + if (JOY_REPT(DPAD_UP)) + { + if (Menu_GetCursorPos() != 0) + { + PlaySE(SE_SELECT); + Menu_MoveCursor(-1); + PrintStringOnWindow0WithDialogueFrame(sItemStorageActionDescriptionPtrs[Menu_GetCursorPos()]); + } + } + else if (JOY_REPT(DPAD_DOWN)) + { + if (Menu_GetCursorPos() != 2) + { + PlaySE(SE_SELECT); + Menu_MoveCursor(+1); + PrintStringOnWindow0WithDialogueFrame(sItemStorageActionDescriptionPtrs[Menu_GetCursorPos()]); + } + } + else if (JOY_NEW(A_BUTTON)) + { + PlaySE(SE_SELECT); + sMenuActions_ItemPc[Menu_GetCursorPos()].func.void_u8(taskId); + } + else if (JOY_NEW(B_BUTTON)) + { + PlaySE(SE_SELECT); + sMenuActions_ItemPc[2].func.void_u8(taskId); + } +} + +static void Task_DepositItem_WaitFadeAndGoToBag(u8 taskId) +{ + if (!gPaletteFade.active) + { + CleanupOverworldWindowsAndTilemaps(); + sub_8107DB4(3, POCKET_ITEMS - 1, CB2_ReturnToField); + gFieldCallback = CB2_ReturnFromDepositMenu; + DestroyTask(taskId); + } +} + +static void Task_PlayerPcDepositItem(u8 taskId) +{ + gTasks[taskId].func = Task_DepositItem_WaitFadeAndGoToBag; + fade_screen(1, 0); +} + +static void Task_ReturnToItemStorageSubmenu(u8 taskId) +{ + if (field_weather_is_fade_finished() == TRUE) + gTasks[taskId].func = Task_TopMenu_ItemStorageSubmenu_HandleInput; +} + +static void CB2_ReturnFromDepositMenu(void) +{ + u8 taskId; + LoadStdWindowFrameGfx(); + DrawDialogueFrame(0, TRUE); + taskId = CreateTask(Task_ReturnToItemStorageSubmenu, 0); + Task_CreateItemStorageSubmenu(taskId, 1); + sub_807DC00(); +} + +static void Task_PlayerPcWithdrawItem(u8 taskId) +{ + s16 *data = gTasks[taskId].data; + tCount = CountItemsInPC(); + if (tCount != 0) + { + tItemPcParam = 0; + gTasks[taskId].func = Task_WithdrawItemBeginFade; + gFieldCallback = CB2_ReturnFromWithdrawMenu; + } + else + { + ClearStdWindowAndFrameToTransparent(tWindowId, FALSE); + ClearWindowTilemap(tWindowId); + RemoveWindow(tWindowId); + DisplayItemMessageOnField(taskId, 2, gText_ThereAreNoItems, Task_PlayerPcItemStorage); + } +} + +static void CB2_ReturnFromWithdrawMenu(void) +{ + u8 taskId; + LoadStdWindowFrameGfx(); + DrawDialogueFrame(0, TRUE); + taskId = CreateTask(Task_ReturnToItemStorageSubmenu, 0); + Task_CreateItemStorageSubmenu(taskId, 0); + sub_807DC00(); +} + +static void Task_WithdrawItem_WaitFadeAndGoToItemStorage(u8 taskId) +{ + s16 *data = gTasks[taskId].data; + if (!gPaletteFade.active) + { + CleanupOverworldWindowsAndTilemaps(); + ItemPc_Init(tItemPcParam, CB2_ReturnToField); + DestroyTask(taskId); + } +} + +static void Task_WithdrawItemBeginFade(u8 taskId) +{ + gTasks[taskId].func = Task_WithdrawItem_WaitFadeAndGoToItemStorage; + ItemPc_SetInitializedFlag(0); + fade_screen(1, 0); +} + +static void Task_PlayerPcCancel(u8 taskId) +{ + s16 *data = gTasks[taskId].data; + ClearStdWindowAndFrameToTransparent(tWindowId, FALSE); + ClearWindowTilemap(tWindowId); + CopyWindowToVram(tWindowId, 1); + RemoveWindow(tWindowId); + Task_ReturnToTopMenu(taskId); +} + +static void Task_SetPageItemVars(u8 taskId) +{ + s16 *data = gTasks[taskId].data; + if (tCount >= 8) + tPageItems = 8; + else + tPageItems = tCount + 1; + if (gPlayerPcMenuManager.count >= 8) + gPlayerPcMenuManager.pageItems = 8; + else + gPlayerPcMenuManager.pageItems = gPlayerPcMenuManager.count + 1; +} + +static u8 CountPCMail(void) +{ + u8 count = 0; + u8 i; + + for (i = PC_MAIL_NUM(0); i < MAIL_COUNT; i++) + { + if (gSaveBlock1Ptr->mail[i].itemId != ITEM_NONE) + count++; + } + return count; +} + +static void PCMailCompaction(void) +{ + u8 i; + u8 j; + for (i = PC_MAIL_NUM(0); i < MAIL_COUNT - 1; i++) + { + for (j = i + 1; j < MAIL_COUNT; j++) + { + if (gSaveBlock1Ptr->mail[i].itemId == ITEM_NONE) + { + struct MailStruct mail = gSaveBlock1Ptr->mail[i]; + gSaveBlock1Ptr->mail[i] = gSaveBlock1Ptr->mail[j]; + gSaveBlock1Ptr->mail[j] = mail; + } + } + } +} + +static void Task_DrawMailboxPcMenu(u8 taskId) +{ + u8 windowId = MailboxPC_GetAddWindow(0); + s32 width = GetStringWidth(2, gText_Mailbox, 0); + MailboxPC_GetAddWindow(1); + AddTextPrinterParameterized(windowId, 2, gText_Mailbox, (80 - width) / 2, 2, 0, NULL); + ScheduleBgCopyTilemapToVram(0); + gTasks[taskId].tListMenuTaskId = MailboxPC_InitListMenu(&gPlayerPcMenuManager); + MailboxPC_AddScrollIndicatorArrows(&gPlayerPcMenuManager); +} + +static void Task_MailboxPcHandleInput(u8 taskId) +{ + s16 *data = gTasks[taskId].data; + s32 input; + if (!gPaletteFade.active) + { + input = ListMenu_ProcessInput(tListMenuTaskId); + ListMenuGetScrollAndRow(tListMenuTaskId, &gPlayerPcMenuManager.scrollOffset, &gPlayerPcMenuManager.selectedRow); + switch (input) + { + case -1: + break; + case -2: + PlaySE(SE_SELECT); + RemoveScrollIndicatorArrowPair(gPlayerPcMenuManager.scrollIndicatorId); + Task_DestroyMailboxPcViewAndCancel(taskId); + break; + default: + PlaySE(SE_SELECT); + MailboxPC_RemoveWindow(0); + MailboxPC_RemoveWindow(1); + DestroyListMenuTask(tListMenuTaskId, &gPlayerPcMenuManager.scrollOffset, &gPlayerPcMenuManager.selectedRow); + ScheduleBgCopyTilemapToVram(0); + RemoveScrollIndicatorArrowPair(gPlayerPcMenuManager.scrollIndicatorId); + gTasks[taskId].func = Task_PrintWhatToDoWithSelectedMail; + break; + } + } +} + +static void Task_PrintWhatToDoWithSelectedMail(u8 taskId) +{ + s32 length; + s32 i; + u8 *ptr; + StringCopy(gStringVar1, SELECTED_MAIL.playerName); + length = StringLength(gStringVar1); + if (length > 5) + { + for (ptr = gStringVar1 + length - 1; ptr >= gStringVar1; ptr--) + { + if (*ptr) + break; + *ptr = EOS; + } + } + else + { + ConvertInternationalString(gStringVar1, LANGUAGE_JAPANESE); + } + StringExpandPlaceholders(gStringVar4, gText_WhatWouldYouLikeToDoWithPlayersMail); + DisplayItemMessageOnField(taskId, 2, gStringVar4, Task_DrawMailSubmenu); +} + +static void Task_DestroyMailboxPcViewAndCancel(u8 taskId) +{ + s16 *data = gTasks[taskId].data; + MailboxPC_RemoveWindow(0); + MailboxPC_RemoveWindow(1); + DestroyListMenuTask(tListMenuTaskId, NULL, NULL); + ScheduleBgCopyTilemapToVram(0); + MailboxPC_DestroyListMenuBuffer(); + Task_ReturnToTopMenu(taskId); +} + +static void Task_DrawMailSubmenu(u8 taskId) +{ + u8 windowId = MailboxPC_GetAddWindow(2); + PrintTextArray(windowId, 2, GetMenuCursorDimensionByFont(2, 0), 2, 16, 4, sMenuActions_MailSubmenu); + Menu_InitCursor(windowId, 2, 0, 2, 16, 4, 0); + ScheduleBgCopyTilemapToVram(0); + gTasks[taskId].func = Task_MailSubmenuHandleInput; +} + +static void Task_MailSubmenuHandleInput(u8 taskId) +{ + s8 input = Menu_ProcessInput_other(); + switch (input) + { + case -1: + PlaySE(SE_SELECT); + Task_PlayerPcExitMailSubmenu(taskId); + break; + case -2: + break; + default: + PlaySE(SE_SELECT); + sMenuActions_MailSubmenu[input].func.void_u8(taskId); + break; + } +} + +static void Task_PlayerPcReadMail(u8 taskId) +{ + fade_screen(1, 0); + gTasks[taskId].func = Task_WaitFadeAndReadSelectedMail; +} + +static void Task_WaitFadeAndReadSelectedMail(u8 taskId) +{ + if (!gPaletteFade.active) + { + MailboxPC_DestroyListMenuBuffer(); + CleanupOverworldWindowsAndTilemaps(); + sub_80BEBEC(&SELECTED_MAIL, CB2_SetCbToReturnToMailbox, 1); + DestroyTask(taskId); + } +} + +static void Task_WaitFadeAndReturnToMailboxPcInputHandler(u8 taskId) +{ + if (field_weather_is_fade_finished() == TRUE) + gTasks[taskId].func = Task_MailboxPcHandleInput; +} + +static void CB2_ReturnToMailbox(void) +{ + u8 taskId; + if (gPlayerPcMenuManager.unk_9 == 0) + HelpSystem_SetSomeVariable2(34); + else + HelpSystem_SetSomeVariable2(30); + LoadStdWindowFrameGfx(); + taskId = CreateTask(Task_WaitFadeAndReturnToMailboxPcInputHandler, 0); + if (MailboxPC_InitBuffers(gPlayerPcMenuManager.count) == TRUE) + Task_DrawMailboxPcMenu(taskId); + else + DestroyTask(taskId); + sub_807DC00(); +} + +static void CB2_SetCbToReturnToMailbox(void) +{ + gFieldCallback = CB2_ReturnToMailbox; + SetMainCallback2(CB2_ReturnToField); +} + +static void Task_PlayerPcMoveMailToBag(u8 taskId) +{ + DisplayItemMessageOnField(taskId, 2, gText_MessageWillBeLost, Task_DrawYesNoMenuToConfirmMoveToBag); +} + +static void Task_DrawYesNoMenuToConfirmMoveToBag(u8 taskId) +{ + DisplayYesNoMenuDefaultYes(); + gTasks[taskId].func = Task_MoveToBagYesNoMenuHandleInput; +} + +static void Task_MoveToBagYesNoMenuHandleInput(u8 taskId) +{ + switch (Menu_ProcessInputNoWrapClearOnChoose()) + { + case -2: + break; + case 0: + Task_TryPutMailInBag_DestroyMsgIfSuccessful(taskId); + break; + case -1: + PlaySE(SE_SELECT); + // fallthrough + case 1: + Task_DeclinedMoveMailToBag(taskId); + break; + } +} + +static void Task_TryPutMailInBag_DestroyMsgIfSuccessful(u8 taskId) +{ + struct MailStruct * mail = &SELECTED_MAIL; + if (!AddBagItem(mail->itemId, 1)) + { + DisplayItemMessageOnField(taskId, 2, gText_BagIsFull, Task_PlayerPcExitMailSubmenu); + } + else + { + DisplayItemMessageOnField(taskId, 2, gText_MailReturnedToBagMessageErased, Task_PlayerPcExitMailSubmenu); + ClearMailStruct(mail); + PCMailCompaction(); + gPlayerPcMenuManager.count--; + if (gPlayerPcMenuManager.count < gPlayerPcMenuManager.pageItems + gPlayerPcMenuManager.scrollOffset) + { + if (gPlayerPcMenuManager.scrollOffset != 0) + gPlayerPcMenuManager.scrollOffset--; + } + Task_SetPageItemVars(taskId); + } +} + +static void Task_DeclinedMoveMailToBag(u8 taskId) +{ + Task_PlayerPcExitMailSubmenu(taskId); +} + +static void Task_PlayerPcGiveMailToMon(u8 taskId) +{ + if (CalculatePlayerPartyCount() == 0) + { + Task_Error_NoPokemon(taskId); + } + else + { + fade_screen(1, 0); + gTasks[taskId].func = Task_WaitFadeAndGoToPartyMenu; + } +} + +static void Task_WaitFadeAndGoToPartyMenu(u8 taskId) +{ + if (!gPaletteFade.active) + { + MailboxPC_DestroyListMenuBuffer(); + CleanupOverworldWindowsAndTilemaps(); + PartyMenuInit_FromPlayerPc(); + DestroyTask(taskId); + } +} + +static void CB2_ReturnToMailboxPc_UpdateScrollVariables(void) +{ + u8 taskId; + u8 count; + if (gPlayerPcMenuManager.unk_9 == 0) + HelpSystem_SetSomeVariable2(34); + else + HelpSystem_SetSomeVariable2(30); + taskId = CreateTask(Task_WaitFadeAndReturnToMailboxPcInputHandler, 0); + count = gPlayerPcMenuManager.count; + gPlayerPcMenuManager.count = CountPCMail(); + PCMailCompaction(); + if (count != gPlayerPcMenuManager.count) + { + if (gPlayerPcMenuManager.count < gPlayerPcMenuManager.pageItems + gPlayerPcMenuManager.scrollOffset) + { + if (gPlayerPcMenuManager.scrollOffset != 0) + gPlayerPcMenuManager.scrollOffset--; + } + } + Task_SetPageItemVars(taskId); + LoadStdWindowFrameGfx(); + if (MailboxPC_InitBuffers(gPlayerPcMenuManager.count) == TRUE) + Task_DrawMailboxPcMenu(taskId); + else + DestroyTask(taskId); + sub_807DC00(); +} + +void CB2_PlayerPC_ReturnFromPartyMenu(void) +{ + gFieldCallback = CB2_ReturnToMailboxPc_UpdateScrollVariables; + SetMainCallback2(CB2_ReturnToField); +} + +static void Task_Error_NoPokemon(u8 taskId) +{ + DisplayItemMessageOnField(taskId, 2, gText_ThereIsNoPokemon, Task_PlayerPcExitMailSubmenu); +} + +static void Task_RedrawPlayerPcMailboxAndSetUpInputHandler(u8 taskId) +{ + ClearDialogWindowAndFrame(0, FALSE); + Task_DrawMailboxPcMenu(taskId); + ScheduleBgCopyTilemapToVram(0); + gTasks[taskId].func = Task_MailboxPcHandleInput; +} + +static void Task_PlayerPcExitMailSubmenu(u8 taskId) +{ + MailboxPC_RemoveWindow(2); + ScheduleBgCopyTilemapToVram(0); + gTasks[taskId].func = Task_RedrawPlayerPcMailboxAndSetUpInputHandler; +} + +#undef tListMenuTaskId +#undef tWindowId +#undef tItemPcParam +#undef tPageItems +#undef tCount diff --git a/src/pokemon.c b/src/pokemon.c index 4685dcbcd..1159b1861 100644 --- a/src/pokemon.c +++ b/src/pokemon.c @@ -13,7 +13,6 @@ #include "event_data.h" #include "util.h" #include "pokemon_storage_system.h" -#include "data.h" #include "battle_gfx_sfx_util.h" #include "battle_controllers.h" #include "evolution_scene.h" diff --git a/src/psychic.c b/src/psychic.c new file mode 100644 index 000000000..662320a2b --- /dev/null +++ b/src/psychic.c @@ -0,0 +1,1083 @@ +#include "global.h" +#include "battle_anim.h" +#include "gpu_regs.h" +#include "palette.h" +#include "sound.h" +#include "scanline_effect.h" +#include "trig.h" +#include "constants/songs.h" + +static void sub_80B2ECC(struct Sprite *sprite); +static void sub_80B31D0(struct Sprite *sprite); +static void sub_80B3278(struct Sprite *sprite); +static void sub_80B32F4(struct Sprite *sprite); +static void sub_80B37EC(struct Sprite *sprite); +static void sub_80B3A34(struct Sprite *sprite); +static void sub_80B3E84(struct Sprite *sprite); +static void sub_80B300C(struct Sprite *sprite); +static void sub_80B3044(struct Sprite *sprite); +static void sub_80B30B0(struct Sprite *sprite); +static void sub_80B3168(struct Sprite *sprite); +static void sub_80B3384(struct Sprite *sprite); +static void sub_80B33B8(struct Sprite *sprite); +static void sub_80B3454(u8 taskId); +static void sub_80B34DC(u8 taskId); +static void sub_80B3618(u8 taskId); +static void sub_80B3980(u8 taskId); +static void sub_80B3B78(u8 taskId); +static void sub_80B3D78(u8 taskId); + +static const union AffineAnimCmd gUnknown_83E6DDC[] = +{ + AFFINEANIMCMD_FRAME(0x100, 0x100, 0, 0), + AFFINEANIMCMD_FRAME(0xFFFE, 0xFFFE, -10, 120), + AFFINEANIMCMD_END, +}; + +static const union AffineAnimCmd *const gUnknown_83E6DF4[] = +{ + gUnknown_83E6DDC, +}; + +const struct SpriteTemplate gUnknown_83E6DF8 = +{ + .tileTag = ANIM_TAG_SPIRAL, + .paletteTag = ANIM_TAG_SPIRAL, + .oam = &gOamData_83ACB60, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gUnknown_83E6DF4, + .callback = sub_8075D9C, +}; + +const struct SpriteTemplate gUnknown_83E6E10 = +{ + .tileTag = ANIM_TAG_GREEN_LIGHT_WALL, + .paletteTag = ANIM_TAG_GREEN_LIGHT_WALL, + .oam = &gOamData_83ACB00, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_80B2ECC, +}; + +const struct SpriteTemplate gUnknown_83E6E28 = +{ + .tileTag = ANIM_TAG_BLUE_LIGHT_WALL, + .paletteTag = ANIM_TAG_BLUE_LIGHT_WALL, + .oam = &gOamData_83ACB00, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_80B2ECC, +}; + +const struct SpriteTemplate gUnknown_83E6E40 = +{ + .tileTag = ANIM_TAG_RED_LIGHT_WALL, + .paletteTag = ANIM_TAG_RED_LIGHT_WALL, + .oam = &gOamData_83ACB00, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_80B2ECC, +}; + +const struct SpriteTemplate gUnknown_83E6E58 = +{ + .tileTag = ANIM_TAG_GRAY_LIGHT_WALL, + .paletteTag = ANIM_TAG_GRAY_LIGHT_WALL, + .oam = &gOamData_83ACB00, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_80B2ECC, +}; + +const struct SpriteTemplate gUnknown_83E6E70 = +{ + .tileTag = ANIM_TAG_ORANGE_LIGHT_WALL, + .paletteTag = ANIM_TAG_ORANGE_LIGHT_WALL, + .oam = &gOamData_83ACB00, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_80B2ECC, +}; + +static const union AnimCmd gUnknown_83E6E88[] = +{ + ANIMCMD_FRAME(0, 3), + ANIMCMD_FRAME(16, 3), + ANIMCMD_FRAME(32, 3), + ANIMCMD_FRAME(48, 3), + ANIMCMD_FRAME(64, 3), + ANIMCMD_END, +}; + +static const union AnimCmd *const gUnknown_83E6EA0[] = +{ + gUnknown_83E6E88, +}; + +const struct SpriteTemplate gUnknown_83E6EA4 = +{ + .tileTag = ANIM_TAG_SPARKLE_4, + .paletteTag = ANIM_TAG_SPARKLE_4, + .oam = &gOamData_83AC9D8, + .anims = gUnknown_83E6EA0, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_80B31D0, +}; + +static const union AnimCmd gUnknown_83E6EBC[] = +{ + ANIMCMD_FRAME(0, 5), + ANIMCMD_FRAME(4, 5), + ANIMCMD_FRAME(8, 5), + ANIMCMD_FRAME(12, 5), + ANIMCMD_END, +}; + +static const union AnimCmd *const gUnknown_83E6ED0[] = +{ + gUnknown_83E6EBC, +}; + +const struct SpriteTemplate gUnknown_83E6ED4 = +{ + .tileTag = ANIM_TAG_SPARKLE_3, + .paletteTag = ANIM_TAG_SPARKLE_3, + .oam = &gOamData_83AC9D0, + .anims = gUnknown_83E6ED0, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_80B31D0, +}; + +const struct SpriteTemplate gUnknown_83E6EEC = +{ + .tileTag = ANIM_TAG_GOLD_RING, + .paletteTag = ANIM_TAG_GOLD_RING, + .oam = &gOamData_83ACA18, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = TranslateAnimSpriteToTargetMonLocation, +}; + +static const union AnimCmd gUnknown_83E6F04[] = +{ + ANIMCMD_FRAME(8, 60, .hFlip = TRUE), + ANIMCMD_FRAME(16, 5, .hFlip = TRUE), + ANIMCMD_FRAME(8, 5, .hFlip = TRUE), + ANIMCMD_FRAME(0, 5, .hFlip = TRUE), + ANIMCMD_FRAME(8, 22, .hFlip = TRUE), + ANIMCMD_LOOP(0), + ANIMCMD_FRAME(16, 5, .hFlip = TRUE), + ANIMCMD_FRAME(8, 5, .hFlip = TRUE), + ANIMCMD_FRAME(0, 5, .hFlip = TRUE), + ANIMCMD_FRAME(8, 5, .hFlip = TRUE), + ANIMCMD_LOOP(1), + ANIMCMD_FRAME(8, 22, .hFlip = TRUE), + ANIMCMD_FRAME(24, 3, .hFlip = TRUE), + ANIMCMD_FRAME(32, 3, .hFlip = TRUE), + ANIMCMD_FRAME(40, 22, .hFlip = TRUE), + ANIMCMD_END, +}; + +const union AnimCmd gUnknown_83E6F44[] = +{ + ANIMCMD_FRAME(8, 60), + ANIMCMD_FRAME(16, 5), + ANIMCMD_FRAME(8, 5), + ANIMCMD_FRAME(0, 5), + ANIMCMD_FRAME(8, 22), + ANIMCMD_LOOP(0), + ANIMCMD_FRAME(16, 5), + ANIMCMD_FRAME(8, 5), + ANIMCMD_FRAME(0, 5), + ANIMCMD_FRAME(8, 5), + ANIMCMD_LOOP(1), + ANIMCMD_FRAME(8, 22), + ANIMCMD_FRAME(24, 3), + ANIMCMD_FRAME(32, 3), + ANIMCMD_FRAME(40, 22), + ANIMCMD_END, +}; + +static const union AnimCmd *const gUnknown_83E6F84[] = +{ + gUnknown_83E6F04, + gUnknown_83E6F44, +}; + +const struct SpriteTemplate gUnknown_83E6F8C = +{ + .tileTag = ANIM_TAG_BENT_SPOON, + .paletteTag = ANIM_TAG_BENT_SPOON, + .oam = &gOamData_83ACA18, + .anims = gUnknown_83E6F84, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_80B3278, +}; + +static const union AnimCmd gUnknown_83E6FA4[] = +{ + ANIMCMD_FRAME(0, 6), + ANIMCMD_FRAME(16, 6), + ANIMCMD_FRAME(32, 6), + ANIMCMD_FRAME(48, 6), + ANIMCMD_FRAME(64, 6), + ANIMCMD_FRAME(80, 6), + ANIMCMD_FRAME(96, 18), + ANIMCMD_END, +}; + +static const union AnimCmd *const gUnknown_83E6FC4[] = +{ + gUnknown_83E6FA4, +}; + +static const union AffineAnimCmd gUnknown_83E6FC8[] = +{ + AFFINEANIMCMD_FRAME(0, 0, 4, 4), + AFFINEANIMCMD_FRAME(0, 0, -4, 8), + AFFINEANIMCMD_FRAME(0, 0, 4, 4), + AFFINEANIMCMD_LOOP(2), + AFFINEANIMCMD_END, +}; + +static const union AffineAnimCmd *const gUnknown_83E6FF0[] = +{ + gUnknown_83E6FC8, +}; + +const struct SpriteTemplate gUnknown_83E6FF4 = +{ + .tileTag = ANIM_TAG_AMNESIA, + .paletteTag = ANIM_TAG_AMNESIA, + .oam = &gOamData_83AC9D8, + .anims = gUnknown_83E6FC4, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_80B32F4, +}; + +static const union AffineAnimCmd gUnknown_83E700C[] = +{ + AFFINEANIMCMD_FRAME(-8, 10, 0, 16), + AFFINEANIMCMD_FRAME(18, -18, 0, 16), + AFFINEANIMCMD_FRAME(-20, 16, 0, 8), + AFFINEANIMCMD_END, +}; + +static const union AffineAnimCmd gUnknown_83E702C[] = +{ + AFFINEANIMCMD_FRAME(64, -4, 0, 20), + AFFINEANIMCMD_FRAME(0, 0, 0, -56), + AFFINEANIMCMD_END, +}; + +static const struct SpriteTemplate gUnknown_83E7044 = +{ + .tileTag = ANIM_TAG_HOLLOW_ORB, + .paletteTag = ANIM_TAG_HOLLOW_ORB, + .oam = &gOamData_83ACAF0, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy, +}; + +const struct SpriteTemplate gUnknown_83E705C = +{ + .tileTag = 0x280A, + .paletteTag = 0x280A, + .oam = &gOamData_83AC9E0, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_80B37EC, +}; + +static const union AffineAnimCmd gUnknown_83E7074[] = +{ + AFFINEANIMCMD_FRAME(0xFFF8, 0xFFF8, 0, 8), + AFFINEANIMCMD_FRAME(0x8, 0x8, 0, 8), + AFFINEANIMCMD_JUMP(0), +}; + +static const union AffineAnimCmd gUnknown_83E708C[] = +{ + AFFINEANIMCMD_FRAME(0xF0, 0xF0, 0, 0), + AFFINEANIMCMD_FRAME(0xFFF8, 0xFFF8, 0, 6), + AFFINEANIMCMD_FRAME(0x8, 0x8, 0, 8), + AFFINEANIMCMD_FRAME(0xFFF8, 0xFFF8, 0, 2), + AFFINEANIMCMD_JUMP(1), +}; + +static const union AffineAnimCmd gUnknown_83E70B4[] = +{ + AFFINEANIMCMD_FRAME(0xD0, 0xD0, 0, 0), + AFFINEANIMCMD_FRAME(0xFFF8, 0xFFF8, 0, 4), + AFFINEANIMCMD_FRAME(0x8, 0x8, 0, 8), + AFFINEANIMCMD_FRAME(0xFFF8, 0xFFF8, 0, 4), + AFFINEANIMCMD_JUMP(1), +}; + +static const union AffineAnimCmd gUnknown_83E70DC[] = +{ + AFFINEANIMCMD_FRAME(0xB0, 0xB0, 0, 0), + AFFINEANIMCMD_FRAME(0xFFF8, 0xFFF8, 0, 2), + AFFINEANIMCMD_FRAME(0x8, 0x8, 0, 8), + AFFINEANIMCMD_FRAME(0xFFF8, 0xFFF8, 0, 6), + AFFINEANIMCMD_JUMP(1), +}; + +static const union AffineAnimCmd *const gUnknown_83E7104[] = +{ + gUnknown_83E7074, + gUnknown_83E708C, + gUnknown_83E70B4, + gUnknown_83E70DC, +}; + +static const struct SpriteTemplate gUnknown_83E7114 = +{ + .tileTag = ANIM_TAG_BLUEGREEN_ORB, + .paletteTag = ANIM_TAG_BLUEGREEN_ORB, + .oam = &gOamData_83ACA30, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gUnknown_83E7104, + .callback = sub_80B3A34, +}; + +static const union AffineAnimCmd gUnknown_83E712C[] = +{ + AFFINEANIMCMD_FRAME(0x20, 0x20, 0, 0), + AFFINEANIMCMD_FRAME(0x4, 0x4, 0, 120), + AFFINEANIMCMD_END_ALT(1), +}; + +static const union AffineAnimCmd *const gUnknown_83E7144[] = +{ + gUnknown_83E712C, +}; + +const struct SpriteTemplate gUnknown_83E7148 = +{ + .tileTag = ANIM_TAG_WHITE_CIRCLE_OF_LIGHT, + .paletteTag = ANIM_TAG_WHITE_CIRCLE_OF_LIGHT, + .oam = &gOamData_83ACBC0, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gUnknown_83E7144, + .callback = sub_8075D9C, +}; + +static const union AffineAnimCmd gUnknown_83E7160[] = +{ + AFFINEANIMCMD_FRAME(0x20, 0x20, 0, 0), + AFFINEANIMCMD_FRAME(0x10, 0x10, 0, 17), + AFFINEANIMCMD_LOOP(0), + AFFINEANIMCMD_FRAME(0xFFF8, 0xFFF8, 0, 10), + AFFINEANIMCMD_FRAME(0x8, 0x8, 0, 10), + AFFINEANIMCMD_LOOP(4), + AFFINEANIMCMD_LOOP(0), + AFFINEANIMCMD_FRAME(0xFFF0, 0xFFF0, 0, 5), + AFFINEANIMCMD_FRAME(0x10, 0x10, 0, 5), + AFFINEANIMCMD_LOOP(7), + AFFINEANIMCMD_END, +}; + +static const union AffineAnimCmd gUnknown_83E71B8[] = +{ + AFFINEANIMCMD_FRAME(0xFFEC, 0x18, 0, 15), + AFFINEANIMCMD_END, +}; + +static const union AffineAnimCmd *const gUnknown_83E71C8[] = +{ + gUnknown_83E7160, + gUnknown_83E71B8, +}; + +const struct SpriteTemplate gUnknown_83E71D0 = +{ + .tileTag = ANIM_TAG_CIRCLE_OF_LIGHT, + .paletteTag = ANIM_TAG_CIRCLE_OF_LIGHT, + .oam = &gOamData_83ACBC0, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gUnknown_83E71C8, + .callback = sub_80B3E84, +}; + +static void sub_80B2ECC(struct Sprite *sprite) +{ + if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER || IsContest()) + { + sprite->oam.priority = 2; + sprite->subpriority = 200; + } + if (!IsContest()) + { + u8 battlerCopy; + u8 battler = battlerCopy = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT); + u8 rank = GetBattlerSpriteBGPriorityRank(battler); + s32 var0 = 1; + bool8 toBG2 = (rank ^ var0) != 0; + + if (IsBattlerSpriteVisible(battler)) + MoveBattlerSpriteToBG(battler, toBG2); + battler = BATTLE_PARTNER(battlerCopy); + if (IsBattlerSpriteVisible(battler)) + MoveBattlerSpriteToBG(battler, toBG2 ^ var0); + } + if (!IsContest() && IsDoubleBattle()) + { + if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER) + { + sprite->pos1.x = 72; + sprite->pos1.y = 80; + } + else + { + sprite->pos1.x = 176; + sprite->pos1.y = 40; + } + } + else + { + if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) + gBattleAnimArgs[0] = -gBattleAnimArgs[0]; + sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X) + gBattleAnimArgs[0]; + sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y) + gBattleAnimArgs[1]; + } + if (IsContest()) + sprite->pos1.y += 9; + sprite->data[0] = 256 + IndexOfSpritePaletteTag(gBattleAnimArgs[2]) * 16; + sprite->callback = sub_80B300C; + sub_80B300C(sprite); +} + +static void sub_80B300C(struct Sprite *sprite) +{ + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(sprite->data[3], 16 - sprite->data[3])); + if (sprite->data[3] == 13) + sprite->callback = sub_80B3044; + else + ++sprite->data[3]; +} + +static void sub_80B3044(struct Sprite *sprite) +{ + u16 color; + u16 startOffset; + s32 i; + + if (++sprite->data[1] == 2) + { + sprite->data[1] = 0; + startOffset = sprite->data[0]; + color = gPlttBufferFaded[startOffset + 8]; + for (i = 8; i > 0; --i) + gPlttBufferFaded[startOffset + i] = gPlttBufferFaded[startOffset + i - 1]; + gPlttBufferFaded[startOffset + 1] = color; + if (++sprite->data[2] == 16) + sprite->callback = sub_80B30B0; + } +} + +static void sub_80B30B0(struct Sprite *sprite) +{ + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(sprite->data[3], 16 - sprite->data[3])); + if (--sprite->data[3] == -1) + { + if (!IsContest()) + { + u8 battlerCopy; + u8 battler = battlerCopy = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT); + + if (IsBattlerSpriteVisible(battler)) + gSprites[gBattlerSpriteIds[battler]].invisible = FALSE; + battler = BATTLE_PARTNER(battlerCopy); + if (IsBattlerSpriteVisible(battler)) + gSprites[gBattlerSpriteIds[battler]].invisible = FALSE; + } + sprite->invisible = TRUE; + sprite->callback = sub_80B3168; + } +} + +static void sub_80B3168(struct Sprite *sprite) +{ + if (!IsContest()) + { + u8 battlerCopy; + u8 battler = battlerCopy = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT); + u8 rank = GetBattlerSpriteBGPriorityRank(battler); + s32 var0 = 1; + bool8 toBG2 = (rank ^ var0) != 0; + + if (IsBattlerSpriteVisible(battler)) + sub_8073128(toBG2); + battler = battlerCopy ^ 2; + if (IsBattlerSpriteVisible(battler)) + sub_8073128(toBG2 ^ var0); + } + sprite->callback = DestroyAnimSprite; +} + +static void sub_80B31D0(struct Sprite *sprite) +{ + if (sprite->data[0] == 0) + { + int arg3 = gBattleAnimArgs[3]; + bool8 respectMonPicOffsets = FALSE; + if (arg3 == 0) + respectMonPicOffsets = TRUE; + if (!IsContest() && IsDoubleBattle()) + { + if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER) + { + sprite->pos1.x = 72 - gBattleAnimArgs[0]; + sprite->pos1.y = gBattleAnimArgs[1] + 80; + } + else + { + sprite->pos1.x = gBattleAnimArgs[0] + 176; + sprite->pos1.y = gBattleAnimArgs[1] + 40; + } + } + else + { + if (gBattleAnimArgs[2] == 0) + InitSpritePosToAnimAttacker(sprite, respectMonPicOffsets); + else + InitSpritePosToAnimTarget(sprite, respectMonPicOffsets); + } + + ++sprite->data[0]; + } + else if (sprite->animEnded || sprite->affineAnimEnded) + { + DestroySpriteAndMatrix(sprite); + } +} + +static void sub_80B3278(struct Sprite *sprite) +{ + sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2); + sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET); + if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) + { + StartSpriteAnim(sprite, 1); + sprite->pos1.x -= 40; + sprite->pos1.y += 10; + sprite->data[1] = -1; + } + else + { + sprite->pos1.x += 40; + sprite->pos1.y -= 10; + sprite->data[1] = 1; + } + StoreSpriteCallbackInData6(sprite, DestroyAnimSprite); + sprite->callback = RunStoredCallbackWhenAnimEnds; +} + +static void sub_80B32F4(struct Sprite *sprite) +{ + s16 x = GetBattlerSpriteCoordAttr(gBattleAnimAttacker, BATTLER_COORD_ATTR_WIDTH) / 2; + s16 y = GetBattlerSpriteCoordAttr(gBattleAnimAttacker, BATTLER_COORD_ATTR_HEIGHT) / -2; + + if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_OPPONENT) + x = -x; + sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 2) + x; + sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, 3) + y; + if (sprite->pos1.y < 16) + sprite->pos1.y = 16; + StoreSpriteCallbackInData6(sprite, sub_80B3384); + sprite->callback = RunStoredCallbackWhenAnimEnds; +} + +static void sub_80B3384(struct Sprite *sprite) +{ + sprite->oam.affineMode = ST_OAM_AFFINE_NORMAL; + sprite->affineAnims = gUnknown_83E6FF0; + sprite->data[0] = 0; + InitSpriteAffineAnim(sprite); + sprite->callback = sub_80B33B8; +} + +static void sub_80B33B8(struct Sprite *sprite) +{ + switch (sprite->data[0]) + { + case 0: + if (sprite->affineAnimEnded) + { + FreeOamMatrix(sprite->oam.matrixNum); + sprite->oam.affineMode = ST_OAM_AFFINE_OFF; + sprite->data[1] = 18; + ++sprite->data[0]; + } + break; + case 1: + if (--sprite->data[1] == -1) + DestroyAnimSprite(sprite); + break; + } +} + +void sub_80B3418(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + u8 spriteId = GetAnimBattlerSpriteId(ANIM_ATTACKER); + + task->data[0] = spriteId; + PrepareAffineAnimInTaskData(task, spriteId, gUnknown_83E700C); + task->func = sub_80B3454; +} + +static void sub_80B3454(u8 taskId) +{ + if (!RunAffineAnimFromTaskData(&gTasks[taskId])) + DestroyAnimVisualTask(taskId); +} + +void sub_80B3480(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + u8 spriteId = GetAnimBattlerSpriteId(ANIM_ATTACKER); + + task->data[0] = spriteId; + task->data[1] = 0; + task->data[2] = 0; + task->data[3] = GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER ? 4 : 8; + PrepareAffineAnimInTaskData(task, task->data[0], gUnknown_83E702C); + task->func = sub_80B34DC; +} + +static void sub_80B34DC(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + + switch (task->data[1]) + { + case 0: + RunAffineAnimFromTaskData(task); + if (++task->data[2] > 19) + ++task->data[1]; + break; + case 1: + if (task->data[3] != 0) + { + gSprites[task->data[0]].pos2.y -= 8; + --task->data[3]; + } + else + { + gSprites[task->data[0]].invisible = TRUE; + gSprites[task->data[0]].pos1.x = 272; + ResetSpriteRotScale(task->data[0]); + DestroyAnimVisualTask(taskId); + } + break; + } +} + +void sub_80B3584(u8 taskId) +{ + u16 var0, var1; + struct Task *task = &gTasks[taskId]; + + task->data[3] = 16; + task->data[4] = 0; + task->data[13] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2); + task->data[14] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET); + var0 = GetBattlerSpriteCoordAttr(gBattleAnimAttacker, BATTLER_COORD_ATTR_WIDTH) / 3; + var1 = GetBattlerSpriteCoordAttr(gBattleAnimAttacker, BATTLER_COORD_ATTR_HEIGHT) / 3; + task->data[12] = var0 > var1 ? var0 : var1; + SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND); + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(16, 0)); + task->func = sub_80B3618; +} + +static void sub_80B3618(u8 taskId) +{ + u16 i; + u8 spriteId; + struct Task *task = &gTasks[taskId]; + + switch (task->data[0]) + { + case 0: + if (++task->data[1] > 8) + { + task->data[1] = 0; + spriteId = CreateSprite(&gUnknown_83E7044, task->data[13], task->data[14], 0); + task->data[task->data[2] + 8] = spriteId; + if (spriteId != MAX_SPRITES) + { + switch (task->data[2]) + { + case 0: + gSprites[spriteId].pos2.x = task->data[12]; + gSprites[spriteId].pos2.y = -task->data[12]; + break; + case 1: + gSprites[spriteId].pos2.x = -task->data[12]; + gSprites[spriteId].pos2.y = task->data[12]; + break; + case 2: + gSprites[spriteId].pos2.x = task->data[12]; + gSprites[spriteId].pos2.y = task->data[12]; + break; + case 3: + gSprites[spriteId].pos2.x = -task->data[12]; + gSprites[spriteId].pos2.y = -task->data[12]; + break; + } + } + + if (++task->data[2] == 5) + ++task->data[0]; + } + break; + case 1: + if (task->data[1] & 1) + --task->data[3]; + else + ++task->data[4]; + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(task->data[3], task->data[4])); + if (++task->data[1] == 32) + { + for (i = 8; i < 13; ++i) + if (task->data[i] != 64) + DestroySprite(&gSprites[task->data[i]]); + ++task->data[0]; + } + break; + case 2: + ++task->data[0]; + break; + case 3: + SetGpuReg(REG_OFFSET_BLDALPHA, 0); + SetGpuReg(REG_OFFSET_BLDCNT, 0); + DestroyAnimVisualTask(taskId); + break; + } +} + +static void sub_80B37A4(struct Sprite *sprite) +{ + if (sprite->data[1] > sprite->data[0] - 10) + sprite->invisible = sprite->data[1] & 1; + if (sprite->data[1] == sprite->data[0]) + DestroyAnimSprite(sprite); + ++sprite->data[1]; +} + +static void sub_80B37EC(struct Sprite *sprite) +{ + if (gBattleAnimArgs[0] == 0) + { + sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2); + sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET); + } + sprite->data[0] = gBattleAnimArgs[1]; + sprite->callback = sub_80B37A4; +} + +void sub_80B3834(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + + if (IsContest()) + { + if (gBattleAnimArgs[0] == 1) + { + task->data[10] = -10; + task->data[11] = GetBattlerSpriteCoordAttr(gBattleAnimTarget, BATTLER_COORD_ATTR_RIGHT) - 8; + task->data[12] = GetBattlerSpriteCoordAttr(gBattleAnimTarget, BATTLER_COORD_ATTR_TOP) + 8; + task->data[13] = GetBattlerSpriteCoordAttr(gBattleAnimAttacker, BATTLER_COORD_ATTR_RIGHT) - 8; + task->data[14] = GetBattlerSpriteCoordAttr(gBattleAnimAttacker, BATTLER_COORD_ATTR_TOP) + 8; + } + else + { + task->data[10] = 10; + task->data[11] = GetBattlerSpriteCoordAttr(gBattleAnimAttacker, BATTLER_COORD_ATTR_LEFT) + 8; + task->data[12] = GetBattlerSpriteCoordAttr(gBattleAnimAttacker, BATTLER_COORD_ATTR_BOTTOM) - 8; + task->data[13] = GetBattlerSpriteCoordAttr(gBattleAnimTarget, BATTLER_COORD_ATTR_LEFT) + 8; + task->data[14] = GetBattlerSpriteCoordAttr(gBattleAnimTarget, BATTLER_COORD_ATTR_BOTTOM) - 8; + } + } + else + { + if (gBattleAnimArgs[0] == 1) + { + task->data[10] = -10; + task->data[11] = GetBattlerSpriteCoordAttr(gBattleAnimTarget, BATTLER_COORD_ATTR_LEFT) + 8; + task->data[12] = GetBattlerSpriteCoordAttr(gBattleAnimTarget, BATTLER_COORD_ATTR_TOP) + 8; + task->data[13] = GetBattlerSpriteCoordAttr(gBattleAnimAttacker, BATTLER_COORD_ATTR_LEFT) + 8; + task->data[14] = GetBattlerSpriteCoordAttr(gBattleAnimAttacker, BATTLER_COORD_ATTR_TOP) + 8; + } + else + { + task->data[10] = 10; + task->data[11] = GetBattlerSpriteCoordAttr(gBattleAnimAttacker, BATTLER_COORD_ATTR_RIGHT) - 8; + task->data[12] = GetBattlerSpriteCoordAttr(gBattleAnimAttacker, BATTLER_COORD_ATTR_BOTTOM) - 8; + task->data[13] = GetBattlerSpriteCoordAttr(gBattleAnimTarget, BATTLER_COORD_ATTR_RIGHT) - 8; + task->data[14] = GetBattlerSpriteCoordAttr(gBattleAnimTarget, BATTLER_COORD_ATTR_BOTTOM) - 8; + } + } + task->data[1] = 6; + task->func = sub_80B3980; +} + +static void sub_80B3980(u8 taskId) +{ + u8 spriteId; + struct Task *task = &gTasks[taskId]; + + switch (task->data[0]) + { + case 0: + if (++task->data[1] > 6) + { + task->data[1] = 0; + spriteId = CreateSprite(&gUnknown_83E7114, task->data[11], task->data[12], 0); + if (spriteId != 64) + { + gSprites[spriteId].data[0] = 16; + gSprites[spriteId].data[2] = task->data[13]; + gSprites[spriteId].data[4] = task->data[14]; + gSprites[spriteId].data[5] = task->data[10]; + InitAnimArcTranslation(&gSprites[spriteId]); + StartSpriteAffineAnim(&gSprites[spriteId], task->data[2] & 3); + } + + if (++task->data[2] == 12) + ++task->data[0]; + } + break; + case 1: + if (++task->data[1] > 17) + DestroyAnimVisualTask(taskId); + break; + } +} + +static void sub_80B3A34(struct Sprite *sprite) +{ + if (TranslateAnimHorizontalArc(sprite)) + { + FreeOamMatrix(sprite->oam.matrixNum); + DestroySprite(sprite); + } +} + +void sub_80B3A58(u8 taskId) +{ + s16 i; + u8 yOffset; + struct ScanlineEffectParams scanlineParams; + struct Task *task = &gTasks[taskId]; + + yOffset = GetBattlerYCoordWithElevation(gBattleAnimTarget); + task->data[14] = yOffset - 32; + switch (gBattleAnimArgs[0]) + { + case 0: + task->data[11] = 2; + task->data[12] = 5; + task->data[13] = 64; + task->data[15] = yOffset + 32; + break; + case 1: + task->data[11] = 2; + task->data[12] = 5; + task->data[13] = 192; + task->data[15] = yOffset + 32; + break; + case 2: + task->data[11] = 4; + task->data[12] = 4; + task->data[13] = 0; + task->data[15] = yOffset + 32; + break; + } + if (task->data[14] < 0) + task->data[14] = 0; + if (GetBattlerSpriteBGPriorityRank(gBattleAnimTarget) == 1) + { + task->data[10] = gBattle_BG1_X; + scanlineParams.dmaDest = ®_BG1HOFS; + } + else + { + task->data[10] = gBattle_BG2_X; + scanlineParams.dmaDest = ®_BG2HOFS; + } + for (i = task->data[14]; i <= task->data[14] + 64; ++i) + { + gScanlineEffectRegBuffers[0][i] = task->data[10]; + gScanlineEffectRegBuffers[1][i] = task->data[10]; + } + scanlineParams.dmaControl = SCANLINE_EFFECT_DMACNT_16BIT; + scanlineParams.initState = 1; + scanlineParams.unused9 = 0; + ScanlineEffect_SetParams(scanlineParams); + task->func = sub_80B3B78; +} + +static void sub_80B3B78(u8 taskId) +{ + s16 sineIndex, i; + struct Task *task = &gTasks[taskId]; + + switch (task->data[0]) + { + case 0: + sineIndex = task->data[13]; + for (i = task->data[14]; i <= task->data[15]; ++i) + { + s16 var2 = (gSineTable[sineIndex] >> task->data[12]); + + if (var2 > 0) + var2 += (task->data[1] & 3); + else if (var2 < 0) + var2 -= (task->data[1] & 3); + gScanlineEffectRegBuffers[0][i] = task->data[10] + var2; + gScanlineEffectRegBuffers[1][i] = task->data[10] + var2; + sineIndex += task->data[11]; + } + if (++task->data[1] > 23) + ++task->data[0]; + break; + case 1: + gScanlineEffect.state = 3; + ++task->data[0]; + break; + case 2: + DestroyAnimVisualTask(taskId); + break; + } +} + +void sub_80B3C78(u8 taskId) +{ + s16 spriteId; + s16 matrixNum; + struct Task *task = &gTasks[taskId]; + + matrixNum = AllocOamMatrix(); + if (matrixNum == 0xFF) + { + DestroyAnimVisualTask(taskId); + return; + } + spriteId = CloneBattlerSpriteWithBlend(gBattleAnimArgs[0]); + if (spriteId < 0) + { + FreeOamMatrix(matrixNum); + DestroyAnimVisualTask(taskId); + return; + } + gSprites[spriteId].callback = SpriteCallbackDummy; + gSprites[spriteId].oam.affineMode = ST_OAM_AFFINE_DOUBLE; + gSprites[spriteId].oam.matrixNum = matrixNum; + gSprites[spriteId].affineAnimPaused = TRUE; + ++gSprites[spriteId].subpriority; + SetSpriteRotScale(spriteId, 256, 256, 0); + CalcCenterToCornerVec(&gSprites[spriteId], gSprites[spriteId].oam.shape, gSprites[spriteId].oam.size, gSprites[spriteId].oam.affineMode); + task->data[13] = GetAnimBattlerSpriteId(gBattleAnimArgs[0]); + task->data[14] = matrixNum; + task->data[15] = spriteId; + task->func = sub_80B3D78; +} + +static void sub_80B3D78(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + + switch (task->data[0]) + { + case 0: + task->data[1] += 4; + task->data[2] = 256 - (gSineTable[task->data[1]] >> 1); + SetSpriteRotScale(task->data[15], task->data[2], task->data[2], 0); + SetBattlerSpriteYOffsetFromOtherYScale(task->data[15], task->data[13]); + if (task->data[1] == 48) + ++task->data[0]; + break; + case 1: + task->data[1] -= 4; + task->data[2] = 256 - (gSineTable[task->data[1]] >> 1);; + SetSpriteRotScale(task->data[15], task->data[2], task->data[2], 0); + SetBattlerSpriteYOffsetFromOtherYScale(task->data[15], task->data[13]); + if (task->data[1] == 0) + ++task->data[0]; + break; + case 2: + obj_delete_but_dont_free_vram(&gSprites[task->data[15]]); + ++task->data[0]; + break; + case 3: + FreeOamMatrix(task->data[14]); + DestroyAnimVisualTask(taskId); + break; + } +} + +static void sub_80B3E84(struct Sprite *sprite) +{ + switch (sprite->data[0]) + { + case 0: + sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X); + sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y); + if (IsContest()) + sprite->pos1.y += 12; + sprite->data[1] = 8; + SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND); + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(sprite->data[1], 16 - sprite->data[1])); + ++sprite->data[0]; + break; + case 1: + if (sprite->affineAnimEnded) + { + PlaySE12WithPanning(SE_W100, BattleAnimAdjustPanning(-64)); + ChangeSpriteAffineAnim(sprite, 1); + ++sprite->data[0]; + } + break; + case 2: + if (sprite->data[2]++ > 1) + { + sprite->data[2] = 0; + --sprite->data[1]; + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(sprite->data[1], 16 - sprite->data[1])); + if (sprite->data[1] == 0) + { + ++sprite->data[0]; + sprite->invisible = TRUE; + } + } + sprite->data[3] += 0x380; + sprite->pos2.y -= sprite->data[3] >> 8; + sprite->data[3] &= 0xFF; + break; + case 3: + SetGpuReg(REG_OFFSET_BLDCNT, 0); + SetGpuReg(REG_OFFSET_BLDALPHA, 0); + DestroyAnimSprite(sprite); + break; + } +} diff --git a/src/quest_log.c b/src/quest_log.c index c8bd19174..ef8f56249 100644 --- a/src/quest_log.c +++ b/src/quest_log.c @@ -92,188 +92,185 @@ struct UnkStruct_203AE98 * gUnknown_3005E94; static struct UnkStruct_300201C * gUnknown_300201C; static u16 gUnknown_3002020; -EWRAM_DATA u8 gUnknown_203ADF8 = 0; +static EWRAM_DATA u8 gUnknown_203ADF8 = 0; static EWRAM_DATA u8 sNumScenes = 0; EWRAM_DATA u8 gUnknown_203ADFA = 0; -EWRAM_DATA u16 gUnknown_203ADFC = 0; -EWRAM_DATA u8 gUnknown_203ADFE[3] = {0}; -EWRAM_DATA u16 * gUnknown_203AE04 = NULL; -EWRAM_DATA u16 * gUnknown_203AE08 = NULL; -EWRAM_DATA u16 * gUnknown_203AE0C[32] = {NULL}; -EWRAM_DATA void (* gUnknown_203AE8C)(void) = NULL; -EWRAM_DATA u16 *gUnknown_203AE90 = NULL; -EWRAM_DATA struct UnkStruct_203AE94 gUnknown_203AE94 = {0}; -EWRAM_DATA struct UnkStruct_203AE98 gUnknown_203AE98[32] = {0}; -EWRAM_DATA u16 gUnknown_203AF98 = 0; -EWRAM_DATA u8 gUnknown_203AF9A[64][2] = {{0}}; -EWRAM_DATA u16 gUnknown_203B01A = 0; -EWRAM_DATA u16 gUnknown_203B01C = 0; -EWRAM_DATA u16 gUnknown_203B01E = 0; -EWRAM_DATA u8 gUnknown_203B020 = 0; -EWRAM_DATA struct UnkStruct_203B024 gUnknown_203B024 = {0}; -EWRAM_DATA struct UnkStruct_203B044 gUnknown_203B044 = {0}; -EWRAM_DATA u8 gUnknown_203B048 = 0; -EWRAM_DATA u8 gUnknown_203B049 = 0; -EWRAM_DATA u8 gUnknown_203B04A = 0; -EWRAM_DATA u8 gUnknown_203B04B = 0; - -void sub_8110A00(void); -void sub_8110A3C(void); -void sub_8110BB0(u8); -void sub_8110BE8(u8); -void sub_8110E3C(void); -void sub_8110D94(void); -void sub_8110E20(void); -void sub_8110D48(u8); -u8 sub_8110E68(struct UnkStruct_203AE98 *); -void sub_8110F90(u8); -void sub_8111150(u8); -void sub_8111368(void); -void sub_81115E8(void); -u16 sub_8111618(void); -u16 sub_811164C(void); -void sub_8111688(void); -void sub_811175C(u8, struct UnkStruct_203AE98 *); -void sub_81118F4(s8); -void sub_8111914(void); -void sub_8111984(void); -void sub_8111A34(u8); -void sub_8111AD8(void); -void sub_8111B80(void); -u8 sub_8111BD4(void); -void sub_8111D10(void); -void sub_8111D90(u8); -void sub_8111E20(void); -void sub_8111E64(s8); -void sub_8111E84(void); -bool8 sub_8111F60(void); -void sub_8111F8C(u8); -void sub_8111FCC(u8); -void sub_8112044(u8); -void sub_81120AC(u8); -bool8 sub_81121D8(u8); -void sub_811229C(void); -void sub_8112364(void); -void sub_8112888(u8); -void sub_8112940(u8, struct UnkStruct_203AE98 *, u16); -u8 sub_8112CAC(void); -bool8 sub_8112CEC(void); -bool8 sub_8112D1C(void); -void sub_8113078(struct Var4038Struct *); -void sub_81130BC(struct Var4038Struct *); -u8 sub_8113194(struct Var4038Struct *); -u16 sub_81132A0(struct Var4038Struct *); -void sub_81132E0(struct Var4038Struct *); -bool16 sub_811337C(struct Var4038Struct *); -void sub_8113390(struct Var4038Struct *); -void sub_8113414(struct LinkBattleRecords *, u8, u8); -void sub_81134CC(struct Var4038Struct *); -bool8 sub_8113508(struct Var4038Struct * ); -void sub_8113524(struct Var4038Struct *); -bool8 sub_81136D4(void); -bool8 sub_8113778(u16, u16 *); -bool8 sub_81137E4(u16, u16 *); -u16 * sub_8113828(u16, u16 *); -bool8 sub_81138A0(u16, u16 *); -bool8 sub_8113954(u16, u16 *); -void sub_8113A1C(u16); -void sub_811381C(void); -void sub_81138F8(void); -bool8 sub_8113A44(u16, u16 *); -u16 * sub_8113A78(u16 *, u16 **); -void sub_8113ABC(u16 *); -bool8 sub_8113AE8(u16 *); -bool8 sub_8113B44(u16 *); -void sub_8113B88(void); -void sub_8113B94(u16); -void sub_8113BD8(void); -u16 * sub_8113BF4(u16 *); -u16 * sub_8113C20(u16 *, struct UnkStruct_203AE98 *); -u16 * sub_8113C5C(u16 *, u16); -u16 * sub_8113C8C(u16 *, struct UnkStruct_203AE98 *); -u16 * sub_8113CC8(u16 *, struct UnkStruct_203AE98 *); -u16 * sub_8113D08(u16 *, struct UnkStruct_203AE98 *); -u16 * sub_8113D48(u16 *, struct UnkStruct_203AE98 *); -u16 * sub_8113D94(u16 *, struct UnkStruct_203AE98 *); -u16 * sub_8113F14(u16 *, const u16 *); -const u16 * sub_8113F3C(const u16 *); -u16 * sub_8113F80(u16 *, const u16 *); -const u16 * sub_8113FBC(const u16 *); -u16 * sub_8114174(u16 *, const u16 *); -const u16 * sub_8114188(const u16 *); -u16 * sub_81141D0(u16 *, const u16 *); -const u16 * sub_81141E4(const u16 *); -u16 * sub_811422C(u16 *, const u16 *); -const u16 * sub_8114240(const u16 *); -u16 * sub_8114288(u16 *, const u16 *); -const u16 * sub_811429C(const u16 *); -u16 * sub_8114310(u16 *, const u16 *); -const u16 * sub_8114324(const u16 *); -u16 * sub_8114380(u16 *, const u16 *); -const u16 * sub_8114394(const u16 *); -u16 * sub_81143F0(u16 *, const u16 *); -const u16 * sub_811443C(const u16 *); -u16 * sub_811445C(u16 *, const u16 *); -const u16 * sub_811448C(const u16 *); -u16 * sub_81144EC(u16 *, const u16 *); -const u16 * sub_8114518(const u16 *); -u16 * sub_8114578(u16 *, const u16 *); -const u16 * sub_81145A4(const u16 *); -u16 * sub_8114604(u16 *, const u16 *); -const u16 * sub_811464C(const u16 *); -u16 * sub_8114710(u16 *, const u16 *); -const u16 * sub_8114724(const u16 *); -u16 * sub_8114744(u16 *, const u16 *); -const u16 * sub_8114758(const u16 *); -u16 * sub_8114778(u16 *, const u16 *); -const u16 * sub_81147A8(const u16 *); -u16 * sub_8114808(u16 *, const u16 *); -const u16 * sub_8114834(const u16 *); -u16 * sub_811488C(u16 *, const u16 *); -const u16 * sub_81148BC(const u16 *); -u16 * sub_8114918(u16 *, const u16 *); -const u16 * sub_8114944(const u16 *); -u16 * sub_8114990(u16 *, const u16 *); -const u16 * sub_81149D0(const u16 *); -u16 * sub_8114A1C(u16 *, const u16 *); -const u16 * sub_8114A4C(const u16 *); -u16 * sub_8114AA0(u16 *, const u16 *); -const u16 * sub_8114AC8(const u16 *); -u16 * sub_8114B0C(u16 *, const u16 *); -const u16 * sub_8114B34(const u16 *); -u16 * sub_8114B78(u16 *, const u16 *); -const u16 * sub_8114BA0(const u16 *); -u16 * sub_8114BE4(u16 *, const u16 *); -const u16 * sub_8114C0C(const u16 *); -u16 * sub_8114C68(u16 *, const u16 *); -const u16 * sub_8114C8C(const u16 *); -u16 * sub_8114CC0(u16 *, const u16 *); -const u16 * sub_8114CE4(const u16 *); -u16 * sub_8114D4C(u16 *, const u16 *); -const u16 * sub_8114D68(const u16 *); -u16 * sub_8114DE8(u16 *, const u16 *); -const u16 * sub_8114E68(const u16 *); -bool8 sub_8114FBC(u16); -u16 * sub_8114FF0(u16 *, const u16 *); -const u16 * sub_811500C(const u16 *); -u16 * sub_8115078(u16 *, const u16 *); -const u16 * sub_81150CC(const u16 *); -u16 * sub_81151C0(u16 *, const u16 *); -const u16 * sub_81151DC(const u16 *); -u16 * sub_8115280(u16 *, const u16 *); -const u16 * sub_81152BC(const u16 *); -bool8 sub_81153A8(u16, u16 *); -bool8 sub_81153E4(u16, u16 *); -u16 * sub_8115410(u16 *, const u16 *); -const u16 * sub_8115460(const u16 *); -u16 * sub_81154DC(u16 *, const u16 *); -const u16 * sub_8115518(const u16 *); -u16 * sub_81155A4(u16 *, const u16 *); -const u16 * sub_81155E0(const u16 *); -u16 * sub_81156D8(u16 *, const u16 *); -const u16 * sub_8115700(const u16 *); -u16 * sub_81157DC(u16 *, const u16 *); -const u16 * sub_8115800(const u16 *); +static EWRAM_DATA u16 gUnknown_203ADFC = 0; +static EWRAM_DATA u8 gUnknown_203ADFE[3] = {0}; +static EWRAM_DATA u16 * gUnknown_203AE04 = NULL; +static EWRAM_DATA u16 * gUnknown_203AE08 = NULL; +static EWRAM_DATA u16 * gUnknown_203AE0C[32] = {NULL}; +static EWRAM_DATA void (* gUnknown_203AE8C)(void) = NULL; +static EWRAM_DATA u16 *gUnknown_203AE90 = NULL; +static EWRAM_DATA struct UnkStruct_203AE94 gUnknown_203AE94 = {0}; +static EWRAM_DATA struct UnkStruct_203AE98 gUnknown_203AE98[32] = {0}; +static EWRAM_DATA u16 gUnknown_203AF98 = 0; +static EWRAM_DATA u8 gUnknown_203AF9A[64][2] = {{0}}; +static EWRAM_DATA u16 gUnknown_203B01A = 0; +static EWRAM_DATA u16 gUnknown_203B01C = 0; +static EWRAM_DATA u16 gUnknown_203B01E = 0; +static EWRAM_DATA u8 sHelpMessageWindowId = 0; +static EWRAM_DATA struct UnkStruct_203B024 gUnknown_203B024 = {0}; +static EWRAM_DATA struct UnkStruct_203B044 gUnknown_203B044 = {0}; +static EWRAM_DATA u8 gUnknown_203B048 = 0; +static EWRAM_DATA u8 gUnknown_203B049 = 0; +static EWRAM_DATA u8 gUnknown_203B04A = 0; +static EWRAM_DATA u8 gUnknown_203B04B = 0; + +static void sub_8110A00(void); +static void sub_8110A3C(void); +static void sub_8110BB0(u8); +static void sub_8110BE8(u8); +static void sub_8110E3C(void); +static void sub_8110D94(void); +static void sub_8110E20(void); +static void sub_8110D48(u8); +static u8 sub_8110E68(struct UnkStruct_203AE98 *); +static void sub_8110F90(u8); +static void sub_8111150(u8); +static void sub_8111368(void); +static void sub_81115E8(void); +static u16 sub_8111618(void); +static u16 sub_811164C(void); +static void sub_8111688(void); +static void sub_811175C(u8, struct UnkStruct_203AE98 *); +static void sub_81118F4(s8); +static void sub_8111914(void); +static void sub_8111984(void); +static void sub_8111A34(u8); +static void sub_8111AD8(void); +static void sub_8111B80(void); +static u8 sub_8111BD4(void); +static void sub_8111D10(void); +static void sub_8111D90(u8); +static void sub_8111E20(void); +static void sub_8111E64(s8); +static void sub_8111E84(void); +static bool8 sub_8111F60(void); +static void sub_8111F8C(u8); +static void sub_8111FCC(u8); +static void sub_8112044(u8); +static void sub_81120AC(u8); +static bool8 sub_81121D8(u8); +static void sub_811229C(void); +static void sub_8112888(u8); +static void sub_8112940(u8, struct UnkStruct_203AE98 *, u16); +static bool8 sub_8112CEC(void); +static bool8 sub_8112D1C(void); +static void sub_8113078(struct Var4038Struct *); +static void sub_81130BC(struct Var4038Struct *); +static u8 sub_8113194(struct Var4038Struct *); +static u16 sub_81132A0(struct Var4038Struct *); +static void sub_81132E0(struct Var4038Struct *); +static bool16 sub_811337C(struct Var4038Struct *); +static void sub_8113390(struct Var4038Struct *); +static void sub_8113414(struct LinkBattleRecords *, u8, u8); +static void sub_81134CC(struct Var4038Struct *); +static bool8 sub_8113508(struct Var4038Struct * ); +static void sub_8113524(struct Var4038Struct *); +static bool8 sub_81136D4(void); +static bool8 sub_8113778(u16, u16 *); +static bool8 sub_81137E4(u16, u16 *); +static u16 * sub_8113828(u16, u16 *); +static bool8 sub_81138A0(u16, u16 *); +static bool8 sub_8113954(u16, u16 *); +static void sub_8113A1C(u16); +static void sub_811381C(void); +static bool8 sub_8113A44(u16, u16 *); +static u16 * sub_8113A78(u16 *, u16 **); +static void sub_8113ABC(u16 *); +static bool8 sub_8113AE8(u16 *); +static bool8 sub_8113B44(u16 *); +static void sub_8113B88(void); +static void sub_8113B94(u16); +static void sub_8113BD8(void); +static u16 * sub_8113BF4(u16 *); +static u16 * sub_8113C20(u16 *, struct UnkStruct_203AE98 *); +static u16 * sub_8113C5C(u16 *, u16); +static u16 * sub_8113C8C(u16 *, struct UnkStruct_203AE98 *); +static u16 * sub_8113CC8(u16 *, struct UnkStruct_203AE98 *); +static u16 * sub_8113D08(u16 *, struct UnkStruct_203AE98 *); +static u16 * sub_8113D48(u16 *, struct UnkStruct_203AE98 *); +static u16 * sub_8113D94(u16 *, struct UnkStruct_203AE98 *); +static u16 * sub_8113F14(u16 *, const u16 *); +static const u16 * sub_8113F3C(const u16 *); +static u16 * sub_8113F80(u16 *, const u16 *); +static const u16 * sub_8113FBC(const u16 *); +static u16 * sub_8114174(u16 *, const u16 *); +static const u16 * sub_8114188(const u16 *); +static u16 * sub_81141D0(u16 *, const u16 *); +static const u16 * sub_81141E4(const u16 *); +static u16 * sub_811422C(u16 *, const u16 *); +static const u16 * sub_8114240(const u16 *); +static u16 * sub_8114288(u16 *, const u16 *); +static const u16 * sub_811429C(const u16 *); +static u16 * sub_8114310(u16 *, const u16 *); +static const u16 * sub_8114324(const u16 *); +static u16 * sub_8114380(u16 *, const u16 *); +static const u16 * sub_8114394(const u16 *); +static u16 * sub_81143F0(u16 *, const u16 *); +static const u16 * sub_811443C(const u16 *); +static u16 * sub_811445C(u16 *, const u16 *); +static const u16 * sub_811448C(const u16 *); +static u16 * sub_81144EC(u16 *, const u16 *); +static const u16 * sub_8114518(const u16 *); +static u16 * sub_8114578(u16 *, const u16 *); +static const u16 * sub_81145A4(const u16 *); +static u16 * sub_8114604(u16 *, const u16 *); +static const u16 * sub_811464C(const u16 *); +static u16 * sub_8114710(u16 *, const u16 *); +static const u16 * sub_8114724(const u16 *); +static u16 * sub_8114744(u16 *, const u16 *); +static const u16 * sub_8114758(const u16 *); +static u16 * sub_8114778(u16 *, const u16 *); +static const u16 * sub_81147A8(const u16 *); +static u16 * sub_8114808(u16 *, const u16 *); +static const u16 * sub_8114834(const u16 *); +static u16 * sub_811488C(u16 *, const u16 *); +static const u16 * sub_81148BC(const u16 *); +static u16 * sub_8114918(u16 *, const u16 *); +static const u16 * sub_8114944(const u16 *); +static u16 * sub_8114990(u16 *, const u16 *); +static const u16 * sub_81149D0(const u16 *); +static u16 * sub_8114A1C(u16 *, const u16 *); +static const u16 * sub_8114A4C(const u16 *); +static u16 * sub_8114AA0(u16 *, const u16 *); +static const u16 * sub_8114AC8(const u16 *); +static u16 * sub_8114B0C(u16 *, const u16 *); +static const u16 * sub_8114B34(const u16 *); +static u16 * sub_8114B78(u16 *, const u16 *); +static const u16 * sub_8114BA0(const u16 *); +static u16 * sub_8114BE4(u16 *, const u16 *); +static const u16 * sub_8114C0C(const u16 *); +static u16 * sub_8114C68(u16 *, const u16 *); +static const u16 * sub_8114C8C(const u16 *); +static u16 * sub_8114CC0(u16 *, const u16 *); +static const u16 * sub_8114CE4(const u16 *); +static u16 * sub_8114D4C(u16 *, const u16 *); +static const u16 * sub_8114D68(const u16 *); +static u16 * sub_8114DE8(u16 *, const u16 *); +static const u16 * sub_8114E68(const u16 *); +static bool8 sub_8114FBC(u16); +static u16 * sub_8114FF0(u16 *, const u16 *); +static const u16 * sub_811500C(const u16 *); +static u16 * sub_8115078(u16 *, const u16 *); +static const u16 * sub_81150CC(const u16 *); +static u16 * sub_81151C0(u16 *, const u16 *); +static const u16 * sub_81151DC(const u16 *); +static u16 * sub_8115280(u16 *, const u16 *); +static const u16 * sub_81152BC(const u16 *); +static bool8 sub_81153A8(u16, u16 *); +static bool8 sub_81153E4(u16, u16 *); +static u16 * sub_8115410(u16 *, const u16 *); +static const u16 * sub_8115460(const u16 *); +static u16 * sub_81154DC(u16 *, const u16 *); +static const u16 * sub_8115518(const u16 *); +static u16 * sub_81155A4(u16 *, const u16 *); +static const u16 * sub_81155E0(const u16 *); +static u16 * sub_81156D8(u16 *, const u16 *); +static const u16 * sub_8115700(const u16 *); +static u16 * sub_81157DC(u16 *, const u16 *); +static const u16 * sub_8115800(const u16 *); void sub_8115834(u8 *); extern const u8 gUnknown_841A155[]; @@ -404,17 +401,17 @@ extern const u8 gUnknown_841B277[]; extern const u8 gUnknown_8418C1B[]; -const struct WindowTemplate gUnknown_845661C[3] = { +static const struct WindowTemplate gUnknown_845661C[3] = { { 0, 0, 0, 30, 2, 15, 0x0e9 }, { 0, 0, 18, 30, 2, 15, 0x0ad }, { 0, 0, 14, 30, 6, 15, 0x14c } }; -const u8 gUnknown_8456634[3] = {15, 1, 12}; +static const u8 gUnknown_8456634[3] = {15, 1, 12}; -const u16 gUnknown_8456638[] = INCBIN_U16("data/graphics/unknown_8456638.bin"); +static const u16 gUnknown_8456638[] = INCBIN_U16("data/graphics/unknown_8456638.bin"); -const u8 gUnknown_8456698[] = {17, 10, 3}; +static const u8 gUnknown_8456698[] = {17, 10, 3}; void sub_8110840(void * oldPointer) { @@ -493,7 +490,7 @@ void sub_81109CC(u8 a0) gUnknown_203AE8C = sub_8110A3C; } -void sub_8110A00(void) +static void sub_8110A00(void) { if (sub_8110E68(gUnknown_203AE98) != 1) { @@ -504,7 +501,7 @@ void sub_8110A00(void) } } -void sub_8110A3C(void) +static void sub_8110A3C(void) { if (gUnknown_203AE94.unk_0_0 == 2) gUnknown_203AE94.unk_0_0 = 0; @@ -556,7 +553,7 @@ void sub_8110AEC(u16 a0) sub_81109CC(1); } -void sub_8110BB0(u8 a0) +static void sub_8110BB0(u8 a0) { struct QuestLog * questLog = &gSaveBlock1Ptr->questLog[a0]; questLog->unk_001 = gSaveBlock1Ptr->location.mapGroup; @@ -567,7 +564,7 @@ void sub_8110BB0(u8 a0) } #ifdef NONMATCHING -void sub_8110BE8(u8 a0) +static void sub_8110BE8(u8 a0) { struct QuestLog * questLog = &gSaveBlock1Ptr->questLog[a0]; u16 i; // r6 @@ -602,7 +599,7 @@ void sub_8110BE8(u8 a0) } #else NAKED -void sub_8110BE8(u8 a0) +static void sub_8110BE8(u8 a0) { asm_unified("\tpush {r4-r7,lr}\n" "\tmov r7, r10\n" @@ -767,7 +764,7 @@ void sub_8110BE8(u8 a0) } #endif // NONMATCHING -void sub_8110D48(u8 a0) +static void sub_8110D48(u8 a0) { struct QuestLog * questLog = &gSaveBlock1Ptr->questLog[a0]; @@ -775,7 +772,7 @@ void sub_8110D48(u8 a0) CpuCopy16(gSaveBlock1Ptr->vars, questLog->vars, VARS_COUNT * sizeof(u16)); } -void sub_8110D94(void) +static void sub_8110D94(void) { u16 i, j; u16 sp0[4]; @@ -794,19 +791,19 @@ void sub_8110D94(void) } } -void sub_8110E20(void) +static void sub_8110E20(void) { VarSet(VAR_0x40AE, gSaveBlock1Ptr->mapDataId); } -void sub_8110E3C(void) +static void sub_8110E3C(void) { sub_8113BF4(gUnknown_203AE08); if (++gUnknown_203ADF8 > 3) gUnknown_203ADF8 = 0; } -bool8 sub_8110E68(struct UnkStruct_203AE98 * a0) +static bool8 sub_8110E68(struct UnkStruct_203AE98 * a0) { u16 i; @@ -865,7 +862,7 @@ void TrySetUpQuestLogScenes_ElseContinueFromSave(u8 taskId) } } -void sub_8110F90(u8 unused) +static void sub_8110F90(u8 unused) { gSaveBlock1Ptr->location.mapGroup = 3; gSaveBlock1Ptr->location.mapNum = 19; @@ -937,7 +934,7 @@ void sub_8111134(void) CopyWindowToVram(gUnknown_203ADFE[1], 1); } -void sub_8111150(u8 a0) +static void sub_8111150(u8 a0) { struct QuestLog *questLog = &gSaveBlock1Ptr->questLog[a0]; u16 i; @@ -982,7 +979,7 @@ void sub_8111274(u8 a0, u8 a1) } } -void sub_8111368(void) +static void sub_8111368(void) { gUnknown_203ADFA = 2; sub_806E6FC(); @@ -1091,14 +1088,14 @@ void sub_8111438(void) Free(r9); } -void sub_81115E8(void) +static void sub_81115E8(void) { u16 r4 = sub_8111618(); u16 r1 = sub_811164C(); VarSet(VAR_0x4027, (r4 << 12) + r1); } -u16 sub_8111618(void) +static u16 sub_8111618(void) { u16 count = 0; u16 i; @@ -1112,7 +1109,7 @@ u16 sub_8111618(void) return count; } -u16 sub_811164C(void) +static u16 sub_811164C(void) { u16 count = 0; u16 i, j; @@ -1129,7 +1126,7 @@ u16 sub_811164C(void) return count; } -void sub_8111688(void) +static void sub_8111688(void) { u16 i, j; u16 sp0[4]; @@ -1161,7 +1158,7 @@ void sub_8111708(void) } } -void sub_811175C(u8 a0, struct UnkStruct_203AE98 * a1) +static void sub_811175C(u8 a0, struct UnkStruct_203AE98 * a1) { u16 i; u16 *r4; @@ -1208,13 +1205,13 @@ void sub_811175C(u8 a0, struct UnkStruct_203AE98 * a1) } } -void sub_81118F4(s8 a0) +static void sub_81118F4(s8 a0) { fade_screen(1, a0); gUnknown_203AE8C = sub_8111914; } -void sub_8111914(void) +static void sub_8111914(void) { if (!gPaletteFade.active) { @@ -1232,7 +1229,7 @@ void sub_8111914(void) } } -void sub_8111984(void) +static void sub_8111984(void) { sub_806E6FC(); Save_ResetSaveCounters(); @@ -1269,7 +1266,7 @@ bool8 sub_81119D4(void (*a0)(void)) return FALSE; } -void sub_8111A34(u8 taskId) +static void sub_8111A34(u8 taskId) { void (*routine)(void); s16 * data = gTasks[taskId].data; @@ -1298,7 +1295,7 @@ void sub_8111A34(u8 taskId) } } -void sub_8111AD8(void) +static void sub_8111AD8(void) { if (gUnknown_203AE94.unk_0_0 == 1) { @@ -1327,7 +1324,7 @@ void sub_8111AD8(void) } } -void sub_8111B80(void) +static void sub_8111B80(void) { if (gUnknown_203AE94.unk_0_0 == 0) { @@ -1344,7 +1341,7 @@ void sub_8111B80(void) sub_8112888(1); } -u8 sub_8111BD4(void) +static u8 sub_8111BD4(void) { u16 i; u16 count = 0; @@ -1405,7 +1402,7 @@ void sub_8111CF0(void) sub_8111070(sNumScenes); } -void sub_8111D10(void) +static void sub_8111D10(void) { u16 i; u8 count = 0; @@ -1422,7 +1419,7 @@ void sub_8111D10(void) ScheduleBgCopyTilemapToVram(0); } -void sub_8111D90(u8 a0) +static void sub_8111D90(u8 a0) { const u16 * src = gUnknown_8456638; u16 * buffer = Alloc(0x1680); @@ -1459,7 +1456,7 @@ void sub_8111D90(u8 a0) } } -void sub_8111E20(void) +static void sub_8111E20(void) { ClearWindowTilemap(gUnknown_203ADFE[2]); FillWindowPixelRect(gUnknown_203ADFE[2], 15, 0, 0, 0xf0, 0x30); @@ -1468,13 +1465,13 @@ void sub_8111E20(void) CopyWindowToVram(gUnknown_203ADFE[1], 1); } -void sub_8111E64(s8 a0) +static void sub_8111E64(s8 a0) { fade_screen(1, a0); gUnknown_203AE8C = sub_8111E84; } -void sub_8111E84(void) +static void sub_8111E84(void) { if (!gPaletteFade.active) { @@ -1501,7 +1498,7 @@ void sub_8111F38(u16 a0, u16 a1) CpuSet(gPlttBufferUnfaded + a0, gUnknown_203AE90 + a0, a1); } -bool8 sub_8111F60(void) +static bool8 sub_8111F60(void) { LoadPalette(stdpal_get(4), 0xF0, 0x20); sub_8111070(0); @@ -1510,7 +1507,7 @@ bool8 sub_8111F60(void) return TRUE; } -void sub_8111F8C(u8 taskId) +static void sub_8111F8C(u8 taskId) { struct Task *task = &gTasks[taskId]; @@ -1524,7 +1521,7 @@ void sub_8111F8C(u8 taskId) } } -void sub_8111FCC(u8 taskId) +static void sub_8111FCC(u8 taskId) { struct Task *task = &gTasks[taskId]; @@ -1544,7 +1541,7 @@ void sub_8111FCC(u8 taskId) } } -void sub_8112044(u8 taskId) +static void sub_8112044(u8 taskId) { struct Task *task = &gTasks[taskId]; @@ -1559,7 +1556,7 @@ void sub_8112044(u8 taskId) task->data[0]++; } -void sub_81120AC(u8 taskId) +static void sub_81120AC(u8 taskId) { s16 * data = gTasks[taskId].data; u8 i; @@ -1609,7 +1606,7 @@ void sub_81120AC(u8 taskId) } } -bool8 sub_81121D8(u8 taskId) +static bool8 sub_81121D8(u8 taskId) { s16 * data = gTasks[taskId].data; @@ -1626,7 +1623,7 @@ bool8 sub_81121D8(u8 taskId) return FALSE; } -void sub_811229C(void) +static void sub_811229C(void) { u16 * buffer = Alloc(0x400); CpuCopy16(gUnknown_203AE90, buffer, 0x400); @@ -1833,7 +1830,7 @@ void sub_81127F8(struct UnkStruct_3005E90 * a0) } } -void sub_8112888(u8 a0) +static void sub_8112888(u8 a0) { switch (a0) { @@ -1875,7 +1872,7 @@ void sub_81128BC(u8 a0) } } -void sub_8112940(u8 a0, struct UnkStruct_203AE98 *a1, u16 a2) +static void sub_8112940(u8 a0, struct UnkStruct_203AE98 *a1, u16 a2) { s32 i; @@ -2218,21 +2215,21 @@ u8 sub_8112CAC(void) } } -bool8 sub_8112CEC(void) +static bool8 sub_8112CEC(void) { if (gUnknown_203AF98 >= gUnknown_3005E8C || ScriptContext2_IsEnabled() == TRUE) return TRUE; return FALSE; } -bool8 sub_8112D1C(void) +static bool8 sub_8112D1C(void) { if (gUnknown_203AF98 >= gUnknown_3005E8C) return TRUE; return FALSE; } -const struct UnkStruct_300201C gUnknown_84566A4 = { +static const struct UnkStruct_300201C gUnknown_84566A4 = { 0, FALSE, 0x7FFF @@ -2294,37 +2291,37 @@ void sub_8112E3C(u8 a0, struct UnkStruct_300201C * a1, u16 a2) const u16 gUnknown_84566A8[] = INCBIN_U16("data/graphics/unknown_84566a8.bin"); -const struct WindowTemplate gUnknown_8456928 = { +static const struct WindowTemplate sHelpMessageWindowTemplate = { 0x00, 0, 15, 30, 5, 15, 0x008F }; void MapNamePopupWindowIdSetDummy(void) { - gUnknown_203B020 = 0xFF; + sHelpMessageWindowId = 0xFF; } -u8 sub_8112EB4(void) +u8 CreateHelpMessageWindow(void) { - if (gUnknown_203B020 == 0xFF) + if (sHelpMessageWindowId == 0xFF) { - gUnknown_203B020 = AddWindow(&gUnknown_8456928); - PutWindowTilemap(gUnknown_203B020); + sHelpMessageWindowId = AddWindow(&sHelpMessageWindowTemplate); + PutWindowTilemap(sHelpMessageWindowId); } - return gUnknown_203B020; + return sHelpMessageWindowId; } -void sub_8112EDC(u8 a0) +void DestroyHelpMessageWindow(u8 a0) { - if (gUnknown_203B020 != 0xFF) + if (sHelpMessageWindowId != 0xFF) { - FillWindowPixelBuffer(gUnknown_203B020, 0x00); - ClearWindowTilemap(gUnknown_203B020); + FillWindowPixelBuffer(sHelpMessageWindowId, PIXEL_FILL(0)); + ClearWindowTilemap(sHelpMessageWindowId); if (a0) - CopyWindowToVram(gUnknown_203B020, a0); + CopyWindowToVram(sHelpMessageWindowId, a0); - RemoveWindow(gUnknown_203B020); - gUnknown_203B020 = 0xFF; + RemoveWindow(sHelpMessageWindowId); + sHelpMessageWindowId = 0xFF; } } @@ -2460,24 +2457,24 @@ void sub_8112F18(u8 a0) void sub_8112FD0(void) { - sub_8112F18(gUnknown_203B020); + sub_8112F18(sHelpMessageWindowId); } -const u8 gUnknown_8456930[3] = { +static const u8 gUnknown_8456930[3] = { 0, 10, 2 }; void sub_8112FE4(const u8 * a0) { - AddTextPrinterParameterized4(gUnknown_203B020, 0x02, 2, 5, 1, 1, gUnknown_8456930, -1, a0); + AddTextPrinterParameterized4(sHelpMessageWindowId, 0x02, 2, 5, 1, 1, gUnknown_8456930, -1, a0); } -void sub_8113018(const u8 * text, u8 mode) +void PrintTextOnHelpMessageWindow(const u8 * text, u8 mode) { sub_8112FD0(); sub_8112FE4(text); if (mode) - CopyWindowToVram(gUnknown_203B020, mode); + CopyWindowToVram(sHelpMessageWindowId, mode); } void sub_8113044(void) @@ -2491,7 +2488,7 @@ void sub_8113064(void) sub_8113078(VAR_0x4038_STRUCT); } -void sub_8113078(struct Var4038Struct * varPtr) +static void sub_8113078(struct Var4038Struct * varPtr) { if (sub_8113508(varPtr)) { @@ -2505,7 +2502,7 @@ void sub_81130A8(void) sub_81130BC(VAR_0x4038_STRUCT); } -void sub_81130BC(struct Var4038Struct * varPtr) +static void sub_81130BC(struct Var4038Struct * varPtr) { if (!varPtr->unk_0_7) { @@ -2543,11 +2540,11 @@ u8 sub_8113114(struct Var4038Struct * a0, u8 a1) return a0->unk_0_0; } -const u8 gUnknown_8456938[] = { +static const u8 gUnknown_8456938[] = { 1, 3, 5, 0, 7, 6, 4, 2 }; -u8 sub_8113194(struct Var4038Struct * a0) +static u8 sub_8113194(struct Var4038Struct * a0) { u8 i; u8 retval = 0; @@ -2568,7 +2565,7 @@ u8 sub_8113194(struct Var4038Struct * a0) return gUnknown_8456938[retval]; } -const u8 gUnknown_8456940[] = { +static const u8 gUnknown_8456940[] = { 5, 6, 3, 7, 4, 1, 0, 2 }; @@ -2602,7 +2599,7 @@ u16 sub_8113288(void) return sub_81132A0(VAR_0x4038_STRUCT); } -u16 sub_81132A0(struct Var4038Struct * a0) +static u16 sub_81132A0(struct Var4038Struct * a0) { u8 count = 0; u8 i; @@ -2621,7 +2618,7 @@ void sub_81132CC(void) sub_81132E0(VAR_0x4038_STRUCT); } -void sub_81132E0(struct Var4038Struct * a0) +static void sub_81132E0(struct Var4038Struct * a0) { u8 i = 0; u16 var_4039; @@ -2653,12 +2650,12 @@ bool16 sub_8113364(void) return sub_811337C(VAR_0x4038_STRUCT); } -bool16 sub_811337C(struct Var4038Struct * a0) +static bool16 sub_811337C(struct Var4038Struct * a0) { return (a0->unk_1 >> gSpecialVar_0x8004) & 1; } -void sub_8113390(struct Var4038Struct * a0) +static void sub_8113390(struct Var4038Struct * a0) { a0->unk_1 |= 1; a0->unk_1 |= 2; @@ -2697,7 +2694,7 @@ void sub_81133A4(void) sub_8113414(&gSaveBlock2Ptr->linkBattleRecords, r3, r2); } -void sub_8113414(struct LinkBattleRecords * a0, u8 a1, u8 a2) +static void sub_8113414(struct LinkBattleRecords * a0, u8 a1, u8 a2) { u8 * str; const u8 * src = a0->entries[a1].name; @@ -2742,7 +2739,7 @@ void sub_81134B8(void) sub_81134CC(VAR_0x4038_STRUCT); } -void sub_81134CC(struct Var4038Struct * a0) +static void sub_81134CC(struct Var4038Struct * a0) { if (VarGet(VAR_MAP_SCENE_SAFFRON_CITY_POKEMON_TRAINER_FAN_CLUB) == 2) { @@ -2754,7 +2751,7 @@ void sub_81134CC(struct Var4038Struct * a0) } } -bool8 sub_8113508(struct Var4038Struct * a0) +static bool8 sub_8113508(struct Var4038Struct * a0) { return a0->unk_0_7; } @@ -2764,7 +2761,7 @@ void sub_8113510(void) sub_8113524(VAR_0x4038_STRUCT); } -void sub_8113524(struct Var4038Struct * a0) +static void sub_8113524(struct Var4038Struct * a0) { a0->unk_0_7 = TRUE; } @@ -3092,7 +3089,7 @@ void sub_8113550(u16 a0, const u16 * a1) } #endif // NONMATCHING -bool8 sub_81136D4(void) +static bool8 sub_81136D4(void) { if (gSaveBlock1Ptr->location.mapGroup == 2 && (gSaveBlock1Ptr->location.mapNum == 1 || gSaveBlock1Ptr->location.mapNum == 2 || gSaveBlock1Ptr->location.mapNum == 3 || gSaveBlock1Ptr->location.mapNum == 4 || gSaveBlock1Ptr->location.mapNum == 5 || gSaveBlock1Ptr->location.mapNum == 6 || gSaveBlock1Ptr->location.mapNum == 7 || gSaveBlock1Ptr->location.mapNum == 8 || gSaveBlock1Ptr->location.mapNum == 9 || gSaveBlock1Ptr->location.mapNum == 10 || gSaveBlock1Ptr->location.mapNum == 11)) return TRUE; @@ -3123,7 +3120,7 @@ bool8 sub_8113748(void) return FALSE; } -bool8 sub_8113778(u16 a0, u16 * a1) +static bool8 sub_8113778(u16 a0, u16 * a1) { if (a0 == 36 || a0 == 11) return TRUE; @@ -3143,7 +3140,7 @@ bool8 sub_8113778(u16 a0, u16 * a1) return FALSE; } -bool8 sub_81137E4(u16 a0, u16 * a1) +static bool8 sub_81137E4(u16 a0, u16 * a1) { if (a0 == 34) { @@ -3158,12 +3155,12 @@ bool8 sub_81137E4(u16 a0, u16 * a1) return FALSE; } -void sub_811381C(void) +static void sub_811381C(void) { gUnknown_203B048 = 0; } -u16 * sub_8113828(u16 a0, u16 * a1) +static u16 * sub_8113828(u16 a0, u16 * a1) { if (sub_8113778(a0, a1) == TRUE) return NULL; @@ -3182,7 +3179,7 @@ u16 * sub_8113828(u16 a0, u16 * a1) return sQuestLogStorageCBs[a0](gUnknown_203AE08, a1); } -bool8 sub_81138A0(u16 a0, u16 * a1) +static bool8 sub_81138A0(u16 a0, u16 * a1) { if (a0 < 12 || a0 > 19) return FALSE; @@ -3218,7 +3215,7 @@ void sub_811390C(void) } } -bool8 sub_8113954(u16 a0, u16 * a1) +static bool8 sub_8113954(u16 a0, u16 * a1) { if (a0 != 34 && a0 != 30 && a0 != 32 && a0 != 33) return FALSE; @@ -3250,13 +3247,13 @@ void sub_81139BC(void) } } -void sub_8113A1C(u16 a0) +static void sub_8113A1C(u16 a0) { gUnknown_203AE08 = sub_8113C5C(gUnknown_203AE08, a0); gUnknown_203AF98++; } -bool8 sub_8113A44(u16 a0, u16 *a1) +static bool8 sub_8113A44(u16 a0, u16 *a1) { if (a0 != 31) return FALSE; @@ -3316,7 +3313,7 @@ static const u16 * (*const sQuestLogScriptParsingCBs[])(const u16 *) = { sub_8115800 }; -const u8 gUnknown_8456AA0[] = { +static const u8 gUnknown_8456AA0[] = { 0x08, 0x08, 0x08, @@ -3362,7 +3359,7 @@ const u8 gUnknown_8456AA0[] = { 0x06 }; -u16 * sub_8113A78(u16 * a0, u16 **a1) +static u16 * sub_8113A78(u16 * a0, u16 **a1) { u16 r2 = a0[0] & 0xfff; u16 r4 = a0[0] >> 12; @@ -3374,7 +3371,7 @@ u16 * sub_8113A78(u16 * a0, u16 **a1) return gUnknown_8456AA0[r2] + (gUnknown_8456AA0[r2] - 4) * r4 + (void *)a0; } -void sub_8113ABC(u16 * a0) +static void sub_8113ABC(u16 * a0) { u8 * r2 = (u8 *)(a0 + 2); if ((a0[0] & 0xFFF) != 35) @@ -3384,7 +3381,7 @@ void sub_8113ABC(u16 * a0) } #ifdef NONMATCHING -bool8 sub_8113AE8(u16 * a0) +static bool8 sub_8113AE8(u16 * a0) { if (a0 == NULL || a0[1] > gUnknown_203AF98) return FALSE; @@ -3398,7 +3395,7 @@ bool8 sub_8113AE8(u16 * a0) } #else NAKED -bool8 sub_8113AE8(u16 * a0) +static bool8 sub_8113AE8(u16 * a0) { asm_unified("\tpush {r4,lr}\n" "\tadds r4, r0, 0\n" @@ -3449,7 +3446,7 @@ bool8 sub_8113AE8(u16 * a0) } #endif -bool8 sub_8113B44(u16 * a0) +static bool8 sub_8113B44(u16 * a0) { if (gUnknown_203B044.unk_2 == 0) return FALSE; @@ -3461,12 +3458,12 @@ bool8 sub_8113B44(u16 * a0) return TRUE; } -void sub_8113B88(void) +static void sub_8113B88(void) { gUnknown_203B044 = (struct UnkStruct_203B044){}; } -void sub_8113B94(u16 a0) +static void sub_8113B94(u16 a0) { if (gUnknown_203B044.unk_0 != (u8)a0 || gUnknown_203B044.unk_2 != gUnknown_203AF98) { @@ -3478,14 +3475,14 @@ void sub_8113B94(u16 a0) gUnknown_203B044.unk_1++; } -void sub_8113BD8(void) +static void sub_8113BD8(void) { gUnknown_203B049 = 0; gUnknown_203B04A = 0; gUnknown_203B04B = 0; } -u16 * sub_8113BF4(u16 * a0) +static u16 * sub_8113BF4(u16 * a0) { if (!sub_8110988(a0, gUnknown_8456AA0[39])) return NULL; @@ -3493,7 +3490,7 @@ u16 * sub_8113BF4(u16 * a0) return a0 + 1; } -u16 * sub_8113C20(u16 * a0, struct UnkStruct_203AE98 * a1) +static u16 * sub_8113C20(u16 * a0, struct UnkStruct_203AE98 * a1) { if (!sub_8110988(a0, gUnknown_8456AA0[39])) return NULL; @@ -3506,7 +3503,7 @@ u16 * sub_8113C20(u16 * a0, struct UnkStruct_203AE98 * a1) return a0 + 1; } -u16 * sub_8113C5C(u16 * a0, u16 a1) +static u16 * sub_8113C5C(u16 * a0, u16 a1) { if (!sub_8110988(a0, gUnknown_8456AA0[41])) return NULL; @@ -3515,7 +3512,7 @@ u16 * sub_8113C5C(u16 * a0, u16 a1) return a0 + 2; } -u16 * sub_8113C8C(u16 * a0, struct UnkStruct_203AE98 * a1) +static u16 * sub_8113C8C(u16 * a0, struct UnkStruct_203AE98 * a1) { if (!sub_8110988(a0, gUnknown_8456AA0[41])) return NULL; @@ -3528,7 +3525,7 @@ u16 * sub_8113C8C(u16 * a0, struct UnkStruct_203AE98 * a1) return a0 + 2; } -u16 * sub_8113CC8(u16 * a0, struct UnkStruct_203AE98 * a1) +static u16 * sub_8113CC8(u16 * a0, struct UnkStruct_203AE98 * a1) { u8 * r6 = (u8 *)a0 + 4; @@ -3543,7 +3540,7 @@ u16 * sub_8113CC8(u16 * a0, struct UnkStruct_203AE98 * a1) return (u16 *)(r6 + 4); } -u16 * sub_8113D08(u16 * a0, struct UnkStruct_203AE98 * a1) +static u16 * sub_8113D08(u16 * a0, struct UnkStruct_203AE98 * a1) { u8 * r6 = (u8 *)a0 + 4; @@ -3558,7 +3555,7 @@ u16 * sub_8113D08(u16 * a0, struct UnkStruct_203AE98 * a1) return (u16 *)(r6 + 4); } -u16 * sub_8113D48(u16 * a0, struct UnkStruct_203AE98 * a1) +static u16 * sub_8113D48(u16 * a0, struct UnkStruct_203AE98 * a1) { u16 * r4 = a0; u8 * r6 = (u8 *)a0 + 4; @@ -3577,7 +3574,7 @@ u16 * sub_8113D48(u16 * a0, struct UnkStruct_203AE98 * a1) return (u16 *)(r6 + 4); } -u16 * sub_8113D94(u16 * a0, struct UnkStruct_203AE98 * a1) +static u16 * sub_8113D94(u16 * a0, struct UnkStruct_203AE98 * a1) { u16 * r5 = a0; u8 * r6 = (u8 *)a0 + 4; @@ -3636,7 +3633,7 @@ u16 * sub_8113DE0(u16 a0, u16 * a1) return r5; } -const u16 * sub_8113E88(u16 a0, const u16 * a1) +static const u16 * sub_8113E88(u16 a0, const u16 * a1) { a1 = (const void *)a1 + (gUnknown_203B044.unk_2 * (gUnknown_8456AA0[a0] - 4) + 4); return a1; @@ -3663,7 +3660,7 @@ void QuestLog_AutoGetSpeciesName(u16 a0, u8 * a1, u8 a2) } } -u16 * sub_8113F14(u16 * a0, const u16 * a1) +static u16 * sub_8113F14(u16 * a0, const u16 * a1) { u16 * r2 = sub_8113DE0(3, a0); if (r2 == NULL) @@ -3674,7 +3671,7 @@ u16 * sub_8113F14(u16 * a0, const u16 * a1) return r2 + 2; } -const u16 * sub_8113F3C(const u16 * a0) +static const u16 * sub_8113F3C(const u16 * a0) { const u16 * r4 = sub_8113E88(3, a0); QuestLog_AutoGetSpeciesName(r4[0], gStringVar1, 0); @@ -3684,7 +3681,7 @@ const u16 * sub_8113F3C(const u16 * a0) return r4; } -u16 * sub_8113F80(u16 * a0, const u16 * a1) +static u16 * sub_8113F80(u16 * a0, const u16 * a1) { u16 * r2 = sub_8113DE0(4, a0); if (r2 == NULL) @@ -3700,7 +3697,7 @@ u16 * sub_8113F80(u16 * a0, const u16 * a1) return r2 + 3; } -const u16 * sub_8113FBC(const u16 * a0) +static const u16 * sub_8113FBC(const u16 * a0) { const u16 * r5 = sub_8113E88(4, a0); @@ -3763,12 +3760,12 @@ u16 * sub_811414C(u16 a0, u16 * a1, const u16 * a2) return r1 + 2; } -u16 * sub_8114174(u16 * a0, const u16 * a1) +static u16 * sub_8114174(u16 * a0, const u16 * a1) { return sub_811414C(5, a0, a1); } -const u16 * sub_8114188(const u16 * a0) +static const u16 * sub_8114188(const u16 * a0) { const u16 * r4 = sub_8113E88(5, a0); QuestLog_AutoGetSpeciesName(r4[1], gStringVar1, 0); @@ -3778,12 +3775,12 @@ const u16 * sub_8114188(const u16 * a0) return r4; } -u16 * sub_81141D0(u16 * a0, const u16 * a1) +static u16 * sub_81141D0(u16 * a0, const u16 * a1) { return sub_811414C(6, a0, a1); } -const u16 * sub_81141E4(const u16 * a0) +static const u16 * sub_81141E4(const u16 * a0) { const u16 * r4 = sub_8113E88(6, a0); @@ -3794,12 +3791,12 @@ const u16 * sub_81141E4(const u16 * a0) return r4; } -u16 * sub_811422C(u16 * a0, const u16 * a1) +static u16 * sub_811422C(u16 * a0, const u16 * a1) { return sub_811414C(7, a0, a1); } -const u16 * sub_8114240(const u16 * a0) +static const u16 * sub_8114240(const u16 * a0) { const u16 * r4 = sub_8113E88(7, a0); @@ -3810,12 +3807,12 @@ const u16 * sub_8114240(const u16 * a0) return r4; } -u16 * sub_8114288(u16 * a0, const u16 * a1) +static u16 * sub_8114288(u16 * a0, const u16 * a1) { return sub_811414C(8, a0, a1); } -const u16 * sub_811429C(const u16 * a0) +static const u16 * sub_811429C(const u16 * a0) { const u16 * r4 = sub_8113E88(8, a0); @@ -3838,12 +3835,12 @@ u16 * sub_81142E4(u16 a0, u16 * a1, const u16 * a2) return r1 + 3; } -u16 * sub_8114310(u16 * a0, const u16 * a1) +static u16 * sub_8114310(u16 * a0, const u16 * a1) { return sub_81142E4(9, a0, a1); } -const u16 * sub_8114324(const u16 * a0) +static const u16 * sub_8114324(const u16 * a0) { const u16 * r4 = sub_8113E88(9, a0); QuestLog_AutoGetSpeciesName(r4[2], gStringVar1, 0); @@ -3854,12 +3851,12 @@ const u16 * sub_8114324(const u16 * a0) return r4; } -u16 * sub_8114380(u16 * a0, const u16 * a1) +static u16 * sub_8114380(u16 * a0, const u16 * a1) { return sub_81142E4(10, a0, a1); } -const u16 * sub_8114394(const u16 * a0) +static const u16 * sub_8114394(const u16 * a0) { const u16 * r4 = sub_8113E88(10, a0); QuestLog_AutoGetSpeciesName(r4[2], gStringVar2, 0); @@ -3870,7 +3867,7 @@ const u16 * sub_8114394(const u16 * a0) return r4; } -u16 * sub_81143F0(u16 * a0, const u16 * a1) +static u16 * sub_81143F0(u16 * a0, const u16 * a1) { u16 * r4 = a0; if (gUnknown_203B044.unk_0 == 11 && gUnknown_203B044.unk_1 != 0) @@ -3884,14 +3881,14 @@ u16 * sub_81143F0(u16 * a0, const u16 * a1) return r4 + 2; } -const u16 * sub_811443C(const u16 * a0) +static const u16 * sub_811443C(const u16 * a0) { StringExpandPlaceholders(gStringVar4, gUnknown_841A2B0); a0 += 2; return a0; } -u16 * sub_811445C(u16 * a0, const u16 * a1) +static u16 * sub_811445C(u16 * a0, const u16 * a1) { u16 * r4 = a0 + 4; @@ -3905,7 +3902,7 @@ u16 * sub_811445C(u16 * a0, const u16 * a1) return r4; } -const u16 * sub_811448C(const u16 * a0) +static const u16 * sub_811448C(const u16 * a0) { const u16 * r6 = a0 + 4; @@ -3920,25 +3917,25 @@ const u16 * sub_811448C(const u16 * a0) return r6; } -const u8 *const gUnknown_8456ACC[] = { +static const u8 *const gUnknown_8456ACC[] = { gUnknown_841A74E, gUnknown_841A756, gUnknown_841A762 }; -const u8 *const gUnknown_8456AD8[] = { +static const u8 *const gUnknown_8456AD8[] = { gUnknown_841AF98, gUnknown_841A762, gUnknown_841AF9F }; -const u8 *const gUnknown_8456AE4[] = { +static const u8 *const gUnknown_8456AE4[] = { gUnknown_841A502, gUnknown_841A506, gUnknown_841AFD1 }; -u16 * sub_81144EC(u16 * a0, const u16 * a1) +static u16 * sub_81144EC(u16 * a0, const u16 * a1) { a0[0] = 13; a0[1] = gUnknown_203AF98; @@ -3948,7 +3945,7 @@ u16 * sub_81144EC(u16 * a0, const u16 * a1) return a0; } -const u16 * sub_8114518(const u16 * a0) +static const u16 * sub_8114518(const u16 * a0) { DynamicPlaceholderTextUtil_Reset(); @@ -3962,7 +3959,7 @@ const u16 * sub_8114518(const u16 * a0) return a0; } -u16 * sub_8114578(u16 * a0, const u16 * a1) +static u16 * sub_8114578(u16 * a0, const u16 * a1) { a0[0] = 14; a0[1] = gUnknown_203AF98; @@ -3972,7 +3969,7 @@ u16 * sub_8114578(u16 * a0, const u16 * a1) return a0; } -const u16 * sub_81145A4(const u16 * a0) +static const u16 * sub_81145A4(const u16 * a0) { DynamicPlaceholderTextUtil_Reset(); @@ -3986,7 +3983,7 @@ const u16 * sub_81145A4(const u16 * a0) return a0; } -u16 * sub_8114604(u16 * a0, const u16 * a1) +static u16 * sub_8114604(u16 * a0, const u16 * a1) { a0[0] = 15; a0[1] = gUnknown_203AF98; @@ -3998,7 +3995,7 @@ u16 * sub_8114604(u16 * a0, const u16 * a1) return a0; } -const u16 * sub_811464C(const u16 * a0) +static const u16 * sub_811464C(const u16 * a0) { DynamicPlaceholderTextUtil_Reset(); @@ -4021,35 +4018,35 @@ const u16 * sub_811464C(const u16 * a0) return a0; } -u16 * sub_8114710(u16 * a0, const u16 * a1) +static u16 * sub_8114710(u16 * a0, const u16 * a1) { a0[0] = 16; a0[1] = gUnknown_203AF98; return a0 + 2; } -const u16 * sub_8114724(const u16 * a0) +static const u16 * sub_8114724(const u16 * a0) { StringExpandPlaceholders(gStringVar4, gUnknown_841A50B); a0 += 2; return a0; } -u16 * sub_8114744(u16 * a0, const u16 * a1) +static u16 * sub_8114744(u16 * a0, const u16 * a1) { a0[0] = 17; a0[1] = gUnknown_203AF98; return a0 + 2; } -const u16 * sub_8114758(const u16 * a0) +static const u16 * sub_8114758(const u16 * a0) { StringExpandPlaceholders(gStringVar4, gUnknown_841A732); a0 += 2; return a0; } -u16 * sub_8114778(u16 * a0, const u16 * a1) +static u16 * sub_8114778(u16 * a0, const u16 * a1) { u8 * r4 = (u8 *)(a0 + 4); a0[0] = 18; @@ -4061,7 +4058,7 @@ u16 * sub_8114778(u16 * a0, const u16 * a1) return (u16 *)r4; } -const u16 * sub_81147A8(const u16 * a0) +static const u16 * sub_81147A8(const u16 * a0) { const u8 * r6 = (const u8 *)(a0 + 4); memset(gStringVar1, EOS, 8); @@ -4074,7 +4071,7 @@ const u16 * sub_81147A8(const u16 * a0) return (const u16 *)r6; } -u16 * sub_8114808(u16 * a0, const u16 * a1) +static u16 * sub_8114808(u16 * a0, const u16 * a1) { a0[0] = 19; a0[1] = gUnknown_203AF98; @@ -4084,7 +4081,7 @@ u16 * sub_8114808(u16 * a0, const u16 * a1) return a0; } -const u16 * sub_8114834(const u16 * a0) +static const u16 * sub_8114834(const u16 * a0) { memset(gStringVar1, EOS, 8); memcpy(gStringVar1, (const u8 *)a0 + 5, 7); @@ -4095,7 +4092,7 @@ const u16 * sub_8114834(const u16 * a0) return a0; } -u16 * sub_811488C(u16 * a0, const u16 * a1) +static u16 * sub_811488C(u16 * a0, const u16 * a1) { a0 = sub_8113DE0(20, a0); if (a0 == NULL) @@ -4107,7 +4104,7 @@ u16 * sub_811488C(u16 * a0, const u16 * a1) return a0 + 3; } -const u16 * sub_81148BC(const u16 * a0) +static const u16 * sub_81148BC(const u16 * a0) { const u8 * boxIdxs; a0 = sub_8113E88(20, a0); @@ -4121,7 +4118,7 @@ const u16 * sub_81148BC(const u16 * a0) return a0 + 3; } -u16 * sub_8114918(u16 * a0, const u16 * a1) +static u16 * sub_8114918(u16 * a0, const u16 * a1) { a0 = sub_8113DE0(21, a0); if (a0 == NULL) @@ -4132,7 +4129,7 @@ u16 * sub_8114918(u16 * a0, const u16 * a1) return a0 + 3; } -const u16 * sub_8114944(const u16 * a0) +static const u16 * sub_8114944(const u16 * a0) { const u8 * boxIdxs; a0 = sub_8113E88(21, a0); @@ -4145,7 +4142,7 @@ const u16 * sub_8114944(const u16 * a0) return a0 + 3; } -u16 * sub_8114990(u16 * a0, const u16 * a1) +static u16 * sub_8114990(u16 * a0, const u16 * a1) { u16 * r2; u16 * ret; @@ -4168,7 +4165,7 @@ u16 * sub_8114990(u16 * a0, const u16 * a1) return ret + 1; } -const u16 * sub_81149D0(const u16 * a0) +static const u16 * sub_81149D0(const u16 * a0) { const u8 * boxIdxs; a0 = sub_8113E88(22, a0); @@ -4181,7 +4178,7 @@ const u16 * sub_81149D0(const u16 * a0) return a0 + 3; } -u16 * sub_8114A1C(u16 * a0, const u16 * a1) +static u16 * sub_8114A1C(u16 * a0, const u16 * a1) { u16 * r2; u16 * ret; @@ -4195,7 +4192,7 @@ u16 * sub_8114A1C(u16 * a0, const u16 * a1) return ret + 1; } -const u16 * sub_8114A4C(const u16 * a0) +static const u16 * sub_8114A4C(const u16 * a0) { const u8 * boxIdxs; a0 = sub_8113E88(23, a0); @@ -4208,7 +4205,7 @@ const u16 * sub_8114A4C(const u16 * a0) return (const u16 *)boxIdxs + 1; } -u16 * sub_8114AA0(u16 * a0, const u16 * a1) +static u16 * sub_8114AA0(u16 * a0, const u16 * a1) { u16 * r2; r2 = sub_8113DE0(24, a0); @@ -4219,7 +4216,7 @@ u16 * sub_8114AA0(u16 * a0, const u16 * a1) return r2 + 2; } -const u16 * sub_8114AC8(const u16 * a0) +static const u16 * sub_8114AC8(const u16 * a0) { const u8 * boxIdxs; a0 = sub_8113E88(24, a0); @@ -4231,7 +4228,7 @@ const u16 * sub_8114AC8(const u16 * a0) return (const u16 *)boxIdxs + 1; } -u16 * sub_8114B0C(u16 * a0, const u16 * a1) +static u16 * sub_8114B0C(u16 * a0, const u16 * a1) { u16 * r2; r2 = sub_8113DE0(25, a0); @@ -4242,7 +4239,7 @@ u16 * sub_8114B0C(u16 * a0, const u16 * a1) return r2 + 2; } -const u16 * sub_8114B34(const u16 * a0) +static const u16 * sub_8114B34(const u16 * a0) { const u8 * boxIdxs; a0 = sub_8113E88(25, a0); @@ -4254,7 +4251,7 @@ const u16 * sub_8114B34(const u16 * a0) return (const u16 *)boxIdxs + 1; } -u16 * sub_8114B78(u16 * a0, const u16 * a1) +static u16 * sub_8114B78(u16 * a0, const u16 * a1) { u16 * r2; r2 = sub_8113DE0(26, a0); @@ -4265,7 +4262,7 @@ u16 * sub_8114B78(u16 * a0, const u16 * a1) return r2 + 2; } -const u16 * sub_8114BA0(const u16 * a0) +static const u16 * sub_8114BA0(const u16 * a0) { const u8 * boxIdxs; a0 = sub_8113E88(26, a0); @@ -4277,7 +4274,7 @@ const u16 * sub_8114BA0(const u16 * a0) return (const u16 *)boxIdxs + 1; } -u16 * sub_8114BE4(u16 * a0, const u16 * a1) +static u16 * sub_8114BE4(u16 * a0, const u16 * a1) { u16 * r2; r2 = sub_8113DE0(27, a0); @@ -4288,7 +4285,7 @@ u16 * sub_8114BE4(u16 * a0, const u16 * a1) return r2 + 1; } -const u16 * sub_8114C0C(const u16 * a0) +static const u16 * sub_8114C0C(const u16 * a0) { const u16 *r4 = sub_8113E88(27, a0); DynamicPlaceholderTextUtil_Reset(); @@ -4301,7 +4298,7 @@ const u16 * sub_8114C0C(const u16 * a0) return r4 + 1; } -u16 * sub_8114C68(u16 * a0, const u16 * a1) +static u16 * sub_8114C68(u16 * a0, const u16 * a1) { a0 = sub_8113DE0(28, a0); if (a0 == NULL) @@ -4310,7 +4307,7 @@ u16 * sub_8114C68(u16 * a0, const u16 * a1) return a0 + 1; } -const u16 * sub_8114C8C(const u16 * a0) +static const u16 * sub_8114C8C(const u16 * a0) { const u16 *r4 = sub_8113E88(28, a0); CopyItemName(r4[0], gStringVar1); @@ -4318,7 +4315,7 @@ const u16 * sub_8114C8C(const u16 * a0) return r4 + 1; } -u16 * sub_8114CC0(u16 * a0, const u16 * a1) +static u16 * sub_8114CC0(u16 * a0, const u16 * a1) { a0 = sub_8113DE0(29, a0); if (a0 == NULL) @@ -4327,7 +4324,7 @@ u16 * sub_8114CC0(u16 * a0, const u16 * a1) return a0 + 1; } -const u16 * sub_8114CE4(const u16 * a0) +static const u16 * sub_8114CE4(const u16 * a0) { const u16 *r4 = sub_8113E88(29, a0); CopyItemName(r4[0], gStringVar1); @@ -4348,13 +4345,13 @@ u16 * sub_8114D18(u16 a0, u16 * a1, const u16 * a2) return a1 + 4; } -u16 * sub_8114D4C(u16 * a0, const u16 * a1) +static u16 * sub_8114D4C(u16 * a0, const u16 * a1) { gUnknown_203B048 = TRUE; return sub_8114D18(30, a0, a1); } -const u16 * sub_8114D68(const u16 * a0) +static const u16 * sub_8114D68(const u16 * a0) { const u8 * r6; a0 = sub_8113E88(30, a0); @@ -4370,7 +4367,7 @@ const u16 * sub_8114D68(const u16 * a0) return a0 + 4; } -u16 * sub_8114DE8(u16 * a0, const u16 * a1) +static u16 * sub_8114DE8(u16 * a0, const u16 * a1) { u16 * r4 = a0; u8 * r5 = (u8 *)a0 + 8; @@ -4393,7 +4390,7 @@ u16 * sub_8114DE8(u16 * a0, const u16 * a1) return (u16 *)(r5 + 4); } -const u16 * sub_8114E68(const u16 * a0) +static const u16 * sub_8114E68(const u16 * a0) { const u8 * r6; if (!sub_8110944(a0, gUnknown_8456AA0[31])) @@ -4441,7 +4438,7 @@ const u16 * sub_8114E68(const u16 * a0) return (const u16 *)(r6 + 4); } -bool8 sub_8114FBC(u16 a0) +static bool8 sub_8114FBC(u16 a0) { switch (a0) { @@ -4454,13 +4451,13 @@ bool8 sub_8114FBC(u16 a0) return FALSE; } -u16 * sub_8114FF0(u16 * a0, const u16 * a1) +static u16 * sub_8114FF0(u16 * a0, const u16 * a1) { gUnknown_203B048 = TRUE; return sub_8114D18(32, a0, a1); } -const u16 * sub_811500C(const u16 * a0) +static const u16 * sub_811500C(const u16 * a0) { const u8 * r5; a0 = sub_8113E88(32, a0); @@ -4474,7 +4471,7 @@ const u16 * sub_811500C(const u16 * a0) return a0 + 4; } -u16 * sub_8115078(u16 * a0, const u16 * a1) +static u16 * sub_8115078(u16 * a0, const u16 * a1) { if (!sub_8110944(a0, gUnknown_8456AA0[33])) return NULL; @@ -4487,7 +4484,7 @@ u16 * sub_8115078(u16 * a0, const u16 * a1) return a0 + 5; } -const u16 * sub_81150CC(const u16 * a0) +static const u16 * sub_81150CC(const u16 * a0) { const u8 * r5; if (!sub_8110944(a0, gUnknown_8456AA0[33])) @@ -4518,13 +4515,13 @@ const u16 * sub_81150CC(const u16 * a0) return (const u16 *)(r5 + 2); } -u16 * sub_81151C0(u16 * a0, const u16 * a1) +static u16 * sub_81151C0(u16 * a0, const u16 * a1) { gUnknown_203B048 = TRUE; return sub_8114D18(34, a0, a1); } -const u16 * sub_81151DC(const u16 * a0) +static const u16 * sub_81151DC(const u16 * a0) { const u16 * r5 = sub_8113E88(34, a0); const u8 * r6 = (const u8 *)r5 + 6; @@ -4546,7 +4543,7 @@ const u16 * sub_81151DC(const u16 * a0) return (const u16 *)(r6 + 2); } -const u8 *const gUnknown_8456AF0[] = { +static const u8 *const gUnknown_8456AF0[] = { gUnknown_841B09F, gUnknown_841B0A4, gUnknown_841B0B5, @@ -4600,7 +4597,7 @@ const u8 *const gUnknown_8456AF0[] = { gUnknown_841B277 }; -const u8 *const gUnknown_8456BBC[] = { +static const u8 *const gUnknown_8456BBC[] = { gUnknown_841A53A, gUnknown_841AD9E, gUnknown_841ADC8, @@ -4613,7 +4610,7 @@ const u8 *const gUnknown_8456BBC[] = { gUnknown_841B005 }; -const u8 gUnknown_8456BE4[] = { +static const u8 gUnknown_8456BE4[] = { 0x03, 0x04, 0x05, @@ -4667,7 +4664,7 @@ const u8 gUnknown_8456BE4[] = { 0x07 }; -const u8 gUnknown_8456C17[] = { +static const u8 gUnknown_8456C17[] = { 0x5a, 0x5b, 0x5d, @@ -4678,7 +4675,7 @@ const u8 gUnknown_8456C17[] = { 0x59 }; -const u8 *const gUnknown_8456C20[] = { +static const u8 *const gUnknown_8456C20[] = { gUnknown_841AC51, gUnknown_841ABAB, gUnknown_841ABCD, @@ -4693,7 +4690,7 @@ const u8 *const gUnknown_8456C20[] = { gUnknown_841AD3C }; -u16 * sub_8115280(u16 * a0, const u16 * a1) +static u16 * sub_8115280(u16 * a0, const u16 * a1) { u16 * r2 = sub_8113DE0(35, a0); if (r2 == NULL) @@ -4704,7 +4701,7 @@ u16 * sub_8115280(u16 * a0, const u16 * a1) return r2 + 1; } -const u16 * sub_81152BC(const u16 * a0) +static const u16 * sub_81152BC(const u16 * a0) { u8 r4, r6; const u16 * r5 = sub_8113E88(35, a0); @@ -4738,7 +4735,7 @@ void sub_811539C(void) gUnknown_203B04B = TRUE; } -bool8 sub_81153A8(u16 a0, u16 * a1) +static bool8 sub_81153A8(u16 a0, u16 * a1) { if (a0 != 35) { @@ -4751,7 +4748,7 @@ bool8 sub_81153A8(u16 a0, u16 * a1) return TRUE; } -bool8 sub_81153E4(u16 a0, u16 * a1) +static bool8 sub_81153E4(u16 a0, u16 * a1) { if (a0 != 35) return TRUE; @@ -4761,7 +4758,7 @@ bool8 sub_81153E4(u16 a0, u16 * a1) return TRUE; } -u16 * sub_8115410(u16 * a0, const u16 * a1) +static u16 * sub_8115410(u16 * a0, const u16 * a1) { u8 * r3; a0 = sub_8113DE0(36, a0); @@ -4778,7 +4775,7 @@ u16 * sub_8115410(u16 * a0, const u16 * a1) return (u16 *)(r3 + 2); } -const u16 * sub_8115460(const u16 * a0) +static const u16 * sub_8115460(const u16 * a0) { const u16 * r4 = sub_8113E88(36, a0); const u8 * r5 = (const u8 *)r4 + 2; @@ -4796,7 +4793,7 @@ const u16 * sub_8115460(const u16 * a0) return (const u16 *)(r5 + 2); } -u16 * sub_81154DC(u16 * a0, const u16 * a1) +static u16 * sub_81154DC(u16 * a0, const u16 * a1) { a0 = sub_8113DE0(37, a0); if (a0 == NULL) @@ -4810,7 +4807,7 @@ u16 * sub_81154DC(u16 * a0, const u16 * a1) return a0 + 5; } -const u16 * sub_8115518(const u16 * a0) +static const u16 * sub_8115518(const u16 * a0) { const u16 * r4 = sub_8113E88(37, a0); const u8 * r7 = (const u8 *)r4 + 8; @@ -4830,7 +4827,7 @@ const u16 * sub_8115518(const u16 * a0) return (const u16 *)(r7 + 2); } -u16 * sub_81155A4(u16 * a0, const u16 * a1) +static u16 * sub_81155A4(u16 * a0, const u16 * a1) { a0 = sub_8113DE0(38, a0); if (a0 == NULL) @@ -4844,7 +4841,7 @@ u16 * sub_81155A4(u16 * a0, const u16 * a1) return a0 + 5; } -const u16 * sub_81155E0(const u16 * a0) { +static const u16 * sub_81155E0(const u16 * a0) { const u16 *r5 = sub_8113E88(38, a0); const u8 *r7 = (const u8 *) r5 + 8; u32 r6 = (r5[2] << 16) + r5[3]; @@ -4876,7 +4873,7 @@ const u16 * sub_81155E0(const u16 * a0) { return (const u16 *)(r7 + 2); } -u16 * sub_81156D8(u16 * a0, const u16 * a1) +static u16 * sub_81156D8(u16 * a0, const u16 * a1) { a0 = sub_8113DE0(40, a0); if (a0 == NULL) @@ -4886,7 +4883,7 @@ u16 * sub_81156D8(u16 * a0, const u16 * a1) return a0 + 2; } -const u16 * sub_8115700(const u16 * a0) +static const u16 * sub_8115700(const u16 * a0) { const u16 * r4 = sub_8113E88(40, a0); const u8 * r5 = (const u8 *)r4 + 2; @@ -4896,7 +4893,7 @@ const u16 * sub_8115700(const u16 * a0) return (const u16 *)(r5 + 2); } -const u16 gUnknown_8456C50[] = { +static const u16 gUnknown_8456C50[] = { 0x0891, 0x0892, 0x0893, @@ -4993,7 +4990,7 @@ void sub_8115798(void) } } -u16 * sub_81157DC(u16 * a0, const u16 * a1) +static u16 * sub_81157DC(u16 * a0, const u16 * a1) { a0 = sub_8113DE0(42, a0); if (a0 == NULL) @@ -5002,7 +4999,7 @@ u16 * sub_81157DC(u16 * a0, const u16 * a1) return a0 + 1; } -const u16 * sub_8115800(const u16 * a0) +static const u16 * sub_8115800(const u16 * a0) { const u16 * r4 = sub_8113E88(42, a0); sub_80C4DF8(gStringVar1, r4[0]); diff --git a/src/rock.c b/src/rock.c new file mode 100644 index 000000000..4db903344 --- /dev/null +++ b/src/rock.c @@ -0,0 +1,830 @@ +#include "global.h" +#include "battle_anim.h" +#include "gpu_regs.h" +#include "graphics.h" +#include "palette.h" +#include "sound.h" +#include "task.h" +#include "trig.h" +#include "constants/songs.h" + +static void sub_80B4634(struct Sprite *sprite); +static void sub_80B46F8(struct Sprite *sprite); +static void AnimDirtParticleAcrossScreen(struct Sprite *sprite); +static void AnimRaiseSprite(struct Sprite *sprite); +static void sub_80B4D00(u8 taskId); +static void sub_80B4F78(struct Sprite *sprite); +static void sub_80B4FE4(struct Sprite *sprite); +static void sub_80B5074(struct Sprite *sprite); +static void sub_80B50A0(struct Sprite *sprite); +static void sub_80B477C(struct Sprite *sprite); +static void sub_80B46B4(struct Sprite *sprite); +static void sub_80B47C4(struct Sprite *sprite); +static void sub_80B490C(u8 taskId); +static void sub_80B4E70(struct Task *task); +static u8 sub_80B4FB8(void); +static void sub_80B5024(struct Sprite *sprite); +static void sub_80B50F8(struct Sprite *sprite); + +static const union AnimCmd gUnknown_83E7390[] = +{ + ANIMCMD_FRAME(32, 1), + ANIMCMD_END, +}; + +static const union AnimCmd gUnknown_83E7398[] = +{ + ANIMCMD_FRAME(48, 1), + ANIMCMD_END, +}; + +static const union AnimCmd gUnknown_83E73A0[] = +{ + ANIMCMD_FRAME(64, 1), + ANIMCMD_END, +}; + +static const union AnimCmd *const gUnknown_83E73A8[] = +{ + gUnknown_83E7390, + gUnknown_83E7398, + gUnknown_83E73A0, +}; + +const struct SpriteTemplate gUnknown_83E73B4 = +{ + .tileTag = ANIM_TAG_ROCKS, + .paletteTag = ANIM_TAG_ROCKS, + .oam = &gOamData_83AC9D8, + .anims = gUnknown_83E73A8, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_80B4634, +}; + +const struct SpriteTemplate gUnknown_83E73CC = +{ + .tileTag = ANIM_TAG_ROCKS, + .paletteTag = ANIM_TAG_ROCKS, + .oam = &gOamData_83AC9D8, + .anims = gUnknown_83E73A8, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_80B46F8, +}; + +const struct SpriteTemplate gUnknown_83E73E4 = +{ + .tileTag = ANIM_TAG_MUD_SAND, + .paletteTag = ANIM_TAG_MUD_SAND, + .oam = &gOamData_83AC9C8, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_80B477C, +}; + +static const union AffineAnimCmd gUnknown_83E73FC[] = +{ + AFFINEANIMCMD_FRAME(0xC0, 0xC0, 0, 0), + AFFINEANIMCMD_FRAME(0x2, 0xFFFD, 0, 5), + AFFINEANIMCMD_FRAME(0xFFFE, 0x3, 0, 5), + AFFINEANIMCMD_JUMP(1), +}; + +static const union AffineAnimCmd *const gUnknown_83E741C[] = +{ + gUnknown_83E73FC, +}; + +const struct SpriteTemplate gUnknown_83E7420 = +{ + .tileTag = ANIM_TAG_WATER_ORB, + .paletteTag = ANIM_TAG_WATER_ORB, + .oam = &gOamData_83ACB50, + .anims = gUnknown_83E5958, + .images = NULL, + .affineAnims = gUnknown_83E741C, + .callback = sub_80B477C, +}; + +const struct SpriteTemplate gUnknown_83E7438 = +{ + .tileTag = ANIM_TAG_SMALL_EMBER, + .paletteTag = ANIM_TAG_SMALL_EMBER, + .oam = &gOamData_83AC9D8, + .anims = gUnknown_83E5D48, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_80B477C, +}; + +const struct SpriteTemplate gUnknown_83E7450 = +{ + .tileTag = ANIM_TAG_FLYING_DIRT, + .paletteTag = ANIM_TAG_FLYING_DIRT, + .oam = &gOamData_83AC9F8, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimDirtParticleAcrossScreen, +}; + +static const struct Subsprite gUnknown_83E7468[] = +{ + { + .x = -16, + .y = 0, + .shape = ST_OAM_H_RECTANGLE, + .size = 2, + .tileOffset = 0, + .priority = 1, + }, + { + .x = 16, + .y = 0, + .shape = ST_OAM_H_RECTANGLE, + .size = 2, + .tileOffset = 8, + .priority = 1, + }, +}; + +static const struct SubspriteTable gUnknown_83E7470[] = +{ + { ARRAY_COUNT(gUnknown_83E7468), gUnknown_83E7468 }, +}; + +static const union AnimCmd gUnknown_83E7478[] = +{ + ANIMCMD_FRAME(0, 1), + ANIMCMD_END, +}; + +static const union AnimCmd gUnknown_83E7480[] = +{ + ANIMCMD_FRAME(16, 1), + ANIMCMD_END, +}; + +static const union AnimCmd gUnknown_83E7488[] = +{ + ANIMCMD_FRAME(32, 1), + ANIMCMD_END, +}; + +static const union AnimCmd gUnknown_83E7490[] = +{ + ANIMCMD_FRAME(48, 1), + ANIMCMD_END, +}; + +static const union AnimCmd gUnknown_83E7498[] = +{ + ANIMCMD_FRAME(64, 1), + ANIMCMD_END, +}; + +static const union AnimCmd gUnknown_83E74A0[] = +{ + ANIMCMD_FRAME(80, 1), + ANIMCMD_END, +}; + +static const union AnimCmd *const gUnknown_83E74A8[] = +{ + gUnknown_83E7478, + gUnknown_83E7480, +}; + +static const union AnimCmd *const gUnknown_83E74B0[] = +{ + gUnknown_83E7488, + gUnknown_83E7490, +}; + +static const union AnimCmd *const gUnknown_83E74B8[] = +{ + gUnknown_83E7498, + gUnknown_83E74A0, +}; + +const struct SpriteTemplate gUnknown_83E74C0 = +{ + .tileTag = ANIM_TAG_ROCKS, + .paletteTag = ANIM_TAG_ROCKS, + .oam = &gOamData_83AC9D8, + .anims = gUnknown_83E74A8, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimRaiseSprite, +}; + +const struct SpriteTemplate gUnknown_83E74D8 = +{ + .tileTag = ANIM_TAG_MUD_SAND, + .paletteTag = ANIM_TAG_MUD_SAND, + .oam = &gOamData_83AC9C8, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_80B4F78, +}; + +const struct SpriteTemplate gUnknown_83E74F0 = +{ + .tileTag = ANIM_TAG_ROCKS, + .paletteTag = ANIM_TAG_ROCKS, + .oam = &gOamData_83AC9D8, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_80B4F78, +}; + +const struct SpriteTemplate gUnknown_83E7508 = +{ + .tileTag = ANIM_TAG_ROCKS, + .paletteTag = ANIM_TAG_ROCKS, + .oam = &gOamData_83AC9D8, + .anims = gUnknown_83E74A8, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_80B4FE4, +}; + +static const union AffineAnimCmd gUnknown_83E7520[] = +{ + AFFINEANIMCMD_FRAME(0x0, 0x0, -5, 5), + AFFINEANIMCMD_JUMP(0), +}; + +static const union AffineAnimCmd gUnknown_83E7530[] = +{ + AFFINEANIMCMD_FRAME(0x0, 0x0, 5, 5), + AFFINEANIMCMD_JUMP(0), +}; + +static const union AffineAnimCmd *const gUnknown_83E7540[] = +{ + gUnknown_83E7520, + gUnknown_83E7530, +}; + +const struct SpriteTemplate gUnknown_83E7548 = +{ + .tileTag = ANIM_TAG_ROCKS, + .paletteTag = ANIM_TAG_ROCKS, + .oam = &gOamData_83ACA38, + .anims = gUnknown_83E74A8, + .images = NULL, + .affineAnims = gUnknown_83E7540, + .callback = sub_80B5074, +}; + +const struct SpriteTemplate gUnknown_83E7560 = +{ + .tileTag = ANIM_TAG_ROCKS, + .paletteTag = ANIM_TAG_ROCKS, + .oam = &gOamData_83ACA38, + .anims = gUnknown_83E74A8, + .images = NULL, + .affineAnims = gUnknown_83E7540, + .callback = sub_80B50A0, +}; + +const struct SpriteTemplate gUnknown_83E7578 = +{ + .tileTag = ANIM_TAG_ROCKS, + .paletteTag = ANIM_TAG_ROCKS, + .oam = &gOamData_83AC9D8, + .anims = gUnknown_83E74B8, + .images = NULL, + .affineAnims = gUnknown_83E7540, + .callback = AnimMoveTwisterParticle, +}; + +const struct SpriteTemplate gUnknown_83E7590 = +{ + .tileTag = ANIM_TAG_ROCKS, + .paletteTag = ANIM_TAG_ROCKS, + .oam = &gOamData_83ACA38, + .anims = gUnknown_83E74B0, + .images = NULL, + .affineAnims = gUnknown_83E7540, + .callback = sub_8077350, +}; + +static void sub_80B4634(struct Sprite *sprite) +{ + if (gBattleAnimArgs[3] != 0) + SetAverageBattlerPositions(gBattleAnimTarget, 0, &sprite->pos1.x, &sprite->pos1.y); + sprite->pos1.x += gBattleAnimArgs[0]; + sprite->pos1.y += 14; + StartSpriteAnim(sprite, gBattleAnimArgs[1]); + AnimateSprite(sprite); + sprite->data[0] = 0; + sprite->data[1] = 0; + sprite->data[2] = 4; + sprite->data[3] = 16; + sprite->data[4] = -70; + sprite->data[5] = gBattleAnimArgs[2]; + StoreSpriteCallbackInData6(sprite, sub_80B46B4); + sprite->callback = TranslateSpriteInEllipseOverDuration; + sprite->callback(sprite); +} + +static void sub_80B46B4(struct Sprite *sprite) +{ + sprite->pos1.x += sprite->data[5]; + sprite->data[0] = 192; + sprite->data[1] = sprite->data[5]; + sprite->data[2] = 4; + sprite->data[3] = 32; + sprite->data[4] = -24; + StoreSpriteCallbackInData6(sprite, DestroySpriteAndMatrix); + sprite->callback = TranslateSpriteInEllipseOverDuration; + sprite->callback(sprite); +} + +static void sub_80B46F8(struct Sprite *sprite) +{ + StartSpriteAnim(sprite, gBattleAnimArgs[5]); + AnimateSprite(sprite); + if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) + sprite->pos1.x -= gBattleAnimArgs[0]; + else + sprite->pos1.x += gBattleAnimArgs[0]; + sprite->pos1.y += gBattleAnimArgs[1]; + sprite->data[0] = gBattleAnimArgs[4]; + sprite->data[1] = sprite->pos1.x; + sprite->data[2] = sprite->pos1.x + gBattleAnimArgs[2]; + sprite->data[3] = sprite->pos1.y; + sprite->data[4] = sprite->pos1.y + gBattleAnimArgs[3]; + InitSpriteDataForLinearTranslation(sprite); + sprite->data[3] = 0; + sprite->data[4] = 0; + sprite->callback = TranslateSpriteLinearFixedPoint; + StoreSpriteCallbackInData6(sprite, DestroySpriteAndMatrix); +} + +static void sub_80B477C(struct Sprite *sprite) +{ + if (gBattleAnimArgs[6] == 0) + InitSpritePosToAnimAttacker(sprite, 0); + else + InitSpritePosToAnimTarget(sprite, FALSE); + sprite->data[0] = gBattleAnimArgs[3]; + sprite->data[1] = gBattleAnimArgs[2]; + sprite->data[2] = gBattleAnimArgs[4]; + sprite->data[3] = gBattleAnimArgs[5]; + sprite->callback = sub_80B47C4; +} + +static void sub_80B47C4(struct Sprite *sprite) +{ + sprite->data[4] += sprite->data[1]; + sprite->pos2.y = -(sprite->data[4] >> 8); + sprite->pos2.x = Sin(sprite->data[5], sprite->data[3]); + sprite->data[5] = (sprite->data[5] + sprite->data[2]) & 0xFF; + if (--sprite->data[0] == -1) + { + DestroyAnimSprite(sprite); + } +} + +void AnimTask_LoadSandstormBackground(u8 taskId) +{ + s32 var0; + struct BattleAnimBgData animBg; + + var0 = 0; + SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG1 | BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND); + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0, 16)); + SetAnimBgAttribute(1, BG_ANIM_PRIORITY, 1); + SetAnimBgAttribute(1, BG_ANIM_SCREEN_SIZE, 0); + if (!IsContest()) + SetAnimBgAttribute(1, BG_ANIM_CHAR_BASE_BLOCK, 1); + gBattle_BG1_X = 0; + gBattle_BG1_Y = 0; + SetGpuReg(REG_OFFSET_BG1HOFS, gBattle_BG1_X); + SetGpuReg(REG_OFFSET_BG1VOFS, gBattle_BG1_Y); + sub_80752A0(&animBg); + AnimLoadCompressedBgTilemap(animBg.bgId, gFile_graphics_battle_anims_backgrounds_sandstorm_brew_tilemap); + AnimLoadCompressedBgGfx(animBg.bgId, gFile_graphics_battle_anims_backgrounds_sandstorm_brew_sheet, animBg.tilesOffset); + LoadCompressedPalette(gBattleAnimSpritePal_FlyingDirt, animBg.paletteId * 16, 32); + if (IsContest()) + sub_80730C0(animBg.paletteId, animBg.bgTilemap, 0, 0); + if (gBattleAnimArgs[0] && GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) + var0 = 1; + gTasks[taskId].data[0] = var0; + gTasks[taskId].func = sub_80B490C; +} + +static void sub_80B490C(u8 taskId) +{ + struct BattleAnimBgData animBg; + + if (gTasks[taskId].data[0] == 0) + gBattle_BG1_X += -6; + else + gBattle_BG1_X += 6; + gBattle_BG1_Y += -1; + switch (gTasks[taskId].data[12]) + { + case 0: + if (++gTasks[taskId].data[10] == 4) + { + gTasks[taskId].data[10] = 0; + ++gTasks[taskId].data[11]; + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gTasks[taskId].data[11], 16 - gTasks[taskId].data[11])); + if (gTasks[taskId].data[11] == 7) + { + ++gTasks[taskId].data[12]; + gTasks[taskId].data[11] = 0; + } + } + break; + case 1: + if (++gTasks[taskId].data[11] == 101) + { + gTasks[taskId].data[11] = 7; + ++gTasks[taskId].data[12]; + } + break; + case 2: + if (++gTasks[taskId].data[10] == 4) + { + gTasks[taskId].data[10] = 0; + --gTasks[taskId].data[11]; + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gTasks[taskId].data[11], 16 - gTasks[taskId].data[11])); + if (gTasks[taskId].data[11] == 0) + { + ++gTasks[taskId].data[12]; + gTasks[taskId].data[11] = 0; + } + } + break; + case 3: + sub_80752A0(&animBg); + sub_8075358(animBg.bgId); + ++gTasks[taskId].data[12]; + break; + case 4: + if (!IsContest()) + SetAnimBgAttribute(1, BG_ANIM_CHAR_BASE_BLOCK, 0); + gBattle_BG1_X = 0; + gBattle_BG1_Y = 0; + SetGpuReg(REG_OFFSET_BLDCNT, 0); + SetGpuReg(REG_OFFSET_BLDALPHA, 0); + SetAnimBgAttribute(1, BG_ANIM_PRIORITY, 1); + DestroyAnimVisualTask(taskId); + break; + } +} + +// Animates the sprites that fly diagonally across the screen +// in Sandstorm and Heat Wave. +// arg 0: initial y pixel offset +// arg 1: projectile speed +// arg 2: y pixel drop +// arg 3: ??? unknown (possibly a color bit) +static void AnimDirtParticleAcrossScreen(struct Sprite *sprite) +{ + if (sprite->data[0] == 0) + { + if (gBattleAnimArgs[3] != 0 && GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) + { + sprite->pos1.x = 304; + gBattleAnimArgs[1] = -gBattleAnimArgs[1]; + sprite->data[5] = 1; + sprite->oam.matrixNum = ST_OAM_HFLIP; + } + else + { + sprite->pos1.x = -64; + } + sprite->pos1.y = gBattleAnimArgs[0]; + SetSubspriteTables(sprite, gUnknown_83E7470); + sprite->data[1] = gBattleAnimArgs[1]; + sprite->data[2] = gBattleAnimArgs[2]; + ++sprite->data[0]; + } + else + { + sprite->data[3] += sprite->data[1]; + sprite->data[4] += sprite->data[2]; + sprite->pos2.x += (sprite->data[3] >> 8); + sprite->pos2.y += (sprite->data[4] >> 8); + sprite->data[3] &= 0xFF; + sprite->data[4] &= 0xFF; + if (sprite->data[5] == 0) + { + if (sprite->pos1.x + sprite->pos2.x > 272) + { + sprite->callback = DestroyAnimSprite; + } + } + else if (sprite->pos1.x + sprite->pos2.x < -32) + { + sprite->callback = DestroyAnimSprite; + } + } +} + +// Animates the rising rocks in Ancient Power. +// arg 0: initial x pixel offset +// arg 1: initial y pixel offset +// arg 2: terminal y offset +// arg 3: duration +// arg 4: sprite size [1,5] +static void AnimRaiseSprite(struct Sprite *sprite) +{ + StartSpriteAnim(sprite, gBattleAnimArgs[4]); + InitSpritePosToAnimAttacker(sprite, 0); + sprite->data[0] = gBattleAnimArgs[3]; + sprite->data[2] = sprite->pos1.x; + sprite->data[4] = sprite->pos1.y + gBattleAnimArgs[2]; + sprite->callback = StartAnimLinearTranslation; + StoreSpriteCallbackInData6(sprite, DestroyAnimSprite); +} + +void sub_80B4BD0(u8 taskId) +{ + u16 var0, var1, var2, var3; + u8 var4; + s32 var5; + s16 pan1, pan2; + struct Task *task; + + task = &gTasks[taskId]; + var0 = GetBattlerSpriteCoord(gBattleAnimAttacker, 2); + var1 = GetBattlerSpriteCoord(gBattleAnimAttacker, 1) + 24; + var2 = GetBattlerSpriteCoord(gBattleAnimTarget, 2); + var3 = GetBattlerSpriteCoord(gBattleAnimTarget, 1) + 24; + if (BATTLE_PARTNER(gBattleAnimAttacker) == gBattleAnimTarget) + var3 = var1; + var4 = sub_80B4FB8(); + if (var4 == 1) + task->data[8] = 32; + else + task->data[8] = 48 - (var4 * 8); + task->data[0] = 0; + task->data[11] = 0; + task->data[9] = 0; + task->data[12] = 1; + var5 = task->data[8]; + if (var5 < 0) + var5 += 7; + task->data[10] = (var5 >> 3) - 1; + task->data[2] = var0 * 8; + task->data[3] = var1 * 8; + task->data[4] = ((var2 - var0) * 8) / task->data[8]; + task->data[5] = ((var3 - var1) * 8) / task->data[8]; + task->data[6] = 0; + task->data[7] = 0; + pan1 = BattleAnimAdjustPanning(PAN_SIDE_PLAYER); + pan2 = BattleAnimAdjustPanning(PAN_SIDE_OPPONENT); + task->data[13] = pan1; + task->data[14] = (pan2 - pan1) / task->data[8]; + task->data[1] = var4; + task->data[15] = GetAnimBattlerSpriteId(0); + task->func = sub_80B4D00; +} + +static void sub_80B4D00(u8 taskId) +{ + struct Task *task; + + task = &gTasks[taskId]; + switch (task->data[0]) + { + case 0: + task->data[6] -= task->data[4]; + task->data[7] -= task->data[5]; + gSprites[task->data[15]].pos2.x = task->data[6] >> 3; + gSprites[task->data[15]].pos2.y = task->data[7] >> 3; + if (++task->data[9] == 10) + { + task->data[11] = 20; + ++task->data[0]; + } + PlaySE12WithPanning(SE_W029, task->data[13]); + break; + case 1: + if (--task->data[11] == 0) + ++task->data[0]; + break; + case 2: + if (--task->data[9] != 0) + { + task->data[6] += task->data[4]; + task->data[7] += task->data[5]; + } + else + { + task->data[6] = 0; + task->data[7] = 0; + ++task->data[0]; + } + gSprites[task->data[15]].pos2.x = task->data[6] >> 3; + gSprites[task->data[15]].pos2.y = task->data[7] >> 3; + break; + case 3: + task->data[2] += task->data[4]; + task->data[3] += task->data[5]; + if (++task->data[9] >= task->data[10]) + { + task->data[9] = 0; + sub_80B4E70(task); + task->data[13] += task->data[14]; + PlaySE12WithPanning(SE_W091, task->data[13]); + } + if (--task->data[8] == 0) + { + ++task->data[0]; + } + break; + case 4: + if (task->data[11] == 0) + DestroyAnimVisualTask(taskId); + break; + } +} + +static void sub_80B4E70(struct Task *task) +{ + const struct SpriteTemplate *spriteTemplate; + s32 var0; + u16 x, y; + u8 spriteId; + + switch (task->data[1]) + { + case 1: + spriteTemplate = &gUnknown_83E74D8; + var0 = 0; + break; + case 2: + case 3: + spriteTemplate = &gUnknown_83E74F0; + var0 = 80; + break; + case 4: + spriteTemplate = &gUnknown_83E74F0; + var0 = 64; + break; + case 5: + spriteTemplate = &gUnknown_83E74F0; + var0 = 48; + break; + default: + return; + } + x = task->data[2] >> 3; + y = task->data[3] >> 3; + x += (task->data[12] * 4); + spriteId = CreateSprite(spriteTemplate, x, y, 35); + if (spriteId != MAX_SPRITES) + { + gSprites[spriteId].data[0] = 18; + gSprites[spriteId].data[2] = ((task->data[12] * 20) + x) + (task->data[1] * 3); + gSprites[spriteId].data[4] = y; + gSprites[spriteId].data[5] = -16 - (task->data[1] * 2); + gSprites[spriteId].oam.tileNum += var0; + InitAnimArcTranslation(&gSprites[spriteId]); + ++task->data[11]; + } + task->data[12] *= -1; +} + +static void sub_80B4F78(struct Sprite *sprite) +{ + if (TranslateAnimHorizontalArc(sprite)) + { + u8 taskId = FindTaskIdByFunc(sub_80B4D00); + + if (taskId != TASK_NONE) + --gTasks[taskId].data[11]; + DestroySprite(sprite); + } +} + +static u8 sub_80B4FB8(void) +{ + u8 retVal = gAnimDisableStructPtr->rolloutTimerStartValue - gAnimDisableStructPtr->rolloutTimer; + u8 var0 = retVal - 1; + + if (var0 > 4) + retVal = 1; + return retVal; +} + +static void sub_80B4FE4(struct Sprite *sprite) +{ + StartSpriteAnim(sprite, gBattleAnimArgs[4]); + sprite->pos2.x = gBattleAnimArgs[0]; + sprite->data[2] = gBattleAnimArgs[1]; + sprite->data[3] -= gBattleAnimArgs[2]; + sprite->data[0] = 3; + sprite->data[1] = gBattleAnimArgs[3]; + sprite->callback = sub_80B5024; + sprite->invisible = TRUE; +} + +static void sub_80B5024(struct Sprite *sprite) +{ + sprite->invisible = FALSE; + if (sprite->data[3] != 0) + { + sprite->pos2.y = sprite->data[2] + sprite->data[3]; + sprite->data[3] += sprite->data[0]; + ++sprite->data[0]; + if (sprite->data[3] > 0) + { + sprite->data[3] = 0; + } + } + else if (--sprite->data[1] == 0) + { + DestroyAnimSprite(sprite); + } +} + +static void sub_80B5074(struct Sprite *sprite) +{ + if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_OPPONENT) + StartSpriteAffineAnim(sprite, 1); + TranslateAnimSpriteToTargetMonLocation(sprite); +} + +static void sub_80B50A0(struct Sprite *sprite) +{ + sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimTarget, 0); + sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimTarget, 1); + sprite->pos1.x += gBattleAnimArgs[0]; + sprite->pos1.y += gBattleAnimArgs[1]; + sprite->data[1] = gBattleAnimArgs[0]; + sprite->data[2] = gBattleAnimArgs[1]; + sprite->data[5] = gBattleAnimArgs[2]; + StartSpriteAnim(sprite, gBattleAnimArgs[3]); + sprite->callback = sub_80B50F8; +} + +static void sub_80B50F8(struct Sprite *sprite) +{ + sprite->data[0] += 8; + sprite->data[3] += sprite->data[1]; + sprite->data[4] += sprite->data[2]; + sprite->pos2.x += sprite->data[3] / 40; + sprite->pos2.y -= Sin(sprite->data[0], sprite->data[5]); + if (sprite->data[0] > 140) + DestroyAnimSprite(sprite); +} + +void AnimTask_GetSeismicTossDamageLevel(u8 taskId) +{ + if (gAnimMoveDmg < 33) + gBattleAnimArgs[7] = 0; + if ((u32)gAnimMoveDmg - 33 < 33) + gBattleAnimArgs[7] = 1; + if (gAnimMoveDmg > 65) + gBattleAnimArgs[7] = 2; + DestroyAnimVisualTask(taskId); +} + +void sub_80B5188(u8 taskId) +{ + if (gTasks[taskId].data[0] == 0) + { + sub_8075458(0); + gTasks[taskId].data[1] = 200; + } + gBattle_BG3_Y += gTasks[taskId].data[1] / 10; + gTasks[taskId].data[1] -= 3; + if (gTasks[taskId].data[0] == 120) + { + sub_8075458(1); + DestroyAnimVisualTask(taskId); + } + ++gTasks[taskId].data[0]; +} + +void sub_80B51EC(u8 taskId) +{ + if (gTasks[taskId].data[0] == 0) + { + sub_8075458(0); + ++gTasks[taskId].data[0]; + gTasks[taskId].data[2] = gBattle_BG3_Y; + } + gTasks[taskId].data[1] += 80; + gTasks[taskId].data[1] &= 0xFF; + gBattle_BG3_Y = gTasks[taskId].data[2] + Cos(4, gTasks[taskId].data[1]); + if (gBattleAnimArgs[7] == 0xFFF) + { + gBattle_BG3_Y = 0; + sub_8075458(1); + DestroyAnimVisualTask(taskId); + } +} diff --git a/src/save.c b/src/save.c index 9f580477b..45f5fc6f0 100644 --- a/src/save.c +++ b/src/save.c @@ -85,7 +85,7 @@ u16 gSaveUnusedVar; u16 gSaveFileStatus; void (*gGameContinueCallback)(void); struct SaveBlockChunk gRamSaveSectionLocations[0xE]; -u16 gUnknown_3005420; +u16 gSaveSucceeded; EWRAM_DATA struct SaveSection gSaveDataBuffer = {0}; EWRAM_DATA u32 gSaveUnusedVar2 = 0; @@ -702,11 +702,11 @@ u8 TrySavingData(u8 saveType) else goto OK; // really? } - gUnknown_3005420 = 0xFF; + gSaveSucceeded = 0xFF; return 0xFF; OK: - gUnknown_3005420 = 1; + gSaveSucceeded = 1; return 1; } diff --git a/src/scrcmd.c b/src/scrcmd.c index 85059691f..ae994fceb 100644 --- a/src/scrcmd.c +++ b/src/scrcmd.c @@ -1284,14 +1284,14 @@ bool8 ScrCmd_loadhelp(struct ScriptContext *ctx) if (msg == NULL) msg = (const u8 *)ctx->data[0]; - sub_80F7974(msg); + DrawHelpMessageWindowWithText(msg); CopyWindowToVram(GetStartMenuWindowId(), 1); return FALSE; } bool8 ScrCmd_unloadhelp(struct ScriptContext *ctx) { - sub_80F7998(); + DestroyHelpMessageWindow_(); return FALSE; } @@ -1566,7 +1566,7 @@ bool8 ScrCmd_braillemessage(struct ScriptContext *ctx) if (ptr == NULL) ptr = (u8 *)ctx->data[0]; - sub_80F6E9C(); + LoadStdWindowFrameGfx(); DrawDialogueFrame(0, 1); AddTextPrinterParameterized(0, 6, ptr, 0, 1, 0, NULL); return FALSE; diff --git a/src/start_menu.c b/src/start_menu.c new file mode 100644 index 000000000..e3854b803 --- /dev/null +++ b/src/start_menu.c @@ -0,0 +1,1008 @@ +#include "global.h" +#include "palette.h" +#include "bg.h" +#include "gpu_regs.h" +#include "scanline_effect.h" +#include "overworld.h" +#include "link.h" +#include "pokedex.h" +#include "item_menu.h" +#include "party_menu.h" +#include "save.h" +#include "link_rfu.h" +#include "event_data.h" +#include "fieldmap.h" +#include "safari_zone.h" +#include "start_menu.h" +#include "menu.h" +#include "load_save.h" +#include "strings.h" +#include "string_util.h" +#include "menu_helpers.h" +#include "text_window.h" +#include "field_fadetransition.h" +#include "field_player_avatar.h" +#include "new_menu_helpers.h" +#include "map_obj_80688E4.h" +#include "map_obj_lock.h" +#include "script.h" +#include "sound.h" +#include "quest_log.h" +#include "new_game.h" +#include "event_scripts.h" +#include "field_weather.h" +#include "field_specials.h" +#include "pokedex_screen.h" +#include "trainer_card.h" +#include "option_menu.h" +#include "save_menu_util.h" +#include "help_system.h" +#include "constants/songs.h" +#include "constants/flags.h" + +enum StartMenuOption +{ + STARTMENU_POKEDEX = 0, + STARTMENU_POKEMON, + STARTMENU_BAG, + STARTMENU_PLAYER, + STARTMENU_SAVE, + STARTMENU_OPTION, + STARTMENU_EXIT, + STARTMENU_RETIRE, + STARTMENU_PLAYER2, + MAX_STARTMENU_ITEMS +}; + +enum SaveCBReturn +{ + SAVECB_RETURN_CONTINUE = 0, + SAVECB_RETURN_OKAY, + SAVECB_RETURN_CANCEL, + SAVECB_RETURN_ERROR +}; + +static EWRAM_DATA bool8 (*sStartMenuCallback)(void) = NULL; +static EWRAM_DATA u8 sStartMenuCursorPos = 0; +static EWRAM_DATA u8 sNumStartMenuItems = 0; +static EWRAM_DATA u8 sStartMenuOrder[MAX_STARTMENU_ITEMS] = {}; +static EWRAM_DATA s8 sDrawStartMenuState[2] = {}; +static EWRAM_DATA u8 sSafariZoneStatsWindowId = 0; +static ALIGNED(4) EWRAM_DATA u8 sSaveStatsWindowId = 0; + +static u8 (*sSaveDialogCB)(void); +static u8 sSaveDialogDelay; +static bool8 sSaveDialogIsPrinting; + +static void SetUpStartMenu_Link(void); +static void SetUpStartMenu_UnionRoom(void); +static void SetUpStartMenu_SafariZone(void); +static void SetUpStartMenu_NormalField(void); +static bool8 StartCB_HandleInput(void); +static void StartMenu_FadeScreenIfLeavingOverworld(void); +static bool8 StartMenuPokedexSanityCheck(void); +static bool8 StartMenuPokedexCallback(void); +static bool8 StartMenuPokemonCallback(void); +static bool8 StartMenuBagCallback(void); +static bool8 StartMenuPlayerCallback(void); +static bool8 StartMenuSaveCallback(void); +static bool8 StartMenuOptionCallback(void); +static bool8 StartMenuExitCallback(void); +static bool8 StartMenuSafariZoneRetireCallback(void); +static bool8 StartMenuLinkPlayerCallback(void); +static bool8 StartCB_Save1(void); +static bool8 StartCB_Save2(void); +static void StartMenu_PrepareForSave(void); +static u8 RunSaveDialogCB(void); +static void task50_save_game(u8 taskId); +static u8 SaveDialogCB_PrintAskSaveText(void); +static u8 SaveDialogCB_AskSavePrintYesNoMenu(void); +static u8 SaveDialogCB_AskSaveHandleInput(void); +static u8 SaveDialogCB_PrintAskOverwriteText(void); +static u8 SaveDialogCB_AskOverwritePrintYesNoMenu(void); +static u8 SaveDialogCB_AskReplacePreviousFilePrintYesNoMenu(void); +static u8 SaveDialogCB_AskOverwriteOrReplacePreviousFileHandleInput(void); +static u8 SaveDialogCB_PrintSavingDontTurnOffPower(void); +static u8 SaveDialogCB_DoSave(void); +static u8 SaveDialogCB_PrintSaveResult(void); +static u8 SaveDialogCB_WaitPrintSuccessAndPlaySE(void); +static u8 SaveDialogCB_ReturnSuccess(void); +static u8 SaveDialogCB_WaitPrintErrorAndPlaySE(void); +static u8 SaveDialogCB_ReturnError(void); +static void CB2_WhileSavingAfterLinkBattle(void); +static void task50_after_link_battle_save(u8 taskId); +static void PrintSaveStats(void); +static void CloseSaveStatsWindow(void); +static void CloseStartMenu(void); + +static const struct MenuAction sStartMenuActionTable[] = { + { gStartMenuText_Pokedex, {.u8_void = StartMenuPokedexCallback} }, + { gStartMenuText_Pokemon, {.u8_void = StartMenuPokemonCallback} }, + { gStartMenuText_Bag, {.u8_void = StartMenuBagCallback} }, + { gStartMenuText_Player, {.u8_void = StartMenuPlayerCallback} }, + { gStartMenuText_Save, {.u8_void = StartMenuSaveCallback} }, + { gStartMenuText_Option, {.u8_void = StartMenuOptionCallback} }, + { gStartMenuText_Exit, {.u8_void = StartMenuExitCallback} }, + { gStartMenuText_Retire, {.u8_void = StartMenuSafariZoneRetireCallback} }, + { gStartMenuText_Player, {.u8_void = StartMenuLinkPlayerCallback} } +}; + +static const struct WindowTemplate sSafariZoneStatsWindowTemplate = { + .bg = 0, + .tilemapLeft = 1, + .tilemapTop = 1, + .width = 10, + .height = 4, + .paletteNum = 15, + .baseBlock = 0x008 +}; + +static const u8 *const sStartMenuDescPointers[] = { + gStartMenuDesc_Pokedex, + gStartMenuDesc_Pokemon, + gStartMenuDesc_Bag, + gStartMenuDesc_Player, + gStartMenuDesc_Save, + gStartMenuDesc_Option, + gStartMenuDesc_Exit, + gStartMenuDesc_Retire, + gStartMenuDesc_Player +}; + +static const struct BgTemplate sBGTemplates_AfterLinkSaveMessage[] = { + { + .bg = 0, + .charBaseIndex = 2, + .mapBaseIndex = 31, + .screenSize = 0, + .paletteMode = 0, + .priority = 0, + .baseTile = 0x000 + } +}; + +static const struct WindowTemplate sWindowTemplates_AfterLinkSaveMessage[] = { + { + .bg = 0, + .tilemapLeft = 2, + .tilemapTop = 15, + .width = 26, + .height = 4, + .paletteNum = 15, + .baseBlock = 0x198 + }, DUMMY_WIN_TEMPLATE +}; + +static const struct WindowTemplate sSaveStatsWindowTemplate = { + .bg = 0, + .tilemapLeft = 1, + .tilemapTop = 1, + .width = 14, + .height = 9, + .paletteNum = 13, + .baseBlock = 0x008 +}; + +static ALIGNED(2) const u8 sTextColor_StatName[] = { 1, 2, 3 }; +static ALIGNED(2) const u8 sTextColor_StatValue[] = { 1, 4, 5 }; +static ALIGNED(2) const u8 sTextColor_LocationHeader[] = { 1, 6, 7 }; + +static void SetUpStartMenu(void) +{ + sNumStartMenuItems = 0; + if (IsUpdateLinkStateCBActive() == TRUE) + SetUpStartMenu_Link(); + else if (InUnionRoom() == TRUE) + SetUpStartMenu_UnionRoom(); + else if (GetSafariZoneFlag() == TRUE) + SetUpStartMenu_SafariZone(); + else + SetUpStartMenu_NormalField(); +} + +static void AppendToStartMenuItems(u8 newEntry) +{ + AppendToList(sStartMenuOrder, &sNumStartMenuItems, newEntry); +} + +static void SetUpStartMenu_NormalField(void) +{ + if (FlagGet(FLAG_0x829) == TRUE) + AppendToStartMenuItems(STARTMENU_POKEDEX); + if (FlagGet(FLAG_0x828) == TRUE) + AppendToStartMenuItems(STARTMENU_POKEMON); + AppendToStartMenuItems(STARTMENU_BAG); + AppendToStartMenuItems(STARTMENU_PLAYER); + AppendToStartMenuItems(STARTMENU_SAVE); + AppendToStartMenuItems(STARTMENU_OPTION); + AppendToStartMenuItems(STARTMENU_EXIT); +} + +static void SetUpStartMenu_SafariZone(void) +{ + AppendToStartMenuItems(STARTMENU_RETIRE); + AppendToStartMenuItems(STARTMENU_POKEDEX); + AppendToStartMenuItems(STARTMENU_POKEMON); + AppendToStartMenuItems(STARTMENU_BAG); + AppendToStartMenuItems(STARTMENU_PLAYER); + AppendToStartMenuItems(STARTMENU_OPTION); + AppendToStartMenuItems(STARTMENU_EXIT); +} + +static void SetUpStartMenu_Link(void) +{ + AppendToStartMenuItems(STARTMENU_POKEMON); + AppendToStartMenuItems(STARTMENU_BAG); + AppendToStartMenuItems(STARTMENU_PLAYER2); + AppendToStartMenuItems(STARTMENU_OPTION); + AppendToStartMenuItems(STARTMENU_EXIT); +} + +static void SetUpStartMenu_UnionRoom(void) +{ + AppendToStartMenuItems(STARTMENU_POKEMON); + AppendToStartMenuItems(STARTMENU_BAG); + AppendToStartMenuItems(STARTMENU_PLAYER); + AppendToStartMenuItems(STARTMENU_OPTION); + AppendToStartMenuItems(STARTMENU_EXIT); +} + +static void DrawSafariZoneStatsWindow(void) +{ + sSafariZoneStatsWindowId = AddWindow(&sSafariZoneStatsWindowTemplate); + PutWindowTilemap(sSafariZoneStatsWindowId); + DrawStdWindowFrame(sSafariZoneStatsWindowId, FALSE); + ConvertIntToDecimalStringN(gStringVar1, gSafariZoneStepCounter, STR_CONV_MODE_RIGHT_ALIGN, 3); + ConvertIntToDecimalStringN(gStringVar2, 600, STR_CONV_MODE_RIGHT_ALIGN, 3); + ConvertIntToDecimalStringN(gStringVar3, gNumSafariBalls, STR_CONV_MODE_RIGHT_ALIGN, 2); + StringExpandPlaceholders(gStringVar4, gUnknown_84162A9); + AddTextPrinterParameterized(sSafariZoneStatsWindowId,2, gStringVar4, 4, 3, 0xFF, NULL); + CopyWindowToVram(sSafariZoneStatsWindowId, 2); +} + +static void DestroySafariZoneStatsWindow(void) +{ + if (GetSafariZoneFlag()) + { + ClearStdWindowAndFrameToTransparent(sSafariZoneStatsWindowId, FALSE); + CopyWindowToVram(sSafariZoneStatsWindowId, 2); + RemoveWindow(sSafariZoneStatsWindowId); + } +} + +static s8 PrintStartMenuItems(s8 *cursor_p, u8 nitems) +{ + s16 i = *cursor_p; + do + { + if (sStartMenuOrder[i] == STARTMENU_PLAYER || sStartMenuOrder[i] == STARTMENU_PLAYER2) + { + Menu_PrintFormatIntlPlayerName(GetStartMenuWindowId(), sStartMenuActionTable[sStartMenuOrder[i]].text, 8, i * 15); + } + else + { + StringExpandPlaceholders(gStringVar4, sStartMenuActionTable[sStartMenuOrder[i]].text); + AddTextPrinterParameterized(GetStartMenuWindowId(), 2, gStringVar4, 8, i * 15, 0xFF, NULL); + } + i++; + if (i >= sNumStartMenuItems) + { + *cursor_p = i; + return TRUE; + } + } while (--nitems); + *cursor_p = i; + return FALSE; +} + +static s8 DoDrawStartMenu(void) +{ + switch (sDrawStartMenuState[0]) + { + case 0: + sDrawStartMenuState[0]++; + break; + case 1: + SetUpStartMenu(); + sDrawStartMenuState[0]++; + break; + case 2: + LoadStdWindowFrameGfx(); + DrawStdWindowFrame(CreateStartMenuWindow(sNumStartMenuItems), FALSE); + sDrawStartMenuState[0]++; + break; + case 3: + if (GetSafariZoneFlag()) + DrawSafariZoneStatsWindow(); + sDrawStartMenuState[0]++; + break; + case 4: + if (PrintStartMenuItems(&sDrawStartMenuState[1], 2) == TRUE) + sDrawStartMenuState[0]++; + break; + case 5: + sStartMenuCursorPos = Menu_InitCursor(GetStartMenuWindowId(), 2, 0, 0, 15, sNumStartMenuItems, sStartMenuCursorPos); + if (!MenuHelpers_LinkSomething() && InUnionRoom() != TRUE && gSaveBlock2Ptr->optionsButtonMode == OPTIONS_BUTTON_MODE_HELP) + { + DrawHelpMessageWindowWithText(sStartMenuDescPointers[sStartMenuOrder[sStartMenuCursorPos]]); + } + CopyWindowToVram(GetStartMenuWindowId(), 1); + return TRUE; + } + return FALSE; +} + +static void DrawStartMenuInOneGo(void) +{ + sDrawStartMenuState[0] = 0; + sDrawStartMenuState[1] = 0; + while (!DoDrawStartMenu()) + ; +} + +static void task50_startmenu(u8 taskId) +{ + if (DoDrawStartMenu() == TRUE) + SwitchTaskToFollowupFunc(taskId); +} + +static void OpenStartMenuWithFollowupFunc(TaskFunc func) +{ + u8 taskId; + sDrawStartMenuState[0] = 0; + sDrawStartMenuState[1] = 0; + taskId = CreateTask(task50_startmenu, 80); + SetTaskFuncWithFollowupFunc(taskId, task50_startmenu, func); +} + +static bool8 FieldCB2_DrawStartMenu(void) +{ + if (!DoDrawStartMenu()) + return FALSE; + FadeTransition_FadeInOnReturnToStartMenu(); + return TRUE; +} + +void SetUpReturnToStartMenu(void) +{ + sDrawStartMenuState[0] = 0; + sDrawStartMenuState[1] = 0; + gFieldCallback2 = FieldCB2_DrawStartMenu; +} + +void Task_StartMenuHandleInput(u8 taskId) +{ + s16 *data = gTasks[taskId].data; + switch (data[0]) + { + case 0: + if (InUnionRoom() == TRUE) + var_800D_set_xB(); + sStartMenuCallback = StartCB_HandleInput; + data[0]++; + break; + case 1: + if (sStartMenuCallback() == TRUE) + DestroyTask(taskId); + break; + } +} + +void ShowStartMenu(void) +{ + if (!IsUpdateLinkStateCBActive()) + { + player_bitmagic(); + sub_805C270(); + sub_805C780(); + } + OpenStartMenuWithFollowupFunc(Task_StartMenuHandleInput); + ScriptContext2_Enable(); +} + +static bool8 StartCB_HandleInput(void) +{ + if (JOY_NEW(DPAD_UP)) + { + PlaySE(SE_SELECT); + sStartMenuCursorPos = Menu_MoveCursor(-1); + if (!MenuHelpers_LinkSomething() && InUnionRoom() != TRUE && gSaveBlock2Ptr->optionsButtonMode == OPTIONS_BUTTON_MODE_HELP) + { + PrintTextOnHelpMessageWindow(sStartMenuDescPointers[sStartMenuOrder[sStartMenuCursorPos]], 2); + } + } + if (JOY_NEW(DPAD_DOWN)) + { + PlaySE(SE_SELECT); + sStartMenuCursorPos = Menu_MoveCursor(+1); + if (!MenuHelpers_LinkSomething() && InUnionRoom() != TRUE && gSaveBlock2Ptr->optionsButtonMode == OPTIONS_BUTTON_MODE_HELP) + { + PrintTextOnHelpMessageWindow(sStartMenuDescPointers[sStartMenuOrder[sStartMenuCursorPos]], 2); + } + } + if (JOY_NEW(A_BUTTON)) + { + PlaySE(SE_SELECT); + if (!StartMenuPokedexSanityCheck()) + return FALSE; + sStartMenuCallback = sStartMenuActionTable[sStartMenuOrder[sStartMenuCursorPos]].func.u8_void; + StartMenu_FadeScreenIfLeavingOverworld(); + return FALSE; + } + if (JOY_NEW(B_BUTTON | START_BUTTON)) + { + DestroySafariZoneStatsWindow(); + DestroyHelpMessageWindow_(); + CloseStartMenu(); + return TRUE; + } + return FALSE; +} + +static void StartMenu_FadeScreenIfLeavingOverworld(void) +{ + if (sStartMenuCallback != StartMenuSaveCallback + && sStartMenuCallback != StartMenuExitCallback + && sStartMenuCallback != StartMenuSafariZoneRetireCallback) + { + sub_80CCB68(); + fade_screen(1, 0); + } +} + +static bool8 StartMenuPokedexSanityCheck(void) +{ + if (sStartMenuActionTable[sStartMenuOrder[sStartMenuCursorPos]].func.u8_void == StartMenuPokedexCallback && GetNationalPokedexCount(0) == 0) + return FALSE; + return TRUE; +} + +static bool8 StartMenuPokedexCallback(void) +{ + if (!gPaletteFade.active) + { + IncrementGameStat(GAME_STAT_CHECKED_POKEDEX); + PlayRainStoppingSoundEffect(); + DestroySafariZoneStatsWindow(); + CleanupOverworldWindowsAndTilemaps(); + SetMainCallback2(CB2_OpenPokedexFromStartMenu); + return TRUE; + } + return FALSE; +} + +static bool8 StartMenuPokemonCallback(void) +{ + if (!gPaletteFade.active) + { + PlayRainStoppingSoundEffect(); + DestroySafariZoneStatsWindow(); + CleanupOverworldWindowsAndTilemaps(); + SetMainCallback2(CB2_PartyMenuFromStartMenu); + return TRUE; + } + return FALSE; +} + +static bool8 StartMenuBagCallback(void) +{ + if (!gPaletteFade.active) + { + PlayRainStoppingSoundEffect(); + DestroySafariZoneStatsWindow(); + CleanupOverworldWindowsAndTilemaps(); + SetMainCallback2(CB2_BagMenuFromStartMenu); + return TRUE; + } + return FALSE; +} + +static bool8 StartMenuPlayerCallback(void) +{ + if (!gPaletteFade.active) + { + PlayRainStoppingSoundEffect(); + DestroySafariZoneStatsWindow(); + CleanupOverworldWindowsAndTilemaps(); + InitTrainerCard(CB2_ReturnToStartMenu); + return TRUE; + } + return FALSE; +} + +static bool8 StartMenuSaveCallback(void) +{ + sStartMenuCallback = StartCB_Save1; + return FALSE; +} + +static bool8 StartMenuOptionCallback(void) +{ + if (!gPaletteFade.active) + { + PlayRainStoppingSoundEffect(); + DestroySafariZoneStatsWindow(); + CleanupOverworldWindowsAndTilemaps(); + SetMainCallback2(CB2_OptionsMenuFromStartMenu); + gMain.savedCallback = CB2_ReturnToStartMenu; + return TRUE; + } + return FALSE; +} + +static bool8 StartMenuExitCallback(void) +{ + DestroySafariZoneStatsWindow(); + DestroyHelpMessageWindow_(); + CloseStartMenu(); + return TRUE; +} + +static bool8 StartMenuSafariZoneRetireCallback(void) +{ + DestroySafariZoneStatsWindow(); + DestroyHelpMessageWindow_(); + CloseStartMenu(); + SafariZoneRetirePrompt(); + return TRUE; +} + + +static bool8 StartMenuLinkPlayerCallback(void) +{ + if (!gPaletteFade.active) + { + PlayRainStoppingSoundEffect(); + CleanupOverworldWindowsAndTilemaps(); + InitLinkPartnerTrainerCard(gUnknown_300502C, CB2_ReturnToStartMenu); + return TRUE; + } + return FALSE; +} + +static bool8 StartCB_Save1(void) +{ + HelpSystem_BackupSomeVariable(); + HelpSystem_SetSomeVariable2(12); + StartMenu_PrepareForSave(); + sStartMenuCallback = StartCB_Save2; + return FALSE; +} + +static bool8 StartCB_Save2(void) +{ + switch (RunSaveDialogCB()) + { + case SAVECB_RETURN_CONTINUE: + break; + case SAVECB_RETURN_OKAY: + ClearDialogWindowAndFrameToTransparent(0, TRUE); + sub_80696C0(); + ScriptContext2_Disable(); + HelpSystem_RestoreSomeVariable(); + return TRUE; + case SAVECB_RETURN_CANCEL: + ClearDialogWindowAndFrameToTransparent(0, FALSE); + DrawStartMenuInOneGo(); + HelpSystem_RestoreSomeVariable(); + sStartMenuCallback = StartCB_HandleInput; + break; + case SAVECB_RETURN_ERROR: + ClearDialogWindowAndFrameToTransparent(0, TRUE); + sub_80696C0(); + ScriptContext2_Disable(); + HelpSystem_RestoreSomeVariable(); + return TRUE; + } + return FALSE; +} + +static void StartMenu_PrepareForSave(void) +{ + save_serialize_map(); + sSaveDialogCB = SaveDialogCB_PrintAskSaveText; + sSaveDialogIsPrinting = FALSE; +} + +static u8 RunSaveDialogCB(void) +{ + if (RunTextPrinters_CheckPrinter0Active() == TRUE) + return 0; + sSaveDialogIsPrinting = FALSE; + return sSaveDialogCB(); +} + +void Field_AskSaveTheGame(void) +{ + HelpSystem_BackupSomeVariable(); + HelpSystem_SetSomeVariable2(12); + StartMenu_PrepareForSave(); + CreateTask(task50_save_game, 80); +} + +static void PrintSaveTextWithFollowupFunc(const u8 *str, bool8 (*saveDialogCB)(void)) +{ + StringExpandPlaceholders(gStringVar4, str); + sub_80F7768(0, TRUE); + AddTextPrinterForMessage(TRUE); + sSaveDialogIsPrinting = TRUE; + sSaveDialogCB = saveDialogCB; +} + +static void task50_save_game(u8 taskId) +{ + switch (RunSaveDialogCB()) + { + case 0: + return; + case 2: + case 3: + gSpecialVar_Result = FALSE; + break; + case 1: + gSpecialVar_Result = TRUE; + break; + } + DestroyTask(taskId); + EnableBothScriptContexts(); + HelpSystem_RestoreSomeVariable(); +} + +static void CloseSaveMessageWindow(void) +{ + ClearDialogWindowAndFrame(0, TRUE); +} + +static void CloseSaveStatsWindow_(void) +{ + CloseSaveStatsWindow(); +} + +static void SetSaveDialogDelayTo60Frames(void) +{ + sSaveDialogDelay = 60; +} + +static bool8 SaveDialog_Wait60FramesOrAButtonHeld(void) +{ + sSaveDialogDelay--; + if (JOY_HELD(A_BUTTON)) + { + PlaySE(SE_SELECT); + return TRUE; + } + else if (sSaveDialogDelay == 0) + { + return TRUE; + } + else + { + return FALSE; + } +} + +static bool8 SaveDialog_Wait60FramesThenCheckAButtonHeld(void) +{ + if (sSaveDialogDelay == 0) + { + if (JOY_HELD(A_BUTTON)) + { + return TRUE; + } + else + { + return FALSE; + } + } + else + { + sSaveDialogDelay--; + return FALSE; + } +} + +static u8 SaveDialogCB_PrintAskSaveText(void) +{ + ClearStdWindowAndFrame(GetStartMenuWindowId(), FALSE); + RemoveStartMenuWindow(); + DestroyHelpMessageWindow(0); + PrintSaveStats(); + PrintSaveTextWithFollowupFunc(gText_WouldYouLikeToSaveTheGame, SaveDialogCB_AskSavePrintYesNoMenu); + return SAVECB_RETURN_CONTINUE; +} + +static u8 SaveDialogCB_AskSavePrintYesNoMenu(void) +{ + DisplayYesNoMenuDefaultYes(); + sSaveDialogCB = SaveDialogCB_AskSaveHandleInput; + return SAVECB_RETURN_CONTINUE; +} + +static u8 SaveDialogCB_AskSaveHandleInput(void) +{ + switch (Menu_ProcessInputNoWrapClearOnChoose()) + { + case 0: + if ((gSaveFileStatus != SAVE_STATUS_EMPTY && gSaveFileStatus != SAVE_STATUS_INVALID) || !gDifferentSaveFile) + sSaveDialogCB = SaveDialogCB_PrintAskOverwriteText; + else + sSaveDialogCB = SaveDialogCB_PrintSavingDontTurnOffPower; + break; + case 1: + case -1: + CloseSaveStatsWindow_(); + CloseSaveMessageWindow(); + return SAVECB_RETURN_CANCEL; + } + return SAVECB_RETURN_CONTINUE; +} + +static u8 SaveDialogCB_PrintAskOverwriteText(void) +{ + if (gDifferentSaveFile == TRUE) + PrintSaveTextWithFollowupFunc(gText_DifferentGameFile, SaveDialogCB_AskReplacePreviousFilePrintYesNoMenu); + else + PrintSaveTextWithFollowupFunc(gText_AlreadySaveFile_WouldLikeToOverwrite, SaveDialogCB_AskOverwritePrintYesNoMenu); + return SAVECB_RETURN_CONTINUE; +} + +static u8 SaveDialogCB_AskOverwritePrintYesNoMenu(void) +{ + DisplayYesNoMenuDefaultYes(); + sSaveDialogCB = SaveDialogCB_AskOverwriteOrReplacePreviousFileHandleInput; + return SAVECB_RETURN_CONTINUE; +} + +static u8 SaveDialogCB_AskReplacePreviousFilePrintYesNoMenu(void) +{ + DisplayYesNoMenuDefaultNo(); + sSaveDialogCB = SaveDialogCB_AskOverwriteOrReplacePreviousFileHandleInput; + return SAVECB_RETURN_CONTINUE; +} + +static u8 SaveDialogCB_AskOverwriteOrReplacePreviousFileHandleInput(void) +{ + switch (Menu_ProcessInputNoWrapClearOnChoose()) + { + case 0: + sSaveDialogCB = SaveDialogCB_PrintSavingDontTurnOffPower; + break; + case 1: + case -1: + CloseSaveStatsWindow_(); + CloseSaveMessageWindow(); + return SAVECB_RETURN_CANCEL; + } + return SAVECB_RETURN_CONTINUE; +} + +static u8 SaveDialogCB_PrintSavingDontTurnOffPower(void) +{ + sub_8112450(); + PrintSaveTextWithFollowupFunc(gText_SavingDontTurnOffThePower, SaveDialogCB_DoSave); + return SAVECB_RETURN_CONTINUE; +} + +static u8 SaveDialogCB_DoSave(void) +{ + IncrementGameStat(GAME_STAT_SAVED_GAME); + if (gDifferentSaveFile == TRUE) + { + TrySavingData(SAVE_OVERWRITE_DIFFERENT_FILE); + gDifferentSaveFile = FALSE; + } + else + { + TrySavingData(SAVE_NORMAL); + } + sSaveDialogCB = SaveDialogCB_PrintSaveResult; + return SAVECB_RETURN_CONTINUE; +} + +static u8 SaveDialogCB_PrintSaveResult(void) +{ + if (gSaveSucceeded == TRUE) + PrintSaveTextWithFollowupFunc(gText_PlayerSavedTheGame, SaveDialogCB_WaitPrintSuccessAndPlaySE); + else + PrintSaveTextWithFollowupFunc(gText_SaveError_PleaseExchangeBackupMemory, SaveDialogCB_WaitPrintErrorAndPlaySE); + SetSaveDialogDelayTo60Frames(); + return SAVECB_RETURN_CONTINUE; +} + +static u8 SaveDialogCB_WaitPrintSuccessAndPlaySE(void) +{ + if (!RunTextPrinters_CheckPrinter0Active()) + { + PlaySE(SE_SAVE); + sSaveDialogCB = SaveDialogCB_ReturnSuccess; + } + return SAVECB_RETURN_CONTINUE; +} + +static u8 SaveDialogCB_ReturnSuccess(void) +{ + if (!IsSEPlaying() && SaveDialog_Wait60FramesOrAButtonHeld()) + { + CloseSaveStatsWindow_(); + return SAVECB_RETURN_OKAY; + } + return SAVECB_RETURN_CONTINUE; +} + +static u8 SaveDialogCB_WaitPrintErrorAndPlaySE(void) +{ + if (!RunTextPrinters_CheckPrinter0Active()) + { + PlaySE(SE_BOO); + sSaveDialogCB = SaveDialogCB_ReturnError; + } + return SAVECB_RETURN_CONTINUE; +} + +static u8 SaveDialogCB_ReturnError(void) +{ + if (!SaveDialog_Wait60FramesThenCheckAButtonHeld()) + return SAVECB_RETURN_CONTINUE; + CloseSaveStatsWindow_(); + return SAVECB_RETURN_ERROR; +} + +static void VBlankCB_WhileSavingAfterLinkBattle(void) +{ + TransferPlttBuffer(); +} + +bool32 DoSetUpSaveAfterLinkBattle(u8 *state) +{ + switch (*state) + { + case 0: + SetGpuReg(REG_OFFSET_DISPCNT, 0); + SetVBlankCallback(NULL); + ScanlineEffect_Stop(); + DmaFill16Defvars(3, 0, (void *)PLTT, PLTT_SIZE); + DmaFillLarge16(3, 0, (void *)VRAM, VRAM_SIZE, 0x1000); + break; + case 1: + ResetSpriteData(); + ResetTasks(); + ResetPaletteFade(); + ScanlineEffect_Clear(); + break; + case 2: + ResetBgsAndClearDma3BusyFlags(FALSE); + InitBgsFromTemplates(0, sBGTemplates_AfterLinkSaveMessage, NELEMS(sBGTemplates_AfterLinkSaveMessage)); + InitWindows(sWindowTemplates_AfterLinkSaveMessage); + TextWindow_SetStdFrame0_WithPal(0, 0x008, 0xF0); + break; + case 3: + ShowBg(0); + BlendPalettes(0xFFFFFFFF, 16, RGB_BLACK); + SetVBlankCallback(VBlankCB_WhileSavingAfterLinkBattle); + EnableInterrupts(INTR_FLAG_VBLANK); + break; + case 4: + return TRUE; + } + (*state)++; + return FALSE; +} + +void CB2_SetUpSaveAfterLinkBattle(void) +{ + if (DoSetUpSaveAfterLinkBattle(&gMain.state)) + { + CreateTask(task50_after_link_battle_save, 80); + SetMainCallback2(CB2_WhileSavingAfterLinkBattle); + } +} + +static void CB2_WhileSavingAfterLinkBattle(void) +{ + RunTasks(); + UpdatePaletteFade(); +} + +static void task50_after_link_battle_save(u8 taskId) +{ + s16 *data = gTasks[taskId].data; + if (!gPaletteFade.active) + { + switch (data[0]) + { + case 0: + FillWindowPixelBuffer(0, PIXEL_FILL(1)); + AddTextPrinterParameterized2(0, 2, gText_SavingDontTurnOffThePower2, 0xFF, NULL, 2, 1, 3); + DrawTextBorderOuter(0, 0x008, 0x0F); + PutWindowTilemap(0); + CopyWindowToVram(0, 3); + BeginNormalPaletteFade(0xFFFFFFFF, 0, 16, 0, RGB_BLACK); + if (gWirelessCommType != 0 && InUnionRoom()) + data[0] = 5; + else + data[0] = 1; + break; + case 1: + sub_804C1C0(); + sub_80DA45C(); + data[0] = 2; + break; + case 2: + if (sub_80DA4A0()) + { + sav2_gender2_inplace_and_xFE(); + data[0] = 3; + } + break; + case 3: + BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB_BLACK); + data[0] = 4; + break; + case 4: + FreeAllWindowBuffers(); + SetMainCallback2(gMain.savedCallback); + DestroyTask(taskId); + break; + case 5: + CreateTask(sub_80DA634, 5); + data[0] = 6; + break; + case 6: + if (!FuncIsActiveTask(sub_80DA634)) + data[0] = 3; + break; + } + } +} + +static void PrintSaveStats(void) +{ + u8 y; + u8 x; + sSaveStatsWindowId = AddWindow(&sSaveStatsWindowTemplate); + TextWindow_SetStdFrame0_WithPal(sSaveStatsWindowId, 0x21D, 0xD0); + DrawStdFrameWithCustomTileAndPalette(sSaveStatsWindowId, FALSE, 0x21D, 0x0D); + SaveStatToString(SAVE_STAT_LOCATION, gStringVar4, 8); + x = (u32)(112 - GetStringWidth(2, gStringVar4, -1)) / 2; + AddTextPrinterParameterized3(sSaveStatsWindowId, 2, x, 0, sTextColor_LocationHeader, -1, gStringVar4); + x = (u32)(112 - GetStringWidth(2, gStringVar4, -1)) / 2; + AddTextPrinterParameterized3(sSaveStatsWindowId, 0, 2, 14, sTextColor_StatName, -1, gSaveStatName_Player); + SaveStatToString(SAVE_STAT_NAME, gStringVar4, 2); + Menu_PrintFormatIntlPlayerName(sSaveStatsWindowId, gStringVar4, 60, 14); + AddTextPrinterParameterized3(sSaveStatsWindowId, 0, 2, 28, sTextColor_StatName, -1, gSaveStatName_Badges); + SaveStatToString(SAVE_STAT_BADGES, gStringVar4, 2); + AddTextPrinterParameterized3(sSaveStatsWindowId, 0, 60, 28, sTextColor_StatValue, -1, gStringVar4); + y = 42; + if (FlagGet(FLAG_0x829) == TRUE) + { + AddTextPrinterParameterized3(sSaveStatsWindowId, 0, 2, 42, sTextColor_StatName, -1, gSaveStatName_Pokedex); + SaveStatToString(SAVE_STAT_POKEDEX, gStringVar4, 2); + AddTextPrinterParameterized3(sSaveStatsWindowId, 0, 60, 42, sTextColor_StatValue, -1, gStringVar4); + y = 56; + } + AddTextPrinterParameterized3(sSaveStatsWindowId, 0, 2, y, sTextColor_StatName, -1, gSaveStatName_Time); + SaveStatToString(SAVE_STAT_TIME, gStringVar4, 2); + AddTextPrinterParameterized3(sSaveStatsWindowId, 0, 60, y, sTextColor_StatValue, -1, gStringVar4); + CopyWindowToVram(sSaveStatsWindowId, 2); +} + +static void CloseSaveStatsWindow(void) +{ + ClearStdWindowAndFrame(sSaveStatsWindowId, FALSE); + RemoveWindow(sSaveStatsWindowId); +} + +static void CloseStartMenu(void) +{ + PlaySE(SE_SELECT); + ClearStdWindowAndFrame(GetStartMenuWindowId(), TRUE); + RemoveStartMenuWindow(); + sub_80696C0(); + ScriptContext2_Disable(); +} + +void AppendToList(u8 *list, u8 *cursor, u8 newEntry) +{ + list[*cursor] = newEntry; + (*cursor)++; +} diff --git a/src/teachy_tv.c b/src/teachy_tv.c index 18da0997c..aa273073b 100644 --- a/src/teachy_tv.c +++ b/src/teachy_tv.c @@ -510,7 +510,7 @@ static void TeachyTvMainCallback(void) ScheduleBgCopyTilemapToVram(1); ScheduleBgCopyTilemapToVram(2); ScheduleBgCopyTilemapToVram(3); - sub_812B1E0(9); // help system something + HelpSystem_SetSomeVariable(9); // help system something BlendPalettes(0xFFFFFFFF, 0x10, 0); BeginNormalPaletteFade(0xFFFFFFFF, 0, 0x10, 0, 0); SetVBlankCallback(TeachyTvVblankHandler); @@ -736,7 +736,7 @@ static void TeachyTvOptionListController(u8 taskId) { input = ListMenu_ProcessInput(data[0]); ListMenuGetScrollAndRow(data[0], &sStaticResources.scrollOffset, &sStaticResources.selectedRow); - if ((JOY_NEW(SELECT_BUTTON) && sStaticResources.callback != ReturnToBagFromKeyItem)) + if ((JOY_NEW(SELECT_BUTTON) && sStaticResources.callback != CB2_BagMenuFromStartMenu)) { PlaySE(SE_SELECT); TeachyTvQuitBeginFade(taskId); diff --git a/src/trade.c b/src/trade.c index 742650e4a..ee28ff224 100644 --- a/src/trade.c +++ b/src/trade.c @@ -137,6 +137,7 @@ void sub_804C718(void) SetMainCallback2(sub_804C728); } +#ifdef NONMATCHING void sub_804C728(void) { int i; @@ -319,6 +320,10 @@ void sub_804C728(void) CreateSprite(&temp, xPos + gTradeUnknownSpriteCoords[LANGUAGE_ENGLISH - 1][0] + (i * 32), gTradeUnknownSpriteCoords[LANGUAGE_ENGLISH - 1][1], 1); } + /* + * These three lines are a pain to match due to register alloc and + * pointer arithmetic misbehavior. + */ id = GetMultiplayerId(); id ^= 1; width = GetStringWidth(1, gLinkPlayers[id].name, 0); @@ -406,3 +411,915 @@ void sub_804C728(void) BuildOamBuffer(); UpdatePaletteFade(); } +#else +NAKED +void sub_804C728(void) +{ + asm_unified("\tpush {r4-r7,lr}\n" + "\tmov r7, r8\n" + "\tpush {r7}\n" + "\tsub sp, 0x28\n" + "\tldr r1, _0804C74C @ =gMain\n" + "\tmovs r2, 0x87\n" + "\tlsls r2, 3\n" + "\tadds r0, r1, r2\n" + "\tldrb r0, [r0]\n" + "\tadds r3, r1, 0\n" + "\tcmp r0, 0x16\n" + "\tbls _0804C742\n" + "\tb _0804CEE6\n" + "_0804C742:\n" + "\tlsls r0, 2\n" + "\tldr r1, _0804C750 @ =_0804C754\n" + "\tadds r0, r1\n" + "\tldr r0, [r0]\n" + "\tmov pc, r0\n" + "\t.align 2, 0\n" + "_0804C74C: .4byte gMain\n" + "_0804C750: .4byte _0804C754\n" + "\t.align 2, 0\n" + "_0804C754:\n" + "\t.4byte _0804C7B0\n" + "\t.4byte _0804C7FC\n" + "\t.4byte _0804C8C8\n" + "\t.4byte _0804C8F4\n" + "\t.4byte _0804C950\n" + "\t.4byte _0804C9B0\n" + "\t.4byte _0804C9F0\n" + "\t.4byte _0804CA10\n" + "\t.4byte _0804CB50\n" + "\t.4byte _0804CB78\n" + "\t.4byte _0804CB9C\n" + "\t.4byte _0804CC30\n" + "\t.4byte _0804CC3E\n" + "\t.4byte _0804CD10\n" + "\t.4byte _0804CDE0\n" + "\t.4byte _0804CE20\n" + "\t.4byte _0804CE3A\n" + "\t.4byte _0804CE48\n" + "\t.4byte _0804CE5C\n" + "\t.4byte _0804CE7C\n" + "\t.4byte _0804CE9C\n" + "\t.4byte _0804CEB0\n" + "\t.4byte _0804CED0\n" + "_0804C7B0:\n" + "\tldr r4, _0804C7E8 @ =gUnknown_2031DA8\n" + "\tldr r0, _0804C7EC @ =0x000010f0\n" + "\tbl AllocZeroed\n" + "\tstr r0, [r4]\n" + "\tbl sub_804C600\n" + "\tldr r4, _0804C7F0 @ =gUnknown_2031C90\n" + "\tmovs r0, 0xE0\n" + "\tlsls r0, 4\n" + "\tbl AllocZeroed\n" + "\tstr r0, [r4]\n" + "\tmovs r6, 0\n" + "\tldr r2, _0804C7F4 @ =gUnknown_2031C94\n" + "_0804C7CE:\n" + "\tlsls r1, r6, 8\n" + "\tldr r0, [r4]\n" + "\tadds r0, r1\n" + "\tstm r2!, {r0}\n" + "\tadds r6, 0x1\n" + "\tcmp r6, 0xD\n" + "\tble _0804C7CE\n" + "\tldr r1, _0804C7F8 @ =gMain\n" + "\tmovs r3, 0x87\n" + "\tlsls r3, 3\n" + "\tadds r1, r3\n" + "\tb _0804CEC2\n" + "\t.align 2, 0\n" + "_0804C7E8: .4byte gUnknown_2031DA8\n" + "_0804C7EC: .4byte 0x000010f0\n" + "_0804C7F0: .4byte gUnknown_2031C90\n" + "_0804C7F4: .4byte gUnknown_2031C94\n" + "_0804C7F8: .4byte gMain\n" + "_0804C7FC:\n" + "\tldr r2, _0804C864 @ =gPaletteFade\n" + "\tldrb r1, [r2, 0x8]\n" + "\tmovs r0, 0x7F\n" + "\tands r0, r1\n" + "\tstrb r0, [r2, 0x8]\n" + "\tmovs r6, 0\n" + "\tmovs r4, 0\n" + "_0804C80A:\n" + "\tmovs r0, 0x64\n" + "\tmuls r0, r6\n" + "\tldr r1, _0804C868 @ =gEnemyParty\n" + "\tadds r0, r1\n" + "\tstr r4, [sp]\n" + "\tstr r4, [sp, 0x4]\n" + "\tstr r4, [sp, 0x8]\n" + "\tstr r4, [sp, 0xC]\n" + "\tmovs r1, 0\n" + "\tmovs r2, 0\n" + "\tmovs r3, 0x20\n" + "\tbl CreateMon\n" + "\tadds r6, 0x1\n" + "\tcmp r6, 0x5\n" + "\tble _0804C80A\n" + "\tmovs r0, 0\n" + "\tbl sub_804F5BC\n" + "\tmovs r0, 0\n" + "\tbl ShowBg\n" + "\tldr r0, _0804C86C @ =gReceivedRemoteLinkPlayers\n" + "\tldrb r2, [r0]\n" + "\tcmp r2, 0\n" + "\tbne _0804C8B4\n" + "\tldr r1, _0804C870 @ =gLinkType\n" + "\tldr r5, _0804C874 @ =0x00001122\n" + "\tadds r0, r5, 0\n" + "\tstrh r0, [r1]\n" + "\tldr r0, _0804C878 @ =gUnknown_2031DA8\n" + "\tldr r0, [r0]\n" + "\tadds r0, 0xA8\n" + "\tstrb r2, [r0]\n" + "\tldr r0, _0804C87C @ =gWirelessCommType\n" + "\tldrb r0, [r0]\n" + "\tcmp r0, 0\n" + "\tbeq _0804C880\n" + "\tbl sub_800B1F4\n" + "\tbl OpenLink\n" + "\tbl sub_80FBB20\n" + "\tb _0804C892\n" + "\t.align 2, 0\n" + "_0804C864: .4byte gPaletteFade\n" + "_0804C868: .4byte gEnemyParty\n" + "_0804C86C: .4byte gReceivedRemoteLinkPlayers\n" + "_0804C870: .4byte gLinkType\n" + "_0804C874: .4byte 0x00001122\n" + "_0804C878: .4byte gUnknown_2031DA8\n" + "_0804C87C: .4byte gWirelessCommType\n" + "_0804C880:\n" + "\tbl OpenLink\n" + "\tldr r1, _0804C8A8 @ =gMain\n" + "\tmovs r7, 0x87\n" + "\tlsls r7, 3\n" + "\tadds r1, r7\n" + "\tldrb r0, [r1]\n" + "\tadds r0, 0x1\n" + "\tstrb r0, [r1]\n" + "_0804C892:\n" + "\tldr r0, _0804C8AC @ =gWirelessCommType\n" + "\tldrb r0, [r0]\n" + "\tcmp r0, 0\n" + "\tbeq _0804C89C\n" + "\tb _0804CEE6\n" + "_0804C89C:\n" + "\tldr r0, _0804C8B0 @ =sub_8081A90\n" + "\tmovs r1, 0x1\n" + "\tbl CreateTask\n" + "\tb _0804CEE6\n" + "\t.align 2, 0\n" + "_0804C8A8: .4byte gMain\n" + "_0804C8AC: .4byte gWirelessCommType\n" + "_0804C8B0: .4byte sub_8081A90\n" + "_0804C8B4:\n" + "\tldr r0, _0804C8C4 @ =gMain\n" + "\tmovs r1, 0x87\n" + "\tlsls r1, 3\n" + "\tadds r0, r1\n" + "\tmovs r1, 0x4\n" + "\tstrb r1, [r0]\n" + "\tb _0804CEE6\n" + "\t.align 2, 0\n" + "_0804C8C4: .4byte gMain\n" + "_0804C8C8:\n" + "\tldr r2, _0804C8F0 @ =gUnknown_2031DA8\n" + "\tldr r1, [r2]\n" + "\tadds r1, 0xA8\n" + "\tldrb r0, [r1]\n" + "\tadds r0, 0x1\n" + "\tstrb r0, [r1]\n" + "\tldr r0, [r2]\n" + "\tadds r1, r0, 0\n" + "\tadds r1, 0xA8\n" + "\tldrb r0, [r1]\n" + "\tcmp r0, 0xB\n" + "\tbhi _0804C8E2\n" + "\tb _0804CEE6\n" + "_0804C8E2:\n" + "\tmovs r0, 0\n" + "\tstrb r0, [r1]\n" + "\tmovs r2, 0x87\n" + "\tlsls r2, 3\n" + "\tadds r1, r3, r2\n" + "\tb _0804CEC2\n" + "\t.align 2, 0\n" + "_0804C8F0: .4byte gUnknown_2031DA8\n" + "_0804C8F4:\n" + "\tbl GetLinkPlayerCount_2\n" + "\tadds r4, r0, 0\n" + "\tbl GetSavedPlayerCount\n" + "\tlsls r4, 24\n" + "\tlsls r0, 24\n" + "\tcmp r4, r0\n" + "\tbcs _0804C908\n" + "\tb _0804CEE6\n" + "_0804C908:\n" + "\tbl IsLinkMaster\n" + "\tlsls r0, 24\n" + "\tcmp r0, 0\n" + "\tbeq _0804C940\n" + "\tldr r0, _0804C938 @ =gUnknown_2031DA8\n" + "\tldr r1, [r0]\n" + "\tadds r1, 0xA8\n" + "\tldrb r0, [r1]\n" + "\tadds r0, 0x1\n" + "\tstrb r0, [r1]\n" + "\tlsls r0, 24\n" + "\tlsrs r0, 24\n" + "\tcmp r0, 0x1E\n" + "\tbhi _0804C928\n" + "\tb _0804CEE6\n" + "_0804C928:\n" + "\tbl CheckShouldAdvanceLinkState\n" + "\tldr r1, _0804C93C @ =gMain\n" + "\tmovs r3, 0x87\n" + "\tlsls r3, 3\n" + "\tadds r1, r3\n" + "\tb _0804CEC2\n" + "\t.align 2, 0\n" + "_0804C938: .4byte gUnknown_2031DA8\n" + "_0804C93C: .4byte gMain\n" + "_0804C940:\n" + "\tldr r1, _0804C94C @ =gMain\n" + "\tmovs r5, 0x87\n" + "\tlsls r5, 3\n" + "\tadds r1, r5\n" + "\tb _0804CEC2\n" + "\t.align 2, 0\n" + "_0804C94C: .4byte gMain\n" + "_0804C950:\n" + "\tldr r0, _0804C9A0 @ =gReceivedRemoteLinkPlayers\n" + "\tldrb r0, [r0]\n" + "\tcmp r0, 0x1\n" + "\tbeq _0804C95A\n" + "\tb _0804CEE6\n" + "_0804C95A:\n" + "\tbl IsLinkPlayerDataExchangeComplete\n" + "\tlsls r0, 24\n" + "\tlsrs r0, 24\n" + "\tcmp r0, 0x1\n" + "\tbeq _0804C968\n" + "\tb _0804CEE6\n" + "_0804C968:\n" + "\tbl sub_80FBB4C\n" + "\tbl CalculatePlayerPartyCount\n" + "\tldr r1, _0804C9A4 @ =gMain\n" + "\tmovs r7, 0x87\n" + "\tlsls r7, 3\n" + "\tadds r1, r7\n" + "\tldrb r0, [r1]\n" + "\tadds r0, 0x1\n" + "\tmovs r2, 0\n" + "\tstrb r0, [r1]\n" + "\tldr r0, _0804C9A8 @ =gUnknown_2031DA8\n" + "\tldr r0, [r0]\n" + "\tadds r0, 0xA8\n" + "\tstrb r2, [r0]\n" + "\tldr r0, _0804C9AC @ =gWirelessCommType\n" + "\tldrb r0, [r0]\n" + "\tcmp r0, 0\n" + "\tbne _0804C992\n" + "\tb _0804CEE6\n" + "_0804C992:\n" + "\tmovs r0, 0x1\n" + "\tbl sub_80FA484\n" + "\tbl sub_800AB9C\n" + "\tb _0804CEE6\n" + "\t.align 2, 0\n" + "_0804C9A0: .4byte gReceivedRemoteLinkPlayers\n" + "_0804C9A4: .4byte gMain\n" + "_0804C9A8: .4byte gUnknown_2031DA8\n" + "_0804C9AC: .4byte gWirelessCommType\n" + "_0804C9B0:\n" + "\tldr r0, _0804C9E0 @ =gWirelessCommType\n" + "\tldrb r0, [r0]\n" + "\tcmp r0, 0\n" + "\tbeq _0804C9E8\n" + "\tbl IsRfuTaskFinished\n" + "\tlsls r0, 24\n" + "\tcmp r0, 0\n" + "\tbne _0804C9C4\n" + "\tb _0804CEE6\n" + "_0804C9C4:\n" + "\tldr r1, _0804C9E4 @ =gMain\n" + "\tmovs r0, 0x87\n" + "\tlsls r0, 3\n" + "\tadds r1, r0\n" + "\tldrb r0, [r1]\n" + "\tadds r0, 0x1\n" + "\tstrb r0, [r1]\n" + "\tbl LoadWirelessStatusIndicatorSpriteGfx\n" + "\tmovs r0, 0\n" + "\tmovs r1, 0\n" + "\tbl CreateWirelessStatusIndicatorSprite\n" + "\tb _0804CEE6\n" + "\t.align 2, 0\n" + "_0804C9E0: .4byte gWirelessCommType\n" + "_0804C9E4: .4byte gMain\n" + "_0804C9E8:\n" + "\tmovs r2, 0x87\n" + "\tlsls r2, 3\n" + "\tadds r1, r3, r2\n" + "\tb _0804CEC2\n" + "_0804C9F0:\n" + "\tbl shedinja_maker_maybe\n" + "\tlsls r0, 24\n" + "\tcmp r0, 0\n" + "\tbne _0804C9FC\n" + "\tb _0804CEE6\n" + "_0804C9FC:\n" + "\tbl sub_804F9D8\n" + "\tldr r1, _0804CA0C @ =gMain\n" + "\tmovs r3, 0x87\n" + "\tlsls r3, 3\n" + "\tadds r1, r3\n" + "\tb _0804CEC2\n" + "\t.align 2, 0\n" + "_0804CA0C: .4byte gMain\n" + "_0804CA10:\n" + "\tbl CalculateEnemyPartyCount\n" + "\tmovs r0, 0\n" + "\tmovs r1, 0\n" + "\tbl SetGpuReg\n" + "\tmovs r0, 0x50\n" + "\tmovs r1, 0\n" + "\tbl SetGpuReg\n" + "\tldr r2, _0804CB2C @ =gUnknown_2031DA8\n" + "\tldr r0, [r2]\n" + "\tldr r1, _0804CB30 @ =gPlayerPartyCount\n" + "\tldrb r1, [r1]\n" + "\tadds r0, 0x36\n" + "\tstrb r1, [r0]\n" + "\tldr r0, [r2]\n" + "\tldr r1, _0804CB34 @ =gEnemyPartyCount\n" + "\tldrb r1, [r1]\n" + "\tadds r0, 0x37\n" + "\tstrb r1, [r0]\n" + "\tmovs r6, 0\n" + "\tldr r0, [r2]\n" + "\tadds r0, 0x36\n" + "\tldrb r0, [r0]\n" + "\tcmp r6, r0\n" + "\tbge _0804CAA8\n" + "\tmov r8, r2\n" + "\tldr r7, _0804CB38 @ =gTradeMonSpriteCoords\n" + "_0804CA4A:\n" + "\tmovs r0, 0x64\n" + "\tadds r4, r6, 0\n" + "\tmuls r4, r0\n" + "\tldr r0, _0804CB3C @ =gPlayerParty\n" + "\tadds r4, r0\n" + "\tadds r0, r4, 0\n" + "\tmovs r1, 0x41\n" + "\tbl GetMonData\n" + "\tadds r5, r0, 0\n" + "\tlsls r5, 16\n" + "\tlsrs r5, 16\n" + "\tadds r0, r4, 0\n" + "\tmovs r1, 0\n" + "\tbl GetMonData\n" + "\tldrb r2, [r7]\n" + "\tlsls r2, 19\n" + "\tmovs r1, 0xE0\n" + "\tlsls r1, 12\n" + "\tadds r2, r1\n" + "\tasrs r2, 16\n" + "\tldrb r3, [r7, 0x1]\n" + "\tlsls r3, 19\n" + "\tldr r1, _0804CB40 @ =0xfff40000\n" + "\tadds r3, r1\n" + "\tasrs r3, 16\n" + "\tmovs r1, 0x1\n" + "\tstr r1, [sp]\n" + "\tstr r0, [sp, 0x4]\n" + "\tstr r1, [sp, 0x8]\n" + "\tadds r0, r5, 0\n" + "\tldr r1, _0804CB44 @ =sub_809718C\n" + "\tbl CreateMonIcon\n" + "\tmov r2, r8\n" + "\tldr r1, [r2]\n" + "\tadds r1, 0x28\n" + "\tadds r1, r6\n" + "\tstrb r0, [r1]\n" + "\tadds r7, 0x2\n" + "\tadds r6, 0x1\n" + "\tldr r0, [r2]\n" + "\tadds r0, 0x36\n" + "\tldrb r0, [r0]\n" + "\tcmp r6, r0\n" + "\tblt _0804CA4A\n" + "_0804CAA8:\n" + "\tmovs r6, 0\n" + "\tldr r1, _0804CB2C @ =gUnknown_2031DA8\n" + "\tldr r0, [r1]\n" + "\tadds r0, 0x37\n" + "\tldrb r0, [r0]\n" + "\tcmp r6, r0\n" + "\tbge _0804CB20\n" + "\tldr r0, _0804CB38 @ =gTradeMonSpriteCoords\n" + "\tmov r8, r1\n" + "\tadds r7, r0, 0\n" + "\tadds r7, 0xC\n" + "_0804CABE:\n" + "\tmovs r0, 0x64\n" + "\tadds r4, r6, 0\n" + "\tmuls r4, r0\n" + "\tldr r0, _0804CB48 @ =gEnemyParty\n" + "\tadds r4, r0\n" + "\tadds r0, r4, 0\n" + "\tmovs r1, 0x41\n" + "\tmovs r2, 0\n" + "\tbl GetMonData\n" + "\tadds r5, r0, 0\n" + "\tlsls r5, 16\n" + "\tlsrs r5, 16\n" + "\tadds r0, r4, 0\n" + "\tmovs r1, 0\n" + "\tbl GetMonData\n" + "\tldrb r2, [r7]\n" + "\tlsls r2, 19\n" + "\tmovs r3, 0xE0\n" + "\tlsls r3, 12\n" + "\tadds r2, r3\n" + "\tasrs r2, 16\n" + "\tldrb r3, [r7, 0x1]\n" + "\tlsls r3, 19\n" + "\tldr r1, _0804CB40 @ =0xfff40000\n" + "\tadds r3, r1\n" + "\tasrs r3, 16\n" + "\tmovs r1, 0x1\n" + "\tstr r1, [sp]\n" + "\tstr r0, [sp, 0x4]\n" + "\tmovs r0, 0\n" + "\tstr r0, [sp, 0x8]\n" + "\tadds r0, r5, 0\n" + "\tldr r1, _0804CB44 @ =sub_809718C\n" + "\tbl CreateMonIcon\n" + "\tmov r2, r8\n" + "\tldr r1, [r2]\n" + "\tadds r1, 0x2E\n" + "\tadds r1, r6\n" + "\tstrb r0, [r1]\n" + "\tadds r7, 0x2\n" + "\tadds r6, 0x1\n" + "\tldr r0, [r2]\n" + "\tadds r0, 0x37\n" + "\tldrb r0, [r0]\n" + "\tcmp r6, r0\n" + "\tblt _0804CABE\n" + "_0804CB20:\n" + "\tldr r1, _0804CB4C @ =gMain\n" + "\tmovs r3, 0x87\n" + "\tlsls r3, 3\n" + "\tadds r1, r3\n" + "\tb _0804CEC2\n" + "\t.align 2, 0\n" + "_0804CB2C: .4byte gUnknown_2031DA8\n" + "_0804CB30: .4byte gPlayerPartyCount\n" + "_0804CB34: .4byte gEnemyPartyCount\n" + "_0804CB38: .4byte gTradeMonSpriteCoords\n" + "_0804CB3C: .4byte gPlayerParty\n" + "_0804CB40: .4byte 0xfff40000\n" + "_0804CB44: .4byte sub_809718C\n" + "_0804CB48: .4byte gEnemyParty\n" + "_0804CB4C: .4byte gMain\n" + "_0804CB50:\n" + "\tbl LoadHeldItemIcons\n" + "\tldr r0, _0804CB70 @ =gUnknown_2031DA8\n" + "\tldr r1, [r0]\n" + "\tadds r0, r1, 0\n" + "\tadds r0, 0x36\n" + "\tadds r1, 0x28\n" + "\tmovs r2, 0\n" + "\tbl sub_812256C\n" + "\tldr r1, _0804CB74 @ =gMain\n" + "\tmovs r5, 0x87\n" + "\tlsls r5, 3\n" + "\tadds r1, r5\n" + "\tb _0804CEC2\n" + "\t.align 2, 0\n" + "_0804CB70: .4byte gUnknown_2031DA8\n" + "_0804CB74: .4byte gMain\n" + "_0804CB78:\n" + "\tldr r0, _0804CB94 @ =gUnknown_2031DA8\n" + "\tldr r1, [r0]\n" + "\tadds r0, r1, 0\n" + "\tadds r0, 0x36\n" + "\tadds r1, 0x28\n" + "\tmovs r2, 0x1\n" + "\tbl sub_812256C\n" + "\tldr r1, _0804CB98 @ =gMain\n" + "\tmovs r7, 0x87\n" + "\tlsls r7, 3\n" + "\tadds r1, r7\n" + "\tb _0804CEC2\n" + "\t.align 2, 0\n" + "_0804CB94: .4byte gUnknown_2031DA8\n" + "_0804CB98: .4byte gMain\n" + "_0804CB9C:\n" + "\tldr r0, _0804CC14 @ =gSaveBlock2Ptr\n" + "\tldr r0, [r0]\n" + "\tldr r6, _0804CC18 @ =gUnknown_2031C94\n" + "\tldr r1, [r6]\n" + "\tldr r5, _0804CC1C @ =gDecompressionBuffer\n" + "\tstr r5, [sp]\n" + "\tmovs r4, 0x3\n" + "\tstr r4, [sp, 0x4]\n" + "\tmovs r2, 0\n" + "\tmovs r3, 0\n" + "\tbl sub_808BEB4\n" + "\tbl GetMultiplayerId\n" + "\tlsls r0, 24\n" + "\tmovs r1, 0x80\n" + "\tlsls r1, 17\n" + "\teors r1, r0\n" + "\tlsrs r1, 24\n" + "\tlsls r0, r1, 3\n" + "\tsubs r0, r1\n" + "\tlsls r0, 2\n" + "\tldr r1, _0804CC20 @ =gLinkPlayers + 8\n" + "\tadds r0, r1\n" + "\tldr r1, [r6, 0xC]\n" + "\tstr r5, [sp]\n" + "\tstr r4, [sp, 0x4]\n" + "\tmovs r2, 0\n" + "\tmovs r3, 0\n" + "\tbl sub_808BEB4\n" + "\tldr r4, _0804CC24 @ =gUnknown_8261ECC\n" + "\tldr r0, [r4]\n" + "\tldr r1, [r6, 0x18]\n" + "\tstr r5, [sp]\n" + "\tmovs r2, 0x2\n" + "\tstr r2, [sp, 0x4]\n" + "\tmovs r2, 0\n" + "\tmovs r3, 0\n" + "\tbl sub_808BEB4\n" + "\tldr r0, [r4, 0x4]\n" + "\tldr r1, [r6, 0x20]\n" + "\tmovs r2, 0x18\n" + "\tbl sub_804F728\n" + "\tldr r1, _0804CC28 @ =gMain\n" + "\tmovs r0, 0x87\n" + "\tlsls r0, 3\n" + "\tadds r1, r0\n" + "\tldrb r0, [r1]\n" + "\tadds r0, 0x1\n" + "\tmovs r2, 0\n" + "\tstrb r0, [r1]\n" + "\tldr r0, _0804CC2C @ =gUnknown_2031DA8\n" + "\tldr r0, [r0]\n" + "\tadds r0, 0xA8\n" + "\tstrb r2, [r0]\n" + "\tb _0804CEE6\n" + "\t.align 2, 0\n" + "_0804CC14: .4byte gSaveBlock2Ptr\n" + "_0804CC18: .4byte gUnknown_2031C94\n" + "_0804CC1C: .4byte gDecompressionBuffer\n" + "_0804CC20: .4byte gLinkPlayers + 8\n" + "_0804CC24: .4byte gUnknown_8261ECC\n" + "_0804CC28: .4byte gMain\n" + "_0804CC2C: .4byte gUnknown_2031DA8\n" + "_0804CC30:\n" + "\tbl sub_804F610\n" + "\tlsls r0, 24\n" + "\tcmp r0, 0\n" + "\tbne _0804CC3C\n" + "\tb _0804CEE6\n" + "_0804CC3C:\n" + "\tb _0804CEBA\n" + "_0804CC3E:\n" + "\tldr r0, _0804CCFC @ =gSaveBlock2Ptr\n" + "\tldr r1, [r0]\n" + "\tmovs r0, 0x1\n" + "\tmovs r2, 0\n" + "\tbl GetStringWidth\n" + "\tadds r1, r0, 0\n" + "\tmovs r0, 0x38\n" + "\tsubs r0, r1\n" + "\tlsrs r1, r0, 31\n" + "\tadds r0, r1\n" + "\tmovs r6, 0\n" + "\tadd r5, sp, 0x10\n" + "\tldr r3, _0804CD00 @ =gTradeUnknownSpriteCoords\n" + "\tmov r8, r3\n" + "\tasrs r0, 1\n" + "\tldrb r7, [r3, 0x4]\n" + "\tadds r4, r0, r7\n" + "_0804CC62:\n" + "\tadd r1, sp, 0x10\n" + "\tldr r0, _0804CD04 @ =gUnknown_8261CC8\n" + "\tldm r0!, {r2,r3,r7}\n" + "\tstm r1!, {r2,r3,r7}\n" + "\tldm r0!, {r2,r3,r7}\n" + "\tstm r1!, {r2,r3,r7}\n" + "\tldrh r0, [r5]\n" + "\tadds r0, r6\n" + "\tstrh r0, [r5]\n" + "\tlsls r1, r4, 16\n" + "\tasrs r1, 16\n" + "\tadd r0, sp, 0x10\n" + "\tmov r3, r8\n" + "\tldrb r2, [r3, 0x5]\n" + "\tmovs r3, 0x1\n" + "\tbl CreateSprite\n" + "\tadds r4, 0x20\n" + "\tadds r6, 0x1\n" + "\tcmp r6, 0x2\n" + "\tble _0804CC62\n" + "\tbl GetMultiplayerId\n" + "\tlsls r0, 24\n" + "\tmovs r1, 0x80\n" + "\tlsls r1, 17\n" + "\teors r1, r0\n" + "\tlsrs r1, 24\n" + "\tlsls r0, r1, 3\n" + "\tsubs r0, r1\n" + "\tlsls r0, 2\n" + "\tldr r1, _0804CD08 @ =gLinkPlayers + 8\n" + "\tadds r1, r0, r1\n" + "\tmovs r0, 0x1\n" + "\tmovs r2, 0\n" + "\tbl GetStringWidth\n" + "\tadds r1, r0, 0\n" + "\tmovs r0, 0x38\n" + "\tsubs r0, r1\n" + "\tlsrs r1, r0, 31\n" + "\tadds r0, r1\n" + "\tmovs r6, 0\n" + "\tadd r5, sp, 0x10\n" + "\tldr r7, _0804CD00 @ =gTradeUnknownSpriteCoords\n" + "\tmov r8, r7\n" + "\tasrs r0, 1\n" + "\tmov r1, r8\n" + "\tldrb r1, [r1, 0x6]\n" + "\tadds r4, r0, r1\n" + "_0804CCC6:\n" + "\tadd r1, sp, 0x10\n" + "\tldr r0, _0804CD04 @ =gUnknown_8261CC8\n" + "\tldm r0!, {r2,r3,r7}\n" + "\tstm r1!, {r2,r3,r7}\n" + "\tldm r0!, {r2,r3,r7}\n" + "\tstm r1!, {r2,r3,r7}\n" + "\tadds r0, r6, 0x3\n" + "\tldrh r1, [r5]\n" + "\tadds r0, r1\n" + "\tstrh r0, [r5]\n" + "\tlsls r1, r4, 16\n" + "\tasrs r1, 16\n" + "\tadd r0, sp, 0x10\n" + "\tmov r3, r8\n" + "\tldrb r2, [r3, 0x7]\n" + "\tmovs r3, 0x1\n" + "\tbl CreateSprite\n" + "\tadds r4, 0x20\n" + "\tadds r6, 0x1\n" + "\tcmp r6, 0x2\n" + "\tble _0804CCC6\n" + "\tldr r1, _0804CD0C @ =gMain\n" + "\tmovs r5, 0x87\n" + "\tlsls r5, 3\n" + "\tadds r1, r5\n" + "\tb _0804CEC2\n" + "\t.align 2, 0\n" + "_0804CCFC: .4byte gSaveBlock2Ptr\n" + "_0804CD00: .4byte gTradeUnknownSpriteCoords\n" + "_0804CD04: .4byte gUnknown_8261CC8\n" + "_0804CD08: .4byte gLinkPlayers + 8\n" + "_0804CD0C: .4byte gMain\n" + "_0804CD10:\n" + "\tldr r4, _0804CDCC @ =gUnknown_8261CC8\n" + "\tadd r1, sp, 0x10\n" + "\tadds r0, r4, 0\n" + "\tldm r0!, {r2,r3,r7}\n" + "\tstm r1!, {r2,r3,r7}\n" + "\tldm r0!, {r2,r5,r7}\n" + "\tstm r1!, {r2,r5,r7}\n" + "\tadd r1, sp, 0x10\n" + "\tadds r0, r1, 0\n" + "\tldrh r0, [r0]\n" + "\tadds r0, 0x6\n" + "\tstrh r0, [r1]\n" + "\tadds r0, r1, 0\n" + "\tmovs r1, 0xD7\n" + "\tmovs r2, 0x97\n" + "\tmovs r3, 0x1\n" + "\tbl CreateSprite\n" + "\tadd r0, sp, 0x10\n" + "\tldm r4!, {r3,r5,r7}\n" + "\tstm r0!, {r3,r5,r7}\n" + "\tldm r4!, {r1-r3}\n" + "\tstm r0!, {r1-r3}\n" + "\tadd r1, sp, 0x10\n" + "\tadds r0, r1, 0\n" + "\tldrh r0, [r0]\n" + "\tadds r0, 0x7\n" + "\tstrh r0, [r1]\n" + "\tadds r0, r1, 0\n" + "\tmovs r1, 0xF7\n" + "\tmovs r2, 0x97\n" + "\tmovs r3, 0x1\n" + "\tbl CreateSprite\n" + "\tmovs r6, 0\n" + "\tadd r4, sp, 0x10\n" + "\tmovs r5, 0xC0\n" + "\tlsls r5, 13\n" + "_0804CD5C:\n" + "\tadd r1, sp, 0x10\n" + "\tldr r0, _0804CDCC @ =gUnknown_8261CC8\n" + "\tldm r0!, {r2,r3,r7}\n" + "\tstm r1!, {r2,r3,r7}\n" + "\tldm r0!, {r2,r3,r7}\n" + "\tstm r1!, {r2,r3,r7}\n" + "\tadds r0, r6, 0\n" + "\tadds r0, 0x8\n" + "\tldrh r7, [r4]\n" + "\tadds r0, r7\n" + "\tstrh r0, [r4]\n" + "\tasrs r1, r5, 16\n" + "\tadd r0, sp, 0x10\n" + "\tmovs r2, 0x96\n" + "\tmovs r3, 0x1\n" + "\tbl CreateSprite\n" + "\tmovs r0, 0x80\n" + "\tlsls r0, 14\n" + "\tadds r5, r0\n" + "\tadds r6, 0x1\n" + "\tcmp r6, 0x5\n" + "\tble _0804CD5C\n" + "\tldr r0, _0804CDD0 @ =gUnknown_8261CB0\n" + "\tldr r2, _0804CDD4 @ =gTradeMonSpriteCoords\n" + "\tldrb r1, [r2]\n" + "\tlsls r1, 19\n" + "\tmovs r3, 0x80\n" + "\tlsls r3, 14\n" + "\tadds r1, r3\n" + "\tasrs r1, 16\n" + "\tldrb r2, [r2, 0x1]\n" + "\tlsls r2, 3\n" + "\tmovs r3, 0x2\n" + "\tbl CreateSprite\n" + "\tldr r2, _0804CDD8 @ =gUnknown_2031DA8\n" + "\tldr r1, [r2]\n" + "\tadds r1, 0x34\n" + "\tmovs r3, 0\n" + "\tstrb r0, [r1]\n" + "\tldr r0, [r2]\n" + "\tadds r0, 0x35\n" + "\tstrb r3, [r0]\n" + "\tldr r1, _0804CDDC @ =gMain\n" + "\tmovs r5, 0x87\n" + "\tlsls r5, 3\n" + "\tadds r1, r5\n" + "\tldrb r0, [r1]\n" + "\tadds r0, 0x1\n" + "\tstrb r0, [r1]\n" + "\tmovs r0, 0\n" + "\tbl rbox_fill_rectangle\n" + "\tb _0804CEE6\n" + "\t.align 2, 0\n" + "_0804CDCC: .4byte gUnknown_8261CC8\n" + "_0804CDD0: .4byte gUnknown_8261CB0\n" + "_0804CDD4: .4byte gTradeMonSpriteCoords\n" + "_0804CDD8: .4byte gUnknown_2031DA8\n" + "_0804CDDC: .4byte gMain\n" + "_0804CDE0:\n" + "\tmovs r0, 0\n" + "\tbl sub_804F748\n" + "\tmovs r0, 0\n" + "\tbl sub_804F020\n" + "\tldr r2, _0804CE14 @ =gUnknown_2031DA8\n" + "\tldr r0, [r2]\n" + "\tmovs r1, 0\n" + "\tstrb r1, [r0]\n" + "\tldr r0, [r2]\n" + "\tstrb r1, [r0, 0x1]\n" + "\tbl sub_804D764\n" + "\tldr r1, _0804CE18 @ =gMain\n" + "\tmovs r7, 0x87\n" + "\tlsls r7, 3\n" + "\tadds r1, r7\n" + "\tldrb r0, [r1]\n" + "\tadds r0, 0x1\n" + "\tstrb r0, [r1]\n" + "\tldr r0, _0804CE1C @ =0x00000111\n" + "\tbl PlayBGM\n" + "\tb _0804CEE6\n" + "\t.align 2, 0\n" + "_0804CE14: .4byte gUnknown_2031DA8\n" + "_0804CE18: .4byte gMain\n" + "_0804CE1C: .4byte 0x00000111\n" + "_0804CE20:\n" + "\tmovs r0, 0x1\n" + "\tbl sub_804F748\n" + "\tmovs r0, 0x1\n" + "\tbl sub_804F020\n" + "\tldr r1, _0804CE44 @ =gMain\n" + "\tmovs r0, 0x87\n" + "\tlsls r0, 3\n" + "\tadds r1, r0\n" + "\tldrb r0, [r1]\n" + "\tadds r0, 0x1\n" + "\tstrb r0, [r1]\n" + "_0804CE3A:\n" + "\tmovs r0, 0\n" + "\tbl sub_804D694\n" + "\tb _0804CEBA\n" + "\t.align 2, 0\n" + "_0804CE44: .4byte gMain\n" + "_0804CE48:\n" + "\tmovs r0, 0x1\n" + "\tbl sub_804D694\n" + "\tldr r1, _0804CE58 @ =gMain\n" + "\tmovs r3, 0x87\n" + "\tlsls r3, 3\n" + "\tadds r1, r3\n" + "\tb _0804CEC2\n" + "\t.align 2, 0\n" + "_0804CE58: .4byte gMain\n" + "_0804CE5C:\n" + "\tmovs r0, 0x1\n" + "\tnegs r0, r0\n" + "\tmovs r1, 0\n" + "\tstr r1, [sp]\n" + "\tmovs r2, 0x10\n" + "\tmovs r3, 0\n" + "\tbl BeginNormalPaletteFade\n" + "\tldr r1, _0804CE78 @ =gMain\n" + "\tmovs r5, 0x87\n" + "\tlsls r5, 3\n" + "\tadds r1, r5\n" + "\tb _0804CEC2\n" + "\t.align 2, 0\n" + "_0804CE78: .4byte gMain\n" + "_0804CE7C:\n" + "\tmovs r1, 0x82\n" + "\tlsls r1, 5\n" + "\tmovs r0, 0\n" + "\tbl SetGpuReg\n" + "\tmovs r0, 0x2\n" + "\tbl sub_804D694\n" + "\tldr r1, _0804CE98 @ =gMain\n" + "\tmovs r7, 0x87\n" + "\tlsls r7, 3\n" + "\tadds r1, r7\n" + "\tb _0804CEC2\n" + "\t.align 2, 0\n" + "_0804CE98: .4byte gMain\n" + "_0804CE9C:\n" + "\tmovs r0, 0\n" + "\tbl sub_804F890\n" + "\tldr r1, _0804CEAC @ =gMain\n" + "\tmovs r0, 0x87\n" + "\tlsls r0, 3\n" + "\tadds r1, r0\n" + "\tb _0804CEC2\n" + "\t.align 2, 0\n" + "_0804CEAC: .4byte gMain\n" + "_0804CEB0:\n" + "\tmovs r0, 0x1\n" + "\tbl sub_804F890\n" + "\tbl sub_804F964\n" + "_0804CEBA:\n" + "\tldr r1, _0804CECC @ =gMain\n" + "\tmovs r2, 0x87\n" + "\tlsls r2, 3\n" + "\tadds r1, r2\n" + "_0804CEC2:\n" + "\tldrb r0, [r1]\n" + "\tadds r0, 0x1\n" + "\tstrb r0, [r1]\n" + "\tb _0804CEE6\n" + "\t.align 2, 0\n" + "_0804CECC: .4byte gMain\n" + "_0804CED0:\n" + "\tldr r0, _0804CF08 @ =gPaletteFade\n" + "\tldrb r1, [r0, 0x7]\n" + "\tmovs r0, 0x80\n" + "\tands r0, r1\n" + "\tcmp r0, 0\n" + "\tbne _0804CEE6\n" + "\tldr r0, _0804CF0C @ =sub_804DFF0\n" + "\tstr r0, [r3]\n" + "\tldr r0, _0804CF10 @ =sub_804D638\n" + "\tbl SetMainCallback2\n" + "_0804CEE6:\n" + "\tbl RunTextPrinters\n" + "\tbl RunTasks\n" + "\tbl AnimateSprites\n" + "\tbl BuildOamBuffer\n" + "\tbl UpdatePaletteFade\n" + "\tadd sp, 0x28\n" + "\tpop {r3}\n" + "\tmov r8, r3\n" + "\tpop {r4-r7}\n" + "\tpop {r0}\n" + "\tbx r0\n" + "\t.align 2, 0\n" + "_0804CF08: .4byte gPaletteFade\n" + "_0804CF0C: .4byte sub_804DFF0\n" + "_0804CF10: .4byte sub_804D638"); +} +#endif //NONMATCHING diff --git a/src/trainer_tower.c b/src/trainer_tower.c index 17f6b9e09..9512e73d1 100644 --- a/src/trainer_tower.c +++ b/src/trainer_tower.c @@ -1278,7 +1278,7 @@ void sub_815E720(void) sub_815EC0C(); windowId = AddWindow(gUnknown_847A218); - sub_80F6E9C(); + LoadStdWindowFrameGfx(); DrawStdWindowFrame(windowId, FALSE); AddTextPrinterParameterized(windowId, 2, gUnknown_83FE982, 0x4A, 0, 0xFF, NULL); |