summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/field_door.c233
-rw-r--r--src/rom4.c4
-rw-r--r--src/scrcmd.c58
3 files changed, 264 insertions, 31 deletions
diff --git a/src/field_door.c b/src/field_door.c
new file mode 100644
index 000000000..68c884af1
--- /dev/null
+++ b/src/field_door.c
@@ -0,0 +1,233 @@
+#include "global.h"
+#include "task.h"
+
+extern u8 MetatileBehavior_IsDoor(u8);
+
+struct DoorGraphics
+{
+ u16 metatileNum;
+ u8 unk2;
+ void *tiles;
+ void *palette;
+};
+
+struct DoorAnimFrame
+{
+ u8 time;
+ u16 offset;
+};
+
+extern struct DoorAnimFrame gDoorOpenAnimFrames[];
+extern struct DoorAnimFrame gDoorCloseAnimFrames[];
+extern struct DoorGraphics gDoorAnimGraphicsTable[];
+
+static void CopyDoorTilesToVram(void *src)
+{
+ CpuFastSet(src, (void *)(VRAM + 0x7F00), 0x40);
+}
+
+static void door_build_blockdef(u16 *a, u16 b, u8 *c)
+{
+ int i;
+ u16 unk;
+
+ for (i = 0; i < 4; i++)
+ {
+ unk = *(c++) << 12;
+ a[i] = unk | (b + i);
+ }
+ for (; i < 8; i++)
+ {
+ unk = *(c++) << 12;
+ a[i] = unk;
+ }
+}
+
+static void DrawCurrentDoorAnimFrame(u32 x, u32 y, u8 *c)
+{
+ u16 arr[8];
+
+ door_build_blockdef(arr, 0x3F8, c);
+ DrawDoorMetatileAt(x, y - 1, arr);
+ door_build_blockdef(arr, 0x3FC, c + 4);
+ DrawDoorMetatileAt(x, y, arr);
+}
+
+static void DrawClosedDoorTiles(u32 x, u32 y)
+{
+ CurrentMapDrawMetatileAt(x, y - 1);
+ CurrentMapDrawMetatileAt(x, y);
+}
+
+static void DrawDoor(struct DoorGraphics *gfx, struct DoorAnimFrame *frame, u32 x, u32 y)
+{
+ if (frame->offset == 0xFFFF)
+ DrawClosedDoorTiles(x, y);
+ else
+ {
+ CopyDoorTilesToVram(gfx->tiles + frame->offset);
+ DrawCurrentDoorAnimFrame(x, y, gfx->palette);
+ }
+}
+
+enum
+{
+ TD_FRAMELIST = 0,
+ TD_GFX = 2,
+ TD_FRAME = 4,
+ TD_COUNTER,
+ TD_X,
+ TD_Y
+};
+
+static bool32 sub_8058464(struct DoorGraphics *gfx, struct DoorAnimFrame *frames, s16 *taskData)
+{
+ if (taskData[TD_COUNTER] == 0)
+ DrawDoor(gfx, &frames[taskData[TD_FRAME]], taskData[TD_X], taskData[TD_Y]);
+ if (taskData[TD_COUNTER] == frames[taskData[TD_FRAME]].time)
+ {
+ taskData[TD_COUNTER] = 0;
+ taskData[TD_FRAME]++;
+ if (frames[taskData[TD_FRAME]].time == 0)
+ return FALSE;
+ else
+ return TRUE;
+ }
+ taskData[TD_COUNTER]++;
+ return TRUE;
+}
+
+static void Task_AnimateDoor(u8 taskId)
+{
+ u16 *taskData = gTasks[taskId].data;
+ struct DoorAnimFrame *frames = (struct DoorAnimFrame *)(taskData[TD_FRAMELIST] << 16 | taskData[TD_FRAMELIST + 1]);
+ struct DoorGraphics *gfx = (struct DoorGraphics *)(taskData[TD_GFX] << 16 | taskData[TD_GFX + 1]);
+
+ if (sub_8058464(gfx, frames, taskData) == FALSE)
+ DestroyTask(taskId);
+}
+
+static struct DoorAnimFrame *GetLastDoorFrame(struct DoorAnimFrame *frame, void *unused)
+{
+ while (frame->time != 0)
+ frame++;
+ return frame - 1;
+}
+
+static struct DoorGraphics *GetDoorGraphics(struct DoorGraphics *gfx, u16 metatileNum)
+{
+ while (gfx->tiles != NULL)
+ {
+ if (gfx->metatileNum == metatileNum)
+ return gfx;
+ gfx++;
+ }
+ return NULL;
+}
+
+static s8 StartDoorAnimationTask(struct DoorGraphics *gfx, struct DoorAnimFrame *frames, u32 x, u32 y)
+{
+ if (FuncIsActiveTask(Task_AnimateDoor) == TRUE)
+ return -1;
+ else
+ {
+ u8 taskId = CreateTask(Task_AnimateDoor, 0x50);
+ s16 *taskData = gTasks[taskId].data;
+
+ taskData[TD_X] = x;
+ taskData[TD_Y] = y;
+
+ taskData[TD_FRAMELIST + 1] = (u32)frames;
+ taskData[TD_FRAMELIST] = (u32)frames >> 16;
+
+ taskData[TD_GFX + 1] = (u32)gfx;
+ taskData[TD_GFX] = (u32)gfx >> 16;
+
+ return taskId;
+ }
+}
+
+static void DrawClosedDoor(struct DoorGraphics *unused, u32 x, u32 y)
+{
+ DrawClosedDoorTiles(x, y);
+}
+
+static void DrawOpenedDoor(struct DoorGraphics *gfx, u32 x, u32 y)
+{
+ gfx = GetDoorGraphics(gfx, MapGridGetMetatileIdAt(x, y));
+ if (gfx != NULL)
+ DrawDoor(gfx, GetLastDoorFrame(gDoorOpenAnimFrames, gDoorOpenAnimFrames), x, y);
+}
+
+static s8 StartDoorOpenAnimation(struct DoorGraphics *gfx, u32 x, u32 y)
+{
+ gfx = GetDoorGraphics(gfx, MapGridGetMetatileIdAt(x, y));
+ if (gfx == NULL)
+ return -1;
+ else
+ return StartDoorAnimationTask(gfx, gDoorOpenAnimFrames, x, y);
+}
+
+static s8 StartDoorCloseAnimation(struct DoorGraphics *gfx, u32 x, u32 y)
+{
+ gfx = GetDoorGraphics(gfx, MapGridGetMetatileIdAt(x, y));
+ if (gfx == NULL)
+ return -1;
+ else
+ return StartDoorAnimationTask(gfx, gDoorCloseAnimFrames, x, y);
+}
+
+static s8 cur_mapdata_get_door_x2_at(struct DoorGraphics *gfx, u32 x, u32 y)
+{
+ gfx = GetDoorGraphics(gfx, MapGridGetMetatileIdAt(x, y));
+ if (gfx == NULL)
+ return -1;
+ else
+ return gfx->unk2;
+}
+
+static void unref_sub_805869C(u32 x, u32 y)
+{
+ StartDoorOpenAnimation(gDoorAnimGraphicsTable, x, y);
+}
+
+void FieldSetDoorOpened(u32 x, u32 y)
+{
+ if (MetatileBehavior_IsDoor(MapGridGetMetatileBehaviorAt(x, y)))
+ DrawOpenedDoor(gDoorAnimGraphicsTable, x, y);
+}
+
+void FieldSetDoorClosed(u32 x, u32 y)
+{
+ if (MetatileBehavior_IsDoor(MapGridGetMetatileBehaviorAt(x, y)))
+ DrawClosedDoor(gDoorAnimGraphicsTable, x, y);
+}
+
+s8 FieldAnimateDoorClose(u32 x, u32 y)
+{
+ if (!MetatileBehavior_IsDoor(MapGridGetMetatileBehaviorAt(x, y)))
+ return -1;
+ else
+ return StartDoorCloseAnimation(gDoorAnimGraphicsTable, x, y);
+}
+
+s8 FieldAnimateDoorOpen(u32 x, u32 y)
+{
+ if (!MetatileBehavior_IsDoor(MapGridGetMetatileBehaviorAt(x, y)))
+ return -1;
+ else
+ return StartDoorOpenAnimation(gDoorAnimGraphicsTable, x, y);
+}
+
+bool8 FieldIsDoorAnimationRunning(void)
+{
+ return FuncIsActiveTask(Task_AnimateDoor);
+}
+
+u8 sub_8058790(u32 x, u32 y)
+{
+ if (cur_mapdata_get_door_x2_at(gDoorAnimGraphicsTable, x, y) == 0)
+ return 8;
+ else
+ return 18;
+}
diff --git a/src/rom4.c b/src/rom4.c
index d7bd9b7a3..15041cb39 100644
--- a/src/rom4.c
+++ b/src/rom4.c
@@ -172,7 +172,7 @@ u8 sub_8053B60(struct UnkPlayerStruct *playerStruct, u8, u16, u8);
u8 MetatileBehavior_IsSurfableWaterOrUnderwater(u8);
bool8 sub_8056F24(u8);
bool8 sub_8056F08(u8);
-bool8 sub_8056EAC(u8);
+bool8 MetatileBehavior_IsDoor(u8);
bool8 MetatileBehavior_IsSouthArrowWarp(u8);
bool8 MetatileBehavior_IsNorthArrowWarp(u8);
bool8 MetatileBehavior_IsWestArrowWarp(u8);
@@ -769,7 +769,7 @@ u8 sub_8053B60(struct UnkPlayerStruct *playerStruct, u8 a2, u16 a3, u8 a4)
return 4;
if (sub_8056F24(a3) == TRUE)
return 2;
- if (sub_8056F08(a3) == TRUE || sub_8056EAC(a3) == TRUE)
+ if (sub_8056F08(a3) == TRUE || MetatileBehavior_IsDoor(a3) == TRUE)
return 1;
if (MetatileBehavior_IsSouthArrowWarp(a3) == TRUE)
return 2;
diff --git a/src/scrcmd.c b/src/scrcmd.c
index aa6fdd5ed..9d6f36a54 100644
--- a/src/scrcmd.c
+++ b/src/scrcmd.c
@@ -123,11 +123,11 @@ extern bool8 FieldEffectActiveListContains(u8);
extern void sub_8053588(u8);
extern void MapGridSetMetatileIdAt(u32, u32, u16);
extern u16 sub_8058790(u32, u32);
-extern bool8 task_overworld_door_add_if_role_69_for_opening_door_at(u32, u32);
-extern bool8 sub_805870C(u32, u32);
-extern bool8 sub_805877C(void);
-extern void sub_80586B4(u32, u32);
-extern void sub_80586E0(u32, u32);
+extern bool8 FieldAnimateDoorOpen(u32, u32);
+extern bool8 FieldAnimateDoorClose(u32, u32);
+extern bool8 FieldIsDoorAnimationRunning(void);
+extern void FieldSetDoorOpened(u32, u32);
+extern void FieldSetDoorClosed(u32, u32);
extern void ScriptAddElevatorMenuItem(u8, u8, u8, u8);
extern void ScriptShowElevatorMenu(void);
extern u16 GetCoins(void);
@@ -1871,28 +1871,28 @@ bool8 ScrCmd_setmaptile(struct ScriptContext *ctx)
bool8 ScrCmd_setdooropened(struct ScriptContext *ctx)
{
- u16 v3 = VarGet(ScriptReadHalfword(ctx));
- u16 v4 = VarGet(ScriptReadHalfword(ctx));
- v3 += 7;
- v4 += 7;
- PlaySE(sub_8058790(v3, v4));
- task_overworld_door_add_if_role_69_for_opening_door_at(v3, v4);
+ u16 x = VarGet(ScriptReadHalfword(ctx));
+ u16 y = VarGet(ScriptReadHalfword(ctx));
+ x += 7;
+ y += 7;
+ PlaySE(sub_8058790(x, y));
+ FieldAnimateDoorOpen(x, y);
return FALSE;
}
bool8 ScrCmd_setdoorclosed(struct ScriptContext *ctx)
{
- u16 v3 = VarGet(ScriptReadHalfword(ctx));
- u16 v5 = VarGet(ScriptReadHalfword(ctx));
- v3 += 7;
- v5 += 7;
- sub_805870C(v3, v5);
+ u16 x = VarGet(ScriptReadHalfword(ctx));
+ u16 y = VarGet(ScriptReadHalfword(ctx));
+ x += 7;
+ y += 7;
+ FieldAnimateDoorClose(x, y);
return FALSE;
}
-bool8 sub_8067D2C()
+bool8 IsDoorAnimationStopped()
{
- if (!sub_805877C())
+ if (!FieldIsDoorAnimationRunning())
return TRUE;
else
return FALSE;
@@ -1900,27 +1900,27 @@ bool8 sub_8067D2C()
bool8 ScrCmd_doorchange(struct ScriptContext *ctx)
{
- SetupNativeScript(ctx, sub_8067D2C);
+ SetupNativeScript(ctx, IsDoorAnimationStopped);
return TRUE;
}
bool8 ScrCmd_setdooropened2(struct ScriptContext *ctx)
{
- u16 v3 = VarGet(ScriptReadHalfword(ctx));
- u16 v5 = VarGet(ScriptReadHalfword(ctx));
- v3 += 7;
- v5 += 7;
- sub_80586B4(v3, v5);
+ u16 x = VarGet(ScriptReadHalfword(ctx));
+ u16 y = VarGet(ScriptReadHalfword(ctx));
+ x += 7;
+ y += 7;
+ FieldSetDoorOpened(x, y);
return FALSE;
}
bool8 ScrCmd_setdoorclosed2(struct ScriptContext *ctx)
{
- u16 v3 = VarGet(ScriptReadHalfword(ctx));
- u16 v5 = VarGet(ScriptReadHalfword(ctx));
- v3 += 7;
- v5 += 7;
- sub_80586E0(v3, v5);
+ u16 x = VarGet(ScriptReadHalfword(ctx));
+ u16 y = VarGet(ScriptReadHalfword(ctx));
+ x += 7;
+ y += 7;
+ FieldSetDoorClosed(x, y);
return FALSE;
}