summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorProjectRevoTPP <projectrevotpp@hotmail.com>2018-01-11 14:55:51 -0500
committerProjectRevoTPP <projectrevotpp@hotmail.com>2018-01-11 14:55:51 -0500
commit8b41179e9349ac3dcc98f2436be2fa70f5040a33 (patch)
treebe57f4b91ef966980e0ed8cee40cd920bb70c473 /src
parent2e713e820ac25a6a68a150c4f07d4865609985f6 (diff)
parente7672a1aeb5e42d6f4e416ede9f6220122d11743 (diff)
merge
Diffstat (limited to 'src')
-rwxr-xr-xsrc/battle/anim/dark.c138
-rwxr-xr-xsrc/battle/anim/dragon.c275
-rwxr-xr-xsrc/battle/anim/draw.c36
-rw-r--r--src/battle/battle_2.c44
-rw-r--r--src/battle/battle_4.c4
-rw-r--r--src/battle/battle_controller_player.c4
-rw-r--r--src/battle/battle_transition.c172
-rw-r--r--src/battle/reshow_battle_screen.c12
-rw-r--r--src/contest.c18
-rw-r--r--src/crt0.s227
-rw-r--r--src/debug/matsuda_debug_menu.c18
-rw-r--r--src/easy_chat_1.c12
-rw-r--r--src/easy_chat_2.c4
-rw-r--r--src/engine/main.c4
-rw-r--r--src/engine/main_menu.c8
-rw-r--r--src/engine/option_menu.c4
-rw-r--r--src/engine/reset_rtc_screen.c6
-rw-r--r--src/engine/trainer_card.c32
-rw-r--r--src/field/diploma.c4
-rw-r--r--src/field/field_screen_effect.c24
-rw-r--r--src/field/item_menu.c4
-rw-r--r--src/field/overworld.c12
-rw-r--r--src/field/party_menu.c4
-rw-r--r--src/field/pokeblock.c4
-rw-r--r--src/field/shop.c4
-rw-r--r--src/field/start_menu.c6
-rw-r--r--src/field/starter_choose.c4
-rw-r--r--src/field/use_pokeblock.c4
-rw-r--r--src/field/wallclock.c4
-rw-r--r--src/libs/libagbsyscall.s91
-rw-r--r--src/libs/libgcnmultiboot.s641
-rw-r--r--src/libs/m4a_1.s1911
-rw-r--r--src/pokemon/mail.c4
-rw-r--r--src/pokemon/pokedex.c6
-rw-r--r--src/pokemon/pokemon_summary_screen.c24
-rw-r--r--src/pokenav_before.c6
-rw-r--r--src/roulette.c4
-rw-r--r--src/scanline_effect.c261
-rw-r--r--src/scene/cable_car.c4
-rw-r--r--src/scene/contest_painting.c4
-rw-r--r--src/scene/evolution_scene.c32
-rw-r--r--src/scene/hall_of_fame.c4
-rw-r--r--src/scene/intro.c4
-rwxr-xr-xsrc/scene/intro_credits_graphics.c2
-rw-r--r--src/scene/title_screen.c8
-rw-r--r--src/unknown_task.c235
46 files changed, 3821 insertions, 512 deletions
diff --git a/src/battle/anim/dark.c b/src/battle/anim/dark.c
new file mode 100755
index 000000000..8ceb00298
--- /dev/null
+++ b/src/battle/anim/dark.c
@@ -0,0 +1,138 @@
+#include "global.h"
+#include "rom_8077ABC.h"
+#include "trig.h"
+#include "battle_anim.h"
+#include "sound.h"
+#include "scanline_effect.h"
+
+void sub_80DFE90(struct Sprite *sprite);
+
+void sub_80DFC9C(u8 taskId);
+void sub_80DFD58(u8 taskId);
+
+extern s16 gBattleAnimArgs[];
+extern u8 gAnimBankAttacker;
+extern u8 gAnimBankTarget;
+extern u8 gObjectBankIDs[];
+
+// used in Smoke Ball escape, Sky Attack, Feint Attack and Camouflage
+
+void sub_80DFC24(u8 taskId)
+{
+ int bank;
+ gTasks[taskId].data[0] = gBattleAnimArgs[0];
+ bank = gAnimBankAttacker;
+ gTasks[taskId].data[1] = 16;
+ REG_BLDALPHA = 16;
+ if (GetBankIdentity_permutated(bank) == 1)
+ REG_BLDCNT = 0x3F42;
+ else
+ REG_BLDCNT = 0x3F44;
+ gTasks[taskId].func = sub_80DFC9C;
+}
+
+void sub_80DFC9C(u8 taskId)
+{
+ u8 r2 = gTasks[taskId].data[1] >> 8;
+ u8 r1 = gTasks[taskId].data[1];
+ if (gTasks[taskId].data[2] == (u8)gTasks[taskId].data[0])
+ {
+ r2++;
+ r1--;
+ gTasks[taskId].data[1] = (r2 << 8) | r1;
+ REG_BLDALPHA = (r2 << 8) | r1;
+ gTasks[taskId].data[2] = 0;
+ if (r2 == 16)
+ {
+ gSprites[gObjectBankIDs[gAnimBankAttacker]].invisible = 1;
+ DestroyAnimVisualTask(taskId);
+ }
+ }
+ else
+ gTasks[taskId].data[2]++;
+}
+
+void sub_80DFD24(u8 taskId)
+{
+ gTasks[taskId].data[0] = gBattleAnimArgs[0];
+ gTasks[taskId].data[1] = 0x1000;
+ gTasks[taskId].func = sub_80DFD58;
+ REG_BLDALPHA = 0x1000;
+}
+
+void sub_80DFD58(u8 taskId)
+{
+ u8 r1 = gTasks[taskId].data[1] >> 8;
+ u8 r5 = gTasks[taskId].data[1];
+ if (gTasks[taskId].data[2] == (u8)gTasks[taskId].data[0])
+ {
+ r1--;
+ r5++;
+ gTasks[taskId].data[1] = (r1 << 8) | r5;
+ REG_BLDALPHA = (r1 << 8) | r5;
+ gTasks[taskId].data[2] = 0;
+ if (r1 == 0)
+ {
+ REG_BLDCNT = 0;
+ REG_BLDALPHA = 0;
+ DestroyAnimVisualTask(taskId);
+ }
+ }
+ else
+ gTasks[taskId].data[2]++;
+}
+
+// unlike the above is only used in Feint Attack
+
+void sub_80DFDC0(u8 taskId)
+{
+ REG_BLDALPHA = 0x1000;
+ if (GetBankIdentity_permutated(gAnimBankAttacker) == 1)
+ REG_BLDCNT = 0x3F42;
+ else
+ REG_BLDCNT = 0x3F44;
+ DestroyAnimVisualTask(taskId);
+}
+
+// unused sprite template's callback
+
+void sub_80DFE14(struct Sprite *sprite)
+{
+ sprite->data[1] = GetBankPosition(gAnimBankTarget, 2);
+ sprite->data[2] = GetBankPosition(gAnimBankAttacker, 2);
+ sprite->data[3] = GetBankPosition(gAnimBankTarget, 3);
+ sprite->data[4] = GetBankPosition(gAnimBankAttacker, 3);
+ sprite->data[0] = 0x7E;
+ sub_8078A5C(sprite);
+ sprite->data[3] = -sprite->data[1];
+ sprite->data[4] = -sprite->data[2];
+ sprite->data[6] = 0xFFD8;
+ sprite->callback = sub_80DFE90;
+ sub_80DFE90(sprite);
+}
+
+void sub_80DFE90(struct Sprite *sprite)
+{
+ sprite->data[3] += sprite->data[1];
+ sprite->data[4] += sprite->data[2];
+ sprite->pos2.x = sprite->data[3] >> 8;
+ sprite->pos2.y = sprite->data[4] >> 8;
+ if (sprite->data[7] == 0)
+ {
+ sprite->data[3] += sprite->data[1];
+ sprite->data[4] += sprite->data[2];
+ sprite->pos2.x = sprite->data[3] >> 8;
+ sprite->pos2.y = sprite->data[4] >> 8;
+ sprite->data[0]--;
+ }
+ sprite->pos2.y += Sin(sprite->data[5], sprite->data[6]);
+ sprite->data[5] = (sprite->data[5] + 3) & 0xFF;
+ if (sprite->data[5] > 0x7F)
+ {
+ sprite->data[5] = 0;
+ sprite->data[6] += 20;
+ sprite->data[7]++;
+ }
+ if (--sprite->data[0] == 0)
+ DestroyAnimSprite(sprite);
+}
diff --git a/src/battle/anim/dragon.c b/src/battle/anim/dragon.c
new file mode 100755
index 000000000..bf39e01c0
--- /dev/null
+++ b/src/battle/anim/dragon.c
@@ -0,0 +1,275 @@
+#include "global.h"
+#include "rom_8077ABC.h"
+#include "trig.h"
+#include "battle_anim.h"
+#include "sound.h"
+#include "scanline_effect.h"
+
+void sub_80DF81C(struct Sprite *sprite);
+void sub_80DFBD8(struct Sprite *sprite);
+
+void sub_80DF9F4(u8 taskId);
+
+void sub_80DFAB0(struct Task *task);
+
+extern s16 gBattleAnimArgs[];
+extern u8 gAnimBankAttacker;
+extern u8 gAnimBankTarget;
+extern u8 gBankAttacker;
+extern u16 gBattle_BG1_X;
+extern u16 gBattle_BG2_X;
+extern u16 gUnknown_03000730[];
+extern u8 gObjectBankIDs[];
+
+// Outrage
+
+void sub_80DF5A0(struct Sprite *sprite)
+{
+ sprite->pos1.x = GetBankPosition(gAnimBankAttacker, 2);
+ sprite->pos1.y = GetBankPosition(gAnimBankAttacker, 3);
+ if (GetBankSide(gAnimBankAttacker))
+ {
+ sprite->pos1.x -= gBattleAnimArgs[0];
+ gBattleAnimArgs[3] = -gBattleAnimArgs[3];
+ gBattleAnimArgs[4] = -gBattleAnimArgs[4];
+ }
+ else
+ sprite->pos1.x += gBattleAnimArgs[0];
+ sprite->pos1.y += gBattleAnimArgs[1];
+ sprite->data[0] = gBattleAnimArgs[2];
+ sprite->data[1] = gBattleAnimArgs[3];
+ sprite->data[3] = gBattleAnimArgs[4];
+ sprite->data[5] = gBattleAnimArgs[5];
+ sprite->invisible = 1;
+ StoreSpriteCallbackInData(sprite, move_anim_8074EE0);
+ sprite->callback = sub_8078504;
+}
+
+// part of Dragon Breath
+
+void sub_80DF63C(struct Sprite *sprite)
+{
+ sub_8078650(sprite);
+ sprite->data[2] = GetBankPosition(gAnimBankTarget, 2);
+ sprite->data[4] = GetBankPosition(gAnimBankTarget, 3);
+ if (GetBankSide(gAnimBankAttacker))
+ {
+ sprite->pos1.x -= gBattleAnimArgs[1];
+ sprite->pos1.y += gBattleAnimArgs[1];
+ sprite->data[2] -= gBattleAnimArgs[2];
+ sprite->data[4] += gBattleAnimArgs[3];
+ }
+ else
+ {
+ sprite->pos1.x += gBattleAnimArgs[0];
+ sprite->pos1.y += gBattleAnimArgs[1];
+ sprite->data[2] += gBattleAnimArgs[2];
+ sprite->data[4] += gBattleAnimArgs[3];
+ StartSpriteAnim(sprite, 1);
+ }
+ sprite->data[0] = gBattleAnimArgs[4];
+ sprite->callback = sub_8078B34;
+ StoreSpriteCallbackInData(sprite, move_anim_8074EE0);
+}
+
+// Dragon Rage
+
+void sub_80DF6F0(struct Sprite *sprite)
+{
+ if (gBattleAnimArgs[0] == 0)
+ {
+ sprite->pos1.x = GetBankPosition(gAnimBankAttacker, 0);
+ sprite->pos1.y = GetBankPosition(gAnimBankAttacker, 1);
+ }
+ else
+ {
+ sprite->pos1.x = GetBankPosition(gAnimBankTarget, 0);
+ sprite->pos1.y = GetBankPosition(gAnimBankTarget, 1);
+ }
+ sub_807867C(sprite, gBattleAnimArgs[1]);
+ sprite->pos1.y += gBattleAnimArgs[2];
+ sprite->callback = sub_8078600;
+ StoreSpriteCallbackInData(sprite, move_anim_8074EE0);
+}
+
+// Dragon Breath init
+
+void sub_80DF760(struct Sprite *sprite)
+{
+ if (GetBankSide(gAnimBankAttacker))
+ StartSpriteAffineAnim(sprite, 1);
+ sub_80DF63C(sprite);
+}
+
+//next 2 tasks might be Dragon Dance orbs?
+
+void sub_80DF78C(struct Sprite *sprite)
+{
+ u16 r5;
+ u16 r0;
+ sprite->pos1.x = GetBankPosition(gAnimBankAttacker, 2);
+ sprite->pos1.y = GetBankPosition(gAnimBankAttacker, 3);
+ sprite->data[4] = 0;
+ sprite->data[5] = 1;
+ sprite->data[6] = gBattleAnimArgs[0];
+ r5 = sub_807A100(gBankAttacker, 0);
+ r0 = sub_807A100(gBankAttacker, 1);
+ if (r5 > r0)
+ sprite->data[7] = r5 / 2;
+ else
+ sprite->data[7] = r0 / 2;
+ sprite->pos2.x = Cos(sprite->data[6], sprite->data[7]);
+ sprite->pos2.y = Sin(sprite->data[6], sprite->data[7]);
+ sprite->callback = sub_80DF81C;
+}
+
+void sub_80DF81C(struct Sprite *sprite)
+{
+ switch (sprite->data[0])
+ {
+ case 0:
+ sprite->data[6] = (sprite->data[6] - sprite->data[5]) & 0xFF;
+ sprite->pos2.x = Cos(sprite->data[6], sprite->data[7]);
+ sprite->pos2.y = Sin(sprite->data[6], sprite->data[7]);
+ if (++sprite->data[4] > 5)
+ {
+ sprite->data[4] = 0;
+ if (sprite->data[5] <= 15 && ++sprite->data[5] > 15)
+ sprite->data[5] = 16;
+ }
+ if (++sprite->data[3] > 0x3C)
+ {
+ sprite->data[3] = 0;
+ sprite->data[0]++;
+ }
+ break;
+ case 1:
+ sprite->data[6] = (sprite->data[6] - sprite->data[5]) & 0xFF;
+ if (sprite->data[7] <= 0x95 && (sprite->data[7] += 8) > 0x95)
+ sprite->data[7] = 0x96;
+ sprite->pos2.x = Cos(sprite->data[6], sprite->data[7]);
+ sprite->pos2.y = Sin(sprite->data[6], sprite->data[7]);
+ if (++sprite->data[4] > 5)
+ {
+ sprite->data[4] = 0;
+ if (sprite->data[5] <= 15 && ++sprite->data[5] > 15)
+ sprite->data[5] = 16;
+ }
+ if (++sprite->data[3] > 20)
+ DestroyAnimSprite(sprite);
+ break;
+ }
+}
+
+// Dragon Dance scanline eff
+
+void sub_80DF924(u8 taskId)
+{
+ struct ScanlineEffectParams sp;
+ struct Task *task = &gTasks[taskId];
+ u16 i;
+ u8 r1;
+ if (GetBankIdentity_permutated(gAnimBankAttacker) == 1)
+ {
+ sp.dmaDest = &REG_BG1HOFS;
+ task->data[2] = gBattle_BG1_X;
+ }
+ else
+ {
+ sp.dmaDest = &REG_BG2HOFS;
+ task->data[2] = gBattle_BG2_X;
+ }
+ sp.dmaControl = 0xA2600001;
+ sp.initState = 1;
+ sp.unused9 = 0;
+ r1 = sub_8077FC0(gAnimBankAttacker);
+ task->data[3] = r1 - 32;
+ task->data[4] = r1 + 32;
+ if (task->data[3] < 0)
+ task->data[3] = 0;
+ for(i = task->data[3];i <= task->data[4];i++)
+ {
+ gScanlineEffectRegBuffers[0][i] = task->data[2];
+ gScanlineEffectRegBuffers[1][i] = task->data[2];
+ }
+ ScanlineEffect_SetParams(sp);
+ task->func = sub_80DF9F4;
+}
+
+void sub_80DF9F4(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+ switch (task->data[0])
+ {
+ case 0:
+ if (++task->data[7] > 1)
+ {
+ task->data[7] = 0;
+ if (++task->data[6] == 3)
+ task->data[0]++;
+ }
+ sub_80DFAB0(task);
+ break;
+ case 1:
+ if (++task->data[1] > 0x3C)
+ task->data[0]++;
+ sub_80DFAB0(task);
+ break;
+ case 2:
+ if (++task->data[7] > 1)
+ {
+ task->data[7] = 0;
+ if (--task->data[6] == 0)
+ task->data[0]++;
+ }
+ sub_80DFAB0(task);
+ break;
+ case 3:
+ gScanlineEffect.state = 3;
+ task->data[0]++;
+ break;
+ case 4:
+ DestroyAnimVisualTask(taskId);
+ break;
+ }
+}
+
+void sub_80DFAB0(struct Task *task)
+{
+ u16 r3 = task->data[5];
+ u16 i;
+ for (i = task->data[3]; i <= task->data[4]; i++)
+ {
+ gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer][i] = ((gSineTable[r3] * task->data[6]) >> 7) + task->data[2];
+ r3 = (r3 + 8) & 0xFF;
+ }
+ task->data[5] = (task->data[5] + 9) & 0xFF;
+}
+
+// Overheat
+
+void sub_80DFB28(struct Sprite *sprite)
+{
+ int r6 = (gBattleAnimArgs[2] * 3) / 5;
+ int i;
+ sprite->pos1.x = GetBankPosition(gAnimBankAttacker, 2);
+ sprite->pos1.y = GetBankPosition(gAnimBankAttacker, 3) + gBattleAnimArgs[4];
+ sprite->data[1] = Cos(gBattleAnimArgs[1], gBattleAnimArgs[2]);
+ sprite->data[2] = Sin(gBattleAnimArgs[1], r6);
+ sprite->pos1.x += sprite->data[1] * gBattleAnimArgs[0];
+ sprite->pos1.y += sprite->data[2] * gBattleAnimArgs[0];
+ sprite->data[3] = gBattleAnimArgs[3];
+ sprite->callback = sub_80DFBD8;
+ for (i = 0; i <= 6; i++)
+ gUnknown_03000730[i] = sprite->data[i];
+}
+
+void sub_80DFBD8(struct Sprite *sprite)
+{
+ sprite->data[4] += sprite->data[1];
+ sprite->data[5] += sprite->data[2];
+ sprite->pos2.x = sprite->data[4] / 10;
+ sprite->pos2.y = sprite->data[5] / 10;
+ if (++sprite->data[0] > sprite->data[3])
+ DestroyAnimSprite(sprite);
+}
diff --git a/src/battle/anim/draw.c b/src/battle/anim/draw.c
index 3adb62e06..f9e505bf2 100755
--- a/src/battle/anim/draw.c
+++ b/src/battle/anim/draw.c
@@ -3,7 +3,7 @@
#include "trig.h"
#include "battle_anim.h"
#include "sound.h"
-#include "unknown_task.h"
+#include "scanline_effect.h"
extern s16 gBattleAnimArgs[];
extern u8 gAnimBankAttacker;
@@ -21,7 +21,8 @@ static void sub_80D0E8C(struct Sprite* sprite);
void sub_80D0C88(u8 taskId)
{
struct Task* task = &gTasks[taskId];
- struct UnknownTaskStruct sp;
+ struct ScanlineEffectParams params;
+
s16 i;
task->data[0] = sub_8077FC0(gAnimBankTarget) + 32;
task->data[1] = 4;
@@ -30,30 +31,31 @@ void sub_80D0C88(u8 taskId)
task->data[4] = 0;
task->data[5] = 0;
task->data[15] = sub_807A100(gAnimBankTarget, 0);
+
if (GetBankIdentity_permutated(gAnimBankTarget) == 1)
{
task->data[6] = gBattle_BG1_X;
- sp.dest = (u16 *)REG_ADDR_BG1HOFS;
+ params.dmaDest = (u16 *)REG_ADDR_BG1HOFS;
}
else
{
task->data[6] = gBattle_BG2_X;
- sp.dest = (u16 *)REG_ADDR_BG2HOFS;
+ params.dmaDest = (u16 *)REG_ADDR_BG2HOFS;
}
for (i = task->data[0] - 0x40; i <= task->data[0];i++)
{
if (i >= 0)
{
- gUnknown_03004DE0[0][i] = task->data[6] + 0xF0;
- gUnknown_03004DE0[1][i] = task->data[6] + 0xF0;
+ gScanlineEffectRegBuffers[0][i] = task->data[6] + 0xF0;
+ gScanlineEffectRegBuffers[1][i] = task->data[6] + 0xF0;
}
}
- sp.control = 0xa2600001;
- sp.unk8 = 1;
- sp.unk9 = 0;
- sub_80895F8(sp);
+ params.dmaControl = SCANLINE_EFFECT_DMACNT_16BIT;
+ params.initState = 1;
+ params.unused9 = 0;
+ ScanlineEffect_SetParams(params);
task->func = sub_80D0D68;
}
@@ -91,13 +93,13 @@ void sub_80D0D68(u8 taskId)
if (task->data[5] >= 0)
{
- gUnknown_03004DE0[0][task->data[5]] = task->data[6];
- gUnknown_03004DE0[1][task->data[5]] = task->data[6];
+ gScanlineEffectRegBuffers[0][task->data[5]] = task->data[6];
+ gScanlineEffectRegBuffers[1][task->data[5]] = task->data[6];
}
if (++task->data[3] >= task->data[15])
{
- gUnknown_03004DC0.unk15 = 3;
+ gScanlineEffect.unk15 = 3;
DestroyAnimVisualTask(taskId);
}
}
@@ -178,7 +180,7 @@ _080D0DE0:\n\
ldrsh r0, [r3, r1]\n\
cmp r0, 0\n\
blt _080D0E04\n\
- ldr r2, _080D0E28 @ =gUnknown_03004DE0\n\
+ ldr r2, _080D0E28 @ =gScanlineEffectRegBuffers\n\
lsls r0, 1\n\
adds r0, r2\n\
ldrh r1, [r3, 0x14]\n\
@@ -202,7 +204,7 @@ _080D0E04:\n\
ldrsh r1, [r3, r2]\n\
cmp r0, r1\n\
blt _080D0E22\n\
- ldr r1, _080D0E2C @ =gUnknown_03004DC0\n\
+ ldr r1, _080D0E2C @ =gScanlineEffect\n\
movs r0, 0x3\n\
strb r0, [r1, 0x15]\n\
adds r0, r4, 0\n\
@@ -212,8 +214,8 @@ _080D0E22:\n\
pop {r0}\n\
bx r0\n\
.align 2, 0\n\
-_080D0E28: .4byte gUnknown_03004DE0\n\
-_080D0E2C: .4byte gUnknown_03004DC0\n\
+_080D0E28: .4byte gScanlineEffectRegBuffers\n\
+_080D0E2C: .4byte gScanlineEffect\n\
.syntax divided\n");
}
#endif
diff --git a/src/battle/battle_2.c b/src/battle/battle_2.c
index 249b67e0d..990535b4e 100644
--- a/src/battle/battle_2.c
+++ b/src/battle/battle_2.c
@@ -34,7 +34,7 @@
#include "trainer.h"
#include "trig.h"
#include "tv.h"
-#include "unknown_task.h"
+#include "scanline_effect.h"
#include "util.h"
#include "constants/battle_move_effects.h"
#include "constants/items.h"
@@ -108,9 +108,9 @@ extern u16 gUnknown_02024DE8;
extern u8 gActionSelectionCursor[];
extern u8 gMoveSelectionCursor[];
extern u8 gUnknown_02038470[];
-extern u16 gUnknown_030041B0;
+extern u16 gBattle_BG3_X;
extern u16 gBattle_BG1_Y;
-extern u16 gUnknown_030041B8;
+extern u16 gBattle_BG3_Y;
extern struct Window gUnknown_030041D0;
extern u16 gBattle_WIN1H;
extern struct Window gUnknown_03004210;
@@ -219,21 +219,21 @@ void InitBattle(void)
REG_WINOUT = 0;
gBattle_WIN0H = 0xF0;
gBattle_WIN0V = 0x5051;
- dp12_8087EA4();
+ ScanlineEffect_Clear();
for (i = 0; i < 80; i++)
{
- gUnknown_03004DE0[0][i] = 0xF0;
- gUnknown_03004DE0[1][i] = 0xF0;
+ gScanlineEffectRegBuffers[0][i] = 0xF0;
+ gScanlineEffectRegBuffers[1][i] = 0xF0;
}
for (i = 80; i < 160; i++)
{
asm(""::"r"(i)); // Needed to stop the compiler from optimizing out the loop counter
- gUnknown_03004DE0[0][i] = 0xFF10;
- gUnknown_03004DE0[1][i] = 0xFF10;
+ gScanlineEffectRegBuffers[0][i] = 0xFF10;
+ gScanlineEffectRegBuffers[1][i] = 0xFF10;
}
- //sub_80895F8(gUnknown_081F9674.unk0, gUnknown_081F9674.unk4, gUnknown_081F9674.unk8);
- sub_80895F8(gUnknown_081F9674);
+ //ScanlineEffect_SetParams(gUnknown_081F9674.unk0, gUnknown_081F9674.unk4, gUnknown_081F9674.unk8);
+ ScanlineEffect_SetParams(gUnknown_081F9674);
Text_LoadWindowTemplate(&gWindowTemplate_81E6C58);
ResetPaletteFade();
gBattle_BG0_X = 0;
@@ -242,8 +242,8 @@ void InitBattle(void)
gBattle_BG1_Y = 0;
gBattle_BG2_X = 0;
gBattle_BG2_Y = 0;
- gUnknown_030041B0 = 0;
- gUnknown_030041B8 = 0;
+ gBattle_BG3_X = 0;
+ gBattle_BG3_Y = 0;
gBattleTerrain = BattleSetup_GetTerrain();
Text_InitWindowWithTemplate(&gUnknown_03004210, &gWindowTemplate_81E6C58);
Text_InitWindowWithTemplate(&gUnknown_030041D0, &gWindowTemplate_81E71D0);
@@ -1064,8 +1064,8 @@ void sub_800FCFC(void)
REG_BG1VOFS = gBattle_BG1_Y;
REG_BG2HOFS = gBattle_BG2_X;
REG_BG2VOFS = gBattle_BG2_Y;
- REG_BG3HOFS = gUnknown_030041B0;
- REG_BG3VOFS = gUnknown_030041B8;
+ REG_BG3HOFS = gBattle_BG3_X;
+ REG_BG3VOFS = gBattle_BG3_Y;
REG_WIN0H = gBattle_WIN0H;
REG_WIN0V = gBattle_WIN0V;
REG_WIN1H = gBattle_WIN1H;
@@ -1073,7 +1073,7 @@ void sub_800FCFC(void)
LoadOam();
ProcessSpriteCopyRequests();
TransferPlttBuffer();
- sub_8089668();
+ ScanlineEffect_InitHBlankDmaTransfer();
}
void nullsub_36(struct Sprite *sprite)
@@ -1197,18 +1197,18 @@ void c2_8011A1C(void)
REG_WINOUT = 0;
gBattle_WIN0H = 0xF0;
gBattle_WIN0V = 0x5051;
- dp12_8087EA4();
+ ScanlineEffect_Clear();
for (i = 0; i < 80; i++)
{
- gUnknown_03004DE0[0][i] = 0xF0;
- gUnknown_03004DE0[1][i] = 0xF0;
+ gScanlineEffectRegBuffers[0][i] = 0xF0;
+ gScanlineEffectRegBuffers[1][i] = 0xF0;
}
for (i = 80; i < 160; i++)
{
asm(""::"r"(i)); // Needed to stop the compiler from optimizing out the loop counter
- gUnknown_03004DE0[0][i] = 0xFF10;
- gUnknown_03004DE0[1][i] = 0xFF10;
+ gScanlineEffectRegBuffers[0][i] = 0xFF10;
+ gScanlineEffectRegBuffers[1][i] = 0xFF10;
}
Text_LoadWindowTemplate(&gWindowTemplate_81E6C58);
ResetPaletteFade();
@@ -1218,8 +1218,8 @@ void c2_8011A1C(void)
gBattle_BG1_Y = 0;
gBattle_BG2_X = 0;
gBattle_BG2_Y = 0;
- gUnknown_030041B0 = 0;
- gUnknown_030041B8 = 0;
+ gBattle_BG3_X = 0;
+ gBattle_BG3_Y = 0;
Text_InitWindowWithTemplate(&gUnknown_03004210, &gWindowTemplate_81E6C58);
Text_InitWindowWithTemplate(&gUnknown_030041D0, &gWindowTemplate_81E71D0);
diff --git a/src/battle/battle_4.c b/src/battle/battle_4.c
index 164329c1b..ae8f94130 100644
--- a/src/battle/battle_4.c
+++ b/src/battle/battle_4.c
@@ -93,7 +93,7 @@ extern u16 gChosenMove; //last used move in battle
extern u8 gBankInMenu;
extern u8 gActionForBanks[4];
extern u16 gUnknown_02024C2C[4]; //last used moves 2, used by sketch
-extern u16 gUnknown_030041B0;
+extern u16 gBattle_BG3_X;
extern u16 gUnknown_02024C4C[4]; //last used moves by banks, another one
extern u8 gCurrentTurnActionNumber;
extern u16 gTrappingMoves[];
@@ -17229,7 +17229,7 @@ static void atkF2_displaydexinfo(void)
LZDecompressVram(gBattleTerrainTilemap_Building, (void*)(0x0600d000));
LoadCompressedPalette(gBattleTerrainPalette_BattleTower, 0x20, 0x60);
REG_BG3CNT = 0x5a0b;
- gUnknown_030041B0 = 0x100;
+ gBattle_BG3_X = 0x100;
BeginNormalPaletteFade(0xfffc, 0, 0x10, 0, 0);
gBattleCommunication[0]++;
}
diff --git a/src/battle/battle_controller_player.c b/src/battle/battle_controller_player.c
index 489581132..a5f833b6c 100644
--- a/src/battle/battle_controller_player.c
+++ b/src/battle/battle_controller_player.c
@@ -67,9 +67,9 @@ extern u8 gUnknown_02024E68[];
extern struct SpriteTemplate gUnknown_02024E8C;
extern u8 gAnimMoveTurn;
extern u8 gUnknown_02038470[];
-extern u16 gUnknown_030041B0;
+extern u16 gBattle_BG3_X;
extern u16 gBattle_BG1_Y;
-extern u16 gUnknown_030041B8;
+extern u16 gBattle_BG3_Y;
extern u16 gBattle_BG2_Y;
extern u16 gBattle_BG2_X;
extern u16 gBattle_BG0_X;
diff --git a/src/battle/battle_transition.c b/src/battle/battle_transition.c
index 985f43945..f7cdc0694 100644
--- a/src/battle/battle_transition.c
+++ b/src/battle/battle_transition.c
@@ -13,12 +13,10 @@
#include "trainer.h"
#include "field_camera.h"
#include "ewram.h"
-#include "unknown_task.h"
+#include "scanline_effect.h"
void sub_807DE10(void);
-void dp12_8087EA4(void);
-
-extern u16 gUnknown_03005560[];
+void ScanlineEffect_Clear(void);
extern const struct OamData gFieldOamData_32x32;
@@ -672,9 +670,9 @@ static bool8 Phase2_Transition_Swirl_Func1(struct Task* task)
u16 savedIME;
sub_811D658();
- dp12_8087EA4();
+ ScanlineEffect_Clear();
BeginNormalPaletteFade(-1, 4, 0, 0x10, 0);
- sub_811D6E8(gUnknown_03005560, TRANSITION_STRUCT.field_14, 0, 2, 0, 160);
+ sub_811D6E8(gScanlineEffectRegBuffers[1], TRANSITION_STRUCT.field_14, 0, 2, 0, 160);
SetVBlankCallback(VBlankCB_Phase2_Transition_Swirl);
SetHBlankCallback(HBlankCB_Phase2_Transition_Swirl);
@@ -695,7 +693,7 @@ static bool8 Phase2_Transition_Swirl_Func2(struct Task* task)
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);
+ sub_811D6E8(gScanlineEffectRegBuffers[0], TRANSITION_STRUCT.field_14, task->data[1], 2, task->data[2], 160);
if (!gPaletteFade.active)
{
@@ -711,12 +709,12 @@ static void VBlankCB_Phase2_Transition_Swirl(void)
{
VBlankCB_BattleTransition();
if (TRANSITION_STRUCT.VBlank_DMA)
- DmaCopy16(3, gUnknown_03004DE0[0], gUnknown_03004DE0[1], 320);
+ DmaCopy16(3, gScanlineEffectRegBuffers[0], gScanlineEffectRegBuffers[1], 320);
}
static void HBlankCB_Phase2_Transition_Swirl(void)
{
- u16 var = gUnknown_03004DE0[1][REG_VCOUNT];
+ u16 var = gScanlineEffectRegBuffers[1][REG_VCOUNT];
REG_BG1HOFS = var;
REG_BG2HOFS = var;
REG_BG3HOFS = var;
@@ -732,10 +730,10 @@ static bool8 Phase2_Transition_Shuffle_Func1(struct Task* task)
u16 savedIME;
sub_811D658();
- dp12_8087EA4();
+ ScanlineEffect_Clear();
BeginNormalPaletteFade(-1, 4, 0, 0x10, 0);
- memset(gUnknown_03005560, TRANSITION_STRUCT.field_16, 0x140);
+ memset(gScanlineEffectRegBuffers[1], TRANSITION_STRUCT.field_16, 0x140);
SetVBlankCallback(VBlankCB_Phase2_Transition_Shuffle);
SetHBlankCallback(HBlankCB_Phase2_Transition_Shuffle);
@@ -764,7 +762,7 @@ static bool8 Phase2_Transition_Shuffle_Func2(struct Task* task)
for (i = 0; i < 160; i++, r4 += 4224)
{
u16 var = r4 / 256;
- gUnknown_03004DE0[0][i] = TRANSITION_STRUCT.field_16 + Sin(var, r3);
+ gScanlineEffectRegBuffers[0][i] = TRANSITION_STRUCT.field_16 + Sin(var, r3);
}
if (!gPaletteFade.active)
@@ -778,12 +776,12 @@ static void VBlankCB_Phase2_Transition_Shuffle(void)
{
VBlankCB_BattleTransition();
if (TRANSITION_STRUCT.VBlank_DMA)
- DmaCopy16(3, gUnknown_03004DE0[0], gUnknown_03004DE0[1], 320);
+ DmaCopy16(3, gScanlineEffectRegBuffers[0], gScanlineEffectRegBuffers[1], 320);
}
static void HBlankCB_Phase2_Transition_Shuffle(void)
{
- u16 var = gUnknown_03004DE0[1][REG_VCOUNT];
+ u16 var = gScanlineEffectRegBuffers[1][REG_VCOUNT];
REG_BG1VOFS = var;
REG_BG2VOFS = var;
REG_BG3VOFS = var;
@@ -800,7 +798,7 @@ static bool8 Phase2_Transition_BigPokeball_Func1(struct Task* task)
u16 *dst1, *dst2;
sub_811D658();
- dp12_8087EA4();
+ ScanlineEffect_Clear();
task->data[1] = 16;
task->data[2] = 0;
@@ -815,7 +813,7 @@ static bool8 Phase2_Transition_BigPokeball_Func1(struct Task* task)
for (i = 0; i < 160; i++)
{
- gUnknown_03005560[i] = 240;
+ gScanlineEffectRegBuffers[1][i] = 240;
}
SetVBlankCallback(VBlankCB0_Phase2_Transition_BigPokeball);
@@ -844,7 +842,7 @@ static bool8 Phase2_Transition_BigPokeball_Func2(struct Task* task)
dst1[i * 32 + j] = *BigPokeballMap | 0xF000;
}
}
- sub_811D6E8(gUnknown_03004DE0[0], 0, task->data[4], 132, task->data[5], 160);
+ sub_811D6E8(gScanlineEffectRegBuffers[0], 0, task->data[4], 132, task->data[5], 160);
task->tState++;
return TRUE;
@@ -864,7 +862,7 @@ static bool8 Phase2_Transition_BigPokeball_Func3(struct Task* task)
task->data[4] += 8;
task->data[5] -= 256;
- sub_811D6E8(gUnknown_03004DE0[0], 0, task->data[4], 132, task->data[5] >> 8, 160);
+ sub_811D6E8(gScanlineEffectRegBuffers[0], 0, task->data[4], 132, task->data[5] >> 8, 160);
TRANSITION_STRUCT.VBlank_DMA++;
return FALSE;
@@ -884,7 +882,7 @@ static bool8 Phase2_Transition_BigPokeball_Func4(struct Task* task)
task->data[4] += 8;
task->data[5] -= 256;
- sub_811D6E8(gUnknown_03004DE0[0], 0, task->data[4], 132, task->data[5] >> 8, 160);
+ sub_811D6E8(gScanlineEffectRegBuffers[0], 0, task->data[4], 132, task->data[5] >> 8, 160);
TRANSITION_STRUCT.VBlank_DMA++;
return FALSE;
@@ -896,7 +894,7 @@ static bool8 Phase2_Transition_BigPokeball_Func5(struct Task* task)
task->data[4] += 8;
task->data[5] -= 256;
- sub_811D6E8(gUnknown_03004DE0[0], 0, task->data[4], 132, task->data[5] >> 8, 160);
+ sub_811D6E8(gScanlineEffectRegBuffers[0], 0, task->data[4], 132, task->data[5] >> 8, 160);
if (task->data[5] <= 0)
{
@@ -921,7 +919,7 @@ static bool8 Phase2_Transition_BigPokeball_Func6(struct Task* task)
if (task->data[1] < 0)
task->data[1] = 0;
}
- sub_811D764(gUnknown_03004DE0[0], 120, 80, task->data[1]);
+ sub_811D764(gScanlineEffectRegBuffers[0], 120, 80, task->data[1]);
if (task->data[1] == 0)
{
DmaStop(0);
@@ -943,7 +941,7 @@ static void Transition_BigPokeball_Vblank(void)
DmaStop(0);
VBlankCB_BattleTransition();
if (TRANSITION_STRUCT.VBlank_DMA)
- DmaCopy16(3, gUnknown_03004DE0[0], gUnknown_03004DE0[1], 320);
+ DmaCopy16(3, gScanlineEffectRegBuffers[0], gScanlineEffectRegBuffers[1], 320);
REG_WININ = TRANSITION_STRUCT.WININ;
REG_WINOUT = TRANSITION_STRUCT.WINOUT;
REG_WIN0V = TRANSITION_STRUCT.WIN0V;
@@ -954,13 +952,13 @@ static void Transition_BigPokeball_Vblank(void)
static void VBlankCB0_Phase2_Transition_BigPokeball(void)
{
Transition_BigPokeball_Vblank();
- DmaSet(0, gUnknown_03005560, &REG_BG0HOFS, 0xA2400001);
+ DmaSet(0, gScanlineEffectRegBuffers[1], &REG_BG0HOFS, 0xA2400001);
}
static void VBlankCB1_Phase2_Transition_BigPokeball(void)
{
Transition_BigPokeball_Vblank();
- DmaSet(0, gUnknown_03005560, &REG_WIN0H, 0xA2400001);
+ DmaSet(0, gScanlineEffectRegBuffers[1], &REG_WIN0H, 0xA2400001);
}
static void Phase2Task_Transition_PokeballsTrail(u8 taskID)
@@ -1078,7 +1076,7 @@ static bool8 Phase2_Transition_Clockwise_BlackFade_Func1(struct Task* task)
u16 i;
sub_811D658();
- dp12_8087EA4();
+ ScanlineEffect_Clear();
TRANSITION_STRUCT.WININ = 0;
TRANSITION_STRUCT.WINOUT = 63;
@@ -1087,7 +1085,7 @@ static bool8 Phase2_Transition_Clockwise_BlackFade_Func1(struct Task* task)
for (i = 0; i < 160; i++)
{
- gUnknown_03005560[i] = 0xF3F4;
+ gScanlineEffectRegBuffers[1][i] = 0xF3F4;
}
SetVBlankCallback(VBlankCB_Phase2_Transition_Clockwise_BlackFade);
@@ -1104,7 +1102,7 @@ static bool8 Phase2_Transition_Clockwise_BlackFade_Func2(struct Task* task)
sub_811D8FC(TRANSITION_STRUCT.data, 120, 80, TRANSITION_STRUCT.data[4], -1, 1, 1);
do
{
- gUnknown_03004DE0[0][TRANSITION_STRUCT.data[3]] = (TRANSITION_STRUCT.data[2] + 1) | 0x7800;
+ gScanlineEffectRegBuffers[0][TRANSITION_STRUCT.data[3]] = (TRANSITION_STRUCT.data[2] + 1) | 0x7800;
} while (!sub_811D978(TRANSITION_STRUCT.data, 1, 1));
TRANSITION_STRUCT.data[4] += 16;
@@ -1132,7 +1130,7 @@ static bool8 Phase2_Transition_Clockwise_BlackFade_Func3(struct Task* task)
r1 = 120, r3 = TRANSITION_STRUCT.data[2] + 1;
if (TRANSITION_STRUCT.data[5] >= 80)
r1 = TRANSITION_STRUCT.data[2], r3 = 240;
- gUnknown_03004DE0[0][TRANSITION_STRUCT.data[3]] = (r3) | (r1 << 8);
+ gScanlineEffectRegBuffers[0][TRANSITION_STRUCT.data[3]] = (r3) | (r1 << 8);
if (var != 0)
break;
var = sub_811D978(TRANSITION_STRUCT.data, 1, 1);
@@ -1148,7 +1146,7 @@ static bool8 Phase2_Transition_Clockwise_BlackFade_Func3(struct Task* task)
{
while (TRANSITION_STRUCT.data[3] < TRANSITION_STRUCT.data[5])
{
- gUnknown_03004DE0[0][++TRANSITION_STRUCT.data[3]] = (r3) | (r1 << 8);
+ gScanlineEffectRegBuffers[0][++TRANSITION_STRUCT.data[3]] = (r3) | (r1 << 8);
}
}
@@ -1163,7 +1161,7 @@ static bool8 Phase2_Transition_Clockwise_BlackFade_Func4(struct Task* task)
sub_811D8FC(TRANSITION_STRUCT.data, 120, 80, TRANSITION_STRUCT.data[4], 160, 1, 1);
do
{
- gUnknown_03004DE0[0][TRANSITION_STRUCT.data[3]] = (TRANSITION_STRUCT.data[2] << 8) | 0xF0;
+ gScanlineEffectRegBuffers[0][TRANSITION_STRUCT.data[3]] = (TRANSITION_STRUCT.data[2] << 8) | 0xF0;
} while (!sub_811D978(TRANSITION_STRUCT.data, 1, 1));
TRANSITION_STRUCT.data[4] -= 16;
@@ -1188,10 +1186,10 @@ static bool8 Phase2_Transition_Clockwise_BlackFade_Func5(struct Task* task)
while (1)
{
- r1 = gUnknown_03004DE0[0][TRANSITION_STRUCT.data[3]] & 0xFF, r2 = TRANSITION_STRUCT.data[2];
+ r1 = gScanlineEffectRegBuffers[0][TRANSITION_STRUCT.data[3]] & 0xFF, r2 = TRANSITION_STRUCT.data[2];
if (TRANSITION_STRUCT.data[5] <= 80)
r2 = 120, r1 = TRANSITION_STRUCT.data[2];
- gUnknown_03004DE0[0][TRANSITION_STRUCT.data[3]] = (r1) | (r2 << 8);
+ gScanlineEffectRegBuffers[0][TRANSITION_STRUCT.data[3]] = (r1) | (r2 << 8);
r3 = 0;
if (var != 0)
break;
@@ -1208,7 +1206,7 @@ static bool8 Phase2_Transition_Clockwise_BlackFade_Func5(struct Task* task)
{
while (TRANSITION_STRUCT.data[3] > TRANSITION_STRUCT.data[5])
{
- gUnknown_03004DE0[0][--TRANSITION_STRUCT.data[3]] = (r1) | (r2 << 8);
+ gScanlineEffectRegBuffers[0][--TRANSITION_STRUCT.data[3]] = (r1) | (r2 << 8);
}
}
@@ -1228,7 +1226,7 @@ static bool8 Phase2_Transition_Clockwise_BlackFade_Func6(struct Task* task)
r2 = 120, r3 = TRANSITION_STRUCT.data[2];
if (TRANSITION_STRUCT.data[2] >= 120)
r2 = 0, r3 = 240;
- gUnknown_03004DE0[0][TRANSITION_STRUCT.data[3]] = (r3) | (r2 << 8);
+ gScanlineEffectRegBuffers[0][TRANSITION_STRUCT.data[3]] = (r3) | (r2 << 8);
} while (!sub_811D978(TRANSITION_STRUCT.data, 1, 1));
@@ -1253,12 +1251,12 @@ static void VBlankCB_Phase2_Transition_Clockwise_BlackFade(void)
DmaStop(0);
VBlankCB_BattleTransition();
if (TRANSITION_STRUCT.VBlank_DMA != 0)
- DmaCopy16(3, gUnknown_03004DE0[0], gUnknown_03004DE0[1], 320);
+ DmaCopy16(3, gScanlineEffectRegBuffers[0], gScanlineEffectRegBuffers[1], 320);
REG_WININ = TRANSITION_STRUCT.WININ;
REG_WINOUT = TRANSITION_STRUCT.WINOUT;
REG_WIN0V = TRANSITION_STRUCT.WIN0V;
- REG_WIN0H = gUnknown_03004DE0[1][0];
- DmaSet(0, gUnknown_03004DE0[1], &REG_WIN0H, 0xA2400001);
+ REG_WIN0H = gScanlineEffectRegBuffers[1][0];
+ DmaSet(0, gScanlineEffectRegBuffers[1], &REG_WIN0H, 0xA2400001);
}
static void Phase2Task_Transition_Ripple(u8 taskID)
@@ -1271,11 +1269,11 @@ static bool8 Phase2_Transition_Ripple_Func1(struct Task* task)
u8 i;
sub_811D658();
- dp12_8087EA4();
+ ScanlineEffect_Clear();
for (i = 0; i < 160; i++)
{
- gUnknown_03005560[i] = TRANSITION_STRUCT.field_16;
+ gScanlineEffectRegBuffers[1][i] = TRANSITION_STRUCT.field_16;
}
SetVBlankCallback(VBlankCB_Phase2_Transition_Ripple);
@@ -1308,7 +1306,7 @@ static bool8 Phase2_Transition_Ripple_Func2(struct Task* task)
// todo: fix the asm
s16 var = r4 >> 8;
asm("");
- gUnknown_03004DE0[0][i] = TRANSITION_STRUCT.field_16 + Sin(var, r3);
+ gScanlineEffectRegBuffers[0][i] = TRANSITION_STRUCT.field_16 + Sin(var, r3);
asm("");
}
@@ -1329,12 +1327,12 @@ static void VBlankCB_Phase2_Transition_Ripple(void)
{
VBlankCB_BattleTransition();
if (TRANSITION_STRUCT.VBlank_DMA)
- DmaCopy16(3, gUnknown_03004DE0[0], gUnknown_03004DE0[1], 320);
+ DmaCopy16(3, gScanlineEffectRegBuffers[0], gScanlineEffectRegBuffers[1], 320);
}
static void HBlankCB_Phase2_Transition_Ripple(void)
{
- u16 var = gUnknown_03004DE0[1][REG_VCOUNT];
+ u16 var = gScanlineEffectRegBuffers[1][REG_VCOUNT];
REG_BG1VOFS = var;
REG_BG2VOFS = var;
REG_BG3VOFS = var;
@@ -1350,7 +1348,7 @@ static bool8 Phase2_Transition_Wave_Func1(struct Task* task)
u8 i;
sub_811D658();
- dp12_8087EA4();
+ ScanlineEffect_Clear();
TRANSITION_STRUCT.WININ = 63;
TRANSITION_STRUCT.WINOUT = 0;
@@ -1359,7 +1357,7 @@ static bool8 Phase2_Transition_Wave_Func1(struct Task* task)
for (i = 0; i < 160; i++)
{
- gUnknown_03004DE0[1][i] = 242;
+ gScanlineEffectRegBuffers[1][i] = 242;
}
SetVBlankCallback(VBlankCB_Phase2_Transition_Wave);
@@ -1375,7 +1373,7 @@ static bool8 Phase2_Transition_Wave_Func2(struct Task* task)
bool8 nextFunc;
TRANSITION_STRUCT.VBlank_DMA = 0;
- toStore = gUnknown_03004DE0[0];
+ toStore = gScanlineEffectRegBuffers[0];
r5 = task->data[2];
task->data[2] += 16;
task->data[1] += 8;
@@ -1411,11 +1409,11 @@ static void VBlankCB_Phase2_Transition_Wave(void)
DmaStop(0);
VBlankCB_BattleTransition();
if (TRANSITION_STRUCT.VBlank_DMA != 0)
- DmaCopy16(3, gUnknown_03004DE0[0], gUnknown_03004DE0[1], 320);
+ DmaCopy16(3, gScanlineEffectRegBuffers[0], gScanlineEffectRegBuffers[1], 320);
REG_WININ = TRANSITION_STRUCT.WININ;
REG_WINOUT = TRANSITION_STRUCT.WINOUT;
REG_WIN0V = TRANSITION_STRUCT.WIN0V;
- DmaSet(0, gUnknown_03004DE0[1], &REG_WIN0H, 0xA2400001);
+ DmaSet(0, gScanlineEffectRegBuffers[1], &REG_WIN0H, 0xA2400001);
}
#define tMugshotOpponentID data[13]
@@ -1462,7 +1460,7 @@ static bool8 Phase2_Mugshot_Func1(struct Task* task)
u8 i;
sub_811D658();
- dp12_8087EA4();
+ ScanlineEffect_Clear();
Mugshots_CreateOpponentPlayerSprites(task);
task->data[1] = 0;
@@ -1474,7 +1472,7 @@ static bool8 Phase2_Mugshot_Func1(struct Task* task)
for (i = 0; i < 160; i++)
{
- gUnknown_03004DE0[1][i] = 0xF0F1;
+ gScanlineEffectRegBuffers[1][i] = 0xF0F1;
}
SetVBlankCallback(VBlankCB0_Phase2_Mugshots);
@@ -1519,7 +1517,7 @@ static bool8 Phase2_Mugshot_Func3(struct Task* task)
TRANSITION_STRUCT.VBlank_DMA = 0;
- toStore = gUnknown_03004DE0[0];
+ toStore = gScanlineEffectRegBuffers[0];
r5 = task->data[1];
task->data[1] += 0x10;
@@ -1565,7 +1563,7 @@ static bool8 Phase2_Mugshot_Func4(struct Task* task)
TRANSITION_STRUCT.VBlank_DMA = 0;
- for (i = 0, toStore = gUnknown_03004DE0[0]; i < 160; i++, toStore++)
+ for (i = 0, toStore = gScanlineEffectRegBuffers[0]; i < 160; i++, toStore++)
{
*toStore = 0xF0;
}
@@ -1608,8 +1606,8 @@ static bool8 Phase2_Mugshot_Func6(struct Task* task)
TRANSITION_STRUCT.VBlank_DMA = 0;
SetVBlankCallback(NULL);
DmaStop(0);
- memset(gUnknown_03004DE0[0], 0, 0x140);
- memset(gUnknown_03004DE0[1], 0, 0x140);
+ memset(gScanlineEffectRegBuffers[0], 0, 0x140);
+ memset(gScanlineEffectRegBuffers[1], 0, 0x140);
REG_WIN0H = 0xF0;
REG_BLDY = 0;
task->tState++;
@@ -1642,15 +1640,15 @@ static bool8 Phase2_Mugshot_Func7(struct Task* task)
{
s16 index1 = 0x50 - i;
s16 index2 = 0x50 + i;
- if (gUnknown_03004DE0[0][index1] <= 15)
+ if (gScanlineEffectRegBuffers[0][index1] <= 15)
{
r6 = TRUE;
- gUnknown_03004DE0[0][index1]++;
+ gScanlineEffectRegBuffers[0][index1]++;
}
- if (gUnknown_03004DE0[0][index2] <= 15)
+ if (gScanlineEffectRegBuffers[0][index2] <= 15)
{
r6 = TRUE;
- gUnknown_03004DE0[0][index2]++;
+ gScanlineEffectRegBuffers[0][index2]++;
}
}
}
@@ -1678,7 +1676,7 @@ static bool8 Phase2_Mugshot_Func9(struct Task* task)
TRANSITION_STRUCT.VBlank_DMA = 0;
task->data[3]++;
- memset(gUnknown_03004DE0[0], task->data[3], 0x140);
+ memset(gScanlineEffectRegBuffers[0], task->data[3], 0x140);
if (task->data[3] > 15)
task->tState++;
@@ -1699,12 +1697,12 @@ static void VBlankCB0_Phase2_Mugshots(void)
DmaStop(0);
VBlankCB_BattleTransition();
if (TRANSITION_STRUCT.VBlank_DMA != 0)
- DmaCopy16(3, gUnknown_03004DE0[0], gUnknown_03004DE0[1], 320);
+ DmaCopy16(3, gScanlineEffectRegBuffers[0], gScanlineEffectRegBuffers[1], 320);
REG_BG0VOFS = TRANSITION_STRUCT.field_1C;
REG_WININ = TRANSITION_STRUCT.WININ;
REG_WINOUT = TRANSITION_STRUCT.WINOUT;
REG_WIN0V = TRANSITION_STRUCT.WIN0V;
- DmaSet(0, gUnknown_03004DE0[1], &REG_WIN0H, 0xA2400001);
+ DmaSet(0, gScanlineEffectRegBuffers[1], &REG_WIN0H, 0xA2400001);
}
static void VBlankCB1_Phase2_Mugshots(void)
@@ -1712,9 +1710,9 @@ static void VBlankCB1_Phase2_Mugshots(void)
DmaStop(0);
VBlankCB_BattleTransition();
if (TRANSITION_STRUCT.VBlank_DMA != 0)
- DmaCopy16(3, gUnknown_03004DE0[0], gUnknown_03004DE0[1], 320);
+ DmaCopy16(3, gScanlineEffectRegBuffers[0], gScanlineEffectRegBuffers[1], 320);
REG_BLDCNT = TRANSITION_STRUCT.BLDCNT;
- DmaSet(0, gUnknown_03004DE0[1], &REG_BLDY, 0xA2400001);
+ DmaSet(0, gScanlineEffectRegBuffers[1], &REG_BLDY, 0xA2400001);
}
static void HBlankCB_Phase2_Mugshots(void)
@@ -1846,7 +1844,7 @@ static bool8 Phase2_Transition_Slice_Func1(struct Task* task)
u16 i;
sub_811D658();
- dp12_8087EA4();
+ ScanlineEffect_Clear();
task->data[2] = 256;
task->data[3] = 1;
@@ -1856,8 +1854,8 @@ static bool8 Phase2_Transition_Slice_Func1(struct Task* task)
for (i = 0; i < 160; i++)
{
- gUnknown_03004DE0[1][i] = TRANSITION_STRUCT.field_14;
- gUnknown_03004DE0[1][160 + i] = 0xF0;
+ gScanlineEffectRegBuffers[1][i] = TRANSITION_STRUCT.field_14;
+ gScanlineEffectRegBuffers[1][160 + i] = 0xF0;
}
REG_IE |= INTR_FLAG_HBLANK;
@@ -1886,8 +1884,8 @@ static bool8 Phase2_Transition_Slice_Func2(struct Task* task)
for (i = 0; i < 160; i++)
{
- u16* storeLoc1 = &gUnknown_03004DE0[0][i];
- u16* storeLoc2 = &gUnknown_03004DE0[0][i + 160];
+ u16* storeLoc1 = &gScanlineEffectRegBuffers[0][i];
+ u16* storeLoc2 = &gScanlineEffectRegBuffers[0][i + 160];
if (1 & i)
{
*storeLoc1 = TRANSITION_STRUCT.field_14 + task->data[1];
@@ -1923,13 +1921,13 @@ static void VBlankCB_Phase2_Transition_Slice(void)
REG_WINOUT = TRANSITION_STRUCT.WINOUT;
REG_WIN0V = TRANSITION_STRUCT.WIN0V;
if (TRANSITION_STRUCT.VBlank_DMA)
- DmaCopy16(3, gUnknown_03004DE0[0], gUnknown_03004DE0[1], 640);
- DmaSet(0, &gUnknown_03004DE0[1][160], &REG_WIN0H, 0xA2400001);
+ DmaCopy16(3, gScanlineEffectRegBuffers[0], gScanlineEffectRegBuffers[1], 640);
+ DmaSet(0, &gScanlineEffectRegBuffers[1][160], &REG_WIN0H, 0xA2400001);
}
static void HBlankCB_Phase2_Transition_Slice(void)
{
- u16 var = gUnknown_03004DE0[1][REG_VCOUNT];
+ u16 var = gScanlineEffectRegBuffers[1][REG_VCOUNT];
REG_BG1HOFS = var;
REG_BG2HOFS = var;
REG_BG3HOFS = var;
@@ -1945,7 +1943,7 @@ static bool8 Phase2_Transition_WhiteFade_Func1(struct Task* task)
u16 i;
sub_811D658();
- dp12_8087EA4();
+ ScanlineEffect_Clear();
TRANSITION_STRUCT.BLDCNT = 0xBF;
TRANSITION_STRUCT.BLDY = 0;
@@ -1955,8 +1953,8 @@ static bool8 Phase2_Transition_WhiteFade_Func1(struct Task* task)
for (i = 0; i < 160; i++)
{
- gUnknown_03004DE0[1][i] = 0;
- gUnknown_03004DE0[1][i + 160] = 0xF0;
+ gScanlineEffectRegBuffers[1][i] = 0;
+ gScanlineEffectRegBuffers[1][i + 160] = 0xF0;
}
REG_IE |= INTR_FLAG_HBLANK;
@@ -2038,8 +2036,8 @@ static void VBlankCB0_Phase2_Transition_WhiteFade(void)
REG_WINOUT = TRANSITION_STRUCT.WINOUT;
REG_WIN0V = TRANSITION_STRUCT.field_6;
if (TRANSITION_STRUCT.VBlank_DMA)
- DmaCopy16(3, gUnknown_03004DE0[0], gUnknown_03004DE0[1], 640);
- DmaSet(0, &gUnknown_03004DE0[1][160], &REG_WIN0H, 0xA2400001);
+ DmaCopy16(3, gScanlineEffectRegBuffers[0], gScanlineEffectRegBuffers[1], 640);
+ DmaSet(0, &gScanlineEffectRegBuffers[1][160], &REG_WIN0H, 0xA2400001);
}
static void VBlankCB1_Phase2_Transition_WhiteFade(void)
@@ -2055,7 +2053,7 @@ static void VBlankCB1_Phase2_Transition_WhiteFade(void)
static void HBlankCB_Phase2_Transition_WhiteFade(void)
{
- REG_BLDY = gUnknown_03004DE0[1][REG_VCOUNT];
+ REG_BLDY = gScanlineEffectRegBuffers[1][REG_VCOUNT];
}
static void sub_811CFD0(struct Sprite* sprite)
@@ -2069,8 +2067,8 @@ static void sub_811CFD0(struct Sprite* sprite)
else
{
u16 i;
- u16* ptr1 = &gUnknown_03004DE0[0][sprite->pos1.y];
- u16* ptr2 = &gUnknown_03004DE0[0][sprite->pos1.y + 160];
+ u16* ptr1 = &gScanlineEffectRegBuffers[0][sprite->pos1.y];
+ u16* ptr2 = &gScanlineEffectRegBuffers[0][sprite->pos1.y + 160];
for (i = 0; i < 20; i++)
{
ptr1[i] = sprite->data[0] >> 8;
@@ -2160,7 +2158,7 @@ static bool8 Phase2_Transition_Shards_Func1(struct Task* task)
u16 i;
sub_811D658();
- dp12_8087EA4();
+ ScanlineEffect_Clear();
TRANSITION_STRUCT.WININ = 0x3F;
TRANSITION_STRUCT.WINOUT = 0;
@@ -2168,10 +2166,10 @@ static bool8 Phase2_Transition_Shards_Func1(struct Task* task)
for (i = 0; i < 160; i++)
{
- gUnknown_03004DE0[0][i] = 0xF0;
+ gScanlineEffectRegBuffers[0][i] = 0xF0;
}
- CpuSet(gUnknown_03004DE0[0], gUnknown_03004DE0[1], 0xA0);
+ CpuSet(gScanlineEffectRegBuffers[0], gScanlineEffectRegBuffers[1], 0xA0);
SetVBlankCallback(VBlankCB_Phase2_Transition_Shards);
task->tState++;
@@ -2200,8 +2198,8 @@ static bool8 Phase2_Transition_Shards_Func3(struct Task* task)
for (i = 0, nextFunc = FALSE; i < 16; i++)
{
- s16 r3 = gUnknown_03004DE0[0][TRANSITION_STRUCT.data[3]] >> 8;
- s16 r4 = gUnknown_03004DE0[0][TRANSITION_STRUCT.data[3]] & 0xFF;
+ s16 r3 = gScanlineEffectRegBuffers[0][TRANSITION_STRUCT.data[3]] >> 8;
+ s16 r4 = gScanlineEffectRegBuffers[0][TRANSITION_STRUCT.data[3]] & 0xFF;
if (task->data[2] == 0)
{
if (r3 < TRANSITION_STRUCT.data[2])
@@ -2216,7 +2214,7 @@ static bool8 Phase2_Transition_Shards_Func3(struct Task* task)
if (r4 <= r3)
r4 = r3;
}
- gUnknown_03004DE0[0][TRANSITION_STRUCT.data[3]] = (r4) | (r3 << 8);
+ gScanlineEffectRegBuffers[0][TRANSITION_STRUCT.data[3]] = (r4) | (r3 << 8);
if (nextFunc)
{
task->tState++;
@@ -2263,12 +2261,12 @@ static void VBlankCB_Phase2_Transition_Shards(void)
DmaStop(0);
VBlankCB_BattleTransition();
if (TRANSITION_STRUCT.VBlank_DMA)
- DmaCopy16(3, gUnknown_03004DE0[0], gUnknown_03004DE0[1], 320);
+ DmaCopy16(3, gScanlineEffectRegBuffers[0], gScanlineEffectRegBuffers[1], 320);
REG_WININ = TRANSITION_STRUCT.WININ;
REG_WINOUT = TRANSITION_STRUCT.WINOUT;
REG_WIN0V = TRANSITION_STRUCT.WIN0V;
- REG_WIN0H = gUnknown_03004DE0[1][0];
- DmaSet(0, gUnknown_03004DE0[1], &REG_WIN0H, 0xA2400001);
+ REG_WIN0H = gScanlineEffectRegBuffers[1][0];
+ DmaSet(0, gScanlineEffectRegBuffers[1], &REG_WIN0H, 0xA2400001);
}
static void CreatePhase1Task(s16 a0, s16 a1, s16 a2, s16 a3, s16 a4)
diff --git a/src/battle/reshow_battle_screen.c b/src/battle/reshow_battle_screen.c
index 42bb3ba7f..a78cb20df 100644
--- a/src/battle/reshow_battle_screen.c
+++ b/src/battle/reshow_battle_screen.c
@@ -3,7 +3,7 @@
#include "battle_anim.h"
#include "palette.h"
#include "main.h"
-#include "unknown_task.h"
+#include "scanline_effect.h"
#include "text.h"
#include "rom_8077ABC.h"
#include "data2.h"
@@ -15,9 +15,9 @@ extern u16 gBattle_BG2_Y;
extern u16 gBattle_BG2_X;
extern u16 gBattle_BG0_X;
extern u16 gBattle_BG1_X;
-extern u16 gUnknown_030041B0;
+extern u16 gBattle_BG3_X;
extern u16 gBattle_BG1_Y;
-extern u16 gUnknown_030041B8;
+extern u16 gBattle_BG3_Y;
extern u16 gBattle_BG0_Y;
extern u8 gReservedSpritePaletteCount;
extern u8 gActionSelectionCursor[4];
@@ -77,7 +77,7 @@ static void CB2_ReshowBattleScreenAfterMenu(void)
switch (gReshowState)
{
case 0:
- dp12_8087EA4();
+ ScanlineEffect_Clear();
Text_LoadWindowTemplate(&gWindowTemplate_81E6C58);
ResetPaletteFade();
Text_InitWindowWithTemplate(&gUnknown_03004210, &gWindowTemplate_81E6C58);
@@ -87,8 +87,8 @@ static void CB2_ReshowBattleScreenAfterMenu(void)
gBattle_BG1_Y = 0;
gBattle_BG2_X = 0;
gBattle_BG2_Y = 0;
- gUnknown_030041B0 = 0;
- gUnknown_030041B8 = 0;
+ gBattle_BG3_X = 0;
+ gBattle_BG3_Y = 0;
break;
case 1:
{
diff --git a/src/contest.c b/src/contest.c
index 8985d6490..875fe4502 100644
--- a/src/contest.c
+++ b/src/contest.c
@@ -29,7 +29,7 @@
#include "task.h"
#include "text.h"
#include "tv.h"
-#include "unknown_task.h"
+#include "scanline_effect.h"
#include "util.h"
extern u8 AreMovesContestCombo(u16, u16); // I don't think this is a bool
@@ -51,9 +51,9 @@ extern u8 gBanksBySide[];
extern u8 gObjectBankIDs[];
extern u8 gIsLinkContest;
extern u8 gContestPlayerMonIndex;
-extern u16 gUnknown_030041B0;
+extern u16 gBattle_BG3_X;
extern s16 gBattle_BG1_Y;
-extern u16 gUnknown_030041B8;
+extern u16 gBattle_BG3_Y;
extern u16 gBattle_WIN1H;
extern struct Window gUnknown_03004210;
extern u16 gBattle_WIN0V;
@@ -330,8 +330,8 @@ void ResetContestGpuRegs(void)
gBattle_BG1_Y = 0;
gBattle_BG2_X = 0;
gBattle_BG2_Y = 0;
- gUnknown_030041B0 = 0;
- gUnknown_030041B8 = 0;
+ gBattle_BG3_X = 0;
+ gBattle_BG3_Y = 0;
gBattle_WIN0H = 0;
gBattle_WIN0V = 0;
gBattle_WIN1H = 0;
@@ -412,7 +412,7 @@ void CB2_StartContest(void)
SetVBlankCallback(NULL);
SetUpContestWindow();
ResetContestGpuRegs();
- dp12_8087EA4();
+ ScanlineEffect_Clear();
ResetPaletteFade();
gPaletteFade.bufferTransferDisabled = TRUE;
DmaClearLarge32(3, (void *)VRAM, VRAM_SIZE, 0x1000);
@@ -626,8 +626,8 @@ void ContestVBlankCallback(void)
REG_BG1VOFS = gBattle_BG1_Y;
REG_BG2HOFS = gBattle_BG2_X;
REG_BG2VOFS = gBattle_BG2_Y;
- REG_BG3HOFS = gUnknown_030041B0;
- REG_BG3VOFS = gUnknown_030041B8;
+ REG_BG3HOFS = gBattle_BG3_X;
+ REG_BG3VOFS = gBattle_BG3_Y;
REG_WIN0H = gBattle_WIN0H;
REG_WIN0V = gBattle_WIN0V;
REG_WIN1H = gBattle_WIN1H;
@@ -635,7 +635,7 @@ void ContestVBlankCallback(void)
TransferPlttBuffer();
LoadOam();
ProcessSpriteCopyRequests();
- sub_8089668();
+ ScanlineEffect_InitHBlankDmaTransfer();
}
void sub_80ABB70(u8 taskId)
diff --git a/src/crt0.s b/src/crt0.s
new file mode 100644
index 000000000..049392be9
--- /dev/null
+++ b/src/crt0.s
@@ -0,0 +1,227 @@
+ .include "constants/gba_constants.inc"
+ .include "constants/misc_constants.inc"
+ .include "constants/version.inc"
+
+ .syntax unified
+
+ .global Start
+
+ .text
+
+ .arm
+
+Start: @ 8000000
+ b Init
+
+ .include "asm/rom_header.inc"
+
+@ 80000C0
+ .word 0
+
+ .global GPIOPortData
+GPIOPortData: @ 80000C4
+ .hword 0
+
+ .global GPIOPortDirection
+GPIOPortDirection: @ 80000C6
+ .hword 0
+
+ .global GPIOPortReadEnable
+GPIOPortReadEnable: @ 80000C8
+ .hword 0
+
+ .space 6
+
+@ 80000D0
+
+@ TODO: figure out what this data is
+
+ .ifdef GERMAN
+ .4byte 0xFFFFFFFF
+ .4byte 0xFFFFFFFF
+ .4byte 0xFFFFFFFF
+ .4byte 0xFFFFFFFF
+ .4byte 0xFFFFFFFF
+ .4byte 0xFFFFFFFF
+ .4byte 0xFFFFFFFF
+ .4byte 0xFFFFFFFF
+ .4byte 0xFFFFFFFF
+ .4byte 0xFFFFFFFF
+ .4byte 0xFFFFFFFF
+ .4byte 0xFFFFFFFF
+ .4byte GAME_VERSION
+ .4byte GAME_LANGUAGE
+ .ifdef SAPPHIRE
+ .ascii "pokemon sapphire version"
+ .space 8
+ .else
+ .ascii "pokemon ruby version"
+ .space 12
+ .endif
+ .4byte gMonFrontPicTable
+ .4byte gMonBackPicTable
+ .4byte gMonPaletteTable
+ .4byte gMonShinyPaletteTable
+ .4byte gMonIconTable
+ .4byte gMonIconPaletteIndices
+ .4byte gMonIconPaletteTable
+ .4byte gSpeciesNames
+ .4byte gMoveNames
+ .4byte gDecorations
+ .4byte 0x1220
+ .4byte 0x1340
+ .4byte 0x18
+ .4byte 0x938
+ .4byte 0x3A8C
+ .4byte 0x46
+ .4byte 0x836
+ .4byte 0x84C
+ .4byte 0x182
+ .4byte 0xA0A0A07
+ .4byte 0xC060C0C
+ .4byte 0xC121006
+ .4byte 0x8010B0F
+ .4byte 0xC
+ .4byte 0x890
+ .4byte 0x3AC0
+ .4byte 0x234
+ .4byte 0x238
+ .4byte 9
+ .4byte 0xA
+ .4byte 0
+ .4byte 8
+ .4byte 0x556
+ .4byte 0x557
+ .4byte 0x312F
+ .4byte 0x311B
+ .4byte 0
+ .4byte 0
+ .4byte 0
+ .4byte 0
+ .4byte 0
+ .4byte 0
+ .4byte 0
+ .4byte 0
+ .4byte 0
+ .4byte 0
+ .4byte 0
+ .4byte 0
+ .4byte 0
+ .4byte 0
+ .4byte 0
+ .4byte 0
+ .4byte 0
+ .4byte 0
+ .4byte 0xFFFFFFFF
+ .endif
+
+ .arm
+ .align 2, 0
+ .global Init
+Init:
+ mov r0, PSR_IRQ_MODE
+ msr cpsr_cf, r0
+ ldr sp, sp_irq
+ mov r0, PSR_SYS_MODE
+ msr cpsr_cf, r0
+ ldr sp, sp_sys
+ ldr r1, =INTR_VECTOR
+ adr r0, IntrMain
+ str r0, [r1]
+ ldr r1, =AgbMain
+ mov lr, pc
+ bx r1
+ b Init
+
+ .align 2, 0
+sp_sys: .word IWRAM_END - 0x1a0
+sp_irq: .word IWRAM_END - 0x60
+
+ .arm
+ .align 2, 0
+ .global IntrMain
+IntrMain:
+ mov r3, REG_BASE
+ add r3, r3, 0x200
+ ldr r2, [r3, OFFSET_REG_IE - 0x200]
+ ldrh r1, [r3, OFFSET_REG_IME - 0x200]
+ mrs r0, spsr
+ stmdb sp!, {r0-r3,lr}
+ mov r0, 1
+ strh r0, [r3, OFFSET_REG_IME - 0x200]
+ and r1, r2, r2, lsr 16
+ mov r12, 0
+ ands r0, r1, INTR_FLAG_SERIAL
+ bne IntrMain_FoundIntr
+ add r12, r12, 0x4
+ ands r0, r1, INTR_FLAG_TIMER3
+ bne IntrMain_FoundIntr
+ add r12, r12, 0x4
+ ands r0, r1, INTR_FLAG_HBLANK
+ bne IntrMain_FoundIntr
+ add r12, r12, 0x4
+ ands r0, r1, INTR_FLAG_VBLANK
+ bne IntrMain_FoundIntr
+ add r12, r12, 0x4
+ ands r0, r1, INTR_FLAG_VCOUNT
+ bne IntrMain_FoundIntr
+ add r12, r12, 0x4
+ ands r0, r1, INTR_FLAG_TIMER0
+ bne IntrMain_FoundIntr
+ add r12, r12, 0x4
+ ands r0, r1, INTR_FLAG_TIMER1
+ bne IntrMain_FoundIntr
+ add r12, r12, 0x4
+ ands r0, r1, INTR_FLAG_TIMER2
+ bne IntrMain_FoundIntr
+ add r12, r12, 0x4
+ ands r0, r1, INTR_FLAG_DMA0
+ bne IntrMain_FoundIntr
+ add r12, r12, 0x4
+ ands r0, r1, INTR_FLAG_DMA1
+ bne IntrMain_FoundIntr
+ add r12, r12, 0x4
+ ands r0, r1, INTR_FLAG_DMA2
+ bne IntrMain_FoundIntr
+ add r12, r12, 0x4
+ ands r0, r1, INTR_FLAG_DMA3
+ bne IntrMain_FoundIntr
+ add r12, r12, 0x4
+ ands r0, r1, INTR_FLAG_KEYPAD
+ bne IntrMain_FoundIntr
+ add r12, r12, 0x4
+ ands r0, r1, INTR_FLAG_GAMEPAK
+ strbne r0, [r3, OFFSET_REG_SOUNDCNT_X - 0x200]
+IntrMain_Loop:
+ bne IntrMain_Loop
+IntrMain_FoundIntr:
+ strh r0, [r3, OFFSET_REG_IF - 0x200]
+ mov r1, INTR_FLAG_SERIAL | INTR_FLAG_TIMER3 | INTR_FLAG_HBLANK
+ bic r2, r2, r0
+ and r1, r1, r2
+ strh r1, [r3, OFFSET_REG_IE - 0x200]
+ mrs r3, cpsr
+ bic r3, r3, PSR_I_BIT | PSR_F_BIT | PSR_MODE_MASK
+ orr r3, r3, PSR_SYS_MODE
+ msr cpsr_cf, r3
+ ldr r1, =gIntrTable
+ add r1, r1, r12
+ ldr r0, [r1]
+ stmdb sp!, {lr}
+ adr lr, IntrMain_RetAddr
+ bx r0
+IntrMain_RetAddr:
+ ldmia sp!, {lr}
+ mrs r3, cpsr
+ bic r3, r3, PSR_I_BIT | PSR_F_BIT | PSR_MODE_MASK
+ orr r3, r3, PSR_I_BIT | PSR_IRQ_MODE
+ msr cpsr_cf, r3
+ ldmia sp!, {r0-r3,lr}
+ strh r2, [r3, OFFSET_REG_IE - 0x200]
+ strh r1, [r3, OFFSET_REG_IME - 0x200]
+ msr spsr_cf, r0
+ bx lr
+
+ .pool
+
+ .align 2, 0 @ Don't pad with nop.
diff --git a/src/debug/matsuda_debug_menu.c b/src/debug/matsuda_debug_menu.c
index 0585c4e00..1da337b04 100644
--- a/src/debug/matsuda_debug_menu.c
+++ b/src/debug/matsuda_debug_menu.c
@@ -14,7 +14,7 @@
#include "string_util.h"
#include "task.h"
#include "text.h"
-#include "unknown_task.h"
+#include "scanline_effect.h"
#include "ewram.h"
extern u8 gUnknown_0203856C;
@@ -35,8 +35,8 @@ extern u16 gBattle_BG1_X;
extern u16 gBattle_BG1_Y;
extern u16 gBattle_BG2_X;
extern u16 gBattle_BG2_Y;
-extern u16 gUnknown_030041B0;
-extern u16 gUnknown_030041B8;
+extern u16 gBattle_BG3_X;
+extern u16 gBattle_BG3_Y;
extern struct Window gUnknown_03004210;
extern u8 (*gCallback_03004AE8)(void);
@@ -463,8 +463,8 @@ static void sub_80A9F50(void)
gBattle_BG1_Y = 0;
gBattle_BG2_X = 0;
gBattle_BG2_Y = 0;
- gUnknown_030041B0 = 0;
- gUnknown_030041B8 = 0;
+ gBattle_BG3_X = 0;
+ gBattle_BG3_Y = 0;
}
static void sub_80A9FE4(void)
@@ -511,12 +511,12 @@ static void sub_80AA090(void)
REG_BG1VOFS = gBattle_BG1_Y;
REG_BG2HOFS = gBattle_BG2_X;
REG_BG2VOFS = gBattle_BG2_Y;
- REG_BG3HOFS = gUnknown_030041B0;
- REG_BG3VOFS = gUnknown_030041B8;
+ REG_BG3HOFS = gBattle_BG3_X;
+ REG_BG3VOFS = gBattle_BG3_Y;
LoadOam();
ProcessSpriteCopyRequests();
TransferPlttBuffer();
- sub_8089668();
+ ScanlineEffect_InitHBlankDmaTransfer();
}
static void sub_80AA10C(void)
@@ -528,7 +528,7 @@ static void sub_80AA10C(void)
gPaletteFade.bufferTransferDisabled = 1;
SetVBlankCallback(0);
sub_80A9F50();
- dp12_8087EA4();
+ ScanlineEffect_Clear();
ResetPaletteFade();
ResetSpriteData();
ResetTasks();
diff --git a/src/easy_chat_1.c b/src/easy_chat_1.c
index cb0e98b71..4b64846f9 100644
--- a/src/easy_chat_1.c
+++ b/src/easy_chat_1.c
@@ -14,7 +14,7 @@
#include "sprite.h"
#include "string_util.h"
#include "strings.h"
-#include "unknown_task.h"
+#include "scanline_effect.h"
extern const struct WindowTemplate gWindowTemplate_81E6D54;
extern const struct WindowTemplate gWindowTemplate_81E6DA8;
@@ -43,7 +43,7 @@ const u16 gBerryMasterWifePhrases[][2] =
// const pointer to gEasyChatStruct-> easy_chat might be two separate files.
struct Shared1000 *const gEasyChatStruct = (struct Shared1000 *)(gSharedMem + 0x1000);
-const struct UnknownTaskStruct gUnknown_083DB698 =
+const struct ScanlineEffectParams gUnknown_083DB698 =
{
&REG_BG3VOFS,
((DMA_ENABLE | DMA_START_HBLANK | DMA_REPEAT | DMA_DEST_RELOAD) << 16) | 1,
@@ -297,10 +297,10 @@ void sub_80E62F8(void)
SetVBlankCallback(0);
ResetPaletteFade();
ResetSpriteData();
- dp12_8087EA4();
- remove_some_task();
+ ScanlineEffect_Clear();
+ ScanlineEffect_Stop();
sub_80EAD08();
- sub_80895F8(gUnknown_083DB698);
+ ScanlineEffect_SetParams(gUnknown_083DB698);
FreeSpriteTileRanges();
FreeAllSpritePalettes();
break;
@@ -655,7 +655,7 @@ void sub_80E6A6C(void)
ProcessSpriteCopyRequests();
sub_80EAC5C();
TransferPlttBuffer();
- sub_8089668();
+ ScanlineEffect_InitHBlankDmaTransfer();
}
void sub_80E6A88(void)
diff --git a/src/easy_chat_2.c b/src/easy_chat_2.c
index 66af7fc04..dc8bddd5a 100644
--- a/src/easy_chat_2.c
+++ b/src/easy_chat_2.c
@@ -17,7 +17,7 @@
#include "strings.h"
#include "strings2.h"
#include "trig.h"
-#include "unknown_task.h"
+#include "scanline_effect.h"
extern void sub_8095C8C();
extern void sub_809D104(void *, u16, u16, const void *, u16, u16, u16, u16);
@@ -2053,7 +2053,7 @@ void sub_80EAD08(void)
u16 r2;
u16 i;
- r4 = gUnknown_03004DE0[gUnknown_03004DC0.srcBank];
+ r4 = gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer];
r4 += 88;
r2 = (gEasyChatStruct->unk1BA - 88) & 0xFF;
diff --git a/src/engine/main.c b/src/engine/main.c
index 92b81d475..54a443e80 100644
--- a/src/engine/main.c
+++ b/src/engine/main.c
@@ -13,7 +13,7 @@
#include "rtc.h"
#include "siirtc.h"
#include "sound.h"
-#include "unknown_task.h"
+#include "scanline_effect.h"
extern struct SoundInfo gSoundInfo;
extern u32 IntrMain[];
@@ -362,7 +362,7 @@ void DoSoftReset(void)
{
REG_IME = 0;
m4aSoundVSyncOff();
- remove_some_task();
+ ScanlineEffect_Stop();
DmaStop(1);
DmaStop(2);
DmaStop(3);
diff --git a/src/engine/main_menu.c b/src/engine/main_menu.c
index 715570fe0..a0b8b7020 100644
--- a/src/engine/main_menu.c
+++ b/src/engine/main_menu.c
@@ -21,7 +21,7 @@
#include "task.h"
#include "text.h"
#include "title_screen.h"
-#include "unknown_task.h"
+#include "scanline_effect.h"
#include "ewram.h"
#define BirchSpeechUpdateWindowText() ((u8)Menu_UpdateWindowTextOverrideLineLength(24))
@@ -229,7 +229,7 @@ u32 InitMainMenu(u8 a1)
ResetPaletteFade();
LoadPalette(gMainMenuPalette, 0, 32);
- remove_some_task();
+ ScanlineEffect_Stop();
ResetTasks();
ResetSpriteData();
FreeAllSpritePalettes();
@@ -763,7 +763,7 @@ static void Task_NewGameSpeech1(u8 taskId)
LZ77UnCompVram(gUnknown_081E7834, (void *)(BG_VRAM + 0x3800));
LoadPalette(gUnknown_081E764C, 0, 0x40);
LoadPalette(gUnknown_081E796C, 1, 0x10);
- remove_some_task();
+ ScanlineEffect_Stop();
ResetSpriteData();
FreeAllSpritePalettes();
AddBirchSpeechObjects(taskId);
@@ -1368,7 +1368,7 @@ void CB_ContinueNewGameSpeechPart2()
gTasks[taskId].tBGhofs = -60;
- remove_some_task();
+ ScanlineEffect_Stop();
ResetSpriteData();
FreeAllSpritePalettes();
AddBirchSpeechObjects(taskId);
diff --git a/src/engine/option_menu.c b/src/engine/option_menu.c
index 868830880..1fc78efaa 100644
--- a/src/engine/option_menu.c
+++ b/src/engine/option_menu.c
@@ -3,12 +3,12 @@
#include "main.h"
#include "menu.h"
#include "palette.h"
+#include "scanline_effect.h"
#include "sprite.h"
#include "strings2.h"
#include "task.h"
extern void SetPokemonCryStereo(u32 val);
-extern void remove_some_task(void);
//Task data
enum {
@@ -110,7 +110,7 @@ void CB2_InitOptionMenu(void)
}
case 1:
ResetPaletteFade();
- remove_some_task();
+ ScanlineEffect_Stop();
ResetTasks();
ResetSpriteData();
gMain.state++;
diff --git a/src/engine/reset_rtc_screen.c b/src/engine/reset_rtc_screen.c
index 6e9efd342..a8b49a8eb 100644
--- a/src/engine/reset_rtc_screen.c
+++ b/src/engine/reset_rtc_screen.c
@@ -13,7 +13,7 @@
#include "strings2.h"
#include "task.h"
#include "text.h"
-#include "unknown_task.h"
+#include "scanline_effect.h"
struct ResetRtcStruct
{
@@ -438,8 +438,8 @@ void CB2_InitResetRtcScreen(void)
ResetOamRange(0, 128);
LoadOam();
- remove_some_task();
- dp12_8087EA4();
+ ScanlineEffect_Stop();
+ ScanlineEffect_Clear();
ResetSpriteData();
ResetTasks();
ResetPaletteFade();
diff --git a/src/engine/trainer_card.c b/src/engine/trainer_card.c
index 70942fc29..ab43ac716 100644
--- a/src/engine/trainer_card.c
+++ b/src/engine/trainer_card.c
@@ -18,7 +18,7 @@
#include "string_util.h"
#include "strings2.h"
#include "task.h"
-#include "unknown_task.h"
+#include "scanline_effect.h"
#include "util.h"
#include "ewram.h"
@@ -256,7 +256,7 @@ static void sub_8093254(void)
ewram0_2.var_5 ^= 1;
}
if (ewram0_2.var_4)
- DmaCopy16(3, &gUnknown_03004DE0[0], &gUnknown_03004DE0[1], 0x140);
+ DmaCopy16(3, &gScanlineEffectRegBuffers[0], &gScanlineEffectRegBuffers[1], 0x140);
}
static void sub_80932AC(Callback callBack)
@@ -730,9 +730,9 @@ bool8 sub_8093AA0(struct Task *task)
u32 i;
ewram0_2.var_4 = FALSE;
- dp12_8087EA4();
+ ScanlineEffect_Clear();
for (i = 0; i < 0xA0; i++)
- gUnknown_03004DE0[1][i] = -4;
+ gScanlineEffectRegBuffers[1][i] = -4;
SetHBlankCallback(sub_8093D7C);
ewram0_2.var_4 = TRUE;
task->data[0]++;
@@ -768,7 +768,7 @@ bool8 sub_8093AF0(struct Task *task)
for (i = 0; i < r7; i++)
{
- gUnknown_03004DE0.filler0[i] = -4 - (u32)i;
+ gScanlineEffectRegBuffers.filler0[i] = -4 - (u32)i;
}
//_08093B74
for (; i < r9; i++)
@@ -776,10 +776,10 @@ bool8 sub_8093AF0(struct Task *task)
u16 var = r6 >> 16;
r6 += r5;
r5 -= sp0;
- gUnknown_03004DE0.filler0[i] = -4 + var;
+ gScanlineEffectRegBuffers.filler0[i] = -4 + var;
}
for (; i < 160; i++)
- gUnknown_03004DE0.filler0[i] = -4 + (u16)(r10 >> 16);
+ gScanlineEffectRegBuffers.filler0[i] = -4 + (u16)(r10 >> 16);
ewram0_2.var_4 = 1;
if (task->data[1] > 0x4A)
task->data[0]++;
@@ -840,7 +840,7 @@ _08093B18:\n\
movs r3, 0\n\
cmp r3, r7\n\
bcs _08093B74\n\
- ldr r2, _08093C04 @ =gUnknown_03004DE0\n\
+ ldr r2, _08093C04 @ =gScanlineEffectRegBuffers\n\
mov r12, r2\n\
ldr r0, _08093C08 @ =0x0000fffc\n\
adds r4, r0, 0\n\
@@ -866,7 +866,7 @@ _08093B74:\n\
lsrs r7, r4, 16\n\
cmp r2, r0\n\
bge _08093BAE\n\
- ldr r0, _08093C04 @ =gUnknown_03004DE0\n\
+ ldr r0, _08093C04 @ =gScanlineEffectRegBuffers\n\
mov r9, r0\n\
ldr r4, _08093C08 @ =0x0000fffc\n\
mov r12, r4\n\
@@ -894,7 +894,7 @@ _08093BAE:\n\
asrs r0, 16\n\
cmp r0, 0x9F\n\
bgt _08093BD4\n\
- ldr r4, _08093C04 @ =gUnknown_03004DE0\n\
+ ldr r4, _08093C04 @ =gScanlineEffectRegBuffers\n\
ldr r0, _08093C08 @ =0x0000fffc\n\
adds r2, r1, r0\n\
_08093BBE:\n\
@@ -934,7 +934,7 @@ _08093BEA:\n\
.align 2, 0\n\
_08093BFC: .4byte gSharedMem\n\
_08093C00: .4byte 0xffff0000\n\
-_08093C04: .4byte gUnknown_03004DE0\n\
+_08093C04: .4byte gScanlineEffectRegBuffers\n\
_08093C08: .4byte 0x0000fffc\n\
.syntax divided\n");
}
@@ -1000,7 +1000,7 @@ _08093C5C:\n\
movs r3, 0\n\
cmp r3, r7\n\
bcs _08093CB8\n\
- ldr r2, _08093D48 @ =gUnknown_03004DE0\n\
+ ldr r2, _08093D48 @ =gScanlineEffectRegBuffers\n\
mov r12, r2\n\
ldr r0, _08093D4C @ =0x0000fffc\n\
adds r4, r0, 0\n\
@@ -1026,7 +1026,7 @@ _08093CB8:\n\
lsrs r7, r4, 16\n\
cmp r2, r0\n\
bge _08093CF2\n\
- ldr r0, _08093D48 @ =gUnknown_03004DE0\n\
+ ldr r0, _08093D48 @ =gScanlineEffectRegBuffers\n\
mov r9, r0\n\
ldr r3, _08093D4C @ =0x0000fffc\n\
mov r12, r3\n\
@@ -1054,7 +1054,7 @@ _08093CF2:\n\
asrs r0, 16\n\
cmp r0, 0x9F\n\
bgt _08093D18\n\
- ldr r4, _08093D48 @ =gUnknown_03004DE0\n\
+ ldr r4, _08093D48 @ =gScanlineEffectRegBuffers\n\
ldr r0, _08093D4C @ =0x0000fffc\n\
adds r2, r1, r0\n\
_08093D02:\n\
@@ -1094,7 +1094,7 @@ _08093D2E:\n\
.align 2, 0\n\
_08093D40: .4byte gSharedMem\n\
_08093D44: .4byte 0xffff0000\n\
-_08093D48: .4byte gUnknown_03004DE0\n\
+_08093D48: .4byte gScanlineEffectRegBuffers\n\
_08093D4C: .4byte 0x0000fffc\n\
.syntax divided\n");
}
@@ -1113,7 +1113,7 @@ bool8 sub_8093D50(struct Task *task)
void sub_8093D7C(void)
{
- u16 bgVOffset = gUnknown_03004DE0[1][REG_VCOUNT & 0xFF];
+ u16 bgVOffset = gScanlineEffectRegBuffers[1][REG_VCOUNT & 0xFF];
REG_BG0VOFS = bgVOffset;
REG_BG1VOFS = bgVOffset;
diff --git a/src/field/diploma.c b/src/field/diploma.c
index 7028eec02..978eca7eb 100644
--- a/src/field/diploma.c
+++ b/src/field/diploma.c
@@ -10,7 +10,7 @@
#include "strings2.h"
#include "task.h"
#include "text.h"
-#include "unknown_task.h"
+#include "scanline_effect.h"
static void VBlankCB(void);
static void MainCB2(void);
@@ -62,7 +62,7 @@ void CB2_ShowDiploma(void)
LZ77UnCompVram(gDiplomaTiles, (void *)VRAM);
LZ77UnCompVram(gDiplomaTilemap, (void *)(VRAM + 0x3000));
- remove_some_task();
+ ScanlineEffect_Stop();
ResetTasks();
ResetSpriteData();
ResetPaletteFade();
diff --git a/src/field/field_screen_effect.c b/src/field/field_screen_effect.c
index 6e818ce68..61301c5a9 100644
--- a/src/field/field_screen_effect.c
+++ b/src/field/field_screen_effect.c
@@ -7,13 +7,13 @@
#include "script.h"
#include "task.h"
#include "text.h"
-#include "unknown_task.h"
+#include "scanline_effect.h"
const static u16 gUnknown_0839ACDC[] = { 0xC8, 0x48, 0x38, 0x28, 0x18, 0x0 };
const s32 gMaxFlashLevel = 4;
-const static struct UnknownTaskStruct gUnknown_0839ACEC =
+const static struct ScanlineEffectParams gUnknown_0839ACEC =
{
(void *)REG_ADDR_WIN0H,
((DMA_ENABLE | DMA_START_HBLANK | DMA_REPEAT | DMA_DEST_RELOAD) << 16) | 1,
@@ -64,18 +64,18 @@ static void sub_8081424(u8 taskId)
switch (data[0])
{
case 0:
- sub_8081398(&gUnknown_03004DE0[gUnknown_03004DC0.srcBank][0], data[1], data[2], data[3]);
+ sub_8081398(gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer], data[1], data[2], data[3]);
data[0] = 1;
break;
case 1:
- sub_8081398(&gUnknown_03004DE0[gUnknown_03004DC0.srcBank][0], data[1], data[2], data[3]);
+ sub_8081398(gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer], data[1], data[2], data[3]);
data[0] = 0;
data[3] += data[5];
if (data[3] > data[4])
{
if (data[6] == 1)
{
- remove_some_task();
+ ScanlineEffect_Stop();
data[0] = 2;
}
else
@@ -85,7 +85,7 @@ static void sub_8081424(u8 taskId)
}
break;
case 2:
- dp12_8087EA4();
+ ScanlineEffect_Clear();
DestroyTask(taskId);
break;
}
@@ -140,8 +140,8 @@ void sub_80815E0(u8 a1)
{
if (a1)
{
- sub_8081398(&gUnknown_03004DE0[0][0], 120, 80, gUnknown_0839ACDC[a1]);
- CpuFastSet(&gUnknown_03004DE0[0], &gUnknown_03004DE0[1], 480);
+ sub_8081398(&gScanlineEffectRegBuffers[0][0], 120, 80, gUnknown_0839ACDC[a1]);
+ CpuFastSet(&gScanlineEffectRegBuffers[0], &gScanlineEffectRegBuffers[1], 480);
}
}
@@ -208,10 +208,10 @@ static void sub_80816A8(u8 taskId)
REG_BLDALPHA = 1804;
REG_WININ = 63;
REG_WINOUT = 30;
- sub_8081398(&gUnknown_03004DE0[0][0], data[2], data[3], 1);
- CpuFastSet(&gUnknown_03004DE0[0], &gUnknown_03004DE0[1], 480);
- //sub_80895F8(gUnknown_0839ACEC[0], gUnknown_0839ACEC[1], gUnknown_0839ACEC[2]);
- sub_80895F8(gUnknown_0839ACEC);
+ sub_8081398(&gScanlineEffectRegBuffers[0][0], data[2], data[3], 1);
+ CpuFastSet(&gScanlineEffectRegBuffers[0], &gScanlineEffectRegBuffers[1], 480);
+ //ScanlineEffect_SetParams(gUnknown_0839ACEC[0], gUnknown_0839ACEC[1], gUnknown_0839ACEC[2]);
+ ScanlineEffect_SetParams(gUnknown_0839ACEC);
data[0] = 1;
break;
case 1:
diff --git a/src/field/item_menu.c b/src/field/item_menu.c
index 2be5f1e1d..e0575af4c 100644
--- a/src/field/item_menu.c
+++ b/src/field/item_menu.c
@@ -33,7 +33,7 @@
#include "string_util.h"
#include "task.h"
#include "text.h"
-#include "unknown_task.h"
+#include "scanline_effect.h"
#include "ewram.h"
// External stuff
@@ -397,7 +397,7 @@ static bool8 SetupBagMultistep(void)
gMain.state++;
break;
case 1:
- remove_some_task();
+ ScanlineEffect_Stop();
gMain.state++;
break;
case 2:
diff --git a/src/field/overworld.c b/src/field/overworld.c
index 9fab20876..86b0a5dac 100644
--- a/src/field/overworld.c
+++ b/src/field/overworld.c
@@ -47,7 +47,7 @@
#include "tileset_anim.h"
#include "time_events.h"
#include "tv.h"
-#include "unknown_task.h"
+#include "scanline_effect.h"
#include "wild_encounter.h"
#ifdef SAPPHIRE
@@ -142,7 +142,7 @@ const struct UCoords32 gUnknown_0821664C[] =
{ 1, -1},
};
-const struct UnknownTaskStruct gUnknown_08216694 =
+const struct ScanlineEffectParams gUnknown_08216694 =
{
(void *)REG_ADDR_WIN0H,
((DMA_ENABLE | DMA_START_HBLANK | DMA_REPEAT | DMA_DEST_RELOAD) << 16) | 1,
@@ -1410,7 +1410,7 @@ void VBlankCB_Field(void)
{
LoadOam();
ProcessSpriteCopyRequests();
- sub_8089668();
+ ScanlineEffect_InitHBlankDmaTransfer();
sub_8057A58();
TransferPlttBuffer();
sub_8072E74();
@@ -1422,7 +1422,7 @@ void sub_8054814(void)
if (val)
{
sub_80815E0(val);
- sub_80895F8(gUnknown_08216694);
+ ScanlineEffect_SetParams(gUnknown_08216694);
}
}
@@ -1669,7 +1669,7 @@ void sub_8054BA8(void)
REG_DISPCNT = 0;
- remove_some_task();
+ ScanlineEffect_Stop();
DmaClear16(3, PLTT + 2, PLTT_SIZE - 2);
@@ -1731,7 +1731,7 @@ void sub_8054D4C(u32 a1)
ResetTasks();
ResetSpriteData();
ResetPaletteFade();
- dp12_8087EA4();
+ ScanlineEffect_Clear();
ResetCameraUpdateInfo();
InstallCameraPanAheadCallback();
sub_805C7C4(0);
diff --git a/src/field/party_menu.c b/src/field/party_menu.c
index 9cad5bd73..7d243f569 100644
--- a/src/field/party_menu.c
+++ b/src/field/party_menu.c
@@ -32,7 +32,7 @@
#include "string_util.h"
#include "strings.h"
#include "task.h"
-#include "unknown_task.h"
+#include "scanline_effect.h"
#include "util.h"
#include "script_pokemon_80F9.h"
#include "ewram.h"
@@ -648,7 +648,7 @@ bool8 InitPartyMenu(void)
gMain.state++;
break;
case 1:
- remove_some_task();
+ ScanlineEffect_Stop();
gMain.state++;
break;
case 2:
diff --git a/src/field/pokeblock.c b/src/field/pokeblock.c
index dd94e1755..7e8bdc2ce 100644
--- a/src/field/pokeblock.c
+++ b/src/field/pokeblock.c
@@ -8,7 +8,7 @@
#include "script.h"
#include "strings.h"
#include "task.h"
-#include "unknown_task.h"
+#include "scanline_effect.h"
#include "text.h"
#include "main.h"
#include "menu.h"
@@ -255,7 +255,7 @@ static bool8 sub_810B6C0(void)
gMain.state++;
break;
case 1:
- remove_some_task();
+ ScanlineEffect_Stop();
gMain.state++;
break;
case 2:
diff --git a/src/field/shop.c b/src/field/shop.c
index d56d65c3f..1dc6ba0cd 100644
--- a/src/field/shop.c
+++ b/src/field/shop.c
@@ -15,7 +15,7 @@
#include "strings.h"
#include "task.h"
#include "tv.h"
-#include "unknown_task.h"
+#include "scanline_effect.h"
#include "field_map_obj.h"
#include "field_player_avatar.h"
#include "fieldmap.h"
@@ -266,7 +266,7 @@ void BuyMenuDrawGraphics(void)
register u16 zero2 asm("r5");
sub_80F9438();
- remove_some_task();
+ ScanlineEffect_Stop();
REG_BG1HOFS = (zero2 = 0);
REG_BG1VOFS = zero2;
REG_BG2HOFS = zero2;
diff --git a/src/field/start_menu.c b/src/field/start_menu.c
index 5b2276d1b..d6881cb01 100644
--- a/src/field/start_menu.c
+++ b/src/field/start_menu.c
@@ -28,7 +28,7 @@
#include "strings2.h"
#include "task.h"
#include "trainer_card.h"
-#include "unknown_task.h"
+#include "scanline_effect.h"
//Menu actions
enum {
@@ -750,7 +750,7 @@ static bool32 sub_80719FC(u8 *step)
REG_DISPCNT = 0;
SetVBlankCallback(NULL);
- remove_some_task();
+ ScanlineEffect_Stop();
DmaClear16(3, PLTT, PLTT_SIZE);
addr = (void *)VRAM;
size = 0x18000;
@@ -771,7 +771,7 @@ static bool32 sub_80719FC(u8 *step)
ResetSpriteData();
ResetTasks();
ResetPaletteFade();
- dp12_8087EA4();
+ ScanlineEffect_Clear();
break;
case 2:
Text_LoadWindowTemplate(&gWindowTemplate_81E6CE4);
diff --git a/src/field/starter_choose.c b/src/field/starter_choose.c
index 91b706e78..418488774 100644
--- a/src/field/starter_choose.c
+++ b/src/field/starter_choose.c
@@ -14,7 +14,7 @@
#include "strings.h"
#include "task.h"
#include "trig.h"
-#include "unknown_task.h"
+#include "scanline_effect.h"
extern u16 gSpecialVar_Result;
extern struct SpriteTemplate gUnknown_02024E8C;
@@ -285,7 +285,7 @@ void CB2_ChooseStarter(void)
LZ77UnCompVram(&gBirchHelpGfx, (void *)VRAM);
LZ77UnCompVram(&gBirchBagTilemap, (void *)(VRAM + 0x3000));
LZ77UnCompVram(&gBirchGrassTilemap, (void *)(VRAM + 0x3800));
- remove_some_task();
+ ScanlineEffect_Stop();
ResetTasks();
ResetSpriteData();
ResetPaletteFade();
diff --git a/src/field/use_pokeblock.c b/src/field/use_pokeblock.c
index 9363498ba..42020c49a 100644
--- a/src/field/use_pokeblock.c
+++ b/src/field/use_pokeblock.c
@@ -117,7 +117,7 @@ static void sub_81365A0(void);
static void sub_81365C8(void);
static void sub_8136638(void);
static void sub_81368A4(void);
-void sub_8089668(void);
+void ScanlineEffect_InitHBlankDmaTransfer(void);
static void sub_8136B44(void);
static u8 sub_81370E4(u8);
static void sub_8136BB8(void);
@@ -194,7 +194,7 @@ static void sub_8136264(void)
ProcessSpriteCopyRequests();
TransferPlttBuffer();
sub_80F5CDC(6);
- sub_8089668();
+ ScanlineEffect_InitHBlankDmaTransfer();
}
static void launch_c3_walk_stairs_and_run_once(void (*const func)(void))
diff --git a/src/field/wallclock.c b/src/field/wallclock.c
index 4f2a6dccd..aaa7f9ae8 100644
--- a/src/field/wallclock.c
+++ b/src/field/wallclock.c
@@ -10,7 +10,7 @@
#include "strings2.h"
#include "task.h"
#include "trig.h"
-#include "unknown_task.h"
+#include "scanline_effect.h"
extern u16 gSpecialVar_0x8004;
extern u8 gMiscClock_Gfx[];
@@ -229,7 +229,7 @@ static void LoadWallClockGraphics(void)
LoadPalette(gMiscClockMale_Pal, 0, 32);
else
LoadPalette(gMiscClockFemale_Pal, 0, 32);
- remove_some_task();
+ ScanlineEffect_Stop();
ResetTasks();
ResetSpriteData();
ResetPaletteFade();
diff --git a/src/libs/libagbsyscall.s b/src/libs/libagbsyscall.s
new file mode 100644
index 000000000..cdf6ca905
--- /dev/null
+++ b/src/libs/libagbsyscall.s
@@ -0,0 +1,91 @@
+ .include "include/macros.inc"
+ .syntax unified
+
+ .text
+
+ thumb_func_start ArcTan2
+ArcTan2: @ 81E07E0
+ swi 0xA
+ bx lr
+ thumb_func_end ArcTan2
+
+ thumb_func_start BgAffineSet
+BgAffineSet: @ 81E07E4
+ swi 0xE
+ bx lr
+ thumb_func_end BgAffineSet
+
+ thumb_func_start CpuFastSet
+CpuFastSet: @ 81E07E8
+ swi 0xC
+ bx lr
+ thumb_func_end CpuFastSet
+
+ thumb_func_start CpuSet
+CpuSet: @ 81E07EC
+ swi 0xB
+ bx lr
+ thumb_func_end CpuSet
+
+ thumb_func_start LZ77UnCompVram
+LZ77UnCompVram: @ 81E07F4
+ swi 0x12
+ bx lr
+ thumb_func_end LZ77UnCompVram
+
+ thumb_func_start LZ77UnCompWram
+LZ77UnCompWram: @ 81E07F8
+ swi 0x11
+ bx lr
+ thumb_func_end LZ77UnCompWram
+
+ thumb_func_start ObjAffineSet
+ObjAffineSet: @ 81E0804
+ swi 0xF
+ bx lr
+ thumb_func_end ObjAffineSet
+
+ thumb_func_start RLUnCompVram
+RLUnCompVram: @ 81E0808
+ swi 0x15
+ bx lr
+ thumb_func_end RLUnCompVram
+
+ thumb_func_start RLUnCompWram
+RLUnCompWram: @ 81E080C
+ swi 0x14
+ bx lr
+ thumb_func_end RLUnCompWram
+
+ thumb_func_start RegisterRamReset
+RegisterRamReset: @ 81E0810
+ swi 0x1
+ bx lr
+ thumb_func_end RegisterRamReset
+
+ thumb_func_start SoftReset
+SoftReset: @ 81E0814
+ ldr r3, =0x04000208
+ movs r2, 0
+ strb r2, [r3]
+ ldr r1, =0x03007f00 @ User Stack
+ mov sp, r1
+ swi 0x1
+ swi 0
+ .pool
+ thumb_func_end SoftReset
+
+ thumb_func_start Sqrt
+Sqrt: @ 81E082C
+ swi 0x8
+ bx lr
+ thumb_func_end Sqrt
+
+ thumb_func_start VBlankIntrWait
+VBlankIntrWait: @ 81E0830
+ movs r2, 0
+ swi 0x5
+ bx lr
+ thumb_func_end VBlankIntrWait
+
+ .align 2, 0 @ Don't pad with nop.
diff --git a/src/libs/libgcnmultiboot.s b/src/libs/libgcnmultiboot.s
new file mode 100644
index 000000000..8c8b94998
--- /dev/null
+++ b/src/libs/libgcnmultiboot.s
@@ -0,0 +1,641 @@
+@ This library can be used to download and execute a multi-boot image from
+@ a GameCube using the JOY Bus protocol over the link cable.
+
+ .include "include/macros.inc"
+ .include "constants/constants.inc"
+
+ .equiv GCMB_STRUCT_COUNTER1, 0x00
+ .equiv GCMB_STRUCT_COUNTER2, 0x01
+ .equiv GCMB_STRUCT_MBPROGRESS, 0x02
+ .equiv GCMB_STRUCT_SAVEDVCOUNT, 0x03
+ .equiv GCMB_STRUCT_KEYA, 0x04
+ .equiv GCMB_STRUCT_KEYB, 0x08
+ .equiv GCMB_STRUCT_KEYC, 0x0C
+ .equiv GCMB_STRUCT_BOOT_KEY, 0x10
+ .equiv GCMB_STRUCT_IMAGE_SIZE, 0x12
+ .equiv GCMB_STRUCT_SESSION_KEY, 0x14
+ .equiv GCMB_STRUCT_HASH_VAL, 0x18
+ .equiv GCMB_STRUCT_KEYC_DERIVATION, 0x1C
+ .equiv GCMB_STRUCT_BASE_DEST_PTR, 0x20
+ .equiv GCMB_STRUCT_CUR_DEST_PTR, 0x24
+ .equiv GCMB_STRUCT_SERIAL_INTR_HANDLER, 0x28
+
+ .equiv ROM_HEADER_NINTENDO_LOGO_OFFSET, 0x04
+ .equiv ROM_HEADER_NINTENDO_LOGO_LENGTH, 0x98
+ .equiv ROM_HEADER_NINTENDO_LOGO_END, 0xA0
+
+ .equiv MBPROGRESS_NONE, 0x00
+ .equiv MBPROGRESS_LOGO_CORRECT, 0x01
+ .equiv MBPROGRESS_READY_TO_BOOT, 0x02
+
+ .equiv GCMB_MAGIC_BOOTKEY_HASHVAL, 0xBB
+ .equiv GCMB_MAGIC_BOOTKEY, 0xBB
+ .equiv GCMB_MAGIC_COUNTER2, 0xCC
+ .equiv GCMB_MAGIC_KEYA, 0xDD
+ .equiv GCMB_MAGIC_KEYB, 0xEE
+ .equiv GCMB_MAGIC_KEYCDERIVATION, 0xFF
+
+ .syntax unified
+
+ .text
+
+ thumb_func_start GameCubeMultiBoot_Hash
+GameCubeMultiBoot_Hash: @ 81DCB38
+ push {r4,lr}
+ ldr r4, pool_HashVal
+ eors r3, r1
+ movs r2, 0x20
+
+GameCubeMultiBoot_Hash_Loop:
+ lsrs r3, 1
+ bcc GameCubeMultiBoot_Hash_SkipEor
+
+ eors r3, r4
+
+GameCubeMultiBoot_Hash_SkipEor:
+ subs r2, 0x1
+ bne GameCubeMultiBoot_Hash_Loop
+
+ pop {r4,pc}
+ thumb_func_end GameCubeMultiBoot_Hash
+
+ thumb_func_start GameCubeMultiBoot_Main
+@ void GameCubeMultiBoot_Main(struct GameCubeMultiBoot *mb)@
+GameCubeMultiBoot_Main: @ 81DCB4C
+ @ If there is no interrupt handler, skip counter manipulation
+ ldr r1, [r0, GCMB_STRUCT_SERIAL_INTR_HANDLER]
+ cmp r1, 0
+ beq GameCubeMultiBoot_Main_SkipCounters
+ @ Increment the second counter
+ ldrb r1, [r0, GCMB_STRUCT_COUNTER2]
+ adds r1, 0x1
+ strb r1, [r0, GCMB_STRUCT_COUNTER2]
+ @ If there is nothing more to do, bail out
+ ldrb r1, [r0, GCMB_STRUCT_MBPROGRESS]
+ cmp r1, MBPROGRESS_READY_TO_BOOT
+ beq GameCubeMultiBoot_Main_Return
+ @ Save current interrupt master register value
+ ldr r3, pool_InterruptRegs
+ ldrh r2, [r3, OFFSET_REG_IME - 0x200]
+ @ Disable all interrupts
+ movs r1, 0
+ strh r1, [r3, OFFSET_REG_IME - 0x200]
+ @ Increment the first counter, if it's less than or equal to 10.
+ ldrb r1, [r0, GCMB_STRUCT_COUNTER1]
+ cmp r1, 0xA
+ bgt GameCubeMultiBoot_Main_SkipCounter1Inc
+ adds r1, 0x1
+ strb r1, [r0, GCMB_STRUCT_COUNTER1]
+GameCubeMultiBoot_Main_SkipCounter1Inc:
+ @ Load the saved interrupt master register value (re-enables interrupts if they were enabled before)
+ strh r2, [r3, OFFSET_REG_IME - 0x200]
+GameCubeMultiBoot_Main_SkipCounters:
+ @ Initialise multiboot structures if required
+ bcs GameCubeMultiBoot_Init
+ @ Skip this section (check Nintendo logo) if the check has already passed
+ ldrb r1, [r0, GCMB_STRUCT_MBPROGRESS]
+ cmp r1, MBPROGRESS_NONE
+ bne GameCubeMultiBoot_Main_SkipLogoCheck
+ @ Bail out if no multiboot image data has been transferred yet
+ ldr r1, [r0, GCMB_STRUCT_CUR_DEST_PTR]
+ ldr r2, [r0, GCMB_STRUCT_BASE_DEST_PTR]
+ subs r1, r2
+ beq GameCubeMultiBoot_Main_Return2
+ @ Also bail out if not enough data has been transferred
+ cmp r1, ROM_HEADER_NINTENDO_LOGO_END
+ bcc GameCubeMultiBoot_Main_Return2
+ @ Compare the Nintendo logo of the transferred multiboot image header, with the one in the ROM image of the inserted cart
+ push {r4-r6}
+ movs r1, ROM_HEADER_NINTENDO_LOGO_LENGTH
+ adds r2, ROM_HEADER_NINTENDO_LOGO_OFFSET
+ ldr r4, pool_NintendoLogo
+GameCubeMultiBoot_Main_LogoCmpLoop:
+ ldm r2!, {r5}
+ ldm r4!, {r6}
+ cmp r5, r6
+ bne GameCubeMultiBoot_Main_LogoCmpEnd
+ subs r1, 0x4
+ bne GameCubeMultiBoot_Main_LogoCmpLoop
+ ldm r2!, {r5}
+ ldm r4!, {r6}
+ eors r5, r6
+ lsrs r5, 8
+ str r2, [r0, GCMB_STRUCT_BASE_DEST_PTR]
+GameCubeMultiBoot_Main_LogoCmpEnd:
+ pop {r4-r6}
+ @ Throw everything away if the logo data didn't match
+ bne GameCubeMultiBoot_Init
+ @ Logo matched, set the relevent multiboot progress bit
+ movs r1, MBPROGRESS_LOGO_CORRECT
+ strb r1, [r0, GCMB_STRUCT_MBPROGRESS]
+ @ XOR together KeyA and KeyB to get the initial multiboot image checksum value
+ ldr r1, [r0, GCMB_STRUCT_KEYA]
+ ldr r2, [r0, GCMB_STRUCT_KEYB]
+ eors r1, r2
+ str r1, [r0, GCMB_STRUCT_HASH_VAL]
+ @ ...also use it as the initial value for the image encryption session key. Algorithm is the same as the GBA BIOS multiboot: sessionkey = (initialvalue * 0x6177614b) + 1
+ ldr r2, pool_Kawa
+ muls r1, r2
+ adds r1, 0x1
+ str r1, [r0, GCMB_STRUCT_SESSION_KEY]
+GameCubeMultiBoot_Main_Return:
+ bx lr
+GameCubeMultiBoot_Main_SkipLogoCheck:
+ @ If this code is executed, then the logo check has passed, and the data being transferred in is encrypted.
+ @ Set up registers.
+ ldr r1, [r0, GCMB_STRUCT_CUR_DEST_PTR]
+ mov r12, r1
+ ldr r3, [r0, GCMB_STRUCT_HASH_VAL]
+ push {r4-r7}
+ ldr r4, [r0, GCMB_STRUCT_BASE_DEST_PTR]
+ ldr r5, pool_Kawa
+ ldr r6, [r0, GCMB_STRUCT_SESSION_KEY]
+ ldr r7, pool_HashVal
+GameCubeMultiBoot_Main_ImageDecryptHashLoop:
+ @ If there's no more data, break out of the loop
+ cmp r4, r12
+ bcs GameCubeMultiBoot_Main_ImageDecryptHashEnd
+ @ Get the next uint32
+ ldr r1, [r4]
+ @ Decrypt the ciphertext: plaintext = (ciphertext ^ sessionkey) + hashval
+ eors r1, r6
+ adds r1, r3
+ @ Save the current uint32 of plaintext and advance the pointer
+ stm r4!, {r1}
+ @ Advance the hashval with this uint32 of plaintext -- this is the same code as GameCubeMultiBoot_Hash.
+ eors r3, r1
+ movs r2, 0x20
+GameCubeMultiBoot_Main_HashLoop:
+ lsrs r3, 1
+ bcc GameCubeMultiBoot_Main_HashSkipEor
+ eors r3, r7
+GameCubeMultiBoot_Main_HashSkipEor:
+ subs r2, 0x1
+ bne GameCubeMultiBoot_Main_HashLoop
+ @ Advance the sessionkey with the usual algorithm: sessionkey = (sessionkey * 0x6177614b) + 1
+ muls r6, r5
+ adds r6, 0x1
+ b GameCubeMultiBoot_Main_ImageDecryptHashLoop
+GameCubeMultiBoot_Main_ImageDecryptHashEnd:
+ @ Save the new pointer, sessionkey, hashval
+ str r4, [r0, GCMB_STRUCT_BASE_DEST_PTR]
+ str r6, [r0, GCMB_STRUCT_SESSION_KEY]
+ pop {r4-r7}
+ str r3, [r0, GCMB_STRUCT_HASH_VAL]
+ @ Bail out if the image size is unknown
+ ldrh r1, [r0, GCMB_STRUCT_IMAGE_SIZE]
+ cmp r1, 0
+ bne GameCubeMultiBoot_Main_Return2
+ @ Bail out if no image data has been transferred
+ ldr r1, [r0, GCMB_STRUCT_CUR_DEST_PTR]
+ ldr r2, [r0, GCMB_STRUCT_BASE_DEST_PTR]
+ cmp r1, r2
+ bne GameCubeMultiBoot_Main_Return2
+ @ If KeyC hasn't been generated yet, go generate it
+ ldr r1, [r0, GCMB_STRUCT_KEYC]
+ cmp r1, 0
+ beq GameCubeMultiBoot_Main_GenerateKeyC
+ @ If the other side hasn't sent its boot key yet, bail out
+ ldrh r1, [r0, GCMB_STRUCT_BOOT_KEY]
+ cmp r1, 0
+ beq GameCubeMultiBoot_Main_Return
+ @ Save off LR so it doesn't get clobbered by the upcoming function call
+ mov r12, lr
+ @ Generate the real boot key, which is the checksum of a hardcoded value and KeyC
+ movs r1, GCMB_MAGIC_BOOTKEY_HASHVAL
+ ldr r3, [r0, GCMB_STRUCT_KEYC]
+ bl GameCubeMultiBoot_Hash
+ ldrh r1, [r0, GCMB_STRUCT_BOOT_KEY]
+ @ Restore the saved LR value
+ mov lr, r12
+ @ Compare the two boot keys (real and passed in), if they don't match then throw everything away
+ subs r1, r3
+ bne GameCubeMultiBoot_Init
+ @ The two boot keys matched, tell the caller that the image is ready to boot
+ movs r1, MBPROGRESS_READY_TO_BOOT
+ strb r1, [r0, GCMB_STRUCT_MBPROGRESS]
+ @ Nothing more to do, return.
+ bx lr
+GameCubeMultiBoot_Main_GenerateKeyC:
+ @ Save off LR so it doesn't get clobbered by the upcoming function call
+ mov r12, lr
+ @ KeyC = (SavedVCount << 24) - 1
+ ldrb r1, [r0, GCMB_STRUCT_SAVEDVCOUNT]
+ lsls r1, 24
+ subs r1, 0x1
+ str r1, [r0, GCMB_STRUCT_KEYC]
+ @ Hash the KeyC with the multiboot image checksum to generate the KeyC derivation material to be sent to the other side of the link
+ bl GameCubeMultiBoot_Hash
+ @ Make sure the sent KeyC derivation material contains a magic value so that the other side can detect it
+ lsls r3, 8
+ adds r3, GCMB_MAGIC_KEYCDERIVATION
+ @ Save off the KeyC derivation material and return to caller
+ str r3, [r0, GCMB_STRUCT_KEYC_DERIVATION]
+ bx r12
+GameCubeMultiBoot_Main_Return2:
+ bx lr
+ thumb_func_end GameCubeMultiBoot_Main
+
+ .align 2, 0
+
+pool_HashVal: .4byte 0xa1c1
+
+pool_Kawa: .ascii "Kawa" @ name of BIOS developer
+
+pool_NintendoLogo: .4byte RomHeaderNintendoLogo
+
+ thumb_func_start GameCubeMultiBoot_ExecuteProgram
+@ void GameCubeMultiBoot_ExecuteProgram(struct GameCubeMultiBoot *mb)@
+GameCubeMultiBoot_ExecuteProgram: @ 81DCC4C
+ @ If there's no multiboot image ready, just return to caller
+ ldrb r1, [r0, GCMB_STRUCT_MBPROGRESS]
+ cmp r1, MBPROGRESS_READY_TO_BOOT
+ bne GameCubeMultiBoot_ExecuteProgram_Fail
+ @ Disable interrupts
+ ldr r3, pool_InterruptRegs
+ movs r1, 0
+ strh r1, [r3, OFFSET_REG_IME - 0x200]
+ @ Jump to the real entry point of the multiboot image (past the image header), in ARM mode
+ ldr r1, pool_MultiBootLoadAddr
+ adds r1, 0xC0
+ bx r1
+GameCubeMultiBoot_ExecuteProgram_Fail:
+ bx lr
+ thumb_func_end GameCubeMultiBoot_ExecuteProgram
+
+ thumb_func_start GameCubeMultiBoot_Init
+@ void GameCubeMultiBoot_Init(struct GameCubeMultiBoot *mb)@
+GameCubeMultiBoot_Init: @ 81DCC60
+ ldr r3, pool_InterruptRegs
+
+@ Save IME register.
+ ldrh r2, [r3, OFFSET_REG_IME - 0x200]
+
+@ Disable interrupts.
+ movs r1, 0
+ strh r1, [r3, OFFSET_REG_IME - 0x200]
+
+@ Set the handler to the "Stop" routine.
+@ Unless the first command that is received is a device reset command, the
+@ "Stop" routine will be executed and no further commands will be processed.
+ adr r3, GcMbIntrHandler_Stop
+ str r3, [r0, GCMB_STRUCT_SERIAL_INTR_HANDLER]
+
+ ldrb r3, [r0, 0x3]
+ push {r3}
+ ldrb r3, [r0, 0x1]
+ push {r0,r3}
+
+ adds r3, r0, 0
+ adds r3, GCMB_STRUCT_BASE_DEST_PTR
+
+@ clear all but the last 3 fields of the struct
+GameCubeMultiBoot_Init_ClearStructLoop:
+ stm r0!, {r1}
+ cmp r0, r3
+ blo GameCubeMultiBoot_Init_ClearStructLoop
+
+ pop {r0,r3}
+ lsrs r3, 1
+ strb r3, [r0, 0x3]
+ pop {r3}
+ strb r3, [r0, 0x1]
+
+ ldr r3, pool_SerialRegs
+
+@ Turn off JOY Bus mode.
+ lsls r0, r3, 10
+ strh r0, [r3, OFFSET_REG_RCNT - 0x120]
+
+@ Turn on JOY Bus mode.
+ movs r0, 0xC0
+ lsls r0, 8
+ strh r0, [r3, OFFSET_REG_RCNT - 0x120]
+
+@ Init JOY Bus registers.
+ movs r0, 0x47
+ strh r0, [r3, OFFSET_REG_JOYCNT - 0x120]
+ strh r1, [r3, OFFSET_REG_JOYSTAT - 0x120]
+
+ ldr r3, pool_InterruptRegs
+
+@ Acknowledge serial interrupt.
+ movs r0, INTR_FLAG_SERIAL
+ strh r0, [r3, OFFSET_REG_IF - 0x200]
+
+@ Enable serial interrupt.
+ ldrh r1, [r3, OFFSET_REG_IE - 0x200]
+ orrs r1, r0
+ strh r1, [r3, OFFSET_REG_IE - 0x200]
+
+@ Restore IME register.
+ strh r2, [r3, OFFSET_REG_IME - 0x200]
+
+ bx lr
+ thumb_func_end GameCubeMultiBoot_Init
+
+ non_word_aligned_thumb_func_start GameCubeMultiBoot_HandleSerialInterrupt
+@ void GameCubeMultiBoot_HandleSerialInterrupt(struct GameCubeMultiBoot *mb)@
+GameCubeMultiBoot_HandleSerialInterrupt: @ 81DCCAA
+ ldr r3, pool_SerialRegs
+
+@ Acknowledge reset/receive/send flags.
+ ldrh r1, [r3, OFFSET_REG_JOYCNT - 0x120]
+ strh r1, [r3, OFFSET_REG_JOYCNT - 0x120]
+
+ movs r2, 0
+ strb r2, [r0]
+
+ ldr r2, [r0, GCMB_STRUCT_SERIAL_INTR_HANDLER]
+ cmp r2, 0
+ beq GameCubeMultiBoot_HandleSerialInterruptDone
+
+ lsrs r1, 1 @ was a device reset command received?
+ bcs GameCubeMultiBoot_BeginHandshake @ branch if so
+
+ mov pc, r2
+
+ .align 2, 0
+
+@ Zero the status and the interrupt handler pointer.
+@ Commands from the GameCube will not be processed after this is executed
+@ unless GameCubeMultiBoot_Init() is called again.
+GcMbIntrHandler_Stop:
+ movs r2, 0
+ strh r2, [r3, OFFSET_REG_JOYSTAT - 0x120]
+
+GameCubeMultiBoot_SetInterruptHandler:
+ str r2, [r0, GCMB_STRUCT_SERIAL_INTR_HANDLER]
+
+GameCubeMultiBoot_ReadVCount:
+ ldr r3, pool_RegDispstat
+ ldrh r1, [r3, OFFSET_REG_VCOUNT - OFFSET_REG_DISPSTAT]
+ strb r1, [r0, 0x3]
+
+GameCubeMultiBoot_HandleSerialInterruptDone:
+ bx lr
+
+GameCubeMultiBoot_BeginHandshake:
+ @ Throw away anything that got sent
+ ldr r1, [r3, OFFSET_REG_JOY_RECV - 0x120]
+ @ Send the game code, the other side of the link must send back the same game code
+ ldr r1, pool_RubyUSAGameCode
+ str r1, [r3, OFFSET_REG_JOY_TRANS - 0x120]
+ movs r1, 0x10
+ strh r1, [r3, OFFSET_REG_JOYSTAT - 0x120]
+ @ Use the saved VCount value to provide 8 bits of entropy for KeyB
+ ldrb r1, [r0, GCMB_STRUCT_SAVEDVCOUNT]
+ strb r1, [r0, GCMB_STRUCT_KEYB + 1]
+ @ If a multiboot image has been transferred at least enough such that the Nintendo logo check has passed, stop everything.
+ ldrb r1, [r0, GCMB_STRUCT_MBPROGRESS]
+ cmp r1, 0
+ bne GcMbIntrHandler_Stop
+ @ Set the image destination pointers.
+ ldr r1, pool_MultiBootLoadAddr
+ str r1, [r0, GCMB_STRUCT_BASE_DEST_PTR]
+ str r1, [r0, GCMB_STRUCT_CUR_DEST_PTR]
+ @ Set the new interrupt handler.
+ adr r2, GcMbIntrHandler_CheckGameCodeSent
+ b GameCubeMultiBoot_SetInterruptHandler
+
+ .align 2, 0
+
+GcMbIntrHandler_CheckGameCodeSent: @ 81DCCEC
+ lsls r1, 31
+ bcc GcMbIntrHandler_Stop @ stop if send failed
+ bmi GameCubeMultiBoot_CheckHandshakeResponse @ branch if receive is complete
+
+@ If the response hasn't been fully received yet,
+@ check again upon the next interrupt.
+ adr r2, GcMbIntrHandler_CheckHandshakeResponse
+ b GameCubeMultiBoot_SetInterruptHandler
+
+ .align 2, 0
+
+GcMbIntrHandler_CheckHandshakeResponse: @ 81DCCF8
+ lsrs r1, 1 @ is receive complete?
+ bcc GcMbIntrHandler_Stop @ stop if not
+
+GameCubeMultiBoot_CheckHandshakeResponse:
+ ldr r1, [r3, OFFSET_REG_JOY_RECV - 0x120]
+ ldr r2, pool_RubyUSAGameCode
+ cmp r1, r2
+ bne GcMbIntrHandler_Stop @ stop if the GameCube didn't reply with the same game code
+ @ Use the saved VCount value to provide another 8 bits of entropy for KeyB.
+ ldrb r1, [r0, GCMB_STRUCT_SAVEDVCOUNT]
+ strb r1, [r0, GCMB_STRUCT_KEYB + 3]
+ adr r2, GcMbIntrHandler_ReceiveKeyA
+ b GameCubeMultiBoot_SetInterruptHandler
+
+ .align 2, 0
+
+GcMbIntrHandler_ReceiveKeyA: @ 81DCD0C
+ lsrs r1, 1 @ is receive complete?
+ bcc GcMbIntrHandler_Stop @ branch if not
+ ldr r1, [r3, OFFSET_REG_JOY_RECV - 0x120]
+ @ make sure top 8 bits of the received value is the KeyA magic number, stop if KeyA is invalid
+ lsrs r2, r1, 24
+ cmp r2, GCMB_MAGIC_KEYA
+ bne GcMbIntrHandler_Stop
+ @ save received KeyA
+ str r1, [r0, GCMB_STRUCT_KEYA]
+ @ use the second GameCubeMultiBoot_Main() counter as another 8 bits of entropy for KeyB
+ ldrb r1, [r0, GCMB_STRUCT_COUNTER2]
+ strb r1, [r0, GCMB_STRUCT_KEYB + 2]
+ movs r2, 0
+ movs r3, 0
+ ldr r1, [r0, GCMB_STRUCT_KEYB]
+ lsrs r1, 8
+ @ make sure KeyB is valid (other side of the link is supposed to check KeyB too), if it's not then change the byte that was just set so it is
+GameCubeMultiBoot_KeyBCheckLoop:
+ lsrs r1, 1
+ adcs r2, r3
+ cmp r1, 0
+ bne GameCubeMultiBoot_KeyBCheckLoop
+ cmp r2, 0xE
+ bgt GameCubeMultiBoot_KeyBSaveNewByte
+ cmp r2, 0x7
+ bge GameCubeMultiBoot_KeyBCheckEnd
+ movs r1, 0xFF
+GameCubeMultiBoot_KeyBSaveNewByte:
+ strb r1, [r0, GCMB_STRUCT_KEYB + 2]
+GameCubeMultiBoot_KeyBCheckEnd:
+ @ add in the KeyB magic number and send off KeyB
+ ldr r1, [r0, GCMB_STRUCT_KEYB]
+ adds r1, GCMB_MAGIC_KEYB
+ ldr r3, pool_SerialRegs
+ str r1, [r3, OFFSET_REG_JOY_TRANS - 0x120]
+ movs r1, 0x30
+ strh r1, [r3, OFFSET_REG_JOYSTAT - 0x120]
+ @ set new interrupt handler
+ adr r2, GcMbIntrHandler_CheckKeyBSent
+ b GameCubeMultiBoot_SetInterruptHandler
+
+ .align 2, 0
+
+GcMbIntrHandler_CheckKeyBSent: @ 81DCD4C
+ lsls r1, 31
+ bcc GcMbIntrHandler_Stop @ stop if send failed
+ bmi GameCubeMultiBoot_CheckImageSizeResponse @ branch if receive is complete
+ adr r2, GcMbIntrHandler_CheckImageSizeResponse
+ b GameCubeMultiBoot_SetInterruptHandler
+
+ .align 2, 0
+
+GcMbIntrHandler_CheckImageSizeResponse: @ 81DCD58
+ lsrs r1, 1 @ is receive complete?
+ bcc GcMbIntrHandler_Stop @ branch if not
+GameCubeMultiBoot_CheckImageSizeResponse:
+ ldr r1, [r3, OFFSET_REG_JOY_RECV - 0x120]
+ ldr r2, GameCubeMultiBoot_MaximumImageSizeUInt32s
+ cmp r1, r2
+ bhs GcMbIntrHandler_Stop
+ adds r1, 0x1
+ adds r1, r1
+ strh r1, [r0, GCMB_STRUCT_IMAGE_SIZE]
+ ldrb r1, [r0, GCMB_STRUCT_MBPROGRESS]
+ cmp r1, 0
+GcMbIntrHandler_StopIfNotEqual:
+ bne GcMbIntrHandler_Stop
+ ldr r1, pool_MultiBootLoadAddr
+ str r1, [r0, GCMB_STRUCT_BASE_DEST_PTR]
+ str r1, [r0, GCMB_STRUCT_CUR_DEST_PTR]
+ adr r2, GcMbIntrHandler_CheckImageResponse
+ b GameCubeMultiBoot_SetInterruptHandler
+
+ .align 2, 0
+
+GcMbIntrHandler_CheckImageResponse: @ 81DCD7C
+ lsrs r1, 1 @ is receive complete?
+ bcc GcMbIntrHandler_Stop @ branch if not
+ ldr r2, [r0, GCMB_STRUCT_CUR_DEST_PTR]
+ movs r1, 0x4
+ ands r1, r2
+ adds r1, 0x8
+ lsls r1, 2
+ strh r1, [r3, OFFSET_REG_JOYSTAT - 0x120]
+ @ get the recieved uint32
+ ldr r1, [r3, OFFSET_REG_JOY_RECV - 0x120]
+ @ put it in the current destination pointer and advance that pointer
+ stm r2!, {r1}
+ @ save off the advanced pointer
+ str r2, [r0, GCMB_STRUCT_CUR_DEST_PTR]
+ @ decrease the image size (in uint32s)
+ ldrh r1, [r0, GCMB_STRUCT_IMAGE_SIZE]
+ subs r1, 0x1
+ strh r1, [r0, GCMB_STRUCT_IMAGE_SIZE]
+ @ branch away if the transfer is not yet complete
+ bne GameCubeMultiBoot_ReadVCount
+
+GcMbIntrHandler_SendCounter2:
+ @ send counter2 with magic number
+ ldrb r1, [r0, GCMB_STRUCT_COUNTER2]
+ lsls r1, 8
+ adds r1, GCMB_MAGIC_COUNTER2
+ str r1, [r3, OFFSET_REG_JOY_TRANS - 0x120]
+ adr r2, GcMbIntrHandler_CheckCounter2Sent
+ b GameCubeMultiBoot_SetInterruptHandler
+
+ .align 2, 0
+
+GcMbIntrHandler_CheckCounter2Sent:
+ lsls r1, 31
+
+GcMbIntrHandler_StopIfSendFailed:
+ bcc GcMbIntrHandler_Stop @ stop if send failed
+ @ if KeyC derivation value has not yet been generated, send Counter2 again, otherwise, send KeyC derivation
+ ldr r1, [r0, GCMB_STRUCT_KEYC_DERIVATION]
+ cmp r1, 0
+ beq GcMbIntrHandler_SendCounter2
+ str r1, [r3, OFFSET_REG_JOY_TRANS - 0x120]
+ adr r2, GcMbIntrHandler_CheckKeyCDerivationSent
+ b GameCubeMultiBoot_SetInterruptHandler
+
+ .align 2, 0
+
+GcMbIntrHandler_CheckKeyCDerivationSent: @ 81DCDB8
+ lsls r1, 31
+ bcc GcMbIntrHandler_StopIfSendFailed @ branch if send failed
+ bmi GameCubeMultiBoot_CheckBootKeyResponse @ branch if receive is complete
+ adr r2, GcMbIntrHandler_CheckBootKeyResponse
+ b GameCubeMultiBoot_SetInterruptHandler
+
+ .align 2, 0
+
+GcMbIntrHandler_CheckBootKeyResponse: @ 81DCDC4
+ lsrs r1, 1 @ is receive complete?
+ bcc GcMbIntrHandler_StopIfSendFailed @ branch if not
+
+GameCubeMultiBoot_CheckBootKeyResponse:
+ ldr r1, [r3, OFFSET_REG_JOY_RECV - 0x120]
+ @ make sure received boot key contains expected magic number, stop if not
+ lsrs r2, r1, 24
+ cmp r2, GCMB_MAGIC_BOOTKEY
+ bne GcMbIntrHandler_StopIfNotEqual
+ @ save received bootkey to be checked in GameCubeMultiBoot_Main()
+ strh r1, [r0, GCMB_STRUCT_BOOT_KEY]
+ @ stop if anything more gets sent
+ adr r2, GcMbIntrHandler_StopUnconditionally
+ b GameCubeMultiBoot_SetInterruptHandler
+
+ .align 2, 0
+
+GcMbIntrHandler_StopUnconditionally: @ 81DCDD8
+ b GcMbIntrHandler_Stop
+
+ thumb_func_end GameCubeMultiBoot_HandleSerialInterrupt
+
+ non_word_aligned_thumb_func_start GameCubeMultiBoot_Quit
+@ void GameCubeMultiBoot_Quit()@
+GameCubeMultiBoot_Quit: @ 81DCDDA
+ ldr r3, pool_InterruptRegs
+
+@ Save IME register.
+ ldrh r2, [r3, OFFSET_REG_IME - 0x200]
+
+@ Disable interrupts.
+ movs r1, 0
+ strh r1, [r3, OFFSET_REG_IME - 0x200]
+
+ ldr r3, pool_SerialRegs
+
+@ Acknowledge all JOYCNT flags.
+ movs r0, 0x7
+ strh r0, [r3, OFFSET_REG_JOYCNT - 0x120]
+
+@ Turn off JOY Bus mode.
+ lsls r0, r3, 10
+ strh r0, [r3, OFFSET_REG_RCNT - 0x120] @ store 0x8000
+
+ ldr r3, pool_InterruptRegs
+
+@ Acknowledge serial interrupt.
+ movs r0, INTR_FLAG_SERIAL
+ strh r0, [r3, OFFSET_REG_IF - 0x200]
+
+@ Disable serial interrupt.
+ ldrh r1, [r3, OFFSET_REG_IE - 0x200]
+ bics r1, r0
+ strh r1, [r3, OFFSET_REG_IE - 0x200]
+
+@ Restore IME register.
+ strh r2, [r3, OFFSET_REG_IME - 0x200]
+
+ bx lr
+ thumb_func_end GameCubeMultiBoot_Quit
+
+ .align 2, 0
+
+GameCubeMultiBoot_MaximumImageSizeUInt32s: .4byte 0x00004000
+
+pool_InterruptRegs: .4byte REG_BASE + 0x200
+
+pool_SerialRegs: .4byte REG_BASE + 0x120
+
+pool_RegDispstat: .4byte REG_DISPSTAT
+
+pool_RubyUSAGameCode: .ascii "AXVE"
+
+pool_MultiBootLoadAddr: .4byte EWRAM_START
+
+ .align 2, 0 @ Don't pad with nop.
diff --git a/src/libs/m4a_1.s b/src/libs/m4a_1.s
new file mode 100644
index 000000000..be8b44488
--- /dev/null
+++ b/src/libs/m4a_1.s
@@ -0,0 +1,1911 @@
+ .include "include/macros.inc"
+ .include "constants/gba_constants.inc"
+ .include "constants/m4a_constants.inc"
+
+ .syntax unified
+
+ .lcomm gUnknown_030007B8, 0x770
+
+ .text
+
+ thumb_func_start umul3232H32
+umul3232H32:
+ adr r2, __umul3232H32
+ bx r2
+ .arm
+__umul3232H32:
+ umull r2, r3, r0, r1
+ add r0, r3, 0
+ bx lr
+ thumb_func_end umul3232H32
+
+ thumb_func_start SoundMain
+SoundMain:
+ ldr r0, lt_SOUND_INFO_PTR
+ ldr r0, [r0]
+ ldr r2, lt_ID_NUMBER
+ ldr r3, [r0, o_SoundInfo_ident]
+ cmp r2, r3
+ beq SoundMain_1
+ bx lr @ Exit the function if ident doesn't match ID_NUMBER.
+SoundMain_1:
+ adds r3, 1
+ str r3, [r0, o_SoundInfo_ident]
+ push {r4-r7,lr}
+ mov r1, r8
+ mov r2, r9
+ mov r3, r10
+ mov r4, r11
+ push {r0-r4}
+ sub sp, 0x18
+ ldrb r1, [r0, o_SoundInfo_maxLines]
+ cmp r1, 0 @ if maxLines is 0, there is no maximum
+ beq SoundMain_3
+ ldr r2, lt_REG_VCOUNT
+ ldrb r2, [r2]
+ cmp r2, VCOUNT_VBLANK
+ bhs SoundMain_2
+ adds r2, TOTAL_SCANLINES
+SoundMain_2:
+ adds r1, r2
+SoundMain_3:
+ str r1, [sp, 0x14]
+ ldr r3, [r0, o_SoundInfo_func]
+ cmp r3, 0
+ beq SoundMain_4
+ ldr r0, [r0, o_SoundInfo_intp]
+ bl _081DD25E
+ ldr r0, [sp, 0x18]
+SoundMain_4:
+ ldr r3, [r0, o_SoundInfo_CgbSound]
+ bl _081DD25E
+ ldr r0, [sp, 0x18]
+ ldr r3, [r0, o_SoundInfo_pcmSamplesPerVBlank]
+ mov r8, r3
+ ldr r5, lt_o_SoundInfo_pcmBuffer
+ adds r5, r0
+ ldrb r4, [r0, o_SoundInfo_pcmDmaCounter]
+ subs r7, r4, 1
+ bls SoundMain_5
+ ldrb r1, [r0, o_SoundInfo_pcmDmaPeriod]
+ subs r1, r7
+ mov r2, r8
+ muls r2, r1
+ adds r5, r2
+SoundMain_5:
+ str r5, [sp, 0x8]
+ ldr r6, lt_PCM_DMA_BUF_SIZE
+ ldr r3, lt_SoundMainRAM_Buffer
+ bx r3
+
+ .align 2, 0
+lt_SOUND_INFO_PTR: .word SOUND_INFO_PTR
+lt_ID_NUMBER: .word ID_NUMBER
+lt_SoundMainRAM_Buffer: .word SoundMainRAM_Buffer + 1
+lt_REG_VCOUNT: .word REG_VCOUNT
+lt_o_SoundInfo_pcmBuffer: .word o_SoundInfo_pcmBuffer
+lt_PCM_DMA_BUF_SIZE: .word PCM_DMA_BUF_SIZE
+ thumb_func_end SoundMain
+
+ thumb_func_start SoundMainRAM
+SoundMainRAM:
+ ldrb r3, [r0, o_SoundInfo_reverb]
+ cmp r3, 0
+ beq SoundMainRAM_NoReverb
+ adr r1, SoundMainRAM_Reverb
+ bx r1
+ .arm
+SoundMainRAM_Reverb:
+ cmp r4, 0x2
+ addeq r7, r0, o_SoundInfo_pcmBuffer
+ addne r7, r5, r8
+ mov r4, r8
+_081DCEC4:
+ ldrsb r0, [r5, r6]
+ ldrsb r1, [r5]
+ add r0, r0, r1
+ ldrsb r1, [r7, r6]
+ add r0, r0, r1
+ ldrsb r1, [r7], 0x1
+ add r0, r0, r1
+ mul r1, r0, r3
+ mov r0, r1, asr 9
+ tst r0, 0x80
+ addne r0, r0, 0x1
+ strb r0, [r5, r6]
+ strb r0, [r5], 0x1
+ subs r4, r4, 0x1
+ bgt _081DCEC4
+ adr r0, _081DCF36 + 1 @ plus 1 because THUMB
+ bx r0
+ .thumb
+SoundMainRAM_NoReverb:
+ movs r0, 0
+ mov r1, r8
+ adds r6, r5
+ lsrs r1, 3
+ bcc SoundMainRAM_NoReverb_Ok
+ stm r5!, {r0}
+ stm r6!, {r0}
+SoundMainRAM_NoReverb_Ok:
+ lsrs r1, 1
+ bcc SoundMainRAM_NoReverb_Loop
+ stm r5!, {r0}
+ stm r6!, {r0}
+ stm r5!, {r0}
+ stm r6!, {r0}
+SoundMainRAM_NoReverb_Loop:
+ stm r5!, {r0}
+ stm r6!, {r0}
+ stm r5!, {r0}
+ stm r6!, {r0}
+ stm r5!, {r0}
+ stm r6!, {r0}
+ stm r5!, {r0}
+ stm r6!, {r0}
+ subs r1, 1
+ bgt SoundMainRAM_NoReverb_Loop
+_081DCF36:
+ ldr r4, [sp, 0x18]
+ ldr r0, [r4, o_SoundInfo_divFreq]
+ mov r12, r0
+ ldrb r0, [r4, o_SoundInfo_maxChans]
+ adds r4, o_SoundInfo_chans
+
+SoundMainRAM_ChanLoop:
+ str r0, [sp, 0x4]
+ ldr r3, [r4, o_SoundChannel_wav]
+ ldr r0, [sp, 0x14]
+ cmp r0, 0
+ beq _081DCF60
+ ldr r1, =REG_VCOUNT
+ ldrb r1, [r1]
+ cmp r1, VCOUNT_VBLANK
+ bhs _081DCF54
+ adds r1, TOTAL_SCANLINES
+_081DCF54:
+ cmp r1, r0
+ blo _081DCF60
+ b _081DD24A
+
+ .pool
+
+_081DCF60:
+ ldrb r6, [r4, o_SoundChannel_status]
+ movs r0, 0xC7
+ tst r0, r6
+ bne _081DCF6A
+ b _081DD240
+_081DCF6A:
+ movs r0, 0x80
+ tst r0, r6
+ beq _081DCFA0
+ movs r0, 0x40
+ tst r0, r6
+ bne _081DCFB0
+ movs r6, 0x3
+ strb r6, [r4, o_SoundChannel_status]
+ adds r0, r3, 0
+ adds r0, 0x10
+ ldr r1, [r4, o_SoundChannel_ct]
+ adds r0, r1
+ str r0, [r4, o_SoundChannel_cp]
+ ldr r0, [r3, 0xC]
+ subs r0, r1
+ str r0, [r4, o_SoundChannel_ct]
+ movs r5, 0
+ strb r5, [r4, o_SoundChannel_ev]
+ str r5, [r4, o_SoundChannel_fw]
+ ldrb r2, [r3, 0x3]
+ movs r0, 0xC0
+ tst r0, r2
+ beq _081DCFF8
+ movs r0, 0x10
+ orrs r6, r0
+ strb r6, [r4, o_SoundChannel_status]
+ b _081DCFF8
+_081DCFA0:
+ ldrb r5, [r4, o_SoundChannel_ev]
+ movs r0, 0x4
+ tst r0, r6
+ beq _081DCFB6
+ ldrb r0, [r4, o_SoundChannel_iel]
+ subs r0, 1
+ strb r0, [r4, o_SoundChannel_iel]
+ bhi _081DD006
+_081DCFB0:
+ movs r0, 0
+ strb r0, [r4, o_SoundChannel_status]
+ b _081DD240
+_081DCFB6:
+ movs r0, 0x40
+ tst r0, r6
+ beq _081DCFD6
+ ldrb r0, [r4, o_SoundChannel_release]
+ muls r5, r0
+ lsrs r5, 8
+ ldrb r0, [r4, o_SoundChannel_iev]
+ cmp r5, r0
+ bhi _081DD006
+_081DCFC8:
+ ldrb r5, [r4, o_SoundChannel_iev]
+ cmp r5, 0
+ beq _081DCFB0
+ movs r0, 0x4
+ orrs r6, r0
+ strb r6, [r4, o_SoundChannel_status]
+ b _081DD006
+_081DCFD6:
+ movs r2, 0x3
+ ands r2, r6
+ cmp r2, 0x2
+ bne _081DCFF4
+ ldrb r0, [r4, o_SoundChannel_decay]
+ muls r5, r0
+ lsrs r5, 8
+ ldrb r0, [r4, o_SoundChannel_sustain]
+ cmp r5, r0
+ bhi _081DD006
+ adds r5, r0, 0
+ beq _081DCFC8
+ subs r6, 0x1
+ strb r6, [r4, o_SoundChannel_status]
+ b _081DD006
+_081DCFF4:
+ cmp r2, 0x3
+ bne _081DD006
+_081DCFF8:
+ ldrb r0, [r4, o_SoundChannel_attack]
+ adds r5, r0
+ cmp r5, 0xFF
+ bcc _081DD006
+ movs r5, 0xFF
+ subs r6, 0x1
+ strb r6, [r4, o_SoundChannel_status]
+_081DD006:
+ strb r5, [r4, o_SoundChannel_ev]
+ ldr r0, [sp, 0x18]
+ ldrb r0, [r0, o_SoundChannel_release]
+ adds r0, 0x1
+ muls r0, r5
+ lsrs r5, r0, 4
+ ldrb r0, [r4, o_SoundChannel_rightVolume]
+ muls r0, r5
+ lsrs r0, 8
+ strb r0, [r4, o_SoundChannel_er]
+ ldrb r0, [r4, o_SoundChannel_leftVolume]
+ muls r0, r5
+ lsrs r0, 8
+ strb r0, [r4, o_SoundChannel_el]
+ movs r0, 0x10
+ ands r0, r6
+ str r0, [sp, 0x10]
+ beq _081DD03A
+ adds r0, r3, 0
+ adds r0, 0x10
+ ldr r1, [r3, 0x8]
+ adds r0, r1
+ str r0, [sp, 0xC]
+ ldr r0, [r3, 0xC]
+ subs r0, r1
+ str r0, [sp, 0x10]
+_081DD03A:
+ ldr r5, [sp, 0x8]
+ ldr r2, [r4, o_SoundChannel_ct]
+ ldr r3, [r4, o_SoundChannel_cp]
+ adr r0, _081DD044
+ bx r0
+ .arm
+_081DD044:
+ str r8, [sp]
+ ldr r9, [r4, o_SoundChannel_fw]
+ ldrb r10, [r4, o_SoundChannel_er]
+ ldrb r11, [r4, o_SoundChannel_el]
+ ldrb r0, [r4, o_SoundChannel_type]
+ tst r0, 0x30
+ beq _081DD068
+ bl sub_81DD264
+ b _081DD228
+_081DD068:
+ mov r10, r10, lsl 16
+ mov r11, r11, lsl 16
+ ldrb r0, [r4, o_SoundChannel_type]
+ tst r0, 0x8
+ beq _081DD19C
+_081DD07C:
+ cmp r2, 0x4
+ ble _081DD0EC
+ subs r2, r2, r8
+ movgt r9, 0
+ bgt _081DD0A8
+ mov r9, r8
+ add r2, r2, r8
+ sub r8, r2, 0x4
+ sub r9, r9, r8
+ ands r2, r2, 0x3
+ moveq r2, 0x4
+_081DD0A8:
+ ldr r6, [r5]
+ ldr r7, [r5, 0x630]
+_081DD0B0:
+ ldrsb r0, [r3], 0x1
+ mul r1, r10, r0
+ bic r1, r1, 0xFF0000
+ add r6, r1, r6, ror 8
+ mul r1, r11, r0
+ bic r1, r1, 0xFF0000
+ add r7, r1, r7, ror 8
+ adds r5, r5, 0x40000000
+ bcc _081DD0B0
+ str r7, [r5, 0x630]
+ str r6, [r5], 0x4
+ subs r8, r8, 0x4
+ bgt _081DD0A8
+ adds r8, r8, r9
+ beq _081DD22C
+_081DD0EC:
+ ldr r6, [r5]
+ ldr r7, [r5, 0x630]
+_081DD0F4:
+ ldrsb r0, [r3], 0x1
+ mul r1, r10, r0
+ bic r1, r1, 0xFF0000
+ add r6, r1, r6, ror 8
+ mul r1, r11, r0
+ bic r1, r1, 0xFF0000
+ add r7, r1, r7, ror 8
+ subs r2, r2, 0x1
+ beq _081DD164
+_081DD118:
+ adds r5, r5, 0x40000000
+ bcc _081DD0F4
+ str r7, [r5, 0x630]
+ str r6, [r5], 0x4
+ subs r8, r8, 0x4
+ bgt _081DD07C
+ b _081DD22C
+_081DD134:
+ ldr r0, [sp, 0x18]
+ cmp r0, 0
+ beq _081DD158
+ ldr r3, [sp, 0x14]
+ rsb lr, r2, 0
+_081DD148:
+ adds r2, r0, r2
+ bgt _081DD1FC
+ sub lr, lr, r0
+ b _081DD148
+_081DD158:
+ pop {r4,r12}
+ mov r2, 0
+ b _081DD174
+_081DD164:
+ ldr r2, [sp, 0x10]
+ cmp r2, 0
+ ldrne r3, [sp, 0xC]
+ bne _081DD118
+_081DD174:
+ strb r2, [r4, o_SoundChannel_status]
+ mov r0, r5, lsr 30
+ bic r5, r5, 0xC0000000
+ rsb r0, r0, 0x3
+ mov r0, r0, lsl 3
+ mov r6, r6, ror r0
+ mov r7, r7, ror r0
+ str r7, [r5, 0x630]
+ str r6, [r5], 0x4
+ b _081DD234
+_081DD19C:
+ push {r4,r12}
+ ldr r1, [r4, o_SoundChannel_freq]
+ mul r4, r12, r1
+ ldrsb r0, [r3]
+ ldrsb r1, [r3, 0x1]!
+ sub r1, r1, r0
+_081DD1B4:
+ ldr r6, [r5]
+ ldr r7, [r5, 0x630]
+_081DD1BC:
+ mul lr, r9, r1
+ add lr, r0, lr, asr 23
+ mul r12, r10, lr
+ bic r12, r12, 0xFF0000
+ add r6, r12, r6, ror 8
+ mul r12, r11, lr
+ bic r12, r12, 0xFF0000
+ add r7, r12, r7, ror 8
+ add r9, r9, r4
+ movs lr, r9, lsr 23
+ beq _081DD208
+ bic r9, r9, 0x3F800000
+ subs r2, r2, lr
+ ble _081DD134
+ subs lr, lr, 0x1
+ addeq r0, r0, r1
+_081DD1FC:
+ ldrsbne r0, [r3, lr]!
+ ldrsb r1, [r3, 0x1]!
+ sub r1, r1, r0
+_081DD208:
+ adds r5, r5, 0x40000000
+ bcc _081DD1BC
+ str r7, [r5, 0x630]
+ str r6, [r5], 0x4
+ subs r8, r8, 0x4
+ bgt _081DD1B4
+ sub r3, r3, 0x1
+ pop {r4,r12}
+_081DD228:
+ str r9, [r4, o_SoundChannel_fw]
+_081DD22C:
+ str r2, [r4, o_SoundChannel_ct]
+ str r3, [r4, o_SoundChannel_cp]
+_081DD234:
+ ldr r8, [sp]
+ add r0, pc, 0x1
+ bx r0
+ .thumb
+_081DD240:
+ ldr r0, [sp, 0x4]
+ subs r0, 1
+ ble _081DD24A
+ adds r4, SoundChannel_size
+ b SoundMainRAM_ChanLoop
+_081DD24A:
+ ldr r0, [sp, 0x18]
+ ldr r3, =ID_NUMBER
+ str r3, [r0]
+ add sp, 0x1C
+ pop {r0-r7}
+ mov r8, r0
+ mov r9, r1
+ mov r10, r2
+ mov r11, r3
+ pop {r3}
+_081DD25E:
+ bx r3
+ .pool
+ thumb_func_end SoundMainRAM
+
+ arm_func_start sub_81DD264
+sub_81DD264:
+ ldr r6, [r4, o_SoundChannel_wav]
+ ldrb r0, [r4, o_SoundChannel_status]
+ tst r0, 0x20
+ bne _081DD2B4
+ orr r0, r0, 0x20
+ strb r0, [r4, o_SoundChannel_status]
+ ldrb r0, [r4, o_SoundChannel_type]
+ tst r0, 0x10
+ beq _081DD29C
+ ldr r1, [r6, 0xC]
+ add r1, r1, r6, lsl 1
+ add r1, r1, 0x20
+ sub r3, r1, r3
+ str r3, [r4, o_SoundChannel_cp]
+_081DD29C:
+ ldrh r0, [r6]
+ cmp r0, 0
+ beq _081DD2B4
+ sub r3, r3, r6
+ sub r3, r3, 0x10
+ str r3, [r4, o_SoundChannel_cp]
+_081DD2B4:
+ push {r8,r12,lr}
+ mov r10, r10, lsl 16
+ mov r11, r11, lsl 16
+ ldr r1, [r4, o_SoundChannel_freq]
+ ldrb r0, [r4, o_SoundChannel_type]
+ tst r0, 0x8
+ movne r8, 0x800000
+ muleq r8, r12, r1
+ ldrh r0, [r6]
+ cmp r0, 0
+ beq _081DD468
+ mov r0, 0xFF000000
+ str r0, [r4, o_SoundChannel_xpi]
+ ldrb r0, [r4, o_SoundChannel_type]
+ tst r0, 0x10
+ bne _081DD3C0
+ bl sub_81DD520
+ mov r0, r1
+ add r3, r3, 0x1
+ bl sub_81DD520
+ sub r1, r1, r0
+_081DD308:
+ ldr r6, [r5]
+ ldr r7, [r5, 0x630]
+_081DD310:
+ mul lr, r9, r1
+ add lr, r0, lr, asr 23
+ mul r12, r10, lr
+ bic r12, r12, 0xFF0000
+ add r6, r12, r6, ror 8
+ mul r12, r11, lr
+ bic r12, r12, 0xFF0000
+ add r7, r12, r7, ror 8
+ add r9, r9, r8
+ movs lr, r9, lsr 23
+ beq _081DD370
+ bic r9, r9, 0x3F800000
+ subs r2, r2, lr
+ ble _081DD398
+ subs lr, lr, 0x1
+ bne _081DD358
+ add r0, r0, r1
+ b _081DD364
+_081DD358:
+ add r3, r3, lr
+ bl sub_81DD520
+ mov r0, r1
+_081DD364:
+ add r3, r3, 0x1
+ bl sub_81DD520
+ sub r1, r1, r0
+_081DD370:
+ adds r5, r5, 0x40000000
+ bcc _081DD310
+ str r7, [r5, 0x630]
+ str r6, [r5], 0x4
+ ldr r6, [sp]
+ subs r6, r6, 0x4
+ str r6, [sp]
+ bgt _081DD308
+ sub r3, r3, 0x1
+ b _081DD4F0
+_081DD398:
+ ldr r0, [sp, 0x1C]
+ cmp r0, 0
+ beq _081DD4F4
+ ldr r3, [r4, o_SoundChannel_wav]
+ ldr r3, [r3, 0x8]
+ rsb lr, r2, 0
+_081DD3B0:
+ adds r2, r2, r0
+ bgt _081DD358
+ sub lr, lr, r0
+ b _081DD3B0
+_081DD3C0:
+ sub r3, r3, 0x1
+ bl sub_81DD520
+ mov r0, r1
+ sub r3, r3, 0x1
+ bl sub_81DD520
+ sub r1, r1, r0
+_081DD3D8:
+ ldr r6, [r5]
+ ldr r7, [r5, 0x630]
+_081DD3E0:
+ mul lr, r9, r1
+ add lr, r0, lr, asr 23
+ mul r12, r10, lr
+ bic r12, r12, 0xFF0000
+ add r6, r12, r6, ror 8
+ mul r12, r11, lr
+ bic r12, r12, 0xFF0000
+ add r7, r12, r7, ror 8
+ add r9, r9, r8
+ movs lr, r9, lsr 23
+ beq _081DD440
+ bic r9, r9, 0x3F800000
+ subs r2, r2, lr
+ ble _081DD4F4
+ subs lr, lr, 0x1
+ bne _081DD428
+ add r0, r0, r1
+ b _081DD434
+_081DD428:
+ sub r3, r3, lr
+ bl sub_81DD520
+ mov r0, r1
+_081DD434:
+ sub r3, r3, 0x1
+ bl sub_81DD520
+ sub r1, r1, r0
+_081DD440:
+ adds r5, r5, 0x40000000
+ bcc _081DD3E0
+ str r7, [r5, 0x630]
+ str r6, [r5], 0x4
+ ldr r6, [sp]
+ subs r6, r6, 0x4
+ str r6, [sp]
+ bgt _081DD3D8
+ add r3, r3, 0x2
+ b _081DD4F0
+_081DD468:
+ ldrb r0, [r4, o_SoundChannel_type]
+ tst r0, 0x10
+ beq _081DD4F0
+ ldrsb r0, [r3, -0x1]!
+ ldrsb r1, [r3, -0x1]
+ sub r1, r1, r0
+_081DD480:
+ ldr r6, [r5]
+ ldr r7, [r5, 0x630]
+_081DD488:
+ mul lr, r9, r1
+ add lr, r0, lr, asr 23
+ mul r12, r10, lr
+ bic r12, r12, 0xFF0000
+ add r6, r12, r6, ror 8
+ mul r12, r11, lr
+ bic r12, r12, 0xFF0000
+ add r7, r12, r7, ror 8
+ add r9, r9, r8
+ movs lr, r9, lsr 23
+ beq _081DD4CC
+ bic r9, r9, 0x3F800000
+ subs r2, r2, lr
+ ble _081DD4F4
+ ldrsb r0, [r3, -lr]!
+ ldrsb r1, [r3, -0x1]
+ sub r1, r1, r0
+_081DD4CC:
+ adds r5, r5, 0x40000000
+ bcc _081DD488
+ str r7, [r5, 0x630]
+ str r6, [r5], 0x4
+ ldr r6, [sp]
+ subs r6, r6, 0x4
+ str r6, [sp]
+ bgt _081DD480
+ add r3, r3, 0x1
+_081DD4F0:
+ pop {r8,r12,pc}
+_081DD4F4:
+ mov r2, 0
+ strb r2, [r4, o_SoundChannel_status]
+ mov r0, r5, lsr 30
+ bic r5, r5, 0xC0000000
+ rsb r0, r0, 0x3
+ mov r0, r0, lsl 3
+ mov r6, r6, ror r0
+ mov r7, r7, ror r0
+ str r7, [r5, 0x630]
+ str r6, [r5], 0x4
+ pop {r8,r12,pc}
+ arm_func_end sub_81DD264
+
+ arm_func_start sub_81DD520
+sub_81DD520:
+ push {r0,r2,r5-r7,lr}
+ mov r0, r3, lsr 6
+ ldr r1, [r4, o_SoundChannel_xpi]
+ cmp r0, r1
+ beq _081DD594
+ str r0, [r4, o_SoundChannel_xpi]
+ mov r1, 0x21
+ mul r2, r1, r0
+ ldr r1, [r4, o_SoundChannel_wav]
+ add r2, r2, r1
+ add r2, r2, 0x10
+ ldr r5, =gUnknown_030007B8
+ ldr r6, =gDeltaEncodingTable
+ mov r7, 0x40
+ ldrb lr, [r2], 1
+ strb lr, [r5], 1
+ ldrb r1, [r2], 1
+ b _081DD57C
+_081DD568:
+ ldrb r1, [r2], 1
+ mov r0, r1, lsr 4
+ ldrsb r0, [r6, r0]
+ add lr, lr, r0
+ strb lr, [r5], 1
+_081DD57C:
+ and r0, r1, 0xF
+ ldrsb r0, [r6, r0]
+ add lr, lr, r0
+ strb lr, [r5], 1
+ subs r7, r7, 2
+ bgt _081DD568
+_081DD594:
+ ldr r5, =gUnknown_030007B8
+ and r0, r3, 0x3F
+ ldrsb r1, [r5, r0]
+ pop {r0,r2,r5-r7,pc}
+ .pool
+ arm_func_end sub_81DD520
+
+ thumb_func_start SoundMainBTM
+SoundMainBTM:
+ mov r12, r4
+ movs r1, 0
+ movs r2, 0
+ movs r3, 0
+ movs r4, 0
+ stm r0!, {r1-r4}
+ stm r0!, {r1-r4}
+ stm r0!, {r1-r4}
+ stm r0!, {r1-r4}
+ mov r4, r12
+ bx lr
+ thumb_func_end SoundMainBTM
+
+ thumb_func_start RealClearChain
+RealClearChain:
+ ldr r3, [r0, 0x2C]
+ cmp r3, 0
+ beq _081DD5E2
+ ldr r1, [r0, 0x34]
+ ldr r2, [r0, 0x30]
+ cmp r2, 0
+ beq _081DD5D6
+ str r1, [r2, 0x34]
+ b _081DD5D8
+_081DD5D6:
+ str r1, [r3, 0x20]
+_081DD5D8:
+ cmp r1, 0
+ beq _081DD5DE
+ str r2, [r1, 0x30]
+_081DD5DE:
+ movs r1, 0
+ str r1, [r0, 0x2C]
+_081DD5E2:
+ bx lr
+ thumb_func_end RealClearChain
+
+ thumb_func_start ply_fine
+ply_fine:
+ push {r4,r5,lr}
+ adds r5, r1, 0
+ ldr r4, [r5, o_MusicPlayerTrack_chan]
+ cmp r4, 0
+ beq ply_fine_done
+ply_fine_loop:
+ ldrb r1, [r4]
+ movs r0, 0xC7
+ tst r0, r1
+ beq ply_fine_ok
+ movs r0, 0x40
+ orrs r1, r0
+ strb r1, [r4]
+ply_fine_ok:
+ adds r0, r4, 0
+ bl RealClearChain
+ ldr r4, [r4, 0x34]
+ cmp r4, 0
+ bne ply_fine_loop
+ply_fine_done:
+ movs r0, 0
+ strb r0, [r5]
+ pop {r4,r5}
+ pop {r0}
+ bx r0
+ thumb_func_end ply_fine
+
+ thumb_func_start MPlayJumpTableCopy
+MPlayJumpTableCopy:
+ mov r12, lr
+ movs r1, 0x24
+ ldr r2, lt_MPlayJumpTableTemplate
+MPlayJumpTableCopy_Loop:
+ ldr r3, [r2]
+ bl chk_adr_r2
+ stm r0!, {r3}
+ adds r2, 0x4
+ subs r1, 0x1
+ bgt MPlayJumpTableCopy_Loop
+ bx r12
+ thumb_func_end MPlayJumpTableCopy
+
+ .align 2, 0
+ .thumb_func
+ldrb_r3_r2:
+ ldrb r3, [r2]
+
+@ This attempts to protect against reading anything from the BIOS ROM
+@ besides the jump table template.
+@ It assumes that the jump table template is located at the end of the ROM.
+ .thumb_func
+chk_adr_r2:
+ push {r0}
+ lsrs r0, r2, 25
+ bne chk_adr_r2_done @ if adr >= 0x2000000 (i.e. not in BIOS ROM), accept it
+ ldr r0, lt_MPlayJumpTableTemplate
+ cmp r2, r0
+ blo chk_adr_r2_reject @ if adr < gMPlayJumpTableTemplate, reject it
+ lsrs r0, r2, 14
+ beq chk_adr_r2_done @ if adr < 0x40000 (i.e. in BIOS ROM), accept it
+chk_adr_r2_reject:
+ movs r3, 0
+chk_adr_r2_done:
+ pop {r0}
+ bx lr
+
+ .align 2, 0
+lt_MPlayJumpTableTemplate: .word gMPlayJumpTableTemplate
+
+ thumb_func_start ld_r3_tp_adr_i
+ld_r3_tp_adr_i:
+ ldr r2, [r1, 0x40]
+_081DD64A:
+ adds r3, r2, 0x1
+ str r3, [r1, 0x40]
+ ldrb r3, [r2]
+ b chk_adr_r2
+ thumb_func_end ld_r3_tp_adr_i
+
+ thumb_func_start ply_goto
+ply_goto:
+ push {lr}
+ply_goto_1:
+ ldr r2, [r1, o_MusicPlayerTrack_cmdPtr]
+ ldrb r0, [r2, 0x3]
+ lsls r0, 8
+ ldrb r3, [r2, 0x2]
+ orrs r0, r3
+ lsls r0, 8
+ ldrb r3, [r2, 0x1]
+ orrs r0, r3
+ lsls r0, 8
+ bl ldrb_r3_r2
+ orrs r0, r3
+ str r0, [r1, o_MusicPlayerTrack_cmdPtr]
+ pop {r0}
+ bx r0
+ thumb_func_end ply_goto
+
+ thumb_func_start ply_patt
+ply_patt:
+ ldrb r2, [r1, o_MusicPlayerTrack_patternLevel]
+ cmp r2, 3
+ bhs ply_patt_done
+ lsls r2, 2
+ adds r3, r1, r2
+ ldr r2, [r1, o_MusicPlayerTrack_cmdPtr]
+ adds r2, 0x4
+ str r2, [r3, o_MusicPlayerTrack_patternStack]
+ ldrb r2, [r1, o_MusicPlayerTrack_patternLevel]
+ adds r2, 1
+ strb r2, [r1, o_MusicPlayerTrack_patternLevel]
+ b ply_goto
+ply_patt_done:
+ b ply_fine
+ thumb_func_end ply_patt
+
+ thumb_func_start ply_pend
+ply_pend:
+ ldrb r2, [r1, o_MusicPlayerTrack_patternLevel]
+ cmp r2, 0
+ beq ply_pend_done
+ subs r2, 1
+ strb r2, [r1, o_MusicPlayerTrack_patternLevel]
+ lsls r2, 2
+ adds r3, r1, r2
+ ldr r2, [r3, o_MusicPlayerTrack_patternStack]
+ str r2, [r1, o_MusicPlayerTrack_cmdPtr]
+ply_pend_done:
+ bx lr
+ thumb_func_end ply_pend
+
+ thumb_func_start ply_rept
+ply_rept:
+ push {lr}
+ ldr r2, [r1, o_MusicPlayerTrack_cmdPtr]
+ ldrb r3, [r2]
+ cmp r3, 0
+ bne ply_rept_1
+ adds r2, 1
+ str r2, [r1, o_MusicPlayerTrack_cmdPtr]
+ b ply_goto_1
+ply_rept_1:
+ ldrb r3, [r1, o_MusicPlayerTrack_repN]
+ adds r3, 1
+ strb r3, [r1, o_MusicPlayerTrack_repN]
+ mov r12, r3
+ bl ld_r3_tp_adr_i
+ cmp r12, r3
+ bhs ply_rept_2
+ b ply_goto_1
+ply_rept_2:
+ movs r3, 0
+ strb r3, [r1, o_MusicPlayerTrack_repN]
+ adds r2, 5
+ str r2, [r1, o_MusicPlayerTrack_cmdPtr]
+ pop {r0}
+ bx r0
+ thumb_func_end ply_rept
+
+ thumb_func_start ply_prio
+ply_prio:
+ mov r12, lr
+ bl ld_r3_tp_adr_i
+ strb r3, [r1, o_MusicPlayerTrack_priority]
+ bx r12
+ thumb_func_end ply_prio
+
+ thumb_func_start ply_tempo
+ply_tempo:
+ mov r12, lr
+ bl ld_r3_tp_adr_i
+ lsls r3, 1
+ strh r3, [r0, o_MusicPlayerInfo_tempoD]
+ ldrh r2, [r0, o_MusicPlayerInfo_tempoU]
+ muls r3, r2
+ lsrs r3, 8
+ strh r3, [r0, o_MusicPlayerInfo_tempoI]
+ bx r12
+ thumb_func_end ply_tempo
+
+ thumb_func_start ply_keysh
+ply_keysh:
+ mov r12, lr
+ bl ld_r3_tp_adr_i
+ strb r3, [r1, o_MusicPlayerTrack_keyShift]
+ ldrb r3, [r1, o_MusicPlayerTrack_flags]
+ movs r2, 0xC
+ orrs r3, r2
+ strb r3, [r1, o_MusicPlayerTrack_flags]
+ bx r12
+ thumb_func_end ply_keysh
+
+ thumb_func_start ply_voice
+ply_voice:
+ mov r12, lr
+ ldr r2, [r1, o_MusicPlayerTrack_cmdPtr]
+ ldrb r3, [r2]
+ adds r2, 1
+ str r2, [r1, o_MusicPlayerTrack_cmdPtr]
+ lsls r2, r3, 1
+ adds r2, r3
+ lsls r2, 2
+ ldr r3, [r0, o_MusicPlayerInfo_tone]
+ adds r2, r3
+ ldr r3, [r2]
+ bl chk_adr_r2
+ str r3, [r1, o_MusicPlayerTrack_ToneData_type]
+ ldr r3, [r2, 0x4]
+ bl chk_adr_r2
+ str r3, [r1, o_MusicPlayerTrack_ToneData_wav]
+ ldr r3, [r2, 0x8]
+ bl chk_adr_r2
+ str r3, [r1, o_MusicPlayerTrack_ToneData_attack]
+ bx r12
+ thumb_func_end ply_voice
+
+ thumb_func_start ply_vol
+ply_vol:
+ mov r12, lr
+ bl ld_r3_tp_adr_i
+ strb r3, [r1, o_MusicPlayerTrack_vol]
+ ldrb r3, [r1, o_MusicPlayerTrack_flags]
+ movs r2, 0x3
+ orrs r3, r2
+ strb r3, [r1, o_MusicPlayerTrack_flags]
+ bx r12
+ thumb_func_end ply_vol
+
+ thumb_func_start ply_pan
+ply_pan:
+ mov r12, lr
+ bl ld_r3_tp_adr_i
+ subs r3, 0x40
+ strb r3, [r1, o_MusicPlayerTrack_pan]
+ ldrb r3, [r1, o_MusicPlayerTrack_flags]
+ movs r2, 0x3
+ orrs r3, r2
+ strb r3, [r1, o_MusicPlayerTrack_flags]
+ bx r12
+ thumb_func_end ply_pan
+
+ thumb_func_start ply_bend
+ply_bend:
+ mov r12, lr
+ bl ld_r3_tp_adr_i
+ subs r3, 0x40
+ strb r3, [r1, o_MusicPlayerTrack_bend]
+ ldrb r3, [r1, o_MusicPlayerTrack_flags]
+ movs r2, 0xC
+ orrs r3, r2
+ strb r3, [r1, o_MusicPlayerTrack_flags]
+ bx r12
+ thumb_func_end ply_bend
+
+ thumb_func_start ply_bendr
+ply_bendr:
+ mov r12, lr
+ bl ld_r3_tp_adr_i
+ strb r3, [r1, o_MusicPlayerTrack_bendRange]
+ ldrb r3, [r1, o_MusicPlayerTrack_flags]
+ movs r2, 0xC
+ orrs r3, r2
+ strb r3, [r1, o_MusicPlayerTrack_flags]
+ bx r12
+ thumb_func_end ply_bendr
+
+ thumb_func_start ply_lfodl
+ply_lfodl:
+ mov r12, lr
+ bl ld_r3_tp_adr_i
+ strb r3, [r1, o_MusicPlayerTrack_lfoDelay]
+ bx r12
+ thumb_func_end ply_lfodl
+
+ thumb_func_start ply_modt
+ply_modt:
+ mov r12, lr
+ bl ld_r3_tp_adr_i
+ ldrb r0, [r1, o_MusicPlayerTrack_modT]
+ cmp r0, r3
+ beq _081DD7AA
+ strb r3, [r1, o_MusicPlayerTrack_modT]
+ ldrb r3, [r1, o_MusicPlayerTrack_flags]
+ movs r2, 0xF
+ orrs r3, r2
+ strb r3, [r1, o_MusicPlayerTrack_flags]
+_081DD7AA:
+ bx r12
+ thumb_func_end ply_modt
+
+ thumb_func_start ply_tune
+ply_tune:
+ mov r12, lr
+ bl ld_r3_tp_adr_i
+ subs r3, 0x40
+ strb r3, [r1, o_MusicPlayerTrack_tune]
+ ldrb r3, [r1, o_MusicPlayerTrack_flags]
+ movs r2, 0xC
+ orrs r3, r2
+ strb r3, [r1, o_MusicPlayerTrack_flags]
+ bx r12
+ thumb_func_end ply_tune
+
+ thumb_func_start ply_port
+ply_port:
+ mov r12, lr
+ ldr r2, [r1, o_MusicPlayerTrack_cmdPtr]
+ ldrb r3, [r2]
+ adds r2, 1
+ ldr r0, =REG_SOUND1CNT_L @ sound register base address
+ adds r0, r3
+ bl _081DD64A
+ strb r3, [r0]
+ bx r12
+ .pool
+ thumb_func_end ply_port
+
+ thumb_func_start m4aSoundVSync
+m4aSoundVSync:
+ ldr r0, lt2_SOUND_INFO_PTR
+ ldr r0, [r0]
+
+ @ Exit the function if ident is not ID_NUMBER or ID_NUMBER+1.
+ ldr r2, lt2_ID_NUMBER
+ ldr r3, [r0, o_SoundInfo_ident]
+ subs r3, r2
+ cmp r3, 1
+ bhi m4aSoundVSync_Done
+
+ @ Decrement the PCM DMA counter. If it reaches 0, we need to do a DMA.
+ ldrb r1, [r0, o_SoundInfo_pcmDmaCounter]
+ subs r1, 1
+ strb r1, [r0, o_SoundInfo_pcmDmaCounter]
+ bgt m4aSoundVSync_Done
+
+ @ Reload the PCM DMA counter.
+ ldrb r1, [r0, o_SoundInfo_pcmDmaPeriod]
+ strb r1, [r0, o_SoundInfo_pcmDmaCounter]
+
+ ldr r2, =REG_DMA1
+
+ ldr r1, [r2, 0x8] @ DMA1CNT
+ lsls r1, 7
+ bcc m4aSoundVSync_SkipDMA1 @ branch if repeat bit isn't set
+
+ ldr r1, =((DMA_ENABLE | DMA_START_NOW | DMA_32BIT | DMA_SRC_INC | DMA_DEST_FIXED) << 16) | 4
+ str r1, [r2, 0x8] @ DMA1CNT
+
+m4aSoundVSync_SkipDMA1:
+ ldr r1, [r2, 0xC + 0x8] @ DMA2CNT
+ lsls r1, 7
+ bcc m4aSoundVSync_SkipDMA2 @ branch if repeat bit isn't set
+
+ ldr r1, =((DMA_ENABLE | DMA_START_NOW | DMA_32BIT | DMA_SRC_INC | DMA_DEST_FIXED) << 16) | 4
+ str r1, [r2, 0xC + 0x8] @ DMA2CNT
+
+m4aSoundVSync_SkipDMA2:
+
+ @ turn off DMA1/DMA2
+ movs r1, DMA_32BIT >> 8
+ lsls r1, 8
+ strh r1, [r2, 0xA] @ DMA1CNT_H
+ strh r1, [r2, 0xC + 0xA] @ DMA2CNT_H
+
+ @ turn on DMA1/DMA2 direct-sound FIFO mode
+ movs r1, (DMA_ENABLE | DMA_START_SPECIAL | DMA_32BIT | DMA_REPEAT) >> 8
+ lsls r1, 8 @ LSB is 0, so DMA_SRC_INC is used (destination is always fixed in FIFO mode)
+ strh r1, [r2, 0xA] @ DMA1CNT_H
+ strh r1, [r2, 0xC + 0xA] @ DMA2CNT_H
+
+m4aSoundVSync_Done:
+ bx lr
+
+ .pool
+ thumb_func_end m4aSoundVSync
+
+ thumb_func_start MPlayMain
+MPlayMain:
+ ldr r2, lt2_ID_NUMBER
+ ldr r3, [r0, o_MusicPlayerInfo_ident]
+ cmp r2, r3
+ beq _081DD82E
+ bx lr
+_081DD82E:
+ adds r3, 0x1
+ str r3, [r0, o_MusicPlayerInfo_ident]
+ push {r0,lr}
+ ldr r3, [r0, o_MusicPlayerInfo_func]
+ cmp r3, 0
+ beq _081DD840
+ ldr r0, [r0, o_MusicPlayerInfo_intp]
+ bl call_r3
+_081DD840:
+ pop {r0}
+ push {r4-r7}
+ mov r4, r8
+ mov r5, r9
+ mov r6, r10
+ mov r7, r11
+ push {r4-r7}
+ adds r7, r0, 0
+ ldr r0, [r7, o_MusicPlayerInfo_status]
+ cmp r0, 0
+ bge _081DD858
+ b _081DDA6C
+_081DD858:
+ ldr r0, lt2_SOUND_INFO_PTR
+ ldr r0, [r0]
+ mov r8, r0
+ adds r0, r7, 0
+ bl FadeOutBody
+ ldr r0, [r7, o_MusicPlayerInfo_status]
+ cmp r0, 0
+ bge _081DD86C
+ b _081DDA6C
+_081DD86C:
+ ldrh r0, [r7, o_MusicPlayerInfo_tempoC]
+ ldrh r1, [r7, o_MusicPlayerInfo_tempoI]
+ adds r0, r1
+ b _081DD9BC
+_081DD874:
+ ldrb r6, [r7, o_MusicPlayerInfo_trackCount]
+ ldr r5, [r7, o_MusicPlayerInfo_tracks]
+ movs r3, 0x1
+ movs r4, 0
+_081DD87C:
+ ldrb r0, [r5]
+ movs r1, 0x80
+ tst r1, r0
+ bne _081DD886
+ b _081DD998
+_081DD886:
+ mov r10, r3
+ orrs r4, r3
+ mov r11, r4
+ ldr r4, [r5, o_MusicPlayerTrack_chan]
+ cmp r4, 0
+ beq _081DD8BA
+_081DD892:
+ ldrb r1, [r4]
+ movs r0, 0xC7
+ tst r0, r1
+ beq _081DD8AE
+ ldrb r0, [r4, 0x10]
+ cmp r0, 0
+ beq _081DD8B4
+ subs r0, 0x1
+ strb r0, [r4, 0x10]
+ bne _081DD8B4
+ movs r0, 0x40
+ orrs r1, r0
+ strb r1, [r4]
+ b _081DD8B4
+_081DD8AE:
+ adds r0, r4, 0
+ bl ClearChain
+_081DD8B4:
+ ldr r4, [r4, 0x34]
+ cmp r4, 0
+ bne _081DD892
+_081DD8BA:
+ ldrb r3, [r5, o_MusicPlayerTrack_flags]
+ movs r0, 0x40
+ tst r0, r3
+ beq _081DD938
+ adds r0, r5, 0
+ bl Clear64byte
+ movs r0, 0x80
+ strb r0, [r5]
+ movs r0, 0x2
+ strb r0, [r5, o_MusicPlayerTrack_bendRange]
+ movs r0, 0x40
+ strb r0, [r5, o_MusicPlayerTrack_volX]
+ movs r0, 0x16
+ strb r0, [r5, o_MusicPlayerTrack_lfoSpeed]
+ movs r0, 0x1
+ adds r1, r5, 0x6
+ strb r0, [r1, o_MusicPlayerTrack_ToneData_type - 0x6]
+ b _081DD938
+_081DD8E0:
+ ldr r2, [r5, o_MusicPlayerTrack_cmdPtr]
+ ldrb r1, [r2]
+ cmp r1, 0x80
+ bhs _081DD8EC
+ ldrb r1, [r5, o_MusicPlayerTrack_runningStatus]
+ b _081DD8F6
+_081DD8EC:
+ adds r2, 0x1
+ str r2, [r5, o_MusicPlayerTrack_cmdPtr]
+ cmp r1, 0xBD
+ bcc _081DD8F6
+ strb r1, [r5, o_MusicPlayerTrack_runningStatus]
+_081DD8F6:
+ cmp r1, 0xCF
+ bcc _081DD90C
+ mov r0, r8
+ ldr r3, [r0, o_SoundInfo_plynote]
+ adds r0, r1, 0
+ subs r0, 0xCF
+ adds r1, r7, 0
+ adds r2, r5, 0
+ bl call_r3
+ b _081DD938
+_081DD90C:
+ cmp r1, 0xB0
+ bls _081DD92E
+ adds r0, r1, 0
+ subs r0, 0xB1
+ strb r0, [r7, o_MusicPlayerInfo_cmd]
+ mov r3, r8
+ ldr r3, [r3, o_SoundInfo_MPlayJumpTable]
+ lsls r0, 2
+ ldr r3, [r3, r0]
+ adds r0, r7, 0
+ adds r1, r5, 0
+ bl call_r3
+ ldrb r0, [r5, o_MusicPlayerTrack_flags]
+ cmp r0, 0
+ beq _081DD994
+ b _081DD938
+_081DD92E:
+ ldr r0, lt_gClockTable
+ subs r1, 0x80
+ adds r1, r0
+ ldrb r0, [r1]
+ strb r0, [r5, o_MusicPlayerTrack_wait]
+_081DD938:
+ ldrb r0, [r5, o_MusicPlayerTrack_wait]
+ cmp r0, 0
+ beq _081DD8E0
+ subs r0, 0x1
+ strb r0, [r5, o_MusicPlayerTrack_wait]
+ ldrb r1, [r5, o_MusicPlayerTrack_lfoSpeed]
+ cmp r1, 0
+ beq _081DD994
+ ldrb r0, [r5, o_MusicPlayerTrack_mod]
+ cmp r0, 0
+ beq _081DD994
+ ldrb r0, [r5, o_MusicPlayerTrack_lfoDelayC]
+ cmp r0, 0
+ beq _081DD95A
+ subs r0, 0x1
+ strb r0, [r5, o_MusicPlayerTrack_lfoDelayC]
+ b _081DD994
+_081DD95A:
+ ldrb r0, [r5, o_MusicPlayerTrack_lfoSpeedC]
+ adds r0, r1
+ strb r0, [r5, o_MusicPlayerTrack_lfoSpeedC]
+ adds r1, r0, 0
+ subs r0, 0x40
+ lsls r0, 24
+ bpl _081DD96E
+ lsls r2, r1, 24
+ asrs r2, 24
+ b _081DD972
+_081DD96E:
+ movs r0, 0x80
+ subs r2, r0, r1
+_081DD972:
+ ldrb r0, [r5, o_MusicPlayerTrack_mod]
+ muls r0, r2
+ asrs r2, r0, 6
+ ldrb r0, [r5, o_MusicPlayerTrack_modM]
+ eors r0, r2
+ lsls r0, 24
+ beq _081DD994
+ strb r2, [r5, o_MusicPlayerTrack_modM]
+ ldrb r0, [r5]
+ ldrb r1, [r5, o_MusicPlayerTrack_modT]
+ cmp r1, 0
+ bne _081DD98E
+ movs r1, 0xC
+ b _081DD990
+_081DD98E:
+ movs r1, 0x3
+_081DD990:
+ orrs r0, r1
+ strb r0, [r5, o_MusicPlayerTrack_flags]
+_081DD994:
+ mov r3, r10
+ mov r4, r11
+_081DD998:
+ subs r6, 0x1
+ ble _081DD9A4
+ movs r0, 0x50
+ adds r5, r0
+ lsls r3, 1
+ b _081DD87C
+_081DD9A4:
+ ldr r0, [r7, o_MusicPlayerInfo_clock]
+ adds r0, 0x1
+ str r0, [r7, o_MusicPlayerInfo_clock]
+ cmp r4, 0
+ bne _081DD9B6
+ movs r0, 0x80
+ lsls r0, 24
+ str r0, [r7, o_MusicPlayerInfo_status]
+ b _081DDA6C
+_081DD9B6:
+ str r4, [r7, o_MusicPlayerInfo_status]
+ ldrh r0, [r7, o_MusicPlayerInfo_tempoC]
+ subs r0, 0x96
+_081DD9BC:
+ strh r0, [r7, o_MusicPlayerInfo_tempoC]
+ cmp r0, 0x96
+ bcc _081DD9C4
+ b _081DD874
+_081DD9C4:
+ ldrb r2, [r7, o_MusicPlayerInfo_trackCount]
+ ldr r5, [r7, o_MusicPlayerInfo_tracks]
+_081DD9C8:
+ ldrb r0, [r5, o_MusicPlayerTrack_flags]
+ movs r1, 0x80
+ tst r1, r0
+ beq _081DDA62
+ movs r1, 0xF
+ tst r1, r0
+ beq _081DDA62
+ mov r9, r2
+ adds r0, r7, 0
+ adds r1, r5, 0
+ bl TrkVolPitSet
+ ldr r4, [r5, o_MusicPlayerTrack_chan]
+ cmp r4, 0
+ beq _081DDA58
+_081DD9E6:
+ ldrb r1, [r4, o_SoundChannel_status]
+ movs r0, 0xC7
+ tst r0, r1
+ bne _081DD9F6
+ adds r0, r4, 0
+ bl ClearChain
+ b _081DDA52
+_081DD9F6:
+ ldrb r0, [r4, o_SoundChannel_type]
+ movs r6, 0x7
+ ands r6, r0
+ ldrb r3, [r5, o_MusicPlayerTrack_flags]
+ movs r0, 0x3
+ tst r0, r3
+ beq _081DDA14
+ bl ChnVolSetAsm
+ cmp r6, 0
+ beq _081DDA14
+ ldrb r0, [r4, o_CgbChannel_mo]
+ movs r1, 0x1
+ orrs r0, r1
+ strb r0, [r4, o_CgbChannel_mo]
+_081DDA14:
+ ldrb r3, [r5, o_MusicPlayerTrack_flags]
+ movs r0, 0xC
+ tst r0, r3
+ beq _081DDA52
+ ldrb r1, [r4, o_SoundChannel_ky]
+ movs r0, 0x8
+ ldrsb r0, [r5, r0]
+ adds r2, r1, r0
+ bpl _081DDA28
+ movs r2, 0
+_081DDA28:
+ cmp r6, 0
+ beq _081DDA46
+ mov r0, r8
+ ldr r3, [r0, o_SoundInfo_MidiKeyToCgbFreq]
+ adds r1, r2, 0
+ ldrb r2, [r5, o_MusicPlayerTrack_pitM]
+ adds r0, r6, 0
+ bl call_r3
+ str r0, [r4, o_CgbChannel_fr]
+ ldrb r0, [r4, o_CgbChannel_mo]
+ movs r1, 0x2
+ orrs r0, r1
+ strb r0, [r4, o_CgbChannel_mo]
+ b _081DDA52
+_081DDA46:
+ adds r1, r2, 0
+ ldrb r2, [r5, o_MusicPlayerTrack_pitM]
+ ldr r0, [r4, o_SoundChannel_wav]
+ bl MidiKeyToFreq
+ str r0, [r4, o_SoundChannel_freq]
+_081DDA52:
+ ldr r4, [r4, o_SoundChannel_np]
+ cmp r4, 0
+ bne _081DD9E6
+_081DDA58:
+ ldrb r0, [r5, o_MusicPlayerTrack_flags]
+ movs r1, 0xF0
+ ands r0, r1
+ strb r0, [r5, o_MusicPlayerTrack_flags]
+ mov r2, r9
+_081DDA62:
+ subs r2, 0x1
+ ble _081DDA6C
+ movs r0, 0x50
+ adds r5, r0
+ bgt _081DD9C8
+_081DDA6C:
+ ldr r0, lt2_ID_NUMBER
+ str r0, [r7, o_MusicPlayerInfo_ident]
+ pop {r0-r7}
+ mov r8, r0
+ mov r9, r1
+ mov r10, r2
+ mov r11, r3
+ pop {r3}
+
+call_r3:
+ bx r3
+
+ .align 2, 0
+lt_gClockTable: .word gClockTable
+lt2_SOUND_INFO_PTR: .word SOUND_INFO_PTR
+lt2_ID_NUMBER: .word ID_NUMBER
+ thumb_func_end MPlayMain
+
+ thumb_func_start TrackStop
+TrackStop:
+ push {r4-r6,lr}
+ adds r5, r1, 0
+ ldrb r1, [r5, o_MusicPlayerTrack_flags]
+ movs r0, 0x80
+ tst r0, r1
+ beq TrackStop_Done
+ ldr r4, [r5, o_MusicPlayerTrack_chan]
+ cmp r4, 0
+ beq TrackStop_3
+ movs r6, 0
+TrackStop_Loop:
+ ldrb r0, [r4, o_SoundChannel_status]
+ cmp r0, 0
+ beq TrackStop_2
+ ldrb r0, [r4, o_SoundChannel_type]
+ movs r3, 0x7
+ ands r0, r3
+ beq TrackStop_1
+ ldr r3, =SOUND_INFO_PTR
+ ldr r3, [r3]
+ ldr r3, [r3, o_SoundInfo_CgbOscOff]
+ bl call_r3
+TrackStop_1:
+ strb r6, [r4, o_SoundChannel_status]
+TrackStop_2:
+ str r6, [r4, o_SoundChannel_track]
+ ldr r4, [r4, o_SoundChannel_np]
+ cmp r4, 0
+ bne TrackStop_Loop
+TrackStop_3:
+ str r4, [r5, o_MusicPlayerTrack_chan]
+TrackStop_Done:
+ pop {r4-r6}
+ pop {r0}
+ bx r0
+ .pool
+ thumb_func_end TrackStop
+
+ thumb_func_start ChnVolSetAsm
+ChnVolSetAsm:
+ ldrb r1, [r4, 0x12]
+ movs r0, 0x14
+ ldrsb r2, [r4, r0]
+ movs r3, 0x80
+ adds r3, r2
+ muls r3, r1
+ ldrb r0, [r5, 0x10]
+ muls r0, r3
+ asrs r0, 14
+ cmp r0, 0xFF
+ bls _081DDAE8
+ movs r0, 0xFF
+_081DDAE8:
+ strb r0, [r4, 0x2]
+ movs r3, 0x7F
+ subs r3, r2
+ muls r3, r1
+ ldrb r0, [r5, 0x11]
+ muls r0, r3
+ asrs r0, 14
+ cmp r0, 0xFF
+ bls _081DDAFC
+ movs r0, 0xFF
+_081DDAFC:
+ strb r0, [r4, 0x3]
+ bx lr
+ thumb_func_end ChnVolSetAsm
+
+ thumb_func_start ply_note
+ply_note:
+ push {r4-r7,lr}
+ mov r4, r8
+ mov r5, r9
+ mov r6, r10
+ mov r7, r11
+ push {r4-r7}
+ sub sp, 0x18
+ str r1, [sp]
+ adds r5, r2, 0
+ ldr r1, =SOUND_INFO_PTR
+ ldr r1, [r1]
+ str r1, [sp, 0x4]
+ ldr r1, =gClockTable
+ adds r0, r1
+ ldrb r0, [r0]
+ strb r0, [r5, o_MusicPlayerTrack_gateTime]
+ ldr r3, [r5, o_MusicPlayerTrack_cmdPtr]
+ ldrb r0, [r3]
+ cmp r0, 0x80
+ bhs _081DDB46
+ strb r0, [r5, o_MusicPlayerTrack_key]
+ adds r3, 0x1
+ ldrb r0, [r3]
+ cmp r0, 0x80
+ bhs _081DDB44
+ strb r0, [r5, o_MusicPlayerTrack_velocity]
+ adds r3, 0x1
+ ldrb r0, [r3]
+ cmp r0, 0x80
+ bhs _081DDB44
+ ldrb r1, [r5, o_MusicPlayerTrack_gateTime]
+ adds r1, r0
+ strb r1, [r5, o_MusicPlayerTrack_gateTime]
+ adds r3, 0x1
+_081DDB44:
+ str r3, [r5, o_MusicPlayerTrack_cmdPtr]
+_081DDB46:
+ movs r0, 0
+ str r0, [sp, 0x14]
+ adds r4, r5, 0
+ adds r4, o_MusicPlayerTrack_ToneData_type
+ ldrb r2, [r4]
+ movs r0, TONEDATA_TYPE_RHY | TONEDATA_TYPE_SPL
+ tst r0, r2
+ beq _081DDB98
+ ldrb r3, [r5, o_MusicPlayerTrack_key]
+ movs r0, TONEDATA_TYPE_SPL
+ tst r0, r2
+ beq _081DDB66
+ ldr r1, [r5, o_MusicPlayerTrack_ToneData_keySplitTable]
+ adds r1, r3
+ ldrb r0, [r1]
+ b _081DDB68
+_081DDB66:
+ adds r0, r3, 0
+_081DDB68:
+ lsls r1, r0, 1
+ adds r1, r0
+ lsls r1, 2
+ ldr r0, [r5, o_MusicPlayerTrack_ToneData_wav]
+ adds r1, r0
+ mov r9, r1
+ mov r6, r9
+ ldrb r1, [r6]
+ movs r0, 0xC0
+ tst r0, r1
+ beq _081DDB80
+ b _081DDCEA
+_081DDB80:
+ movs r0, 0x80
+ tst r0, r2
+ beq _081DDB9C
+ ldrb r1, [r6, 0x3]
+ movs r0, 0x80
+ tst r0, r1
+ beq _081DDB94
+ subs r1, 0xC0
+ lsls r1, 1
+ str r1, [sp, 0x14]
+_081DDB94:
+ ldrb r3, [r6, 0x1]
+ b _081DDB9C
+_081DDB98:
+ mov r9, r4
+ ldrb r3, [r5, 0x5]
+_081DDB9C:
+ str r3, [sp, 0x8]
+ ldr r6, [sp]
+ ldrb r1, [r6, 0x9]
+ ldrb r0, [r5, 0x1D]
+ adds r0, r1
+ cmp r0, 0xFF
+ bls _081DDBAC
+ movs r0, 0xFF
+_081DDBAC:
+ str r0, [sp, 0x10]
+ mov r6, r9
+ ldrb r0, [r6]
+ movs r6, 0x7
+ ands r6, r0
+ str r6, [sp, 0xC]
+ beq _081DDBEC
+ ldr r0, [sp, 0x4]
+ ldr r4, [r0, 0x1C]
+ cmp r4, 0
+ bne _081DDBC4
+ b _081DDCEA
+_081DDBC4:
+ subs r6, 0x1
+ lsls r0, r6, 6
+ adds r4, r0
+ ldrb r1, [r4]
+ movs r0, 0xC7
+ tst r0, r1
+ beq _081DDC40
+ movs r0, 0x40
+ tst r0, r1
+ bne _081DDC40
+ ldrb r1, [r4, 0x13]
+ ldr r0, [sp, 0x10]
+ cmp r1, r0
+ bcc _081DDC40
+ beq _081DDBE4
+ b _081DDCEA
+_081DDBE4:
+ ldr r0, [r4, 0x2C]
+ cmp r0, r5
+ bcs _081DDC40
+ b _081DDCEA
+_081DDBEC:
+ ldr r6, [sp, 0x10]
+ adds r7, r5, 0
+ movs r2, 0
+ mov r8, r2
+ ldr r4, [sp, 0x4]
+ ldrb r3, [r4, 0x6]
+ adds r4, 0x50
+_081DDBFA:
+ ldrb r1, [r4]
+ movs r0, 0xC7
+ tst r0, r1
+ beq _081DDC40
+ movs r0, 0x40
+ tst r0, r1
+ beq _081DDC14
+ cmp r2, 0
+ bne _081DDC18
+ adds r2, 0x1
+ ldrb r6, [r4, 0x13]
+ ldr r7, [r4, 0x2C]
+ b _081DDC32
+_081DDC14:
+ cmp r2, 0
+ bne _081DDC34
+_081DDC18:
+ ldrb r0, [r4, 0x13]
+ cmp r0, r6
+ bcs _081DDC24
+ adds r6, r0, 0
+ ldr r7, [r4, 0x2C]
+ b _081DDC32
+_081DDC24:
+ bhi _081DDC34
+ ldr r0, [r4, 0x2C]
+ cmp r0, r7
+ bls _081DDC30
+ adds r7, r0, 0
+ b _081DDC32
+_081DDC30:
+ bcc _081DDC34
+_081DDC32:
+ mov r8, r4
+_081DDC34:
+ adds r4, 0x40
+ subs r3, 0x1
+ bgt _081DDBFA
+ mov r4, r8
+ cmp r4, 0
+ beq _081DDCEA
+_081DDC40:
+ adds r0, r4, 0
+ bl ClearChain
+ movs r1, 0
+ str r1, [r4, 0x30]
+ ldr r3, [r5, 0x20]
+ str r3, [r4, 0x34]
+ cmp r3, 0
+ beq _081DDC54
+ str r4, [r3, 0x30]
+_081DDC54:
+ str r4, [r5, 0x20]
+ str r5, [r4, 0x2C]
+ ldrb r0, [r5, 0x1B]
+ strb r0, [r5, 0x1C]
+ cmp r0, r1
+ beq _081DDC66
+ adds r1, r5, 0
+ bl clear_modM
+_081DDC66:
+ ldr r0, [sp]
+ adds r1, r5, 0
+ bl TrkVolPitSet
+ ldr r0, [r5, 0x4]
+ str r0, [r4, 0x10]
+ ldr r0, [sp, 0x10]
+ strb r0, [r4, 0x13]
+ ldr r0, [sp, 0x8]
+ strb r0, [r4, 0x8]
+ ldr r0, [sp, 0x14]
+ strb r0, [r4, 0x14]
+ mov r6, r9
+ ldrb r0, [r6]
+ strb r0, [r4, 0x1]
+ ldr r7, [r6, 0x4]
+ str r7, [r4, 0x24]
+ ldr r0, [r6, 0x8]
+ str r0, [r4, 0x4]
+ ldrh r0, [r5, 0x1E]
+ strh r0, [r4, 0xC]
+ bl ChnVolSetAsm
+ ldrb r1, [r4, 0x8]
+ movs r0, 0x8
+ ldrsb r0, [r5, r0]
+ adds r3, r1, r0
+ bpl _081DDCA0
+ movs r3, 0
+_081DDCA0:
+ ldr r6, [sp, 0xC]
+ cmp r6, 0
+ beq _081DDCCE
+ mov r6, r9
+ ldrb r0, [r6, 0x2]
+ strb r0, [r4, 0x1E]
+ ldrb r1, [r6, 0x3]
+ movs r0, 0x80
+ tst r0, r1
+ bne _081DDCBA
+ movs r0, 0x70
+ tst r0, r1
+ bne _081DDCBC
+_081DDCBA:
+ movs r1, 0x8
+_081DDCBC:
+ strb r1, [r4, 0x1F]
+ ldrb r2, [r5, 0x9]
+ adds r1, r3, 0
+ ldr r0, [sp, 0xC]
+ ldr r3, [sp, 0x4]
+ ldr r3, [r3, 0x30]
+ bl call_r3
+ b _081DDCDC
+_081DDCCE:
+ ldr r0, [r5, o_MusicPlayerTrack_unk_3C]
+ str r0, [r4, 0x18]
+ ldrb r2, [r5, 0x9]
+ adds r1, r3, 0
+ adds r0, r7, 0
+ bl MidiKeyToFreq
+_081DDCDC:
+ str r0, [r4, 0x20]
+ movs r0, 0x80
+ strb r0, [r4]
+ ldrb r1, [r5]
+ movs r0, 0xF0
+ ands r0, r1
+ strb r0, [r5]
+_081DDCEA:
+ add sp, 0x18
+ pop {r0-r7}
+ mov r8, r0
+ mov r9, r1
+ mov r10, r2
+ mov r11, r3
+ pop {r0}
+ bx r0
+ .pool
+ thumb_func_end ply_note
+
+ thumb_func_start ply_endtie
+ply_endtie:
+ push {r4,r5}
+ ldr r2, [r1, o_MusicPlayerTrack_cmdPtr]
+ ldrb r3, [r2]
+ cmp r3, 0x80
+ bhs _081DDD16
+ strb r3, [r1, o_MusicPlayerTrack_key]
+ adds r2, 0x1
+ str r2, [r1, o_MusicPlayerTrack_cmdPtr]
+ b _081DDD18
+_081DDD16:
+ ldrb r3, [r1, o_MusicPlayerTrack_key]
+_081DDD18:
+ ldr r1, [r1, o_MusicPlayerTrack_chan]
+ cmp r1, 0
+ beq _081DDD40
+ movs r4, 0x83
+ movs r5, 0x40
+_081DDD22:
+ ldrb r2, [r1, o_SoundChannel_status]
+ tst r2, r4
+ beq _081DDD3A
+ tst r2, r5
+ bne _081DDD3A
+ ldrb r0, [r1, o_SoundChannel_mk]
+ cmp r0, r3
+ bne _081DDD3A
+ movs r0, 0x40
+ orrs r2, r0
+ strb r2, [r1, o_SoundChannel_status]
+ b _081DDD40
+_081DDD3A:
+ ldr r1, [r1, o_SoundChannel_np]
+ cmp r1, 0
+ bne _081DDD22
+_081DDD40:
+ pop {r4,r5}
+ bx lr
+ thumb_func_end ply_endtie
+
+ thumb_func_start clear_modM
+clear_modM:
+ movs r2, 0
+ strb r2, [r1, o_MusicPlayerTrack_modM]
+ strb r2, [r1, o_MusicPlayerTrack_lfoSpeedC]
+ ldrb r2, [r1, o_MusicPlayerTrack_modT]
+ cmp r2, 0
+ bne _081DDD54
+ movs r2, 0xC
+ b _081DDD56
+_081DDD54:
+ movs r2, 0x3
+_081DDD56:
+ ldrb r3, [r1, o_MusicPlayerTrack_flags]
+ orrs r3, r2
+ strb r3, [r1, o_MusicPlayerTrack_flags]
+ bx lr
+ thumb_func_end clear_modM
+
+ thumb_func_start ld_r3_tp_adr_i
+ld_r3_tp_adr_i_unchecked:
+ ldr r2, [r1, o_MusicPlayerTrack_cmdPtr]
+ adds r3, r2, 1
+ str r3, [r1, o_MusicPlayerTrack_cmdPtr]
+ ldrb r3, [r2]
+ bx lr
+ thumb_func_end ld_r3_tp_adr_i
+
+ thumb_func_start ply_lfos
+ply_lfos:
+ mov r12, lr
+ bl ld_r3_tp_adr_i_unchecked
+ strb r3, [r1, o_MusicPlayerTrack_lfoSpeed]
+ cmp r3, 0
+ bne _081DDD7C
+ bl clear_modM
+_081DDD7C:
+ bx r12
+ thumb_func_end ply_lfos
+
+ thumb_func_start ply_mod
+ply_mod:
+ mov r12, lr
+ bl ld_r3_tp_adr_i_unchecked
+ strb r3, [r1, o_MusicPlayerTrack_mod]
+ cmp r3, 0
+ bne _081DDD90
+ bl clear_modM
+_081DDD90:
+ bx r12
+ thumb_func_end ply_mod
+
+ .align 2, 0 @ Don't pad with nop.
diff --git a/src/pokemon/mail.c b/src/pokemon/mail.c
index ab43c033a..921a3ad93 100644
--- a/src/pokemon/mail.c
+++ b/src/pokemon/mail.c
@@ -15,7 +15,7 @@
#include "strings2.h"
#include "task.h"
#include "text.h"
-#include "unknown_task.h"
+#include "scanline_effect.h"
#include "ewram.h"
struct UnkMailStruct
@@ -320,7 +320,7 @@ static u8 sub_80F8A28(void)
{
case 0:
SetVBlankCallback(NULL);
- remove_some_task();
+ ScanlineEffect_Stop();
REG_DISPCNT = 0;
RETURN_UP_STATE;
diff --git a/src/pokemon/pokedex.c b/src/pokemon/pokedex.c
index 48ce26bb8..4fb6a4920 100644
--- a/src/pokemon/pokedex.c
+++ b/src/pokemon/pokedex.c
@@ -23,7 +23,7 @@
#include "strings.h"
#include "task.h"
#include "trig.h"
-#include "unknown_task.h"
+#include "scanline_effect.h"
#include "ewram.h"
#define NATIONAL_DEX_COUNT 386
@@ -1419,7 +1419,7 @@ void CB2_InitPokedex(void)
}
break;
case 1:
- remove_some_task();
+ ScanlineEffect_Stop();
ResetTasks();
ResetSpriteData();
ResetPaletteFade();
@@ -1494,7 +1494,7 @@ u8 unref_sub_808C540(void (*func)(u8))
SetVBlankCallback(NULL);
sub_8091060(0x200);
- remove_some_task();
+ ScanlineEffect_Stop();
ResetTasks();
ResetPaletteFade();
savedIme = REG_IME;
diff --git a/src/pokemon/pokemon_summary_screen.c b/src/pokemon/pokemon_summary_screen.c
index d98383c6d..bf8306fc0 100644
--- a/src/pokemon/pokemon_summary_screen.c
+++ b/src/pokemon/pokemon_summary_screen.c
@@ -29,7 +29,7 @@
#include "strings2.h"
#include "task.h"
#include "tv.h"
-#include "unknown_task.h"
+#include "scanline_effect.h"
static void sub_809FC0C(void);
static void sub_809FEB8(void);
@@ -123,12 +123,12 @@ extern u8 StorageSystemGetNextMonIndex(struct BoxPokemon *, u8, u8, u8);
extern struct MusicPlayerInfo gMPlay_BGM;
extern u8 gUnknown_020384F0;
extern u8 gUnknown_08208238[];
-extern u16 gUnknown_030041B8;
+extern u16 gBattle_BG3_Y;
extern u16 gBattle_BG2_Y;
extern u16 gBattle_BG1_Y;
extern u16 gBattle_BG1_X;
extern u16 gBattle_BG2_X;
-extern u16 gUnknown_030041B0;
+extern u16 gBattle_BG3_X;
extern TaskFunc gUnknown_03005CF0;
extern struct Sprite *gUnknown_020384F4;
extern struct SpriteTemplate gUnknown_02024E8C;
@@ -586,8 +586,8 @@ void sub_809D85C(void)
REG_BG1VOFS = gBattle_BG1_Y;
REG_BG2HOFS = gBattle_BG2_X;
REG_BG2VOFS = gBattle_BG2_Y;
- REG_BG3HOFS = gUnknown_030041B0;
- REG_BG3VOFS = gUnknown_030041B8;
+ REG_BG3HOFS = gBattle_BG3_X;
+ REG_BG3VOFS = gBattle_BG3_Y;
LoadOam();
ProcessSpriteCopyRequests();
@@ -701,7 +701,7 @@ bool8 sub_809DA84(void)
gMain.state++;
break;
case 1:
- remove_some_task();
+ ScanlineEffect_Stop();
gMain.state++;
break;
case 2:
@@ -813,11 +813,11 @@ bool8 sub_809DA84(void)
case 20:
if (GetMonData(&pssData.loadedMon, MON_DATA_IS_EGG))
{
- gUnknown_030041B0 = 256;
+ gBattle_BG3_X = 256;
}
else
{
- gUnknown_030041B0 = 0;
+ gBattle_BG3_X = 0;
}
gMain.state++;
@@ -872,8 +872,8 @@ static void sub_809DE64(void)
gBattle_BG1_Y = 0;
gBattle_BG2_X = 0;
gBattle_BG2_Y = 0;
- gUnknown_030041B0 = 0;
- gUnknown_030041B8 = 0;
+ gBattle_BG3_X = 0;
+ gBattle_BG3_Y = 0;
REG_BG0HOFS = 0;
REG_BG0VOFS = 0;
@@ -2176,11 +2176,11 @@ void sub_809F43C(u8 taskId)
pssData.loadGfxState = 0;
if (GetMonData(&pssData.loadedMon, MON_DATA_IS_EGG))
{
- gUnknown_030041B0 = 256;
+ gBattle_BG3_X = 256;
}
else
{
- gUnknown_030041B0 = 0;
+ gBattle_BG3_X = 0;
}
gMain.state++;
diff --git a/src/pokenav_before.c b/src/pokenav_before.c
index 3b534c96c..b31be2ce1 100644
--- a/src/pokenav_before.c
+++ b/src/pokenav_before.c
@@ -18,7 +18,7 @@
#include "sound.h"
#include "task.h"
#include "text.h"
-#include "unknown_task.h"
+#include "scanline_effect.h"
extern u8 ewram[];
@@ -329,7 +329,7 @@ void sub_80EBA5C()
ResetTasks();
break;
case 6:
- remove_some_task();
+ ScanlineEffect_Stop();
break;
case 7:
sub_80F1A90();
@@ -436,7 +436,7 @@ void sub_80EBD4C()
ProcessSpriteCopyRequests();
TransferPlttBuffer();
sub_80F5BF0();
- sub_8089668();
+ ScanlineEffect_InitHBlankDmaTransfer();
}
void sub_80EBD68()
diff --git a/src/roulette.c b/src/roulette.c
index e88c36c01..6d79f9d38 100644
--- a/src/roulette.c
+++ b/src/roulette.c
@@ -23,7 +23,7 @@
#include "task.h"
#include "text.h"
#include "trig.h"
-#include "unknown_task.h"
+#include "scanline_effect.h"
asm(".include \"constants/gba_constants.inc\"");
@@ -578,7 +578,7 @@ void sub_8115384(void)
{
case 0x0:
SetVBlankCallback(NULL);
- remove_some_task();
+ ScanlineEffect_Stop();
sub_80F9438();
sub_80F9368();
REG_BG2CNT = 0x4686;
diff --git a/src/scanline_effect.c b/src/scanline_effect.c
new file mode 100644
index 000000000..b4de0689f
--- /dev/null
+++ b/src/scanline_effect.c
@@ -0,0 +1,261 @@
+#include "global.h"
+#include "data2.h"
+#include "task.h"
+#include "trig.h"
+#include "scanline_effect.h"
+
+static void CopyValue16Bit(void);
+static void CopyValue32Bit(void);
+
+extern u16 gBattle_BG0_Y;
+extern u16 gBattle_BG0_X;
+extern u16 gBattle_BG1_X;
+extern u16 gBattle_BG1_Y;
+extern u16 gBattle_BG2_X;
+extern u16 gBattle_BG2_Y;
+extern u16 gBattle_BG3_X;
+extern u16 gBattle_BG3_Y;
+
+EWRAM_DATA static u8 sShouldStopWaveTask = FALSE;
+
+struct ScanlineEffect gScanlineEffect;
+
+// Per-scanline register values.
+// This is double buffered so that it can be safely written to at any time
+// without overwriting the buffer that the DMA is currently reading
+u16 gScanlineEffectRegBuffers[2][0x3C0];
+
+void ScanlineEffect_Stop(void)
+{
+ gScanlineEffect.state = 0;
+ DmaStop(0);
+ if (gScanlineEffect.waveTaskId != 0xFF)
+ {
+ DestroyTask(gScanlineEffect.waveTaskId);
+ gScanlineEffect.waveTaskId = 0xFF;
+ }
+}
+
+void ScanlineEffect_Clear(void)
+{
+ CpuFill16(0, gScanlineEffectRegBuffers, sizeof(gScanlineEffectRegBuffers));
+ gScanlineEffect.dmaSrcBuffers[0] = NULL;
+ gScanlineEffect.dmaSrcBuffers[1] = NULL;
+ gScanlineEffect.dmaDest = NULL;
+ gScanlineEffect.dmaControl = 0;
+ gScanlineEffect.srcBuffer = 0;
+ gScanlineEffect.state = 0;
+ gScanlineEffect.unused16 = 0;
+ gScanlineEffect.unused17 = 0;
+ gScanlineEffect.waveTaskId = 0xFF;
+}
+
+void ScanlineEffect_SetParams(struct ScanlineEffectParams params)
+{
+ if (params.dmaControl == SCANLINE_EFFECT_DMACNT_16BIT) // 16-bit
+ {
+ // Set the DMA src to the value for the second scanline because the
+ // first DMA transfer occurs in HBlank *after* the first scanline is drawn
+ gScanlineEffect.dmaSrcBuffers[0] = (u16 *)gScanlineEffectRegBuffers[0] + 1;
+ gScanlineEffect.dmaSrcBuffers[1] = (u16 *)gScanlineEffectRegBuffers[1] + 1;
+ gScanlineEffect.setFirstScanlineReg = CopyValue16Bit;
+ }
+ else // assume 32-bit
+ {
+ // Set the DMA src to the value for the second scanline because the
+ // first DMA transfer occurs in HBlank *after* the first scanline is drawn
+ gScanlineEffect.dmaSrcBuffers[0] = (u32 *)gScanlineEffectRegBuffers[0] + 1;
+ gScanlineEffect.dmaSrcBuffers[1] = (u32 *)gScanlineEffectRegBuffers[1] + 1;
+ gScanlineEffect.setFirstScanlineReg = CopyValue32Bit;
+ }
+
+ gScanlineEffect.dmaControl = params.dmaControl;
+ gScanlineEffect.dmaDest = params.dmaDest;
+ gScanlineEffect.state = params.initState;
+ gScanlineEffect.unused16 = params.unused9;
+ gScanlineEffect.unused17 = params.unused9;
+}
+
+void ScanlineEffect_InitHBlankDmaTransfer(void)
+{
+ if (gScanlineEffect.state == 0)
+ {
+ return;
+ }
+ else if (gScanlineEffect.state == 3)
+ {
+ gScanlineEffect.state = 0;
+ DmaStop(0);
+ sShouldStopWaveTask = TRUE;
+ }
+ else
+ {
+ DmaStop(0);
+ // Set DMA to copy to dest register on each HBlank for the next frame.
+ // The HBlank DMA transfers do not occurr during VBlank, so the transfer
+ // will begin on the HBlank after the first scanline
+ DmaSet(0, gScanlineEffect.dmaSrcBuffers[gScanlineEffect.srcBuffer], gScanlineEffect.dmaDest, gScanlineEffect.dmaControl);
+ // Manually set the reg for the first scanline
+ gScanlineEffect.setFirstScanlineReg();
+ // Swap current buffer
+ gScanlineEffect.srcBuffer ^= 1;
+ }
+}
+
+// These two functions are used to copy the register for the first scanline,
+// depending whether it is a 16-bit register or a 32-bit register.
+
+static void CopyValue16Bit(void)
+{
+ u16 *dest = (u16 *)gScanlineEffect.dmaDest;
+ u16 *src = (u16 *)&gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer];
+
+ *dest = *src;
+}
+
+static void CopyValue32Bit(void)
+{
+ u32 *dest = (u32 *)gScanlineEffect.dmaDest;
+ u32 *src = (u32 *)&gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer];
+
+ *dest = *src;
+}
+
+#define tStartLine data[0]
+#define tEndLine data[1]
+#define tWaveLength data[2]
+#define tSrcBufferOffset data[3]
+#define tFramesUntilMove data[4]
+#define tDelayInterval data[5]
+#define tRegOffset data[6]
+#define tApplyBattleBgOffsets data[7]
+
+static void TaskFunc_UpdateWavePerFrame(u8 taskId)
+{
+ int value = 0;
+ int i;
+ int offset;
+
+ if (sShouldStopWaveTask)
+ {
+ DestroyTask(taskId);
+ gScanlineEffect.waveTaskId = 0xFF;
+ }
+ else
+ {
+ if (gTasks[taskId].tApplyBattleBgOffsets)
+ {
+ switch (gTasks[taskId].tRegOffset)
+ {
+ case SCANLINE_EFFECT_REG_BG0HOFS:
+ value = gBattle_BG0_X;
+ break;
+ case SCANLINE_EFFECT_REG_BG0VOFS:
+ value = gBattle_BG0_Y;
+ break;
+ case SCANLINE_EFFECT_REG_BG1HOFS:
+ value = gBattle_BG1_X;
+ break;
+ case SCANLINE_EFFECT_REG_BG1VOFS:
+ value = gBattle_BG1_Y;
+ break;
+ case SCANLINE_EFFECT_REG_BG2HOFS:
+ value = gBattle_BG2_X;
+ break;
+ case SCANLINE_EFFECT_REG_BG2VOFS:
+ value = gBattle_BG2_Y;
+ break;
+ case SCANLINE_EFFECT_REG_BG3HOFS:
+ value = gBattle_BG3_X;
+ break;
+ case SCANLINE_EFFECT_REG_BG3VOFS:
+ value = gBattle_BG3_Y;
+ break;
+ }
+ }
+ if (gTasks[taskId].tFramesUntilMove != 0)
+ {
+ gTasks[taskId].tFramesUntilMove--;
+ offset = gTasks[taskId].tSrcBufferOffset + 320;
+ for (i = gTasks[taskId].tStartLine; i < gTasks[taskId].tEndLine; i++)
+ {
+ gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer][i] = gScanlineEffectRegBuffers[0][offset] + value;
+ offset++;
+ }
+ }
+ else
+ {
+ gTasks[taskId].tFramesUntilMove = gTasks[taskId].tDelayInterval;
+ offset = gTasks[taskId].tSrcBufferOffset + 320;
+ for (i = gTasks[taskId].tStartLine; i < gTasks[taskId].tEndLine; i++)
+ {
+ gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer][i] = gScanlineEffectRegBuffers[0][offset] + value;
+ offset++;
+ }
+
+ // increment src buffer offset
+ gTasks[taskId].tSrcBufferOffset++;
+ if (gTasks[taskId].tSrcBufferOffset == gTasks[taskId].tWaveLength)
+ gTasks[taskId].tSrcBufferOffset = 0;
+ }
+ }
+}
+
+static void GenerateWave(u16 *buffer, u8 frequency, u8 amplitude, u8 unused)
+{
+ u16 i = 0;
+ u8 theta = 0;
+
+ while (i < 256)
+ {
+ buffer[i] = (gSineTable[theta] * amplitude) / 256;
+ theta += frequency;
+ i++;
+ }
+}
+
+// Initializes a background "wave" effect that affects scanlines startLine (inclusive) to endLine (exclusive).
+// 'frequency' and 'amplitude' control the frequency and amplitude of the wave.
+// 'delayInterval' controls how fast the wave travels up the screen. The wave will shift upwards one scanline every 'delayInterval'+1 frames.
+// 'regOffset' is the offset of the video register to modify.
+u8 ScanlineEffect_InitWave(u8 startLine, u8 endLine, u8 frequency, u8 amplitude, u8 delayInterval, u8 regOffset, bool8 applyBattleBgOffsets)
+{
+ int i;
+ int offset;
+ struct ScanlineEffectParams params;
+ u8 taskId;
+
+ ScanlineEffect_Clear();
+
+ params.dmaDest = (void *)(REG_ADDR_BG0HOFS + regOffset);
+ params.dmaControl = SCANLINE_EFFECT_DMACNT_16BIT;
+ params.initState = 1;
+ params.unused9 = 0;
+ ScanlineEffect_SetParams(params);
+
+ taskId = CreateTask(TaskFunc_UpdateWavePerFrame, 0);
+
+ gTasks[taskId].tStartLine = startLine;
+ gTasks[taskId].tEndLine = endLine;
+ gTasks[taskId].tWaveLength = 256 / frequency;
+ gTasks[taskId].tSrcBufferOffset = 0;
+ gTasks[taskId].tFramesUntilMove = delayInterval;
+ gTasks[taskId].tDelayInterval = delayInterval;
+ gTasks[taskId].tRegOffset = regOffset;
+ gTasks[taskId].tApplyBattleBgOffsets = applyBattleBgOffsets;
+
+ gScanlineEffect.waveTaskId = taskId;
+ sShouldStopWaveTask = FALSE;
+
+ GenerateWave(&gScanlineEffectRegBuffers[0][320], frequency, amplitude, endLine - startLine);
+
+ offset = 320;
+ for (i = startLine; i < endLine; i++)
+ {
+ gScanlineEffectRegBuffers[0][i] = gScanlineEffectRegBuffers[0][offset];
+ gScanlineEffectRegBuffers[1][i] = gScanlineEffectRegBuffers[0][offset];
+ offset++;
+ }
+
+ return taskId;
+}
diff --git a/src/scene/cable_car.c b/src/scene/cable_car.c
index 52a0aeebf..d8e099130 100644
--- a/src/scene/cable_car.c
+++ b/src/scene/cable_car.c
@@ -14,7 +14,7 @@
#include "decompress.h"
#include "field_weather.h"
#include "field_map_obj.h"
-#include "unknown_task.h"
+#include "scanline_effect.h"
#include "event_data.h"
#include "cable_car_util.h"
#include "constants/map_objects.h"
@@ -208,7 +208,7 @@ static void CableCarMainCallback_Setup(void)
case 0:
default:
SetVBlankCallback(NULL);
- remove_some_task();
+ ScanlineEffect_Stop();
DmaFill16Large(3, 0, VRAM, VRAM_SIZE, 0x1000);
DmaFill32Defvars(3, 0, OAM, OAM_SIZE);
DmaFill16Defvars(3, 0, PLTT, PLTT_SIZE);
diff --git a/src/scene/contest_painting.c b/src/scene/contest_painting.c
index 401872644..3aa898b03 100644
--- a/src/scene/contest_painting.c
+++ b/src/scene/contest_painting.c
@@ -11,7 +11,7 @@
#include "string_util.h"
#include "strings.h"
#include "text.h"
-#include "unknown_task.h"
+#include "scanline_effect.h"
#include "ewram.h"
static u8 gUnknown_03000750;
@@ -147,7 +147,7 @@ static void ShowContestPainting(void)
switch (gMain.state)
{
case 0:
- remove_some_task();
+ ScanlineEffect_Stop();
SetVBlankCallback(NULL);
gUnknown_03005E8C = &ewram15DE0;
ContestPaintingInitVars(TRUE);
diff --git a/src/scene/evolution_scene.c b/src/scene/evolution_scene.c
index 167130aa5..53eb2f1e8 100644
--- a/src/scene/evolution_scene.c
+++ b/src/scene/evolution_scene.c
@@ -9,7 +9,7 @@
#include "pokemon.h"
#include "string_util.h"
#include "battle.h"
-#include "unknown_task.h"
+#include "scanline_effect.h"
#include "data2.h"
#include "decompress.h"
#include "m4a.h"
@@ -71,8 +71,8 @@ extern u16 gBattle_BG1_X;
extern u16 gBattle_BG1_Y;
extern u16 gBattle_BG2_X;
extern u16 gBattle_BG2_Y;
-extern u16 gUnknown_030041B0;
-extern u16 gUnknown_030041B8;
+extern u16 gBattle_BG3_X;
+extern u16 gBattle_BG3_Y;
extern u8 gBattleTerrain;
extern u8 gReservedSpritePaletteCount;
extern u16 gMoveToLearn;
@@ -206,8 +206,8 @@ void EvolutionScene(struct Pokemon* mon, u16 speciesToEvolve, bool8 canStopEvo,
gBattle_BG1_Y = 0;
gBattle_BG2_X = 0;
gBattle_BG2_Y = 0;
- gUnknown_030041B0 = 256;
- gUnknown_030041B8 = 0;
+ gBattle_BG3_X = 256;
+ gBattle_BG3_Y = 0;
Text_InitWindowWithTemplate(&gUnknown_03004210, &gWindowTemplate_81E6C58);
gBattleTerrain = BATTLE_TERRAIN_PLAIN;
@@ -215,7 +215,7 @@ void EvolutionScene(struct Pokemon* mon, u16 speciesToEvolve, bool8 canStopEvo,
sub_800D6D4();
sub_800DAB8();
ResetSpriteData();
- remove_some_task();
+ ScanlineEffect_Stop();
ResetTasks();
FreeAllSpritePalettes();
@@ -314,8 +314,8 @@ static void CB2_EvolutionSceneLoadGraphics(void)
gBattle_BG1_Y = 0;
gBattle_BG2_X = 0;
gBattle_BG2_Y = 0;
- gUnknown_030041B0 = 256;
- gUnknown_030041B8 = 0;
+ gBattle_BG3_X = 256;
+ gBattle_BG3_Y = 0;
Text_InitWindowWithTemplate(&gUnknown_03004210, &gWindowTemplate_81E6C58);
gBattleTerrain = BATTLE_TERRAIN_PLAIN;
@@ -368,8 +368,8 @@ static void CB2_TradeEvolutionSceneLoadGraphics(void)
gBattle_BG1_Y = 0;
gBattle_BG2_X = 0;
gBattle_BG2_Y = 0;
- gUnknown_030041B0 = 256;
- gUnknown_030041B8 = 0;
+ gBattle_BG3_X = 256;
+ gBattle_BG3_Y = 0;
gMain.state++;
break;
case 1:
@@ -3929,12 +3929,12 @@ static void VBlankCB_EvolutionScene(void)
REG_BG1VOFS = gBattle_BG1_Y;
REG_BG2HOFS = gBattle_BG2_X;
REG_BG2VOFS = gBattle_BG2_Y;
- REG_BG3HOFS = gUnknown_030041B0;
- REG_BG3VOFS = gUnknown_030041B8;
+ REG_BG3HOFS = gBattle_BG3_X;
+ REG_BG3VOFS = gBattle_BG3_Y;
LoadOam();
ProcessSpriteCopyRequests();
TransferPlttBuffer();
- sub_8089668();
+ ScanlineEffect_InitHBlankDmaTransfer();
}
static void VBlankCB_TradeEvolutionScene(void)
@@ -3945,12 +3945,12 @@ static void VBlankCB_TradeEvolutionScene(void)
REG_BG1VOFS = gBattle_BG1_Y;
REG_BG2HOFS = gBattle_BG2_X;
REG_BG2VOFS = gBattle_BG2_Y;
- REG_BG3HOFS = gUnknown_030041B0;
- REG_BG3VOFS = gUnknown_030041B8;
+ REG_BG3HOFS = gBattle_BG3_X;
+ REG_BG3VOFS = gBattle_BG3_Y;
LoadOam();
ProcessSpriteCopyRequests();
TransferPlttBuffer();
- sub_8089668();
+ ScanlineEffect_InitHBlankDmaTransfer();
}
static void sub_81150D8(void)
diff --git a/src/scene/hall_of_fame.c b/src/scene/hall_of_fame.c
index 948c288ff..303dcf3e0 100644
--- a/src/scene/hall_of_fame.c
+++ b/src/scene/hall_of_fame.c
@@ -16,6 +16,7 @@
#include "data2.h"
#include "decompress.h"
#include "random.h"
+#include "scanline_effect.h"
#include "trig.h"
#include "ewram.h"
@@ -95,7 +96,6 @@ bool8 sub_80C5DCC(void);
bool8 sub_80C5F98(void);
void ReturnFromHallOfFamePC(void);
u16 SpeciesToPokedexNum(u16 species);
-void remove_some_task(void);
// data and gfx
@@ -1278,7 +1278,7 @@ static void sub_81433E0(void)
static void sub_8143570(void)
{
- remove_some_task();
+ ScanlineEffect_Stop();
ResetTasks();
ResetSpriteData();
FreeAllSpritePalettes();
diff --git a/src/scene/intro.c b/src/scene/intro.c
index 4dc6cc91c..d7d772a40 100644
--- a/src/scene/intro.c
+++ b/src/scene/intro.c
@@ -19,7 +19,7 @@
#include "task.h"
#include "title_screen.h"
#include "trig.h"
-#include "unknown_task.h"
+#include "scanline_effect.h"
#include "ewram.h"
extern struct SpriteTemplate gUnknown_02024E8C;
@@ -873,7 +873,7 @@ static u8 SetUpCopyrightScreen(void)
DmaFill16(3, 0, (void *)(PLTT + 2), PLTT_SIZE - 2);
ResetPaletteFade();
LoadCopyrightGraphics(0, 0x3800, 0);
- remove_some_task();
+ ScanlineEffect_Stop();
ResetTasks();
ResetSpriteData();
FreeAllSpritePalettes();
diff --git a/src/scene/intro_credits_graphics.c b/src/scene/intro_credits_graphics.c
index 6cee74cce..f0f1264a0 100755
--- a/src/scene/intro_credits_graphics.c
+++ b/src/scene/intro_credits_graphics.c
@@ -19,7 +19,7 @@
#include "task.h"
#include "title_screen.h"
#include "trig.h"
-#include "unknown_task.h"
+#include "scanline_effect.h"
// define register constants for the inline asm
asm(".include \"constants/gba_constants.inc\"\n");
diff --git a/src/scene/title_screen.c b/src/scene/title_screen.c
index 26fe088d5..202b752a6 100644
--- a/src/scene/title_screen.c
+++ b/src/scene/title_screen.c
@@ -13,7 +13,7 @@
#include "sound.h"
#include "sprite.h"
#include "task.h"
-#include "unknown_task.h"
+#include "scanline_effect.h"
#if ENGLISH
#define VERSION_BANNER_SHAPE 1
@@ -598,7 +598,7 @@ static void StartPokemonLogoShine(bool8 flashBackground)
static void VBlankCB(void)
{
- sub_8089668();
+ ScanlineEffect_InitHBlankDmaTransfer();
LoadOam();
ProcessSpriteCopyRequests();
TransferPlttBuffer();
@@ -644,7 +644,7 @@ void CB2_InitTitleScreen(void)
LZ77UnCompVram(sLegendaryMonTilemap, (void *)(VRAM + 0xC000));
LZ77UnCompVram(sBackdropTilemap, (void *)(VRAM + 0xC800));
LoadPalette(sLegendaryMonPalettes, 0xE0, sizeof(sLegendaryMonPalettes));
- remove_some_task();
+ ScanlineEffect_Stop();
ResetTasks();
ResetSpriteData();
FreeAllSpritePalettes();
@@ -711,7 +711,7 @@ void CB2_InitTitleScreen(void)
if (!UpdatePaletteFade())
{
StartPokemonLogoShine(FALSE);
- sub_8089944(0, 0xA0, 4, 4, 0, 4, 1);
+ ScanlineEffect_InitWave(0, DISPLAY_HEIGHT, 4, 4, 0, SCANLINE_EFFECT_REG_BG1HOFS, TRUE);
SetMainCallback2(MainCB2);
}
break;
diff --git a/src/unknown_task.c b/src/unknown_task.c
deleted file mode 100644
index 2c71bfb08..000000000
--- a/src/unknown_task.c
+++ /dev/null
@@ -1,235 +0,0 @@
-#include "global.h"
-#include "data2.h"
-#include "task.h"
-#include "trig.h"
-#include "unknown_task.h"
-
-static void sub_80896F4(void);
-static void sub_8089714(void);
-
-extern u16 gUnknown_030041B0;
-extern u16 gBattle_BG1_Y;
-extern u16 gUnknown_030041B8;
-extern u16 gBattle_BG2_Y;
-extern u16 gBattle_BG2_X;
-extern u16 gBattle_BG0_Y;
-extern u16 gBattle_BG0_X;
-extern u16 gBattle_BG1_X;
-
-extern u8 gUnknown_0202FFA4;
-
-extern struct UnknownTaskStruct2 gUnknown_03004DC0;
-
-// Is this a struct?
-extern u16 gUnknown_03004DE0[][0x3C0];
-
-void remove_some_task(void)
-{
- gUnknown_03004DC0.unk15 = 0;
- DmaStop(0);
- if (gUnknown_03004DC0.taskId != 0xFF)
- {
- DestroyTask(gUnknown_03004DC0.taskId);
- gUnknown_03004DC0.taskId = 0xFF;
- }
-}
-
-void dp12_8087EA4(void)
-{
- CpuFill16(0, gUnknown_03004DE0, 0x780 * 2);
- gUnknown_03004DC0.src[0] = 0;
- gUnknown_03004DC0.src[1] = 0;
- gUnknown_03004DC0.dest = 0;
- gUnknown_03004DC0.unkC = 0;
- gUnknown_03004DC0.srcBank = 0;
- gUnknown_03004DC0.unk15 = 0;
- gUnknown_03004DC0.unk16 = 0;
- gUnknown_03004DC0.unk17 = 0;
- gUnknown_03004DC0.taskId = 0xFF;
-}
-
-void sub_80895F8(struct UnknownTaskStruct unk)
-{
- if (unk.control == (((DMA_ENABLE | DMA_START_HBLANK | DMA_REPEAT | DMA_DEST_RELOAD) << 16) | 1))
- {
- gUnknown_03004DC0.src[0] = &gUnknown_03004DE0[0][1];
- gUnknown_03004DC0.src[1] = &gUnknown_03004DE0[1][1];
- gUnknown_03004DC0.unk10 = sub_80896F4;
- }
- else
- {
- gUnknown_03004DC0.src[0] = &gUnknown_03004DE0[0][2];
- gUnknown_03004DC0.src[1] = &gUnknown_03004DE0[1][2];
- gUnknown_03004DC0.unk10 = sub_8089714;
- }
-
- gUnknown_03004DC0.unkC = unk.control;
- gUnknown_03004DC0.dest = unk.dest;
- gUnknown_03004DC0.unk15 = unk.unk8;
- gUnknown_03004DC0.unk16 = unk.unk9;
- gUnknown_03004DC0.unk17 = unk.unk9;
-}
-
-void sub_8089668(void)
-{
- if (gUnknown_03004DC0.unk15)
- {
- if (gUnknown_03004DC0.unk15 == 3)
- {
- gUnknown_03004DC0.unk15 = 0;
- DmaStop(0);
- gUnknown_0202FFA4 = 1;
- }
- else
- {
- DmaStop(0);
- DmaSet(0, gUnknown_03004DC0.src[gUnknown_03004DC0.srcBank], gUnknown_03004DC0.dest, gUnknown_03004DC0.unkC);
- gUnknown_03004DC0.unk10();
- gUnknown_03004DC0.srcBank ^= 1;
- }
- }
-}
-
-static void sub_80896F4(void)
-{
- u16 *dest = (u16 *)gUnknown_03004DC0.dest;
- u16 *src = (u16 *)&gUnknown_03004DE0[gUnknown_03004DC0.srcBank];
- *dest = *src;
-}
-
-static void sub_8089714(void)
-{
- u32 *dest = (u32 *)gUnknown_03004DC0.dest;
- u32 *src = (u32 *)&gUnknown_03004DE0[gUnknown_03004DC0.srcBank];
- *dest = *src;
-}
-
-static void task00_for_dp12(u8 taskId)
-{
- int value = 0;
-
- if (gUnknown_0202FFA4)
- {
- DestroyTask(taskId);
- gUnknown_03004DC0.taskId = 0xFF;
- }
- else
- {
- if (gTasks[taskId].data[7])
- {
- switch (gTasks[taskId].data[6])
- {
- case 0x0:
- value = gBattle_BG0_X;
- break;
- case 0x2:
- value = gBattle_BG0_Y;
- break;
- case 0x4:
- value = gBattle_BG1_X;
- break;
- case 0x6:
- value = gBattle_BG1_Y;
- break;
- case 0x8:
- value = gBattle_BG2_X;
- break;
- case 0xA:
- value = gBattle_BG2_Y;
- break;
- case 0xC:
- value = gUnknown_030041B0;
- break;
- case 0xE:
- value = gUnknown_030041B8;
- break;
- }
- }
- if (gTasks[taskId].data[4])
- {
- int i;
- int offset;
- gTasks[taskId].data[4]--;
- offset = gTasks[taskId].data[3] + 320;
- for (i = gTasks[taskId].data[0]; i < gTasks[taskId].data[1]; i++)
- {
- gUnknown_03004DE0[gUnknown_03004DC0.srcBank][i] = gUnknown_03004DE0[0][offset] + value;
- offset++;
- }
- }
- else
- {
- int i;
- int offset;
- gTasks[taskId].data[4] = gTasks[taskId].data[5];
- offset = gTasks[taskId].data[3] + 320;
- for (i = gTasks[taskId].data[0]; i < gTasks[taskId].data[1]; i++)
- {
- gUnknown_03004DE0[gUnknown_03004DC0.srcBank][i] = gUnknown_03004DE0[0][offset] + value;
- offset++;
- }
- gTasks[taskId].data[3]++;
- if (gTasks[taskId].data[3] == gTasks[taskId].data[2])
- {
- gTasks[taskId].data[3] = 0;
- }
- }
- }
-}
-
-static void sub_80898FC(u16 *a1, u8 a2, u8 a3, u8 a4)
-{
- u16 i = 0;
- u8 offset = 0;
-
- while (i < 0x100)
- {
- a1[i] = (gSineTable[offset] * a3) / 256;
- offset += a2;
- i++;
- }
-}
-
-u8 sub_8089944(u8 a1, u8 a2, u8 a3, u8 a4, u8 a5, u8 a6, u8 a7)
-{
- int i;
- int offset;
- struct UnknownTaskStruct unk;
- u8 taskId;
-
- dp12_8087EA4();
-
- unk.dest = (void *)(REG_ADDR_BG0HOFS + a6);
- unk.control = ((DMA_ENABLE | DMA_START_HBLANK | DMA_REPEAT | DMA_DEST_RELOAD) << 16) | 1;
- unk.unk8 = 1;
- unk.unk9 = 0;
-
- sub_80895F8(unk);
-
- taskId = CreateTask(task00_for_dp12, 0);
-
- gTasks[taskId].data[0] = a1;
- gTasks[taskId].data[1] = a2;
- gTasks[taskId].data[2] = 256 / a3;
- gTasks[taskId].data[3] = 0;
- gTasks[taskId].data[4] = a5;
- gTasks[taskId].data[5] = a5;
- gTasks[taskId].data[6] = a6;
- gTasks[taskId].data[7] = a7;
-
- gUnknown_03004DC0.taskId = taskId;
- gUnknown_0202FFA4 = 0;
-
- sub_80898FC(&gUnknown_03004DE0[0][320], a3, a4, a2 - a1);
-
- offset = 320;
-
- for (i = a1; i < a2; i++)
- {
- gUnknown_03004DE0[0][i] = gUnknown_03004DE0[0][offset];
- gUnknown_03004DE0[1][i] = gUnknown_03004DE0[0][offset];
- offset++;
- }
-
- return taskId;
-}