summaryrefslogtreecommitdiff
path: root/src/battle_transition.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/battle_transition.c')
-rw-r--r--src/battle_transition.c388
1 files changed, 388 insertions, 0 deletions
diff --git a/src/battle_transition.c b/src/battle_transition.c
new file mode 100644
index 000000000..ed6bdf387
--- /dev/null
+++ b/src/battle_transition.c
@@ -0,0 +1,388 @@
+#include "global.h"
+#include "main.h"
+#include "rom4.h"
+#include "task.h"
+#include "palette.h"
+#include "trig.h"
+
+void sub_807DE10(void);
+void dp12_8087EA4(void);
+
+typedef bool8 (*TransitionState)(struct Task* task);
+
+extern const TransitionState sMainTransitionPhases[];
+extern const TransitionState sPhase2_Transition0_Funcs[];
+extern const TransitionState sPhase2_Transition1_Funcs[];
+extern const TransitionState sPhase2_Transition2_Funcs[];
+extern const TransitionState sPhase2_Transition3_Funcs[];
+
+extern const TaskFunc sPhase1_Tasks[];
+extern const TaskFunc sPhase2_Tasks[];
+
+extern u8 ewram[];
+extern s16 gUnknown_03005560[];
+
+extern u16 gUnknown_03004DE0[][0x3C0];
+
+struct TransitionData
+{
+ vs8 field_0; // now that's interesting
+ s8 field_1;
+ s16 field_2;
+ s16 field_4;
+ s16 field_6;
+ s16 field_8;
+ s16 field_A;
+ s16 field_C;
+ s16 field_E;
+ s16 field_10;
+ s16 field_12;
+ s16 field_14;
+ s16 field_16;
+ s16 field_18;
+};
+
+#define TRANSITION_STRUCT (*(struct TransitionData *) (ewram + 0xC000))
+
+// this file's functions
+static void LaunchBattleTransitionTask(u8 transitionID);
+static void Task_BattleTransitionMain(u8 taskID);
+void sub_811D4C8(s16 a0, s16 a1, s16 a2, s16 a3, s16 a4);
+bool8 sub_811D52C(void);
+void sub_811D658(void);
+
+static void VBlankCB_Phase2_Transition1(void);
+static void HBlankCB_Phase2_Transition1(void);
+static void VBlankCB_Phase2_Transition2(void);
+static void HBlankCB_Phase2_Transition2(void);
+void VBlankCB_Phase2_Transition3(void);
+
+void VBlankCB_BattleTransition(void);
+void sub_811D6E8(s16* a0, s16 a1, s16 a2, s16 a3, s16 a4, s16 a5);
+void sub_811D6A8(u16** a0, u16** a1);
+
+void sub_811AABC(u8 transitionID)
+{
+ gMain.callback2 = sub_8054398;
+ LaunchBattleTransitionTask(transitionID);
+}
+
+void sub_811AAD8(u8 transitionID)
+{
+ LaunchBattleTransitionTask(transitionID);
+}
+
+#define tState data[0]
+#define tTransitionID data[1]
+#define tTransitionDone data[15]
+
+bool8 IsBattleTransitionDone(void)
+{
+ u8 taskID = FindTaskIdByFunc(Task_BattleTransitionMain);
+ if (gTasks[taskID].tTransitionDone)
+ {
+ DestroyTask(taskID);
+ return 1;
+ }
+ else
+ return 0;
+}
+
+static void LaunchBattleTransitionTask(u8 transitionID)
+{
+ u8 taskID = CreateTask(Task_BattleTransitionMain, 2);
+ gTasks[taskID].tTransitionID = transitionID;
+}
+
+static void Task_BattleTransitionMain(u8 taskID)
+{
+ while (sMainTransitionPhases[gTasks[taskID].tState](&gTasks[taskID]));
+}
+
+bool8 Transition_Phase1(struct Task* task)
+{
+ sub_807DE10();
+ CpuSet(gPlttBufferFaded, gPlttBufferUnfaded, 0x4000100);
+ if (sPhase1_Tasks[task->tTransitionID] != NULL)
+ {
+ CreateTask(sPhase1_Tasks[task->tTransitionID], 4);
+ task->tState++;
+ return 0;
+ }
+ else
+ {
+ task->tState = 2;
+ return 1;
+ }
+}
+
+bool8 Transition_WaitForPhase1(struct Task* task)
+{
+ if (FindTaskIdByFunc(sPhase1_Tasks[task->tTransitionID]) == 0xFF)
+ {
+ task->tState++;
+ return 1;
+ }
+ else
+ return 0;
+}
+
+bool8 Transition_Phase2(struct Task* task)
+{
+ CreateTask(sPhase2_Tasks[task->tTransitionID], 0);
+ task->tState++;
+ return 0;
+}
+
+bool8 Transition_WaitForPhase2(struct Task* task)
+{
+ task->tTransitionDone = 0;
+ if (FindTaskIdByFunc(sPhase2_Tasks[task->tTransitionID]) == 0xFF)
+ task->tTransitionDone = 1;
+ return 0;
+}
+
+void Phase1Task_TransitionAll(u8 taskID)
+{
+ if (gTasks[taskID].tState == 0)
+ {
+ gTasks[taskID].tState++;
+ sub_811D4C8(0, 0, 3, 2, 2);
+ }
+ else if (sub_811D52C())
+ DestroyTask(taskID);
+}
+
+void Phase2Task_Transition0(u8 taskID)
+{
+ while (sPhase2_Transition0_Funcs[gTasks[taskID].tState](&gTasks[taskID]));
+}
+
+bool8 Phase2_Transition0_Func1(struct Task* task)
+{
+ REG_MOSAIC = 0;
+ REG_BG1CNT |= 0x40;
+ REG_BG2CNT |= 0x40;
+ REG_BG3CNT |= 0x40;
+ task->tState++;
+ return 1;
+}
+
+bool8 Phase2_Transition0_Func2(struct Task* task)
+{
+ if (task->data[1] != 0)
+ task->data[1]--;
+ else
+ {
+ task->data[1] = 4;
+ if (++task->data[2] == 10)
+ BeginNormalPaletteFade(-1, -1, 0, 0x10, 0);
+ REG_MOSAIC = (task->data[2] & 15) * 17;
+ if (task->data[2] > 14)
+ task->tState++;
+ }
+ return 0;
+}
+
+bool8 Phase2_Transition0_Func3(struct Task* task)
+{
+ if (!gPaletteFade.active)
+ {
+ u8 taskID = FindTaskIdByFunc(Phase2Task_Transition0);
+ DestroyTask(taskID);
+ }
+ return 0;
+}
+
+void Phase2Task_Transition1(u8 taskID)
+{
+ while (sPhase2_Transition1_Funcs[gTasks[taskID].tState](&gTasks[taskID]));
+}
+
+bool8 Phase2_Transition1_Func1(struct Task* task)
+{
+ u16 savedIME;
+
+ sub_811D658();
+ dp12_8087EA4();
+ BeginNormalPaletteFade(-1, 4, 0, 0x10, 0);
+ sub_811D6E8(gUnknown_03005560, TRANSITION_STRUCT.field_14, 0, 2, 0, 160);
+
+ SetVBlankCallback(VBlankCB_Phase2_Transition1);
+ SetHBlankCallback(HBlankCB_Phase2_Transition1);
+
+ savedIME = REG_IME;
+ REG_IME = 0;
+ REG_IE |= 3;
+ REG_IME = savedIME;
+ REG_DISPSTAT |= 0x18;
+
+ task->tState++;
+ return 0;
+}
+
+bool8 Phase2_Transition1_Func2(struct Task* task)
+{
+ TRANSITION_STRUCT.field_0 = 0;
+ task->data[1] += 4;
+ task->data[2] += 8;
+
+ sub_811D6E8(gUnknown_03004DE0[0], TRANSITION_STRUCT.field_14, task->data[1], 2, task->data[2], 160);
+
+ if (!gPaletteFade.active)
+ {
+ u8 taskID = FindTaskIdByFunc(Phase2Task_Transition1);
+ DestroyTask(taskID);
+ }
+
+ TRANSITION_STRUCT.field_0++;
+ return 0;
+}
+
+static void VBlankCB_Phase2_Transition1(void)
+{
+ VBlankCB_BattleTransition();
+ if (TRANSITION_STRUCT.field_0)
+ DmaCopy16(3, gUnknown_03004DE0[0], gUnknown_03004DE0[1], 320);
+}
+
+static void HBlankCB_Phase2_Transition1(void)
+{
+ u16 var = gUnknown_03004DE0[1][REG_VCOUNT];
+ REG_BG1HOFS = var;
+ REG_BG2HOFS = var;
+ REG_BG3HOFS = var;
+}
+
+void Phase2Task_Transition2(u8 taskID)
+{
+ while (sPhase2_Transition2_Funcs[gTasks[taskID].tState](&gTasks[taskID]));
+}
+
+bool8 Phase2_Transition2_Func1(struct Task* task)
+{
+ u16 savedIME;
+
+ sub_811D658();
+ dp12_8087EA4();
+
+ BeginNormalPaletteFade(-1, 4, 0, 0x10, 0);
+ memset(gUnknown_03005560, TRANSITION_STRUCT.field_16, 0x140);
+
+ SetVBlankCallback(VBlankCB_Phase2_Transition2);
+ SetHBlankCallback(HBlankCB_Phase2_Transition2);
+
+ savedIME = REG_IME;
+ REG_IME = 0;
+ REG_IE |= 3;
+ REG_IME = savedIME;
+ REG_DISPSTAT |= 0x18;
+
+ task->tState++;
+ return 0;
+}
+
+bool8 Phase2_Transition2_Func2(struct Task* task)
+{
+ u8 i;
+ u16 r3, r4;
+
+ TRANSITION_STRUCT.field_0 = 0;
+ r4 = task->data[1];
+ r3 = task->data[2] >> 8;
+ task->data[1] += 4224;
+ task->data[2] += 384;
+
+ for (i = 0; i < 160; i++, r4 += 4224)
+ {
+ u16 var = r4 / 256;
+ gUnknown_03004DE0[0][i] = TRANSITION_STRUCT.field_16 + Sin(var, r3);
+ }
+
+ if (!gPaletteFade.active)
+ DestroyTask(FindTaskIdByFunc(Phase2Task_Transition2));
+
+ TRANSITION_STRUCT.field_0++;
+ return 0;
+}
+
+static void VBlankCB_Phase2_Transition2(void)
+{
+ VBlankCB_BattleTransition();
+ if (TRANSITION_STRUCT.field_0)
+ DmaCopy16(3, gUnknown_03004DE0[0], gUnknown_03004DE0[1], 320);
+}
+
+static void HBlankCB_Phase2_Transition2(void)
+{
+ u16 var = gUnknown_03004DE0[1][REG_VCOUNT];
+ REG_BG1VOFS = var;
+ REG_BG2VOFS = var;
+ REG_BG3VOFS = var;
+}
+
+void Phase2Task_Transition3(u8 taskID)
+{
+ while (sPhase2_Transition3_Funcs[gTasks[taskID].tState](&gTasks[taskID]));
+}
+
+extern const u8 gUnknown_083FBB88[];
+extern const u16 gFieldEffectObjectPalette10[];
+
+bool8 Phase2_Transition3_Func1(struct Task* task)
+{
+ u16 i;
+ u16 *dst1, *dst2;
+
+ sub_811D658();
+ dp12_8087EA4();
+
+ task->data[1] = 16;
+ task->data[2] = 0;
+ task->data[4] = 0;
+ task->data[5] = 0x4000;
+ TRANSITION_STRUCT.field_2 = 63;
+ TRANSITION_STRUCT.field_4 = 0;
+ TRANSITION_STRUCT.field_6 = 240;
+ TRANSITION_STRUCT.field_8 = 160;
+ TRANSITION_STRUCT.field_E = 0x3F41;
+ TRANSITION_STRUCT.field_10 = task->data[1] * 256; // 16 * 256 = 0x1000
+
+ for (i = 0; i < 160; i++)
+ {
+ gUnknown_03005560[i] = 240;
+ }
+
+ SetVBlankCallback(VBlankCB_Phase2_Transition3);
+
+ sub_811D6A8(&dst1, & dst2);
+ CpuFill16(0, dst1, 0x800);
+ CpuSet(gUnknown_083FBB88, dst2, 0x2C0);
+ LoadPalette(gFieldEffectObjectPalette10, 240, 32);
+
+ task->tState++;
+ return 0;
+}
+
+extern const u16 gUnknown_083FDB44[];
+
+bool8 Phase2_Transition3_Func2(struct Task* task)
+{
+ s16 i, j;
+ u16 *dst1, *dst2;
+ const u16* var;
+
+ var = gUnknown_083FDB44;
+ sub_811D6A8(&dst1, &dst2);
+ for (i = 0; i < 20; i++)
+ {
+ for (j = 0; j < 30; j++, var++)
+ {
+ dst1[i * 32 + j] = *var | 0xF000;
+ }
+ }
+ sub_811D6E8(gUnknown_03004DE0[0], 0, task->data[4], 132, task->data[5], 160);
+
+ task->tState++;
+ return 1;
+}