#include "global.h" #include "gflib.h" #include "field_effect.h" #include "field_effect_scripts.h" #include "field_weather.h" #include "overworld.h" #include "quest_log.h" #define FIELD_EFFECT_COUNT 32 static u8 sFieldEffectActiveList[FIELD_EFFECT_COUNT]; void FieldEffectActiveListAdd(u8 fldeff); void FieldEffectScript_LoadTiles(const u8 **script); void FieldEffectScript_LoadFadedPal(const u8 **script); void FieldEffectScript_LoadPal(const u8 **script); void FieldEffectScript_CallNative(const u8 **script, u32 *result); void FieldEffectFreeTilesIfUnused(u16 tilesTag); void FieldEffectFreePaletteIfUnused(u8 paletteNum); extern bool8 (*const sFldEffScrcmdTable[])(const u8 **script, u32 *result); u32 FieldEffectStart(u8 fldeff) { const u8 *script; u32 result; FieldEffectActiveListAdd(fldeff); script = gFieldEffectScriptPointers[fldeff]; while (sFldEffScrcmdTable[*script](&script, &result)) ; return result; } bool8 FieldEffectCmd_loadtiles(const u8 **script, u32 *result) { (*script)++; FieldEffectScript_LoadTiles(script); return TRUE; } bool8 FieldEffectCmd_loadfadedpal(const u8 **script, u32 *result) { (*script)++; FieldEffectScript_LoadFadedPal(script); return TRUE; } bool8 FieldEffectCmd_loadpal(const u8 **script, u32 *result) { (*script)++; FieldEffectScript_LoadPal(script); return TRUE; } bool8 FieldEffectCmd_callnative(const u8 **script, u32 *result) { (*script)++; FieldEffectScript_CallNative(script, result); return TRUE; } bool8 FieldEffectCmd_end(const u8 **script, u32 *result) { return FALSE; } bool8 FieldEffectCmd_loadgfx_callnative(const u8 **script, u32 *result) { (*script)++; FieldEffectScript_LoadTiles(script); FieldEffectScript_LoadFadedPal(script); FieldEffectScript_CallNative(script, result); return TRUE; } bool8 FieldEffectCmd_loadtiles_callnative(const u8 **script, u32 *result) { (*script)++; FieldEffectScript_LoadTiles(script); FieldEffectScript_CallNative(script, result); return TRUE; } bool8 FieldEffectCmd_loadfadedpal_callnative(const u8 **script, u32 *result) { (*script)++; FieldEffectScript_LoadFadedPal(script); FieldEffectScript_CallNative(script, result); return TRUE; } u32 FieldEffectScript_ReadWord(const u8 **script) { return T2_READ_32(*script); } void FieldEffectScript_LoadTiles(const u8 **script) { const struct SpriteSheet * spriteSheet = (const struct SpriteSheet *)FieldEffectScript_ReadWord(script); if (GetSpriteTileStartByTag(spriteSheet->tag) == 0xFFFF) LoadSpriteSheet(spriteSheet); *script += sizeof(u32); } void sub_8083598(u8 paletteIdx) { switch (gUnknown_2036E28) { case 0: return; case 1: TintPalette_GrayScale(&gPlttBufferUnfaded[(paletteIdx + 16) * 16], 0x10); break; case 2: TintPalette_SepiaTone(&gPlttBufferUnfaded[(paletteIdx + 16) * 16], 0x10); break; case 3: sub_8111F38((paletteIdx + 16) * 16, 0x10); TintPalette_GrayScale(&gPlttBufferUnfaded[(paletteIdx + 16) * 16], 0x10); break; default: return; } CpuFastCopy(&gPlttBufferUnfaded[(paletteIdx + 16) * 16], &gPlttBufferFaded[(paletteIdx + 16) * 16], 0x20); } void FieldEffectScript_LoadFadedPal(const u8 **script) { const struct SpritePalette * spritePalette = (const struct SpritePalette *)FieldEffectScript_ReadWord(script); u8 idx = IndexOfSpritePaletteTag(spritePalette->tag); LoadSpritePalette(spritePalette); if (idx == 0xFF) sub_8083598(IndexOfSpritePaletteTag(spritePalette->tag)); sub_807AA8C(IndexOfSpritePaletteTag(spritePalette->tag)); *script += sizeof(u32); } void FieldEffectScript_LoadPal(const u8 **script) { const struct SpritePalette * spritePalette = (const struct SpritePalette *)FieldEffectScript_ReadWord(script); u8 idx = IndexOfSpritePaletteTag(spritePalette->tag); LoadSpritePalette(spritePalette); if (idx != 0xFF) sub_8083598(IndexOfSpritePaletteTag(spritePalette->tag)); *script += sizeof(u32); } void FieldEffectScript_CallNative(const u8 **script, u32 *result) { u32 (*func)(void) = (u32 (*)(void))FieldEffectScript_ReadWord(script); *result = func(); *script += sizeof(u32); } void FieldEffectFreeGraphicsResources(struct Sprite * sprite) { u16 tileStart = sprite->sheetTileStart; u8 paletteNum = sprite->oam.paletteNum; DestroySprite(sprite); FieldEffectFreeTilesIfUnused(tileStart); FieldEffectFreePaletteIfUnused(paletteNum); } void FieldEffectStop(struct Sprite * sprite, u8 fldeff) { FieldEffectFreeGraphicsResources(sprite); FieldEffectActiveListRemove(fldeff); } void FieldEffectFreeTilesIfUnused(u16 tileStart) { u8 i; u16 tileTag = GetSpriteTileTagByTileStart(tileStart); if (tileTag == 0xFFFF) return; for (i = 0; i < MAX_SPRITES; i++) { if (gSprites[i].inUse && gSprites[i].usingSheet && tileStart == gSprites[i].sheetTileStart) return; } FreeSpriteTilesByTag(tileTag); } void FieldEffectFreePaletteIfUnused(u8 paletteNum) { u8 i; u16 paletteTag = GetSpritePaletteTagByPaletteNum(paletteNum); if (paletteTag == 0xFFFF) return; for (i = 0; i < MAX_SPRITES; i++) { if (gSprites[i].inUse && gSprites[i].oam.paletteNum == paletteNum) return; } FreeSpritePaletteByTag(paletteTag); } void FieldEffectActiveListClear(void) { u8 i; for (i = 0; i < FIELD_EFFECT_COUNT; i++) { sFieldEffectActiveList[i] = 0xFF; } } void FieldEffectActiveListAdd(u8 fldeff) { u8 i; for (i = 0; i < FIELD_EFFECT_COUNT; i++) { if (sFieldEffectActiveList[i] == 0xFF) { sFieldEffectActiveList[i] = fldeff; return; } } } void FieldEffectActiveListRemove(u8 fldeff) { u8 i; for (i = 0; i < FIELD_EFFECT_COUNT; i++) { if (sFieldEffectActiveList[i] == fldeff) { sFieldEffectActiveList[i] = 0xFF; return; } } } bool8 FieldEffectActiveListContains(u8 fldeff) { u8 i; for (i = 0; i < FIELD_EFFECT_COUNT; i++) { if (sFieldEffectActiveList[i] == fldeff) { return TRUE; } } return FALSE; }