diff --git a/include/battle_gimmick.h b/include/battle_gimmick.h index de1352a611..d0e975462a 100644 --- a/include/battle_gimmick.h +++ b/include/battle_gimmick.h @@ -17,8 +17,8 @@ struct GimmickInfo const struct SpritePalette *triggerPal; // trigger gfx data const struct SpriteSheet *triggerSheet; const struct SpriteTemplate *triggerTemplate; - const struct SpritePalette *indicatorPal; // indicator gfx data - const struct SpriteSheet *indicatorSheet; + const u32 indicatorPalTag; + const u8 *indicatorData; bool32 (*CanActivate)(u32 battler); void (*ActivateGimmick)(u32 battler); }; diff --git a/src/battle_gimmick.c b/src/battle_gimmick.c index 0b725811ee..4cdc754ea4 100644 --- a/src/battle_gimmick.c +++ b/src/battle_gimmick.c @@ -265,20 +265,9 @@ static void SpriteCb_GimmickTrigger(struct Sprite *sprite) void LoadIndicatorSpritesGfx(void) { - u32 gimmick; - for (gimmick = 0; gimmick < GIMMICKS_COUNT; ++gimmick) - { - if (gimmick == GIMMICK_TERA) // special case - LoadSpriteSheets(sTeraIndicatorSpriteSheets); - else if (gGimmicksInfo[gimmick].indicatorSheet != NULL) - LoadSpriteSheet(gGimmicksInfo[gimmick].indicatorSheet); - - if (gGimmicksInfo[gimmick].indicatorPal != NULL) - LoadSpritePalette(gGimmicksInfo[gimmick].indicatorPal); - } - // Primal reversion graphics aren't loaded as part of gimmick data - LoadSpriteSheet(&sSpriteSheet_AlphaIndicator); - LoadSpriteSheet(&sSpriteSheet_OmegaIndicator); + LoadSpritePalette(&sSpritePalette_MiscIndicator); + LoadSpritePalette(&sSpritePalette_MegaIndicator); + LoadSpritePalette(&sSpritePalette_TeraIndicator); } static void SpriteCb_GimmickIndicator(struct Sprite *sprite) @@ -295,28 +284,28 @@ static inline u32 GetIndicatorSpriteId(u32 healthboxId) return gBattleStruct->gimmick.indicatorSpriteId[gSprites[healthboxId].hMain_Battler]; } -u32 GetIndicatorTileTag(u32 battler) +const u32 *GetIndicatorSpriteSrc(u32 battler) { u32 gimmick = GetActiveGimmick(battler); if (IsBattlerPrimalReverted(battler)) { if (gBattleMons[battler].species == SPECIES_GROUDON_PRIMAL) - return TAG_OMEGA_INDICATOR_TILE; + return (u32 *)&sOmegaIndicatorGfx; else - return TAG_ALPHA_INDICATOR_TILE; + return (u32 *)&sAlphaIndicatorGfx; } else if (gimmick == GIMMICK_TERA) // special case { - return sTeraIndicatorSpriteSheets[GetBattlerTeraType(battler)].tag; + return (u32 *)sTeraIndicatorDataPtrs[GetBattlerTeraType(battler)]; } - else if (gGimmicksInfo[gimmick].indicatorSheet != NULL) + else if (gGimmicksInfo[gimmick].indicatorData != NULL) { - return gGimmicksInfo[gimmick].indicatorSheet->tag; + return (u32 *)gGimmicksInfo[gimmick].indicatorData; } else { - return TAG_NONE; + return NULL; } } @@ -325,27 +314,34 @@ u32 GetIndicatorPalTag(u32 battler) u32 gimmick = GetActiveGimmick(battler); if (IsBattlerPrimalReverted(battler)) return TAG_MISC_INDICATOR_PAL; - else if (gGimmicksInfo[gimmick].indicatorPal != NULL) - return gGimmicksInfo[gimmick].indicatorPal->tag; + else if (gGimmicksInfo[gimmick].indicatorPalTag != 0) + return gGimmicksInfo[gimmick].indicatorPalTag; else return TAG_NONE; } +#define INDICATOR_SIZE (8 * 16 / 2) + void UpdateIndicatorVisibilityAndType(u32 healthboxId, bool32 invisible) { u32 battler = gSprites[healthboxId].hMain_Battler; - u32 tileTag = GetIndicatorTileTag(battler); u32 palTag = GetIndicatorPalTag(battler); struct Sprite *sprite = &gSprites[GetIndicatorSpriteId(healthboxId)]; if (GetIndicatorSpriteId(healthboxId) == 0) // safari zone means the player doesn't have an indicator sprite id return; - if (tileTag != TAG_NONE && palTag != TAG_NONE) + if (palTag != TAG_NONE) { - sprite->oam.tileNum = GetSpriteTileStartByTag(tileTag); sprite->oam.paletteNum = IndexOfSpritePaletteTag(palTag); sprite->invisible = invisible; + + u32 *dst = (u32 *)(OBJ_VRAM0 + TILE_SIZE_4BPP * GetSpriteTileStartByTag(BATTLER_INDICATOR_TAG + battler)); + + const u32 *src = GetIndicatorSpriteSrc(battler); + + for (u32 i = 0; i < INDICATOR_SIZE / 4; i++) + dst[i] = src[i]; } else // in case of error { @@ -353,6 +349,8 @@ void UpdateIndicatorVisibilityAndType(u32 healthboxId, bool32 invisible) } } +#undef INDICATOR_SIZE + void UpdateIndicatorOamPriority(u32 healthboxId, u32 oamPriority) { gSprites[GetIndicatorSpriteId(healthboxId)].oam.priority = oamPriority; @@ -389,7 +387,8 @@ void CreateIndicatorSprite(u32 battler) x = sIndicatorPositions[position][0]; y += sIndicatorPositions[position][1]; - spriteId = CreateSpriteAtEnd(&sSpriteTemplate_GimmickIndicator, 0, y, 0); + LoadSpriteSheet(&sBattler_GimmickSpritesheets[battler]); + spriteId = CreateSprite(&(sSpriteTemplate_BattlerIndicators[battler]), 0, y, 0); gBattleStruct->gimmick.indicatorSpriteId[battler] = spriteId; gSprites[spriteId].tBattler = battler; gSprites[spriteId].tPosX = x; diff --git a/src/battle_interface.c b/src/battle_interface.c index d20848f321..1f85e68eea 100644 --- a/src/battle_interface.c +++ b/src/battle_interface.c @@ -922,7 +922,7 @@ static void UpdateLvlInHealthbox(u8 healthboxSpriteId, u8 lvl) u8 battler = gSprites[healthboxSpriteId].hMain_Battler; // Don't print Lv char if mon has a gimmick with an indicator active. - if (GetIndicatorTileTag(battler) != TAG_NONE) + if (GetIndicatorPalTag(battler) != TAG_NONE) { objVram = ConvertIntToDecimalStringN(text, lvl, STR_CONV_MODE_LEFT_ALIGN, 3); xPos = 5 * (3 - (objVram - (text + 2))) - 1; diff --git a/src/data/gimmicks.h b/src/data/gimmicks.h index 5b06feddef..0ea19ea1e4 100644 --- a/src/data/gimmicks.h +++ b/src/data/gimmicks.h @@ -10,8 +10,8 @@ const struct GimmickInfo gGimmicksInfo[GIMMICKS_COUNT] = .triggerSheet = &sSpriteSheet_MegaTrigger, .triggerPal = &sSpritePalette_MegaTrigger, .triggerTemplate = &sSpriteTemplate_GimmickTrigger, - .indicatorSheet = &sSpriteSheet_MegaIndicator, - .indicatorPal = &sSpritePalette_MegaIndicator, + .indicatorData = sMegaIndicatorGfx, + .indicatorPalTag = TAG_MEGA_INDICATOR_PAL, .CanActivate = CanMegaEvolve, .ActivateGimmick = ActivateMegaEvolution, }, @@ -36,8 +36,8 @@ const struct GimmickInfo gGimmicksInfo[GIMMICKS_COUNT] = .triggerSheet = &sSpriteSheet_DynamaxTrigger, .triggerPal = &sSpritePalette_DynamaxTrigger, .triggerTemplate = &sSpriteTemplate_GimmickTrigger, - .indicatorSheet = &sSpriteSheet_DynamaxIndicator, - .indicatorPal = &sSpritePalette_MiscIndicator, + .indicatorData = sDynamaxIndicatorGfx, + .indicatorPalTag = TAG_MISC_INDICATOR_PAL, .CanActivate = CanDynamax, .ActivateGimmick = ActivateDynamax, }, @@ -46,8 +46,8 @@ const struct GimmickInfo gGimmicksInfo[GIMMICKS_COUNT] = .triggerSheet = &sSpriteSheet_TeraTrigger, .triggerPal = &sSpritePalette_TeraTrigger, .triggerTemplate = &sSpriteTemplate_GimmickTrigger, - .indicatorSheet = NULL, // handled separately - .indicatorPal = &sSpritePalette_TeraIndicator, + .indicatorData = NULL, // handled separately + .indicatorPalTag = TAG_TERA_INDICATOR_PAL, .CanActivate = CanTerastallize, .ActivateGimmick = ActivateTera, } diff --git a/src/data/graphics/gimmicks.h b/src/data/graphics/gimmicks.h index f16b2f83c0..483cf2218b 100644 --- a/src/data/graphics/gimmicks.h +++ b/src/data/graphics/gimmicks.h @@ -99,34 +99,29 @@ static const u16 sMiscIndicatorPal[] = INCBIN_U16("graphics/battle_interface/mis static const u16 sMegaIndicatorPal[] = INCBIN_U16("graphics/battle_interface/mega_indicator.gbapal"); static const u16 sTeraIndicatorPal[] = INCBIN_U16("graphics/battle_interface/tera_indicator.gbapal"); -static const struct SpriteSheet sSpriteSheet_MegaIndicator = {sMegaIndicatorGfx, sizeof(sMegaIndicatorGfx), TAG_MEGA_INDICATOR_TILE}; -static const struct SpriteSheet sSpriteSheet_AlphaIndicator = {sAlphaIndicatorGfx, sizeof(sAlphaIndicatorGfx), TAG_ALPHA_INDICATOR_TILE}; -static const struct SpriteSheet sSpriteSheet_OmegaIndicator = {sOmegaIndicatorGfx, sizeof(sOmegaIndicatorGfx), TAG_OMEGA_INDICATOR_TILE}; -static const struct SpriteSheet sSpriteSheet_DynamaxIndicator = {sDynamaxIndicatorGfx, sizeof(sDynamaxIndicatorGfx), TAG_DYNAMAX_INDICATOR_TILE}; -static const struct SpriteSheet sTeraIndicatorSpriteSheets[NUMBER_OF_MON_TYPES + 1] = +static const u8 *sTeraIndicatorDataPtrs[] = { - {sNormalIndicatorGfx, sizeof(sNormalIndicatorGfx), TAG_NORMAL_INDICATOR_TILE}, // TYPE_NONE - {sNormalIndicatorGfx, sizeof(sNormalIndicatorGfx), TAG_NORMAL_INDICATOR_TILE}, - {sFightingIndicatorGfx, sizeof(sFightingIndicatorGfx), TAG_FIGHTING_INDICATOR_TILE}, - {sFlyingIndicatorGfx, sizeof(sFlyingIndicatorGfx), TAG_FLYING_INDICATOR_TILE}, - {sPoisonIndicatorGfx, sizeof(sPoisonIndicatorGfx), TAG_POISON_INDICATOR_TILE}, - {sGroundIndicatorGfx, sizeof(sGroundIndicatorGfx), TAG_GROUND_INDICATOR_TILE}, - {sRockIndicatorGfx, sizeof(sRockIndicatorGfx), TAG_ROCK_INDICATOR_TILE}, - {sBugIndicatorGfx, sizeof(sBugIndicatorGfx), TAG_BUG_INDICATOR_TILE}, - {sGhostIndicatorGfx, sizeof(sGhostIndicatorGfx), TAG_GHOST_INDICATOR_TILE}, - {sSteelIndicatorGfx, sizeof(sSteelIndicatorGfx), TAG_STEEL_INDICATOR_TILE}, - {sNormalIndicatorGfx, sizeof(sNormalIndicatorGfx), TAG_NORMAL_INDICATOR_TILE}, // TYPE_MYSTERY - {sFireIndicatorGfx, sizeof(sFireIndicatorGfx), TAG_FIRE_INDICATOR_TILE}, - {sWaterIndicatorGfx, sizeof(sWaterIndicatorGfx), TAG_WATER_INDICATOR_TILE}, - {sGrassIndicatorGfx, sizeof(sGrassIndicatorGfx), TAG_GRASS_INDICATOR_TILE}, - {sElectricIndicatorGfx, sizeof(sElectricIndicatorGfx), TAG_ELECTRIC_INDICATOR_TILE}, - {sPsychicIndicatorGfx, sizeof(sPsychicIndicatorGfx), TAG_PSYCHIC_INDICATOR_TILE}, - {sIceIndicatorGfx, sizeof(sIceIndicatorGfx), TAG_ICE_INDICATOR_TILE}, - {sDragonIndicatorGfx, sizeof(sDragonIndicatorGfx), TAG_DRAGON_INDICATOR_TILE}, - {sDarkIndicatorGfx, sizeof(sDarkIndicatorGfx), TAG_DARK_INDICATOR_TILE}, - {sFairyIndicatorGfx, sizeof(sFairyIndicatorGfx), TAG_FAIRY_INDICATOR_TILE}, - {sStellarIndicatorGfx, sizeof(sStellarIndicatorGfx), TAG_STELLAR_INDICATOR_TILE}, - {0} + sNormalIndicatorGfx, + sNormalIndicatorGfx, + sFightingIndicatorGfx, + sFlyingIndicatorGfx, + sPoisonIndicatorGfx, + sGroundIndicatorGfx, + sRockIndicatorGfx, + sBugIndicatorGfx, + sGhostIndicatorGfx, + sSteelIndicatorGfx, + sNormalIndicatorGfx, + sFireIndicatorGfx, + sWaterIndicatorGfx, + sGrassIndicatorGfx, + sElectricIndicatorGfx, + sPsychicIndicatorGfx, + sIceIndicatorGfx, + sDragonIndicatorGfx, + sDarkIndicatorGfx, + sFairyIndicatorGfx, + sStellarIndicatorGfx, }; static const struct SpritePalette sSpritePalette_MiscIndicator = {sMiscIndicatorPal, TAG_MISC_INDICATOR_PAL}; @@ -141,13 +136,56 @@ static const struct OamData sOamData_GimmickIndicator = }; static void SpriteCb_GimmickIndicator(struct Sprite *sprite); -static const struct SpriteTemplate sSpriteTemplate_GimmickIndicator = + +#define BATTLER_INDICATOR_TAG 0xDEDE +static const struct SpriteSheet sBattler_GimmickSpritesheets[] = { - .tileTag = TAG_NORMAL_INDICATOR_TILE, // updated dynamically - .paletteTag = TAG_TERA_INDICATOR_PAL, // updated dynamically - .oam = &sOamData_GimmickIndicator, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCb_GimmickIndicator, + {sNormalIndicatorGfx, sizeof(sNormalIndicatorGfx), BATTLER_INDICATOR_TAG}, + {sNormalIndicatorGfx, sizeof(sNormalIndicatorGfx), BATTLER_INDICATOR_TAG+1}, + {sNormalIndicatorGfx, sizeof(sNormalIndicatorGfx), BATTLER_INDICATOR_TAG+2}, + {sNormalIndicatorGfx, sizeof(sNormalIndicatorGfx), BATTLER_INDICATOR_TAG+3}, +}; + +static const struct SpriteTemplate sSpriteTemplate_BattlerIndicators[] = +{ + [0] = + { + .tileTag = BATTLER_INDICATOR_TAG, // updated dynamically + .paletteTag = TAG_TERA_INDICATOR_PAL, // updated dynamically + .oam = &sOamData_GimmickIndicator, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCb_GimmickIndicator, + }, + [1] = + { + .tileTag = BATTLER_INDICATOR_TAG + 1, // updated dynamically + .paletteTag = TAG_TERA_INDICATOR_PAL, // updated dynamically + .oam = &sOamData_GimmickIndicator, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCb_GimmickIndicator, + }, + [2] = + { + .tileTag = BATTLER_INDICATOR_TAG + 2, // updated dynamically + .paletteTag = TAG_TERA_INDICATOR_PAL, // updated dynamically + .oam = &sOamData_GimmickIndicator, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCb_GimmickIndicator, + }, + [3] = + { + .tileTag = BATTLER_INDICATOR_TAG + 3, // updated dynamically + .paletteTag = TAG_TERA_INDICATOR_PAL, // updated dynamically + .oam = &sOamData_GimmickIndicator, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCb_GimmickIndicator, + }, };