pokefirered/src/field_door.c
2020-08-29 03:11:03 -04:00

488 lines
22 KiB
C

#include "global.h"
#include "field_camera.h"
#include "task.h"
#include "fieldmap.h"
#include "metatile_behavior.h"
#include "constants/songs.h"
#include "constants/metatile_labels.h"
#define DOOR_SOUND_NORMAL 0
#define DOOR_SOUND_SLIDING 1
struct DoorAnimFrame
{
u8 duration;
u16 tile;
};
struct DoorGraphics
{
u16 metatileId;
u8 sound;
u8 size;
const u8 * tiles;
const u8 * palettes;
};
static void DrawDoorDefaultImage(const struct DoorGraphics * gfx, int x, int y);
static void LoadDoorFrameTiles(const u8 *a0);
static void SetDoorFramePalettes(const struct DoorGraphics * gfx, int x, int y, const u8 *a3);
static void BufferDoorFrameTilesWithPalettes(u16 *a0, u16 a1, const u8 *a2);
static bool32 PlayDoorAnimationFrame(const struct DoorGraphics * gfx, const struct DoorAnimFrame * frames, s16 *data);
static const struct DoorAnimFrame * SeekToEndOfDoorAnim(const struct DoorAnimFrame * frames);
static s8 GetDoorSoundType(const struct DoorGraphics * gfx, int x, int y);
static const u8 sDoorAnimTiles_General[] = INCBIN_U8("graphics/door_anims/general.4bpp");
static const u16 sDoorNullPalette1[16] = {};
static const u8 sDoorAnimTiles_SlidingSingle[] = INCBIN_U8("graphics/door_anims/sliding_single.4bpp");
static const u16 sDoorNullPalette2[16] = {};
static const u8 sDoorAnimTiles_SlidingDouble[] = INCBIN_U8("graphics/door_anims/sliding_double.4bpp");
static const u16 sDoorNullPalette3[16] = {};
static const u8 sDoorAnimTiles_Pallet[] = INCBIN_U8("graphics/door_anims/pallet.4bpp");
static const u16 sDoorNullPalette4[16] = {};
static const u8 sDoorAnimTiles_OaksLab[] = INCBIN_U8("graphics/door_anims/oaks_lab.4bpp");
static const u16 sDoorNullPalette5[16] = {};
static const u8 sDoorAnimTiles_Viridian[] = INCBIN_U8("graphics/door_anims/viridian.4bpp");
static const u16 sDoorNullPalette6[16] = {};
static const u8 sDoorAnimTiles_Pewter[] = INCBIN_U8("graphics/door_anims/pewter.4bpp");
static const u16 sDoorNullPalette7[16] = {};
static const u8 sDoorAnimTiles_Saffron[] = INCBIN_U8("graphics/door_anims/saffron.4bpp");
static const u16 sDoorNullPalette8[16] = {};
static const u8 sDoorAnimTiles_SilphCo[] = INCBIN_U8("graphics/door_anims/silph_co.4bpp");
static const u16 sDoorNullPalette9[16] = {};
static const u8 sDoorAnimTiles_Cerulean[] = INCBIN_U8("graphics/door_anims/cerulean.4bpp");
static const u16 sDoorNullPalette10[16] = {};
static const u8 sDoorAnimTiles_Lavender[] = INCBIN_U8("graphics/door_anims/lavender.4bpp");
static const u16 sDoorNullPalette11[16] = {};
static const u8 sDoorAnimTiles_Vermilion[] = INCBIN_U8("graphics/door_anims/vermilion.4bpp");
static const u16 sDoorNullPalette12[16] = {};
static const u8 sDoorAnimTiles_PokemonFanClub[] = INCBIN_U8("graphics/door_anims/pokemon_fan_club.4bpp");
static const u16 sDoorNullPalette13[16] = {};
static const u8 sDoorAnimTiles_DeptStore[] = INCBIN_U8("graphics/door_anims/dept_store.4bpp");
static const u16 sDoorNullPalette14[16] = {};
static const u8 sDoorAnimTiles_Fuchsia[] = INCBIN_U8("graphics/door_anims/fuchsia.4bpp");
static const u16 sDoorNullPalette15[16] = {};
static const u8 sDoorAnimTiles_SafariZone[] = INCBIN_U8("graphics/door_anims/safari_zone.4bpp");
static const u16 sDoorNullPalette16[16] = {};
static const u8 sDoorAnimTiles_CinnabarLab[] = INCBIN_U8("graphics/door_anims/cinnabar_lab.4bpp");
static const u16 sDoorNullPalette17[16] = {};
static const u8 sDoorAnimTiles_DeptStoreElevator[] = INCBIN_U8("graphics/door_anims/dept_store_elevator.4bpp");
static const u16 sDoorNullPalette18[16] = {};
static const u8 sDoorAnimTiles_CableClub[] = INCBIN_U8("graphics/door_anims/cable_club.4bpp");
static const u16 sDoorNullPalette19[16] = {};
static const u8 sDoorAnimTiles_HideoutElevator[] = INCBIN_U8("graphics/door_anims/hideout_elevator.4bpp");
static const u16 sDoorNullPalette20[16] = {};
static const u8 sDoorAnimTiles_SSAnne[] = INCBIN_U8("graphics/door_anims/ss_anne.4bpp");
static const u16 sDoorNullPalette21[16] = {};
// Doors from R/S dummied below
static const u8 sDoorAnimTiles_Empty1[256 * 3] = {};
static const u16 sDoorNullPalette22[16] = {};
static const u8 sDoorAnimTiles_Empty2[256 * 3] = {};
static const u16 sDoorNullPalette23[16] = {};
static const u8 sDoorAnimTiles_Empty3[256 * 3] = {};
static const u16 sDoorNullPalette24[16] = {};
static const u8 sDoorAnimTiles_Empty4[256 * 3] = {};
static const u16 sDoorNullPalette25[16] = {};
static const u8 sDoorAnimTiles_Empty5[256 * 3] = {};
static const u16 sDoorNullPalette26[16] = {};
static const u8 sDoorAnimTiles_Empty6[256 * 3] = {};
static const u16 sDoorNullPalette27[16] = {};
static const u8 sDoorAnimTiles_Empty7[256 * 3] = {};
static const u16 sDoorNullPalette28[16] = {};
static const u8 sDoorAnimTiles_Empty8[128 * 3] = {};
static const u16 sDoorNullPalette29[16] = {};
static const u8 sDoorAnimTiles_Empty9[128 * 3] = {};
static const u16 sDoorNullPalette30[16] = {};
static const u8 sDoorAnimTiles_Empty10[128 * 3] = {};
static const u16 sDoorNullPalette31[16] = {};
static const u8 sDoorAnimTiles_Empty11[128 * 3] = {};
static const u16 sDoorNullPalette32[16] = {};
static const u8 sDoorAnimTiles_Empty12[128 * 3] = {};
static const u16 sDoorNullPalette33[16] = {};
static const u8 sDoorAnimTiles_Empty13[128 * 3] = {};
static const u16 sDoorNullPalette34[16] = {};
static const u8 sDoorAnimTiles_Empty14[128 * 3] = {};
static const u16 sDoorNullPalette35[16] = {};
static const u8 sDoorAnimTiles_Empty15[128 * 3] = {};
static const u16 sDoorNullPalette36[16] = {};
static const u8 sDoorAnimTiles_Empty16[128 * 3] = {};
static const u16 sDoorNullPalette37[16] = {};
static const u8 sDoorAnimTiles_Empty17[128 * 3] = {};
static const u16 sDoorNullPalette38[16] = {};
static const u8 sDoorAnimTiles_Empty18[128 * 3] = {};
static const u16 sDoorNullPalette39[16] = {};
static const u8 sDoorAnimTiles_Empty19[128 * 3] = {};
static const u16 sDoorNullPalette40[16] = {};
static const u8 sDoorAnimTiles_Empty20[128 * 3] = {};
static const u16 sDoorNullPalette41[16] = {};
static const u8 sDoorAnimTiles_Empty21[128 * 3] = {};
static const u16 sDoorNullPalette42[16] = {};
static const u8 sDoorAnimTiles_Empty22[128 * 3] = {};
static const u16 sDoorNullPalette43[16] = {};
static const u8 sDoorAnimTiles_Empty23[128 * 3] = {};
static const u16 sDoorNullPalette44[16] = {};
static const u8 sDoorAnimTiles_Empty24[128 * 3] = {};
static const u16 sDoorNullPalette45[16] = {};
static const u8 sDoorAnimTiles_Empty25[128 * 3] = {};
static const u16 sDoorNullPalette46[16] = {};
static const u8 sDoorAnimTiles_Empty26[128 * 3] = {};
static const u16 sDoorNullPalette47[16] = {};
static const u8 sDoorAnimTiles_Empty27[128 * 3] = {};
static const u16 sDoorNullPalette48[16] = {};
static const u8 sDoorAnimTiles_Empty28[128 * 3] = {};
static const u16 sDoorNullPalette49[16] = {};
static const u8 sDoorAnimTiles_Empty29[128 * 3] = {};
static const u16 sDoorNullPalette50[16] = {};
static const u8 sDoorAnimTiles_Empty30[128 * 3] = {};
static const u16 sDoorNullPalette51[16] = {};
static const u8 sDoorAnimTiles_Empty31[128 * 3] = {};
static const u16 sDoorNullPalette52[16] = {};
// Unused block of door tiles
static const u8 sDoorAnimTiles_UnusedTop[] = INCBIN_U8("graphics/door_anims/unused_top.4bpp");
static const u8 sDoorAnimTiles_Empty32[256] = {};
static const u8 sDoorAnimTiles_UnusedMidTop[] = INCBIN_U8("graphics/door_anims/unused_midtop.4bpp");
static const u8 sDoorAnimTiles_Empty33[256] = {};
static const u8 sDoorAnimTiles_UnusedMidBottom[] = INCBIN_U8("graphics/door_anims/unused_midbottom.4bpp");
static const u8 sDoorAnimTiles_Empty34[256] = {};
static const u8 sDoorAnimTiles_UnusedBottom[] = INCBIN_U8("graphics/door_anims/unused_bottom.4bpp");
static const u16 sDoorNullPalette53[16] = {};
// Used FRLG doors resume
static const u8 sDoorAnimTiles_SilphCoElevator[] = INCBIN_U8("graphics/door_anims/silph_co_elevator.4bpp");
static const u16 sDoorNullPalette54[16] = {};
static const u8 sDoorAnimTiles_Sevii123[] = INCBIN_U8("graphics/door_anims/sevii_123.4bpp");
static const u16 sDoorNullPalette55[16] = {};
static const u8 sDoorAnimTiles_JoyfulGameCorner[] = INCBIN_U8("graphics/door_anims/joyful_game_corner.4bpp");
static const u16 sDoorNullPalette56[16] = {};
static const u8 sDoorAnimTiles_OneIslandPokeCenter[] = INCBIN_U8("graphics/door_anims/one_island_poke_center.4bpp");
static const u16 sDoorNullPalette57[16] = {};
static const u8 sDoorAnimTiles_Sevii45[] = INCBIN_U8("graphics/door_anims/sevii_45.4bpp");
static const u16 sDoorNullPalette58[16] = {};
static const u8 sDoorAnimTiles_FourIslandDayCare[] = INCBIN_U8("graphics/door_anims/four_island_day_care.4bpp");
static const u16 sDoorNullPalette59[16] = {};
static const u8 sDoorAnimTiles_RocketWarehouse[] = INCBIN_U8("graphics/door_anims/rocket_warehouse.4bpp");
static const u16 sDoorNullPalette60[16] = {};
static const u8 sDoorAnimTiles_Sevii67[] = INCBIN_U8("graphics/door_anims/sevii_67.4bpp");
static const u16 sDoorNullPalette61[16] = {};
static const u8 sDoorAnimTiles_Teleporter[] = INCBIN_U8("graphics/door_anims/teleporter.4bpp");
static const u16 sDoorNullPalette62[16] = {};
static const u8 sDoorAnimTiles_TrainerTowerLobbyElevator[] = INCBIN_U8("graphics/door_anims/trainer_tower_lobby_elevator.4bpp");
static const u16 sDoorNullPalette63[16] = {};
static const u8 sDoorAnimTiles_TrainerTowerRoofElevator[] = INCBIN_U8("graphics/door_anims/trainer_tower_roof_elevator.4bpp");
static const u16 sDoorNullPalette64[16] = {};
static const struct DoorAnimFrame sDoorAnimFrames_OpenSmall[] = {
{4, 0xFFFF},
{4, 0x0000},
{4, 0x0080},
{4, 0x0100},
{}
};
static const struct DoorAnimFrame sDoorAnimFrames_OpenLarge[] = {
{4, 0xFFFF},
{4, 0x0000},
{4, 0x0100},
{4, 0x0200},
{}
};
static const struct DoorAnimFrame sDoorAnimFrames_CloseSmall[] = {
{4, 0x0100},
{4, 0x0080},
{4, 0x0000},
{4, 0xFFFF},
{}
};
static const struct DoorAnimFrame sDoorAnimFrames_CloseLarge[] = {
{4, 0x0200},
{4, 0x0100},
{4, 0x0000},
{4, 0xFFFF},
{}
};
static const u8 sDoorAnimPalettes_General[] = {2, 2, 2, 2, 2, 2, 2, 2};
static const u8 sDoorAnimPalettes_SlidingSingle[] = {3, 3, 3, 3, 3, 3, 3, 3};
static const u8 sDoorAnimPalettes_SlidingDouble[] = {3, 3, 3, 3, 3, 3, 3, 3};
static const u8 sDoorAnimPalettes_Pallet[] = {8, 8, 8, 8, 8, 8, 8, 8};
static const u8 sDoorAnimPalettes_OaksLab[] = {10, 10, 10, 10, 10, 10, 10, 10};
static const u8 sDoorAnimPalettes_Viridian[] = {8, 8, 8, 8, 8, 8, 8, 8};
static const u8 sDoorAnimPalettes_Pewter[] = {8, 8, 8, 8, 8, 8, 8, 8};
static const u8 sDoorAnimPalettes_Saffron[] = {8, 8, 8, 8, 8, 8, 8, 8};
static const u8 sDoorAnimPalettes_SilphCo[] = {3, 3, 3, 3, 3, 3, 3, 3};
static const u8 sDoorAnimPalettes_Cerulean[] = {12, 12, 12, 12, 12, 12, 12, 12};
static const u8 sDoorAnimPalettes_Lavender[] = {9, 9, 9, 9, 9, 9, 9, 9};
static const u8 sDoorAnimPalettes_Vermilion[] = {9, 9, 9, 9, 9, 9, 9, 9};
static const u8 sDoorAnimPalettes_PokemonFanClub[] = {9, 9, 9, 9, 9, 9, 9, 9};
static const u8 sDoorAnimPalettes_DeptStore[] = {3, 3, 3, 3, 3, 3, 3, 3};
static const u8 sDoorAnimPalettes_Fuchsia[] = {8, 8, 8, 8, 8, 8, 8, 8};
static const u8 sDoorAnimPalettes_SafariZone[] = {9, 9, 9, 9, 9, 9, 9, 9};
static const u8 sDoorAnimPalettes_CinnabarLab[] = {3, 3, 3, 3, 3, 3, 3, 3};
static const u8 sDoorAnimPalettes_DeptStoreElevator[] = {8, 8, 8, 8, 8, 8, 8, 8};
static const u8 sDoorAnimPalettes_CableClub[] = {8, 8, 8, 8, 8, 8, 8, 8};
static const u8 sDoorAnimPalettes_HideoutElevator[] = {12, 12, 2, 2, 2, 2, 2, 2};
static const u8 sDoorAnimPalettes_SSAnne[] = {7, 7, 7, 7, 7, 7, 7, 7};
static const u8 sDoorAnimPalettes_SilphCoElevator[] = {8, 8, 2, 2, 2, 2, 2, 2};
static const u8 sDoorAnimPalettes_Sevii123[] = {5, 5, 5, 5, 5, 5, 5, 5};
static const u8 sDoorAnimPalettes_JoyfulGameCorner[] = {3, 3, 3, 3, 3, 3, 3, 3};
static const u8 sDoorAnimPalettes_OneIslandPokeCenter[] = {3, 3, 3, 3, 3, 3, 3, 3};
static const u8 sDoorAnimPalettes_Sevii45[] = {5, 5, 5, 5, 5, 5, 5, 5};
static const u8 sDoorAnimPalettes_FourIslandDayCare[] = {3, 3, 3, 3, 3, 3, 3, 3};
static const u8 sDoorAnimPalettes_RocketWarehouse[] = {10, 10, 10, 10, 10, 10, 10, 10};
static const u8 sDoorAnimPalettes_Sevii67[] = {5, 5, 5, 5, 5, 5, 5, 5};
static const u8 sDoorAnimPalettes_Teleporter[] = {8, 8, 8, 8, 8, 8, 8, 8};
static const u8 sDoorAnimPalettes_TrainerTowerLobbyElevator[] = {8, 8, 2, 2, 2, 2, 2, 2};
static const u8 sDoorAnimPalettes_TrainerTowerRoofElevator[] = {11, 11, 2, 2, 2, 2, 2, 2};
static const struct DoorGraphics sDoorGraphics[] = {
{METATILE_General_Door, DOOR_SOUND_NORMAL, 0, sDoorAnimTiles_General, sDoorAnimPalettes_General},
{METATILE_General_SlidingSingleDoor, DOOR_SOUND_SLIDING, 0, sDoorAnimTiles_SlidingSingle, sDoorAnimPalettes_SlidingSingle},
{METATILE_General_SlidingDoubleDoor, DOOR_SOUND_SLIDING, 0, sDoorAnimTiles_SlidingDouble, sDoorAnimPalettes_SlidingDouble},
{METATILE_PalletTown_Door, DOOR_SOUND_NORMAL, 0, sDoorAnimTiles_Pallet, sDoorAnimPalettes_Pallet},
{METATILE_PalletTown_OaksLabDoor, DOOR_SOUND_NORMAL, 0, sDoorAnimTiles_OaksLab, sDoorAnimPalettes_OaksLab},
{METATILE_ViridianCity_Door, DOOR_SOUND_NORMAL, 0, sDoorAnimTiles_Viridian, sDoorAnimPalettes_Viridian},
{METATILE_PewterCity_Door, DOOR_SOUND_NORMAL, 0, sDoorAnimTiles_Pewter, sDoorAnimPalettes_Pewter},
{METATILE_SaffronCity_Door, DOOR_SOUND_NORMAL, 0, sDoorAnimTiles_Saffron, sDoorAnimPalettes_Saffron},
{METATILE_SaffronCity_SilphCoDoor, DOOR_SOUND_SLIDING, 0, sDoorAnimTiles_SilphCo, sDoorAnimPalettes_SilphCo},
{METATILE_CeruleanCity_Door, DOOR_SOUND_NORMAL, 0, sDoorAnimTiles_Cerulean, sDoorAnimPalettes_Cerulean},
{METATILE_LavenderTown_Door, DOOR_SOUND_NORMAL, 0, sDoorAnimTiles_Lavender, sDoorAnimPalettes_Lavender},
{METATILE_VermilionCity_Door, DOOR_SOUND_NORMAL, 0, sDoorAnimTiles_Vermilion, sDoorAnimPalettes_Vermilion},
{METATILE_VermilionCity_PokemonFanClubDoor, DOOR_SOUND_NORMAL, 0, sDoorAnimTiles_PokemonFanClub, sDoorAnimPalettes_PokemonFanClub},
{METATILE_CeladonCity_DeptStoreDoor, DOOR_SOUND_SLIDING, 0, sDoorAnimTiles_DeptStore, sDoorAnimPalettes_DeptStore},
{METATILE_FuchsiaCity_Door, DOOR_SOUND_NORMAL, 0, sDoorAnimTiles_Fuchsia, sDoorAnimPalettes_Fuchsia},
{METATILE_FuchsiaCity_SafariZoneDoor, DOOR_SOUND_SLIDING, 0, sDoorAnimTiles_SafariZone, sDoorAnimPalettes_SafariZone},
{METATILE_CinnabarIsland_LabDoor, DOOR_SOUND_NORMAL, 0, sDoorAnimTiles_CinnabarLab, sDoorAnimPalettes_CinnabarLab},
{METATILE_SeviiIslands123_Door, DOOR_SOUND_NORMAL, 0, sDoorAnimTiles_Sevii123, sDoorAnimPalettes_Sevii123},
{METATILE_SeviiIslands123_GameCornerDoor, DOOR_SOUND_SLIDING, 0, sDoorAnimTiles_JoyfulGameCorner, sDoorAnimPalettes_JoyfulGameCorner},
{METATILE_SeviiIslands123_PokeCenterDoor, DOOR_SOUND_NORMAL, 0, sDoorAnimTiles_OneIslandPokeCenter, sDoorAnimPalettes_OneIslandPokeCenter},
{METATILE_SeviiIslands45_Door, DOOR_SOUND_NORMAL, 0, sDoorAnimTiles_Sevii45, sDoorAnimPalettes_Sevii45},
{METATILE_SeviiIslands45_DayCareDoor, DOOR_SOUND_NORMAL, 0, sDoorAnimTiles_FourIslandDayCare, sDoorAnimPalettes_FourIslandDayCare},
{METATILE_SeviiIslands45_RocketWarehouseDoor_Unlocked, DOOR_SOUND_NORMAL, 0, sDoorAnimTiles_RocketWarehouse, sDoorAnimPalettes_RocketWarehouse},
{METATILE_SeviiIslands67_Door, DOOR_SOUND_NORMAL, 0, sDoorAnimTiles_Sevii67, sDoorAnimPalettes_Sevii67},
{METATILE_DepartmentStore_ElevatorDoor, DOOR_SOUND_SLIDING, 1, sDoorAnimTiles_DeptStoreElevator, sDoorAnimPalettes_DeptStoreElevator},
{METATILE_PokemonCenter_CableClubDoor, DOOR_SOUND_SLIDING, 1, sDoorAnimTiles_CableClub, sDoorAnimPalettes_CableClub},
{METATILE_SilphCo_HideoutElevatorDoor, DOOR_SOUND_SLIDING, 1, sDoorAnimTiles_HideoutElevator, sDoorAnimPalettes_HideoutElevator},
{METATILE_SSAnne_Door, DOOR_SOUND_NORMAL, 1, sDoorAnimTiles_SSAnne, sDoorAnimPalettes_SSAnne},
{METATILE_SilphCo_ElevatorDoor, DOOR_SOUND_SLIDING, 1, sDoorAnimTiles_SilphCoElevator, sDoorAnimPalettes_SilphCoElevator},
{METATILE_SeaCottage_Teleporter_Door, DOOR_SOUND_SLIDING, 1, sDoorAnimTiles_Teleporter, sDoorAnimPalettes_Teleporter},
{METATILE_TrainerTower_LobbyElevatorDoor, DOOR_SOUND_SLIDING, 1, sDoorAnimTiles_TrainerTowerLobbyElevator, sDoorAnimPalettes_TrainerTowerLobbyElevator},
{METATILE_TrainerTower_RoofElevatorDoor, DOOR_SOUND_SLIDING, 1, sDoorAnimTiles_TrainerTowerRoofElevator, sDoorAnimPalettes_TrainerTowerRoofElevator},
{}
};
static void UpdateDrawDoorFrame(const struct DoorGraphics * gfx, const struct DoorAnimFrame * frames, int x, int y)
{
if (frames->tile == 0xFFFF)
{
DrawDoorDefaultImage(gfx, x, y);
}
else
{
LoadDoorFrameTiles(&gfx->tiles[frames->tile]);
SetDoorFramePalettes(gfx, x, y, gfx->palettes);
}
}
static void DrawDoorDefaultImage(const struct DoorGraphics * gfx, int x, int y)
{
if (gfx->size == 0)
{
CurrentMapDrawMetatileAt(x, y);
}
else
{
CurrentMapDrawMetatileAt(x, y);
CurrentMapDrawMetatileAt(x, y - 1);
}
}
static void LoadDoorFrameTiles(const u8 *a0)
{
CpuFastCopy(a0, (void *)(BG_VRAM + 0x7F00), 0x100);
}
static void SetDoorFramePalettes(const struct DoorGraphics * gfx, int x, int y, const u8 *a3)
{
u16 sp00[8];
if (gfx->size == 0)
{
BufferDoorFrameTilesWithPalettes(sp00, 0x3F8, a3);
}
else
{
BufferDoorFrameTilesWithPalettes(sp00, 0x3F8, a3);
DrawDoorMetatileAt(x, y - 1, sp00);
BufferDoorFrameTilesWithPalettes(sp00, 0x3FC, a3 + 4);
}
DrawDoorMetatileAt(x, y, sp00);
}
static void BufferDoorFrameTilesWithPalettes(u16 *a0, u16 a1, const u8 *a2)
{
int i;
u16 tile;
for (i = 0; i < 4; i++)
{
tile = *(a2++) << 12;
a0[i] = tile | (a1 + i);
}
for (; i < 8; i++)
{
tile = *(a2++) << 12;
a0[i] = tile;
}
}
static void Task_AnimateDoor(u8 taskId)
{
s16 *data = (void *)gTasks[taskId].data;
const struct DoorAnimFrame * frames = (const void *)(((u16)data[0] << 16) | (u16)data[1]);
const struct DoorGraphics * gfx = (const void *)(((u16)data[2] << 16) | (u16)data[3]);
if (!PlayDoorAnimationFrame(gfx, frames, data))
DestroyTask(taskId);
}
static bool32 PlayDoorAnimationFrame(const struct DoorGraphics * gfx, const struct DoorAnimFrame * frames, s16 *data)
{
if (data[5] == 0)
{
UpdateDrawDoorFrame(gfx, &frames[data[4]], data[6], data[7]);
}
if (data[5] == frames[data[4]].duration)
{
data[5] = 0;
data[4]++;
if (frames[data[4]].duration == 0)
return FALSE;
}
else
{
data[5]++;
}
return TRUE;
}
static const struct DoorGraphics * GetDoorGraphics(const struct DoorGraphics * gfx, u16 id)
{
while (gfx->tiles != NULL)
{
if (gfx->metatileId == id)
return gfx;
gfx++;
}
return NULL;
}
static s8 StartDoorAnimationTask(const struct DoorGraphics * gfx, const struct DoorAnimFrame * frames, int x, int y)
{
u8 taskId;
s16 *data;
if (FuncIsActiveTask(Task_AnimateDoor) == TRUE)
return -1;
taskId = CreateTask(Task_AnimateDoor, 80);
data = gTasks[taskId].data;
data[6] = x;
data[7] = y;
data[1] = (uintptr_t)frames;
data[0] = (uintptr_t)frames >> 16;
data[3] = (uintptr_t)gfx;
data[2] = (uintptr_t)gfx >> 16;
return taskId;
}
static void DrawClosedDoor(const struct DoorGraphics * gfx, int x, int y)
{
DrawDoorDefaultImage(gfx, x, y);
}
static void DrawOpenedDoor(const struct DoorGraphics * gfx, int x, int y)
{
gfx = GetDoorGraphics(gfx, MapGridGetMetatileIdAt(x, y));
if (gfx != NULL)
{
UpdateDrawDoorFrame(gfx, SeekToEndOfDoorAnim(gfx->size == 0 ? sDoorAnimFrames_OpenSmall : sDoorAnimFrames_OpenLarge), x, y);
}
}
static const struct DoorAnimFrame * SeekToEndOfDoorAnim(const struct DoorAnimFrame * frames)
{
while (frames->duration != 0)
frames++;
return frames - 1;
}
static s8 AnimateDoorOpenInternal(const struct DoorGraphics * gfx, int x, int y)
{
gfx = GetDoorGraphics(gfx, MapGridGetMetatileIdAt(x, y));
if (gfx == NULL)
return -1;
else if (gfx->size == 0)
return StartDoorAnimationTask(gfx, sDoorAnimFrames_OpenSmall, x, y);
else
return StartDoorAnimationTask(gfx, sDoorAnimFrames_OpenLarge, x, y);
}
static s8 AnimateDoorCloseInternal(const struct DoorGraphics * gfx, int x, int y)
{
gfx = GetDoorGraphics(gfx, MapGridGetMetatileIdAt(x, y));
if (gfx == NULL)
return -1;
else if (gfx->size == 0)
return StartDoorAnimationTask(gfx, sDoorAnimFrames_CloseSmall, x, y);
else
return StartDoorAnimationTask(gfx, sDoorAnimFrames_CloseLarge, x, y);
}
void FieldSetDoorOpened(int x, int y)
{
if (MetatileBehavior_IsWarpDoor_2(MapGridGetMetatileBehaviorAt((s16)x, (s16)y)))
DrawOpenedDoor(sDoorGraphics, x, y);
}
void FieldSetDoorClosed(int x, int y)
{
if (MetatileBehavior_IsWarpDoor_2(MapGridGetMetatileBehaviorAt((s16)x, (s16)y)))
DrawClosedDoor(sDoorGraphics, x, y);
}
s8 FieldAnimateDoorClose(int x, int y)
{
if (!MetatileBehavior_IsWarpDoor_2(MapGridGetMetatileBehaviorAt((s16)x, (s16)y)))
return -1;
return AnimateDoorCloseInternal(sDoorGraphics, x, y);
}
s8 FieldAnimateDoorOpen(int x, int y)
{
if (!MetatileBehavior_IsWarpDoor_2(MapGridGetMetatileBehaviorAt((s16)x, (s16)y)))
return -1;
return AnimateDoorOpenInternal(sDoorGraphics, x, y);
}
bool8 FieldIsDoorAnimationRunning(void)
{
return FuncIsActiveTask(Task_AnimateDoor);
}
u16 GetDoorSoundEffect(int x, int y)
{
if (GetDoorSoundType(sDoorGraphics, x, y) == DOOR_SOUND_NORMAL)
return SE_DOOR;
else // DOOR_SOUND_SLIDING
return SE_SLIDING_DOOR;
}
static s8 GetDoorSoundType(const struct DoorGraphics * gfx, int x, int y)
{
gfx = GetDoorGraphics(gfx, MapGridGetMetatileIdAt(x, y));
if (gfx == NULL)
return -1;
return gfx->sound;
}