diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/field_door.c | 225 |
1 files changed, 184 insertions, 41 deletions
diff --git a/src/field_door.c b/src/field_door.c index 116cdddee..a0b470c58 100644 --- a/src/field_door.c +++ b/src/field_door.c @@ -1,82 +1,87 @@ #include "global.h" #include "field_camera.h" #include "task.h" +#include "fieldmap.h" +#include "metatile_behavior.h" +#include "constants/songs.h" struct DoorAnimFrame { - u8 unk_0; - u16 unk_2; + u8 duration; + u16 tile; }; struct DoorGraphics { - u16 unk_0; - u8 unk_2; - u8 unk_3; - const u8 * unk_4; - const u8 * unk_8; + u16 metatileId; + s8 sliding; + u8 size; + const u8 * tiles; + const u8 * palettes; }; -void sub_805AF54(const struct DoorGraphics * a0, int a1, int a2); -void sub_805AF80(const u8 *a0); -void sub_805AF94(const struct DoorGraphics * a0, int a1, int a2, const u8 *a3); -void sub_805AFE8(u16 *a0, u16 a1, const u8 *a2); -bool32 sub_805B060(const struct DoorGraphics * gfx, const struct DoorAnimFrame * frames, u16 *data); +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 GetDoorOpenType(const struct DoorGraphics * gfx, int x, int y); -extern const struct DoorAnimFrame gUnknown_835B488[]; -extern const struct DoorAnimFrame gUnknown_835B49C[]; -extern const struct DoorAnimFrame gUnknown_835B4B0[]; -extern const struct DoorAnimFrame gUnknown_835B4C4[]; -extern const struct DoorGraphics gUnknown_835B5D8[]; +extern const struct DoorAnimFrame sDoorAnimFrames_OpenSmall[]; +extern const struct DoorAnimFrame sDoorAnimFrames_OpenLarge[]; +extern const struct DoorAnimFrame sDoorAnimFrames_CloseSmall[]; +extern const struct DoorAnimFrame sDoorAnimFrames_CloseLarge[]; +extern const struct DoorGraphics sDoorGraphics[]; -void sub_805AF14(const struct DoorGraphics * a0, const struct DoorAnimFrame * a1, int a2, int a3) +static void UpdateDrawDoorFrame(const struct DoorGraphics * gfx, const struct DoorAnimFrame * frames, int x, int y) { - if (a1->unk_2 == 0xFFFF) + if (frames->tile == 0xFFFF) { - sub_805AF54(a0, a2, a3); + DrawDoorDefaultImage(gfx, x, y); } else { - sub_805AF80(&a0->unk_4[a1->unk_2]); - sub_805AF94(a0, a2, a3, a0->unk_8); + LoadDoorFrameTiles(&gfx->tiles[frames->tile]); + SetDoorFramePalettes(gfx, x, y, gfx->palettes); } } -void sub_805AF54(const struct DoorGraphics * a0, int a1, int a2) +static void DrawDoorDefaultImage(const struct DoorGraphics * gfx, int x, int y) { - if (a0->unk_3 == 0) + if (gfx->size == 0) { - CurrentMapDrawMetatileAt(a1, a2); + CurrentMapDrawMetatileAt(x, y); } else { - CurrentMapDrawMetatileAt(a1, a2); - CurrentMapDrawMetatileAt(a1, a2 - 1); + CurrentMapDrawMetatileAt(x, y); + CurrentMapDrawMetatileAt(x, y - 1); } } -void sub_805AF80(const u8 *a0) +static void LoadDoorFrameTiles(const u8 *a0) { CpuFastCopy(a0, (void *)(BG_VRAM + 0x7F00), 0x100); } -void sub_805AF94(const struct DoorGraphics * a0, int a1, int a2, const u8 *a3) +static void SetDoorFramePalettes(const struct DoorGraphics * gfx, int x, int y, const u8 *a3) { u16 sp00[8]; - if (a0->unk_3 == 0) + if (gfx->size == 0) { - sub_805AFE8(sp00, 0x3F8, a3); + BufferDoorFrameTilesWithPalettes(sp00, 0x3F8, a3); } else { - sub_805AFE8(sp00, 0x3F8, a3); - sub_805A91C(a1, a2 - 1, sp00); - sub_805AFE8(sp00, 0x3FC, a3 + 4); + BufferDoorFrameTilesWithPalettes(sp00, 0x3F8, a3); + DrawDoorMetatileAt(x, y - 1, sp00); + BufferDoorFrameTilesWithPalettes(sp00, 0x3FC, a3 + 4); } - sub_805A91C(a1, a2, sp00); + DrawDoorMetatileAt(x, y, sp00); } -void sub_805AFE8(u16 *a0, u16 a1, const u8 *a2) +static void BufferDoorFrameTilesWithPalettes(u16 *a0, u16 a1, const u8 *a2) { int i; u16 tile; @@ -92,11 +97,149 @@ void sub_805AFE8(u16 *a0, u16 a1, const u8 *a2) } } -void sub_805B028(u8 taskId) +static void Task_AnimateDoor(u8 taskId) { - u16 *data = (void *)gTasks[taskId].data; - const struct DoorAnimFrame * frames = (const void *)((data[0] << 16) | data[1]); - const struct DoorGraphics * gfx = (const void *)((data[2] << 16) | data[3]); - if (!sub_805B060(gfx, frames, data)) + 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 * door_find(const struct DoorGraphics * gfx, u16 id) +{ + while (gfx->tiles != NULL) + { + if (gfx->metatileId == id) + return gfx; + gfx++; + } + return NULL; +} + +static s8 task_overworld_door_add_if_inactive(const struct DoorGraphics * gfx, const struct DoorAnimFrame * frames, int a2, int a3) +{ + u8 taskId; + s16 *data; + if (FuncIsActiveTask(Task_AnimateDoor) == TRUE) + return -1; + taskId = CreateTask(Task_AnimateDoor, 80); + data = gTasks[taskId].data; + data[6] = a2; + data[7] = a3; + 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 a1, int a2) +{ + DrawDoorDefaultImage(gfx, a1, a2); +} + +static void DrawOpenedDoor(const struct DoorGraphics * gfx, int x, int y) +{ + gfx = door_find(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 = door_find(gfx, MapGridGetMetatileIdAt(x, y)); + if (gfx == NULL) + return -1; + else if (gfx->size == 0) + return task_overworld_door_add_if_inactive(gfx, sDoorAnimFrames_OpenSmall, x, y); + else + return task_overworld_door_add_if_inactive(gfx, sDoorAnimFrames_OpenLarge, x, y); +} + +static s8 AnimateDoorCloseInternal(const struct DoorGraphics * gfx, int x, int y) +{ + gfx = door_find(gfx, MapGridGetMetatileIdAt(x, y)); + if (gfx == NULL) + return -1; + else if (gfx->size == 0) + return task_overworld_door_add_if_inactive(gfx, sDoorAnimFrames_CloseSmall, x, y); + else + return task_overworld_door_add_if_inactive(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(x, y) +{ + if (!GetDoorOpenType(sDoorGraphics, x, y)) + return MUS_W_DOOR; + else + return SE_JIDO_DOA; +} + +static s8 GetDoorOpenType(const struct DoorGraphics * gfx, int x, int y) +{ + gfx = door_find(gfx, MapGridGetMetatileIdAt(x, y)); + if (gfx == NULL) + return -1; + return gfx->sliding; +} |