summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/field_door.c225
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;
+}