diff options
Diffstat (limited to 'src/battle_transition.c')
-rw-r--r-- | src/battle_transition.c | 302 |
1 files changed, 302 insertions, 0 deletions
diff --git a/src/battle_transition.c b/src/battle_transition.c new file mode 100644 index 000000000..35d3baf0c --- /dev/null +++ b/src/battle_transition.c @@ -0,0 +1,302 @@ +#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 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); +void VBlankCB_Phase2_Transition2(void); +void HBlankCB_Phase2_Transition2(void); +void VBlankCB_BattleTransition(void); +void sub_811D6E8(s16* a0, s16 a1, s16 a2, s16 a3, s16 a4, s16 a5); + +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] = Sin(var, r3) + TRANSITION_STRUCT.field_16; + } + + if (!gPaletteFade.active) + DestroyTask(FindTaskIdByFunc(Phase2Task_Transition2)); + + TRANSITION_STRUCT.field_0++; + return 0; +} |