summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhuderlem <huderlem@gmail.com>2019-08-03 20:06:17 -0500
committerGitHub <noreply@github.com>2019-08-03 20:06:17 -0500
commit71442a109c3859d1a1e1418924a1a56823b9631c (patch)
treeef04c74a98cafa7da2b3556d6af4067555b9e498
parentc427a4af00fa46f33f7167977ea834218c37cfa8 (diff)
parentb97a0894bfa099ba5ec8363f8cdc08a1c0d9e6db (diff)
Merge pull request #3 from camthesaxman/headers
move all externs to header files and update m4a library
-rwxr-xr-xMakefile1
-rwxr-xr-xasm/m4a_3.s577
-rw-r--r--common_syms/m4a.txt11
-rw-r--r--graphics/intro/copyright.pal518
-rw-r--r--include/functions.h845
-rwxr-xr-xinclude/gba/m4a_internal.h2
-rwxr-xr-xinclude/global.h7
-rwxr-xr-xinclude/m4a.h8
-rwxr-xr-xinclude/main.h44
-rw-r--r--include/types.h37
-rw-r--r--include/variables.h167
-rwxr-xr-xld_script.txt13
-rwxr-xr-xsrc/gbplayer.c12
-rwxr-xr-xsrc/m4a.c1791
-rwxr-xr-xsrc/m4a_2.c931
-rwxr-xr-xsrc/m4a_4.c548
-rwxr-xr-xsrc/main.c12
-rwxr-xr-xsrc/rom_850.c10
-rwxr-xr-xsrc/titlescreen.c43
-rwxr-xr-xsrc/util.c3
-rwxr-xr-xsym_bss.txt3
-rwxr-xr-xsym_common.txt2
-rwxr-xr-xsym_ewram.txt30
23 files changed, 3139 insertions, 2476 deletions
diff --git a/Makefile b/Makefile
index 8e1cabe..94bfc73 100755
--- a/Makefile
+++ b/Makefile
@@ -110,6 +110,7 @@ $(C_BUILDDIR)/libc.o: CFLAGS := -O2
$(C_BUILDDIR)/m4a_2.o: CC1 := tools/agbcc/bin/old_agbcc
$(C_BUILDDIR)/m4a_4.o: CC1 := tools/agbcc/bin/old_agbcc
+$(C_BUILDDIR)/m4a.o: CC1 := tools/agbcc/bin/old_agbcc
ifeq ($(NODEP),)
$(C_BUILDDIR)/%.o: c_dep = $(shell $(SCANINC) -I include $(C_SUBDIR)/$*.c)
diff --git a/asm/m4a_3.s b/asm/m4a_3.s
deleted file mode 100755
index c0ac04f..0000000
--- a/asm/m4a_3.s
+++ /dev/null
@@ -1,577 +0,0 @@
- .include "asm/macros.inc"
- .include "constants/gba_constants.inc"
- .include "constants/m4a_constants.inc"
-
- .syntax unified
-
- @ extern
- .set gCgb3Vol, 0x0852DAFC
-
- .text
-
- thumb_func_start CgbSound
-CgbSound: @ 8054920
- push {r4-r7,lr}
- mov r7, r10
- mov r6, r9
- mov r5, r8
- push {r5-r7}
- sub sp, 0x1C
- ldr r0, =SOUND_INFO_PTR
- ldr r0, [r0]
- str r0, [sp, 0x4]
- ldrb r0, [r0, 0xA]
- cmp r0, 0
- beq _08054944
- subs r0, 0x1
- ldr r1, [sp, 0x4]
- strb r0, [r1, 0xA]
- b _0805494A
- .pool
-_08054944:
- movs r0, 0xE
- ldr r2, [sp, 0x4]
- strb r0, [r2, 0xA]
-_0805494A:
- movs r6, 0x1
- ldr r0, [sp, 0x4]
- ldr r4, [r0, 0x1C]
-_08054950:
- ldrb r1, [r4]
- movs r0, 0xC7
- ands r0, r1
- adds r2, r6, 0x1
- mov r10, r2
- movs r2, 0x40
- adds r2, r4
- mov r9, r2
- cmp r0, 0
- bne _08054966
- b _08054D50
-_08054966:
- cmp r6, 0x2
- beq _08054988
- cmp r6, 0x2
- bgt _08054974
- cmp r6, 0x1
- beq _0805497A
- b _080549D0
-_08054974:
- cmp r6, 0x3
- beq _080549B0
- b _080549D0
-_0805497A:
- ldr r0, =REG_NR10
- str r0, [sp, 0x8]
- ldr r7, =REG_NR11
- ldr r2, =REG_NR12
- str r2, [sp, 0xC]
- adds r0, 0x4
- str r0, [sp, 0x10]
- adds r2, 0x2
- b _080549E0
- .pool
-_08054988:
- ldr r0, =REG_NR10 + 1
- str r0, [sp, 0x8]
- ldr r7, =REG_NR21
- ldr r2, =REG_NR22
- b _080549D8
- .pool
-_080549B0:
- ldr r0, =REG_NR30
- str r0, [sp, 0x8]
- ldr r7, =REG_NR31
- ldr r2, =REG_NR32
- str r2, [sp, 0xC]
- adds r0, 0x4
- str r0, [sp, 0x10]
- adds r2, 0x2
- b _080549E0
- .pool
-_080549D0:
- ldr r0, =REG_NR30 + 1
- str r0, [sp, 0x8]
- ldr r7, =REG_NR41
- ldr r2, =REG_NR42
-_080549D8:
- str r2, [sp, 0xC]
- adds r0, 0xB
- str r0, [sp, 0x10]
- adds r2, 0x4
-_080549E0:
- str r2, [sp, 0x14]
- ldr r0, [sp, 0x4]
- ldrb r0, [r0, 0xA]
- str r0, [sp]
- ldr r2, [sp, 0xC]
- ldrb r0, [r2]
- mov r8, r0
- adds r2, r1, 0
- movs r0, 0x80
- ands r0, r2
- cmp r0, 0
- beq _08054AD6
- movs r3, 0x40
- adds r0, r3, 0
- ands r0, r2
- lsls r0, 24
- lsrs r5, r0, 24
- adds r0, r6, 0x1
- mov r10, r0
- movs r1, 0x40
- adds r1, r4
- mov r9, r1
- cmp r5, 0
- bne _08054AFA
- movs r0, 0x3
- strb r0, [r4]
- strb r0, [r4, 0x1D]
- adds r0, r4, 0
- str r3, [sp, 0x18]
- bl CgbModVol
- ldr r3, [sp, 0x18]
- cmp r6, 0x2
- beq _08054A48
- cmp r6, 0x2
- bgt _08054A3C
- cmp r6, 0x1
- beq _08054A42
- b _08054A9C
- .pool
-_08054A3C:
- cmp r6, 0x3
- beq _08054A54
- b _08054A9C
-_08054A42:
- ldrb r0, [r4, 0x1F]
- ldr r2, [sp, 0x8]
- strb r0, [r2]
-_08054A48:
- ldr r0, [r4, 0x24]
- lsls r0, 6
- ldrb r1, [r4, 0x1E]
- adds r0, r1, r0
- strb r0, [r7]
- b _08054AA8
-_08054A54:
- ldr r1, [r4, 0x24]
- ldr r0, [r4, 0x28]
- cmp r1, r0
- beq _08054A7C
- ldr r2, [sp, 0x8]
- strb r3, [r2]
- ldr r1, =REG_WAVE_RAM
- ldr r2, [r4, 0x24]
- ldr r0, [r2]
- str r0, [r1]
- adds r1, 0x4
- ldr r0, [r2, 0x4]
- str r0, [r1]
- adds r1, 0x4
- ldr r0, [r2, 0x8]
- str r0, [r1]
- adds r1, 0x4
- ldr r0, [r2, 0xC]
- str r0, [r1]
- str r2, [r4, 0x28]
-_08054A7C:
- ldr r0, [sp, 0x8]
- strb r5, [r0]
- ldrb r0, [r4, 0x1E]
- strb r0, [r7]
- ldrb r0, [r4, 0x1E]
- cmp r0, 0
- beq _08054A94
- movs r0, 0xC0
- b _08054AB6
- .pool
-_08054A94:
- movs r1, 0x80
- negs r1, r1
- strb r1, [r4, 0x1A]
- b _08054AB8
-_08054A9C:
- ldrb r0, [r4, 0x1E]
- strb r0, [r7]
- ldr r0, [r4, 0x24]
- lsls r0, 3
- ldr r2, [sp, 0x10]
- strb r0, [r2]
-_08054AA8:
- ldrb r0, [r4, 0x4]
- adds r0, 0x8
- mov r8, r0
- ldrb r0, [r4, 0x1E]
- cmp r0, 0
- beq _08054AB6
- movs r0, 0x40
-_08054AB6:
- strb r0, [r4, 0x1A]
-_08054AB8:
- ldrb r1, [r4, 0x4]
- movs r2, 0
- strb r1, [r4, 0xB]
- movs r0, 0xFF
- ands r0, r1
- adds r1, r6, 0x1
- mov r10, r1
- movs r1, 0x40
- adds r1, r4
- mov r9, r1
- cmp r0, 0
- bne _08054AD2
- b _08054C0E
-_08054AD2:
- strb r2, [r4, 0x9]
- b _08054C3C
-_08054AD6:
- movs r0, 0x4
- ands r0, r2
- cmp r0, 0
- beq _08054B08
- ldrb r0, [r4, 0xD]
- subs r0, 0x1
- strb r0, [r4, 0xD]
- movs r2, 0xFF
- ands r0, r2
- lsls r0, 24
- adds r1, r6, 0x1
- mov r10, r1
- movs r2, 0x40
- adds r2, r4
- mov r9, r2
- cmp r0, 0
- ble _08054AFA
- b _08054C4E
-_08054AFA:
- lsls r0, r6, 24
- lsrs r0, 24
- bl CgbOscOff
- movs r0, 0
- strb r0, [r4]
- b _08054D4C
-_08054B08:
- movs r0, 0x40
- ands r0, r1
- adds r2, r6, 0x1
- mov r10, r2
- movs r2, 0x40
- adds r2, r4
- mov r9, r2
- cmp r0, 0
- beq _08054B48
- movs r0, 0x3
- ands r0, r1
- cmp r0, 0
- beq _08054B48
- movs r0, 0xFC
- ands r0, r1
- movs r2, 0
- strb r0, [r4]
- ldrb r1, [r4, 0x7]
- strb r1, [r4, 0xB]
- movs r0, 0xFF
- ands r0, r1
- cmp r0, 0
- beq _08054B7A
- movs r0, 0x1
- ldrb r1, [r4, 0x1D]
- orrs r0, r1
- strb r0, [r4, 0x1D]
- cmp r6, 0x3
- beq _08054C3C
- ldrb r2, [r4, 0x7]
- mov r8, r2
- b _08054C3C
-_08054B48:
- ldrb r0, [r4, 0xB]
- cmp r0, 0
- bne _08054C3C
- cmp r6, 0x3
- bne _08054B5A
- movs r0, 0x1
- ldrb r1, [r4, 0x1D]
- orrs r0, r1
- strb r0, [r4, 0x1D]
-_08054B5A:
- adds r0, r4, 0
- bl CgbModVol
- movs r0, 0x3
- ldrb r2, [r4]
- ands r0, r2
- cmp r0, 0
- bne _08054BAE
- ldrb r0, [r4, 0x9]
- subs r0, 0x1
- strb r0, [r4, 0x9]
- movs r1, 0xFF
- ands r0, r1
- lsls r0, 24
- cmp r0, 0
- bgt _08054BAA
-_08054B7A:
- ldrb r2, [r4, 0xC]
- ldrb r1, [r4, 0xA]
- adds r0, r2, 0
- muls r0, r1
- adds r0, 0xFF
- asrs r0, 8
- movs r1, 0
- strb r0, [r4, 0x9]
- lsls r0, 24
- cmp r0, 0
- beq _08054AFA
- movs r0, 0x4
- ldrb r2, [r4]
- orrs r0, r2
- strb r0, [r4]
- movs r0, 0x1
- ldrb r1, [r4, 0x1D]
- orrs r0, r1
- strb r0, [r4, 0x1D]
- cmp r6, 0x3
- beq _08054C4E
- movs r2, 0x8
- mov r8, r2
- b _08054C4E
-_08054BAA:
- ldrb r0, [r4, 0x7]
- b _08054C3A
-_08054BAE:
- cmp r0, 0x1
- bne _08054BBA
-_08054BB2:
- ldrb r0, [r4, 0x19]
- strb r0, [r4, 0x9]
- movs r0, 0x7
- b _08054C3A
-_08054BBA:
- cmp r0, 0x2
- bne _08054BFE
- ldrb r0, [r4, 0x9]
- subs r0, 0x1
- strb r0, [r4, 0x9]
- movs r1, 0xFF
- ands r0, r1
- lsls r0, 24
- ldrb r2, [r4, 0x19]
- lsls r1, r2, 24
- cmp r0, r1
- bgt _08054BFA
-_08054BD2:
- ldrb r0, [r4, 0x6]
- cmp r0, 0
- bne _08054BE2
- movs r0, 0xFC
- ldrb r1, [r4]
- ands r0, r1
- strb r0, [r4]
- b _08054B7A
-_08054BE2:
- ldrb r0, [r4]
- subs r0, 0x1
- strb r0, [r4]
- movs r0, 0x1
- ldrb r2, [r4, 0x1D]
- orrs r0, r2
- strb r0, [r4, 0x1D]
- cmp r6, 0x3
- beq _08054BB2
- movs r0, 0x8
- mov r8, r0
- b _08054BB2
-_08054BFA:
- ldrb r0, [r4, 0x5]
- b _08054C3A
-_08054BFE:
- ldrb r0, [r4, 0x9]
- adds r0, 0x1
- strb r0, [r4, 0x9]
- movs r1, 0xFF
- ands r0, r1
- ldrb r2, [r4, 0xA]
- cmp r0, r2
- bcc _08054C38
-_08054C0E:
- ldrb r0, [r4]
- subs r0, 0x1
- movs r2, 0
- strb r0, [r4]
- ldrb r1, [r4, 0x5]
- strb r1, [r4, 0xB]
- movs r0, 0xFF
- ands r0, r1
- cmp r0, 0
- beq _08054BD2
- movs r0, 0x1
- ldrb r1, [r4, 0x1D]
- orrs r0, r1
- strb r0, [r4, 0x1D]
- ldrb r0, [r4, 0xA]
- strb r0, [r4, 0x9]
- cmp r6, 0x3
- beq _08054C3C
- ldrb r2, [r4, 0x5]
- mov r8, r2
- b _08054C3C
-_08054C38:
- ldrb r0, [r4, 0x4]
-_08054C3A:
- strb r0, [r4, 0xB]
-_08054C3C:
- ldrb r0, [r4, 0xB]
- subs r0, 0x1
- strb r0, [r4, 0xB]
- ldr r0, [sp]
- cmp r0, 0
- bne _08054C4E
- subs r0, 0x1
- str r0, [sp]
- b _08054B48
-_08054C4E:
- movs r0, 0x2
- ldrb r1, [r4, 0x1D]
- ands r0, r1
- cmp r0, 0
- beq _08054CC6
- cmp r6, 0x3
- bgt _08054C8E
- movs r0, 0x8
- ldrb r2, [r4, 0x1]
- ands r0, r2
- cmp r0, 0
- beq _08054C8E
- ldr r0, =REG_SOUNDBIAS + 1
- ldrb r0, [r0]
- cmp r0, 0x3F
- bgt _08054C80
- ldr r0, [r4, 0x20]
- adds r0, 0x2
- ldr r1, =0x000007fc
- b _08054C8A
- .pool
-_08054C80:
- cmp r0, 0x7F
- bgt _08054C8E
- ldr r0, [r4, 0x20]
- adds r0, 0x1
- ldr r1, =0x000007fe
-_08054C8A:
- ands r0, r1
- str r0, [r4, 0x20]
-_08054C8E:
- cmp r6, 0x4
- beq _08054CA0
- ldr r0, [r4, 0x20]
- ldr r1, [sp, 0x10]
- strb r0, [r1]
- b _08054CAE
- .pool
-_08054CA0:
- ldr r2, [sp, 0x10]
- ldrb r0, [r2]
- movs r1, 0x8
- ands r1, r0
- ldr r0, [r4, 0x20]
- orrs r0, r1
- strb r0, [r2]
-_08054CAE:
- movs r0, 0xC0
- ldrb r1, [r4, 0x1A]
- ands r0, r1
- adds r1, r4, 0
- adds r1, 0x21
- ldrb r1, [r1]
- adds r0, r1, r0
- strb r0, [r4, 0x1A]
- movs r2, 0xFF
- ands r0, r2
- ldr r1, [sp, 0x14]
- strb r0, [r1]
-_08054CC6:
- movs r0, 0x1
- ldrb r2, [r4, 0x1D]
- ands r0, r2
- cmp r0, 0
- beq _08054D4C
- ldr r1, =REG_NR51
- ldrb r0, [r1]
- ldrb r2, [r4, 0x1C]
- bics r0, r2
- ldrb r2, [r4, 0x1B]
- orrs r0, r2
- strb r0, [r1]
- cmp r6, 0x3
- bne _08054D18
- ldr r0, =gCgb3Vol
- ldrb r1, [r4, 0x9]
- adds r0, r1, r0
- ldrb r0, [r0]
- ldr r2, [sp, 0xC]
- strb r0, [r2]
- movs r1, 0x80
- adds r0, r1, 0
- ldrb r2, [r4, 0x1A]
- ands r0, r2
- cmp r0, 0
- beq _08054D4C
- ldr r0, [sp, 0x8]
- strb r1, [r0]
- ldrb r0, [r4, 0x1A]
- ldr r1, [sp, 0x14]
- strb r0, [r1]
- movs r0, 0x7F
- ldrb r2, [r4, 0x1A]
- ands r0, r2
- strb r0, [r4, 0x1A]
- b _08054D4C
- .pool
-_08054D18:
- movs r0, 0xF
- mov r1, r8
- ands r1, r0
- mov r8, r1
- ldrb r2, [r4, 0x9]
- lsls r0, r2, 4
- add r0, r8
- ldr r1, [sp, 0xC]
- strb r0, [r1]
- movs r2, 0x80
- ldrb r0, [r4, 0x1A]
- orrs r0, r2
- ldr r1, [sp, 0x14]
- strb r0, [r1]
- cmp r6, 0x1
- bne _08054D4C
- ldr r0, [sp, 0x8]
- ldrb r1, [r0]
- movs r0, 0x8
- ands r0, r1
- cmp r0, 0
- bne _08054D4C
- ldrb r0, [r4, 0x1A]
- orrs r0, r2
- ldr r1, [sp, 0x14]
- strb r0, [r1]
-_08054D4C:
- movs r0, 0
- strb r0, [r4, 0x1D]
-_08054D50:
- mov r6, r10
- mov r4, r9
- cmp r6, 0x4
- bgt _08054D5A
- b _08054950
-_08054D5A:
- add sp, 0x1C
- pop {r3-r5}
- mov r8, r3
- mov r9, r4
- mov r10, r5
- pop {r4-r7}
- pop {r0}
- bx r0
- thumb_func_end CgbSound
-
- .align 2, 0 @ Don't pad with nop.
diff --git a/common_syms/m4a.txt b/common_syms/m4a.txt
new file mode 100644
index 0000000..7fb31f6
--- /dev/null
+++ b/common_syms/m4a.txt
@@ -0,0 +1,11 @@
+gSoundInfo
+gPokemonCrySongs
+gPokemonCryMusicPlayers
+gMPlayJumpTable
+gCgbChans
+gPokemonCryTracks
+gPokemonCrySong
+gMPlayInfo_BGM
+gMPlayInfo_SE1
+gMPlayInfo_SE2
+gMPlayMemAccArea \ No newline at end of file
diff --git a/graphics/intro/copyright.pal b/graphics/intro/copyright.pal
index e9172c2..e1d2963 100644
--- a/graphics/intro/copyright.pal
+++ b/graphics/intro/copyright.pal
@@ -1,259 +1,259 @@
-JASC-PAL
-0100
-256
-224 248 224
-248 248 248
-192 192 192
-128 128 128
-64 64 64
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
+JASC-PAL
+0100
+256
+224 248 224
+248 248 248
+192 192 192
+128 128 128
+64 64 64
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
diff --git a/include/functions.h b/include/functions.h
new file mode 100644
index 0000000..89b93dc
--- /dev/null
+++ b/include/functions.h
@@ -0,0 +1,845 @@
+#ifndef GUARD_FUNCTIONS_H
+#define GUARD_FUNCTIONS_H
+
+// Place all external function declarations in this file
+
+// src/gbplayer.c
+
+void InitGameBoyPlayer(void);
+void sub_10C0(void);
+void sub_111C(void);
+int sub_1170(void);
+void sub_1198(void);
+void sub_11B0(int arg0);
+void sub_11E4(int arg0);
+void sub_11F0(int arg0);
+void sub_11FC(void);
+void sub_1340(void);
+
+// src/main.c
+
+void AgbMain(void);
+void sub_9BC_Main(void);
+void HBlankIntr(void);
+void VCountIntr(void);
+void SerialIntr(void);
+void Timer3Intr(void);
+void IntrDummy(void);
+u32 Random(void);
+s16 sub_C24(u16 arg0);
+s16 sub_C24(u16 arg0);
+s16 sub_C74(u16 arg0);
+void sub_CBC(void);
+void sub_D10(void);
+void sub_D74(void);
+void sub_DC4(void);
+
+// src/rom_3219C.c
+
+void sub_3219C(void);
+void sub_3219C(void);
+
+// src/rom_850.c
+
+u16 sub_850(void);
+void sub_898(void (*func)(void));
+void sub_8BC(void);
+void sub_8D4(void (*func)(void));
+void sub_8FC(void);
+void sub_918(void (*func)(void));
+void sub_940(void);
+
+// src/titlescreen.c
+
+void TitlescreenMain(void);
+void LoadTitlescreenGraphics(void);
+void sub_10AC0(void);
+void sub_10BB8(void);
+void sub_10CF0(void);
+void sub_10D84(void);
+void sub_10E00(void);
+void sub_10EF4(void);
+void sub_11020(void);
+void sub_110FC(void);
+void sub_11228(void);
+void sub_11320(void);
+void sub_11428(void);
+void sub_114B4(void);
+
+// src/util.c
+
+void SetMainGameState(u16 mainState);
+void sub_24C(void);
+void sub_2B4(void);
+s16 LoadSpriteSets(const struct SpriteSet *const *spriteSets, u16 numSpriteSets, struct SpriteGroup *spriteGroups);
+void sub_438(void);
+void sub_490(void);
+void sub_518(void);
+void sub_578(void);
+void sub_678(u8 *arg0, s16 arg1, s16 arg2);
+void SetMatrixScale(s16 xScale, s16 yScale, s16 matrixNum);
+
+// asm/bonus_field_select.s
+
+//extern ? BonusFieldSelectMain();
+//extern ? sub_25C4();
+//extern ? sub_2710();
+//extern ? sub_2768();
+//extern ? sub_2990();
+//extern ? sub_29C8();
+
+// asm/ereader.s
+
+//extern ? EReaderMain();
+//extern ? sub_2C78();
+//extern ? sub_2DF0();
+//extern ? sub_2E40();
+//extern ? sub_2FC0();
+//extern ? sub_304C();
+//extern ? sub_3208();
+//extern ? sub_33A0();
+//extern ? sub_343C();
+//extern ? sub_35C8();
+//extern ? sub_374C();
+//extern ? sub_377C();
+//extern ? sub_37B4();
+//extern ? sub_3828();
+//extern ? sub_38A0();
+//extern ? sub_38F0();
+//extern ? sub_394C();
+//extern ? sub_3AB4();
+//extern ? sub_3C1C();
+//extern ? sub_3C78();
+//extern ? sub_3CD8();
+
+// asm/field_select.s
+
+//extern ? FieldSelectMain();
+//extern ? LoadFieldSelectGraphics();
+//extern ? sub_8C38();
+//extern ? sub_8C7C();
+//extern ? sub_8F64();
+//extern ? sub_8F94();
+
+// asm/high_scores.s
+
+//extern ? HighScoresMain();
+//extern ? IdleHighScoresMain();
+//extern ? sub_CE88();
+//extern ? sub_CFD4();
+//extern ? sub_D20C();
+//extern ? sub_D308();
+//extern ? sub_D4B8();
+//extern ? sub_D664();
+//extern ? sub_D9F8();
+//extern ? sub_DA20();
+//extern ? sub_DB4C();
+//extern ? sub_DB70();
+//extern ? sub_DBF4();
+//extern ? sub_DCF0();
+//extern ? sub_DD4C();
+//extern ? sub_DD70();
+//extern ? sub_DEB4();
+//extern ? sub_DF68();
+//extern ? sub_E0C4();
+//extern ? sub_E0EC();
+//extern ? sub_E230();
+//extern ? sub_E390();
+//extern ? sub_E3A8();
+//extern ? sub_E464();
+//extern ? sub_E860();
+//extern ? sub_E908();
+//extern ? sub_E94C();
+//extern ? sub_E970();
+//extern ? sub_E994();
+//extern ? sub_EAC0();
+//extern ? sub_EBEC();
+//extern ? sub_ED28();
+//extern ? sub_EE64();
+//extern ? sub_F21C();
+//extern ? sub_F3BC();
+//extern ? sub_F3DC();
+//extern ? sub_F434();
+//extern ? sub_F4FC();
+//extern ? sub_F670();
+//extern ? sub_F6E0();
+//extern ? sub_F74C();
+//extern ? sub_F8B0();
+//extern ? sub_FAE8();
+//extern ? sub_FD20();
+extern void sub_FD5C(void (*func)(void));
+extern void sub_FE04(void (*func)(void));
+//extern ? sub_FEB8();
+//extern ? sub_FF74();
+//extern ? sub_1001C();
+//extern ? sub_10170();
+//extern ? sub_102A8();
+//extern ? sub_10424();
+//extern ? sub_10480();
+//extern ? sub_1050C();
+//extern ? sub_10528();
+//extern ? sub_10544();
+//extern ? sub_105A0();
+//extern ? sub_10618();
+
+// asm/intro.s
+
+//extern ? IntroMain();
+//extern ? sub_929C();
+//extern ? sub_9348();
+//extern ? sub_9370();
+//extern ? sub_938C();
+//extern ? sub_93D0();
+//extern ? sub_93F8();
+//extern ? sub_9498();
+//extern ? sub_96A8();
+//extern ? sub_978C();
+//extern ? sub_9830();
+//extern ? sub_9878();
+//extern ? sub_98B4();
+//extern ? sub_9920();
+//extern ? sub_999C();
+//extern ? sub_9AB8();
+//extern ? nullsub_4();
+//extern ? sub_9C10();
+//extern ? nullsub_5();
+//extern ? nullsub_17();
+//extern ? sub_9C9C();
+//extern ? sub_9CB8();
+//extern ? sub_9D70();
+//extern ? sub_9E90();
+//extern ? sub_A154();
+//extern ? sub_A16C();
+//extern ? sub_A2A8();
+//extern ? nullsub_6();
+//extern ? sub_A2F0();
+//extern ? nullsub_7();
+//extern ? sub_A39C();
+//extern ? sub_A43C();
+//extern ? sub_A454();
+//extern ? sub_A628();
+//extern ? sub_A674();
+//extern ? sub_A710();
+//extern ? nullsub_8();
+//extern ? sub_A860();
+//extern ? sub_A87C();
+//extern ? sub_A950();
+//extern ? sub_A968();
+//extern ? sub_AAA8();
+//extern ? nullsub_9();
+//extern ? sub_AAF4();
+//extern ? nullsub_10();
+//extern ? sub_AB90();
+//extern ? sub_AC20();
+//extern ? sub_AC38();
+//extern ? sub_ADFC();
+//extern ? sub_AE74();
+//extern ? sub_AF80();
+//extern ? nullsub_11();
+//extern ? sub_B090();
+//extern ? sub_B0E8();
+//extern ? sub_B2E0();
+//extern ? sub_B2F8();
+//extern ? sub_B4A0();
+//extern ? sub_B560();
+//extern ? sub_B6C4();
+//extern ? sub_B7A0();
+//extern ? sub_B7F8();
+//extern ? sub_BA2C();
+//extern ? sub_BA3C();
+//extern ? sub_BBE0();
+//extern ? sub_BC54();
+//extern ? sub_BCE8();
+//extern ? sub_BDC0();
+//extern ? sub_BED0();
+//extern ? sub_C018();
+//extern ? sub_C0BC();
+//extern ? sub_C0D8();
+//extern ? sub_C210();
+//extern ? sub_C228();
+//extern ? sub_C2F0();
+//extern ? sub_C38C();
+//extern ? sub_C3D0();
+//extern ? sub_C450();
+//extern ? nullsub_12();
+//extern ? nullsub_13();
+//extern ? sub_C498();
+//extern ? sub_C4F0();
+//extern ? sub_C814();
+//extern ? sub_C948();
+//extern ? sub_CA28();
+//extern ? sub_CAA0();
+//extern ? sub_CB6C();
+//extern ? sub_CBA4();
+//extern ? nullsub_14();
+//extern ? sub_CC94();
+//extern ? sub_CCF8();
+//extern ? sub_CD18();
+
+// asm/libagbsyscall.s
+
+//extern ? ArcTan2();
+//extern ? CpuSet();
+//extern ? LZ77UnCompWram();
+//extern ? RegisterRamReset();
+//extern ? Sqrt();
+//extern ? VBlankIntrWait();
+
+// asm/m4a_1.s
+
+//extern ? umul3232H32();
+//extern ? SoundMain();
+//extern ? SoundMainRAM();
+//extern ? SoundMainBTM();
+//extern ? RealClearChain();
+//extern ? ply_fine();
+//extern ? MPlayJumpTableCopy();
+//extern ? ld_r3_tp_adr_i();
+//extern ? ply_goto();
+//extern ? ply_patt();
+//extern ? ply_pend();
+//extern ? ply_rept();
+//extern ? ply_prio();
+//extern ? ply_tempo();
+//extern ? ply_keysh();
+//extern ? ply_voice();
+//extern ? ply_vol();
+//extern ? ply_pan();
+//extern ? ply_bend();
+//extern ? ply_bendr();
+//extern ? ply_lfodl();
+//extern ? ply_modt();
+//extern ? ply_tune();
+//extern ? ply_port();
+//extern ? m4aSoundVSync();
+//extern ? MPlayMain();
+//extern ? TrackStop();
+//extern ? ChnVolSetAsm();
+//extern ? ply_note();
+//extern ? ply_endtie();
+//extern ? clear_modM();
+//extern ? ld_r3_tp_adr_i();
+//extern ? ply_lfos();
+//extern ? ply_mod();
+
+// asm/m4a_3.s
+
+//extern ? CgbSound();
+
+// asm/options.s
+
+//extern ? OptionsMain();
+//extern ? sub_51240();
+//extern ? sub_513B8();
+//extern ? sub_514B8();
+//extern ? sub_51C3C();
+//extern ? sub_51C60();
+//extern ? sub_51C9C();
+//extern ? sub_524BC();
+//extern ? sub_52528();
+//extern ? sub_525CC();
+
+// asm/pokedex.s
+
+//extern ? PokedexMain();
+//extern ? sub_3DCC();
+//extern ? sub_3FAC();
+//extern ? sub_4150();
+//extern ? sub_43D4();
+//extern ? sub_4428();
+//extern ? sub_45A4();
+//extern ? sub_4860();
+//extern ? sub_49A8();
+//extern ? sub_49D0();
+//extern ? sub_4B10();
+//extern ? sub_4B34();
+//extern ? sub_4BB4();
+//extern ? sub_4C80();
+//extern ? sub_4D50();
+//extern ? sub_4D74();
+//extern ? sub_4E34();
+//extern ? sub_4EF0();
+//extern ? sub_4F50();
+//extern ? sub_4FC8();
+//extern ? sub_5064();
+//extern ? sub_5134();
+//extern ? sub_5174();
+//extern ? sub_51CC();
+//extern ? sub_51FC();
+//extern ? sub_599C();
+//extern ? sub_5E60();
+//extern ? sub_5EA4();
+//extern ? sub_5EC8();
+//extern ? sub_5EEC();
+//extern ? sub_6144();
+//extern ? sub_639C();
+//extern ? sub_65DC();
+//extern ? sub_681C();
+//extern ? sub_6BEC();
+//extern ? sub_6CA0();
+//extern ? sub_6F30();
+//extern ? sub_6F78();
+//extern ? sub_70E0();
+//extern ? sub_71DC();
+//extern ? sub_88E4();
+//extern ? sub_8974();
+//extern ? sub_8A78();
+//extern ? sub_8ABC();
+
+// asm/rom_1068C.s
+
+//extern ? sub_1068C();
+extern void sub_10708(void*, void*, u16, s16);
+//extern ? sub_10750();
+//extern ? sub_10798();
+//extern ? sub_10860();
+extern void sub_1090C(void);
+
+// asm/rom_11B9C.s
+
+//extern ? sub_11B9C();
+//extern ? sub_11C14();
+//extern ? sub_11C98();
+//extern ? sub_11F88();
+//extern ? sub_12524();
+//extern ? sub_12BF8();
+//extern ? sub_1332C();
+//extern ? sub_1333C();
+//extern ? sub_13824();
+//extern ? sub_13934();
+//extern ? sub_13B28();
+//extern ? sub_13D24();
+//extern ? sub_14074();
+//extern ? sub_14488();
+//extern ? sub_1467C();
+//extern ? sub_14740();
+//extern ? sub_1493C();
+//extern ? sub_14AF4();
+//extern ? sub_14B84();
+//extern ? sub_14E08();
+//extern ? sub_15054();
+//extern ? sub_153CC();
+//extern ? sub_16090();
+//extern ? sub_162B8();
+//extern ? sub_1642C();
+//extern ? sub_171C8();
+//extern ? sub_173FC();
+//extern ? sub_17634();
+//extern ? sub_176B0();
+//extern ? sub_17898();
+//extern ? sub_179D0();
+//extern ? sub_17C1C();
+//extern ? sub_17F28();
+//extern ? sub_18180();
+//extern ? sub_182B4();
+//extern ? sub_18324();
+//extern ? sub_1857C();
+//extern ? sub_18784();
+//extern ? sub_187F4();
+//extern ? sub_18A4C();
+//extern ? sub_18AE0();
+//extern ? sub_18B50();
+//extern ? sub_18DAC();
+//extern ? sub_18F38();
+//extern ? IdlePinballGameMain();
+//extern ? sub_19048();
+//extern ? sub_19190();
+//extern ? sub_19288();
+//extern ? sub_19304();
+//extern ? sub_1931C();
+//extern ? sub_19490();
+//extern ? sub_195C4();
+//extern ? sub_19734();
+//extern ? sub_19894();
+//extern ? sub_19A20();
+//extern ? sub_19B10();
+//extern ? sub_19B64();
+//extern ? sub_19B90();
+//extern ? sub_19C04();
+//extern ? sub_19CC8();
+//extern ? sub_19D04();
+//extern ? sub_19E10();
+//extern ? sub_19F70();
+//extern ? sub_19FA0();
+//extern ? sub_1A0F4();
+//extern ? sub_1A2C0();
+//extern ? sub_1A98C();
+//extern ? sub_1A9E8();
+//extern ? sub_1AA38();
+//extern ? sub_1AAA0();
+//extern ? sub_1AD84();
+//extern ? sub_1ADF4();
+//extern ? sub_1AF84();
+//extern ? sub_1AFD4();
+//extern ? sub_1B140();
+//extern ? sub_1BB68();
+//extern ? sub_1C544();
+//extern ? sub_1C560();
+//extern ? sub_1C5AC();
+//extern ? sub_1C73C();
+//extern ? sub_1C7F4();
+//extern ? sub_1D128();
+//extern ? sub_1D4D0();
+//extern ? sub_1D5D8();
+//extern ? sub_1DA74();
+//extern ? sub_1DAD8();
+//extern ? sub_1DC7C();
+//extern ? sub_1DDDC();
+//extern ? sub_1EC48();
+//extern ? sub_1F158();
+//extern ? sub_1F2A4();
+//extern ? sub_1F59C();
+//extern ? sub_1F698();
+//extern ? sub_1FA48();
+//extern ? sub_1FBC4();
+//extern ? sub_1FF0C();
+//extern ? sub_201B8();
+//extern ? sub_203CC();
+//extern ? sub_20EC0();
+//extern ? sub_21238();
+//extern ? sub_21300();
+//extern ? sub_21320();
+//extern ? sub_21514();
+//extern ? sub_21578();
+//extern ? sub_216FC();
+//extern ? sub_219A8();
+//extern ? sub_219EC();
+//extern ? sub_21B0C();
+//extern ? sub_21D78();
+//extern ? sub_21FBC();
+//extern ? sub_225F0();
+//extern ? sub_22978();
+//extern ? sub_22A30();
+//extern ? sub_22C6C();
+//extern ? sub_22D54();
+//extern ? sub_22FA4();
+//extern ? sub_23070();
+//extern ? sub_2310C();
+//extern ? sub_2312C();
+//extern ? sub_23300();
+//extern ? sub_23954();
+//extern ? sub_239A4();
+//extern ? sub_23E18();
+//extern ? sub_242B4();
+//extern ? sub_24350();
+//extern ? sub_24408();
+//extern ? sub_2530C();
+//extern ? sub_253E0();
+//extern ? sub_25808();
+//extern ? sub_25F64();
+//extern ? sub_260B8();
+//extern ? sub_26778();
+//extern ? sub_26820();
+//extern ? sub_268CC();
+//extern ? sub_269A4();
+//extern ? sub_26A10();
+//extern ? sub_26EA4();
+//extern ? sub_26F38();
+//extern ? sub_27080();
+//extern ? sub_278F4();
+//extern ? sub_27D44();
+//extern ? sub_27E08();
+//extern ? sub_27F94();
+//extern ? sub_28404();
+//extern ? sub_28544();
+//extern ? sub_28AE0();
+//extern ? sub_28BFC();
+//extern ? sub_28C90();
+//extern ? sub_28E2C();
+//extern ? sub_28EA0();
+//extern ? sub_292A0();
+//extern ? sub_29334();
+//extern ? sub_293D8();
+//extern ? sub_29624();
+//extern ? sub_29664();
+//extern ? sub_2971C();
+//extern ? sub_29924();
+//extern ? sub_29A6C();
+//extern ? sub_29D9C();
+//extern ? sub_2A054();
+//extern ? sub_2A354();
+//extern ? sub_2AADC();
+//extern ? sub_2C518();
+//extern ? sub_2C538();
+//extern ? sub_2C9A4();
+//extern ? sub_2CA9C();
+//extern ? sub_2CD98();
+//extern ? sub_2CE80();
+//extern ? sub_2D104();
+//extern ? sub_2D204();
+//extern ? sub_2DE54();
+//extern ? sub_2E094();
+//extern ? sub_2E67C();
+//extern ? sub_2E6AC();
+//extern ? sub_2F140();
+//extern ? sub_2F26C();
+//extern ? sub_2F504();
+//extern ? sub_2F79C();
+//extern ? sub_2FCD0();
+//extern ? sub_300D8();
+//extern ? sub_30178();
+//extern ? sub_30480();
+//extern ? sub_304C8();
+//extern ? sub_308DC();
+//extern ? sub_30EB4();
+//extern ? sub_31144();
+//extern ? sub_313A0();
+//extern ? sub_31498();
+//extern ? sub_31B30();
+//extern ? sub_31BE8();
+//extern ? sub_31CF8();
+//extern ? sub_31F6C();
+
+// asm/rom_3219C.s
+
+//extern ? sub_32484();
+//extern ? sub_325E0();
+//extern ? sub_326F4();
+//extern ? sub_3276C();
+//extern ? sub_327C0();
+//extern ? sub_328C8();
+//extern ? sub_32914();
+//extern ? sub_32968();
+//extern ? sub_329B0();
+//extern ? sub_329F4();
+//extern ? sub_32B74();
+//extern ? sub_32BE4();
+//extern ? sub_32DF8();
+//extern ? sub_32F3C();
+//extern ? sub_33130();
+//extern ? sub_3342C();
+//extern ? sub_336E0();
+//extern ? sub_340EC();
+//extern ? sub_34450();
+//extern ? sub_350F0();
+//extern ? sub_351A8();
+//extern ? sub_356A0();
+//extern ? sub_357B8();
+//extern ? sub_35860();
+//extern ? sub_35AA4();
+//extern ? sub_35D54();
+//extern ? sub_36CB4();
+//extern ? sub_372B4();
+//extern ? sub_3751C();
+//extern ? sub_37850();
+//extern ? sub_38218();
+//extern ? sub_383E4();
+//extern ? sub_3869C();
+//extern ? sub_38A20();
+//extern ? sub_395D8();
+//extern ? sub_39A40();
+//extern ? sub_3A150();
+//extern ? sub_3ADA0();
+//extern ? sub_3AE14();
+//extern ? sub_3B120();
+//extern ? sub_3B49C();
+//extern ? sub_3B7C4();
+//extern ? sub_3C6E0();
+//extern ? sub_3CBC4();
+//extern ? sub_3E5D0();
+//extern ? sub_3E644();
+//extern ? sub_3E79C();
+//extern ? sub_3EB2C();
+//extern ? sub_3EDF0();
+//extern ? sub_3FAE0();
+//extern ? sub_40288();
+//extern ? sub_41580();
+//extern ? sub_417F8();
+//extern ? sub_423D8();
+//extern ? sub_42E48();
+//extern ? sub_43228();
+//extern ? sub_43500();
+//extern ? sub_4387C();
+//extern ? sub_44D58();
+//extern ? sub_44F3C();
+//extern ? sub_45164();
+//extern ? sub_455D0();
+//extern ? sub_45E08();
+//extern ? sub_45E90();
+//extern ? sub_467F4();
+//extern ? sub_46FD4();
+//extern ? sub_47030();
+//extern ? sub_47100();
+//extern ? sub_47110();
+//extern ? sub_47160();
+//extern ? sub_472E4();
+//extern ? sub_47344();
+//extern ? sub_474F4();
+//extern ? sub_47670();
+//extern ? sub_478D8();
+//extern ? sub_47FBC();
+//extern ? sub_47FF8();
+//extern ? sub_48124();
+//extern ? sub_48190();
+//extern ? sub_495A0();
+//extern ? sub_497BC();
+//extern ? sub_49850();
+//extern ? sub_49A34();
+//extern ? PinballGameMain();
+//extern ? sub_49ED4();
+//extern ? sub_4A270();
+//extern ? sub_4A518();
+//extern ? sub_4A6A0();
+//extern ? sub_4A90C();
+//extern ? sub_4AAD8();
+//extern ? sub_4ABC8();
+//extern ? sub_4ABEC();
+//extern ? sub_4ACF0();
+//extern ? sub_4AE8C();
+//extern ? sub_4B000();
+//extern ? sub_4B20C();
+//extern ? nullsub_19();
+//extern ? sub_4B280();
+//extern ? sub_4B334();
+//extern ? sub_4B408();
+//extern ? sub_4B654();
+//extern ? sub_4B678();
+//extern ? sub_4BC34();
+//extern ? sub_4C290();
+//extern ? sub_4C808();
+//extern ? sub_4CA18();
+//extern ? sub_4CAE8();
+//extern ? sub_4CB0C();
+//extern ? sub_4CB30();
+//extern ? sub_4CBB4();
+//extern ? sub_4CC58();
+//extern ? sub_4CD60();
+//extern ? nullsub_18();
+//extern ? sub_4CEA8();
+//extern ? sub_4CEB4();
+//extern ? sub_4D3D0();
+//extern ? sub_4D648();
+//extern ? sub_4D6C4();
+//extern ? sub_4D960();
+//extern ? sub_4DBFC();
+//extern ? sub_4DFA0();
+//extern ? sub_4E2F8();
+//extern ? sub_4E468();
+//extern ? sub_4E598();
+//extern ? sub_4E814();
+//extern ? sub_4E920();
+//extern ? sub_4E9F0();
+//extern ? sub_4EA44();
+//extern ? sub_4EAB0();
+//extern ? sub_4EAF8();
+//extern ? sub_4EBD0();
+//extern ? sub_4ECDC();
+//extern ? sub_4EDC0();
+//extern ? sub_4EE74();
+//extern ? sub_4EF38();
+//extern ? sub_4F028();
+//extern ? sub_4F0F0();
+//extern ? sub_4F258();
+//extern ? sub_4F2B8();
+//extern ? sub_4F30C();
+//extern ? sub_4F4B4();
+//extern ? sub_4F660();
+//extern ? sub_4F814();
+//extern ? sub_4F95C();
+//extern ? sub_4F9F0();
+//extern ? sub_4FAC0();
+//extern ? sub_4FB08();
+//extern ? sub_4FBA4();
+//extern ? sub_4FC7C();
+//extern ? sub_4FD88();
+//extern ? sub_4FE6C();
+//extern ? sub_50000();
+//extern ? sub_500B4();
+//extern ? sub_50154();
+//extern ? sub_5030C();
+//extern ? sub_504C0();
+//extern ? sub_505A4();
+//extern ? sub_506B0();
+//extern ? sub_50710();
+//extern ? sub_507D4();
+//extern ? sub_50848();
+//extern ? sub_50918();
+//extern ? sub_50AD4();
+//extern ? sub_50B80();
+//extern ? sub_50D48();
+//extern ? sub_50DB8();
+//extern ? sub_50DE0();
+//extern ? nullsub_20();
+//extern ? sub_50F04();
+//extern ? sub_50FAC();
+//extern ? sub_50FD4();
+//extern ? sub_51068();
+//extern ? sub_51090();
+//extern ? sub_51128();
+//extern ? sub_51150();
+//extern ? sub_511F8();
+
+// asm/rom_528AC.s
+
+//extern ? sub_528AC();
+//extern ? sub_528DC();
+//extern ? sub_5291C();
+//extern ? sub_52940();
+extern void sub_52A18(void);
+//extern ? sub_52A68();
+//extern ? sub_52B30();
+//extern ? sub_52BB0();
+extern void sub_52C44(void);
+//extern ? sub_52C64();
+
+// asm/rom_9BC.s
+
+extern void sub_13FC(void);
+//extern ? sub_1668();
+//extern ? sub_16A0();
+//extern ? sub_170C();
+//extern ? sub_1748();
+//extern ? sub_17D8();
+extern void sub_1828(void);
+//extern ? sub_1884();
+//extern ? sub_19B4();
+//extern ? sub_19CC();
+//extern ? sub_1A78();
+//extern ? nullsub_15();
+//extern ? sub_1AA4();
+//extern ? sub_1B04();
+//extern ? sub_1C5C();
+//extern ? sub_1C84();
+//extern ? sub_1CD4();
+//extern ? sub_1DB8();
+//extern ? sub_1EC0();
+extern void sub_1F4C(void);
+extern void sub_1F5C(void);
+//extern ? sub_1FEC();
+//extern ? sub_1FFC();
+//extern ? sub_20FC();
+//extern ? sub_223C();
+//extern ? sub_2308();
+//extern ? sub_2338();
+//extern ? sub_2364();
+//extern ? sub_23B4();
+//extern ? sub_2414();
+//extern ? nullsub_16();
+//extern ? sub_24DC();
+//extern ? sub_250C();
+//extern ? sub_2538();
+//extern ? sub_2568();
+
+// asm/start.s
+
+
+// asm/titlescreen.s
+
+//extern ? sub_11640();
+extern void sub_1175C(void);
+extern void sub_11968(void);
+extern void sub_11B74(void);
+
+// asm/unknown_lib_2.s
+
+extern int sub_55A24(u8*); // Rumble Pak?
+
+// asm/unknown_lib.s
+
+//extern ? sub_554F0();
+//extern ? sub_55530();
+//extern ? sub_55570();
+//extern ? sub_555BC();
+//extern ? sub_55654();
+
+#endif // GUARD_FUNCTIONS_H \ No newline at end of file
diff --git a/include/gba/m4a_internal.h b/include/gba/m4a_internal.h
index 339a077..0bd6ed7 100755
--- a/include/gba/m4a_internal.h
+++ b/include/gba/m4a_internal.h
@@ -100,7 +100,7 @@ struct CgbChannel
u8 le;
u8 sw;
u32 fr;
- u32 wp;
+ u32 *wp;
u32 cp;
u32 tp;
u32 pp;
diff --git a/include/global.h b/include/global.h
index 16b8e51..2a9b072 100755
--- a/include/global.h
+++ b/include/global.h
@@ -4,6 +4,13 @@
#include <string.h>
#include "gba/gba.h"
+#define NUM_SPRITE_GROUPS 100
+#define MAX_SPRITES_IN_GROUP 22
+
+#include "types.h"
+#include "functions.h"
+#include "variables.h"
+
// Prevent cross-jump optimization.
#define BLOCK_CROSS_JUMP asm("");
diff --git a/include/m4a.h b/include/m4a.h
index 1a68f8c..4e6c236 100755
--- a/include/m4a.h
+++ b/include/m4a.h
@@ -8,8 +8,8 @@ void m4aSoundVSyncOn(void);
void m4aSoundInit(void);
void m4aSoundMain(void);
-void m4aSongNumStart(u16);
-void m4aSongNumStop(u16 n);
+void m4aSongNumStart(u16 n);
+void m4aSongNumStartOrChange(u16 n);
void m4aMPlayAllStop(void);
void m4aMPlayContinue(struct MusicPlayerInfo *mplayInfo);
void m4aMPlayVolumeControl(struct MusicPlayerInfo *mplayInfo, u16 trackBits, u16 volume);
@@ -18,7 +18,9 @@ void m4aMPlayFadeOutTemporarily(struct MusicPlayerInfo *mplayInfo, u16 speed);
void m4aMPlayFadeIn(struct MusicPlayerInfo *mplayInfo, u16 speed);
void m4aMPlayImmInit(struct MusicPlayerInfo *mplayInfo);
-extern struct MusicPlayerInfo gMPlayInfo_02032EE0;
+extern struct MusicPlayerInfo gMPlayInfo_BGM;
+extern struct MusicPlayerInfo gMPlayInfo_SE1;
+extern struct MusicPlayerInfo gMPlayInfo_SE2;
extern struct SoundInfo gSoundInfo;
#endif //GUARD_M4A_H
diff --git a/include/main.h b/include/main.h
index df03d5d..4b97e5e 100755
--- a/include/main.h
+++ b/include/main.h
@@ -3,40 +3,6 @@
#include "global.h"
-#define NUM_SPRITE_GROUPS 100
-#define MAX_SPRITES_IN_GROUP 22
-
-typedef void (*StateFunc)(void);
-typedef void (*IntrFunc)(void);
-
-struct MainUnk2E8
-{
- u16 unk0;
- u16 unk2;
-};
-
-struct SpriteSet
-{
- u16 count;
- u8 oamData[0];
-};
-
-struct OamDataSimple
-{
- u16 oamId;
- s16 xOffset;
- s16 yOffset;
-};
-
-struct SpriteGroup
-{
- u16 available;
- s16 baseX;
- s16 baseY;
- struct OamDataSimple oam[MAX_SPRITES_IN_GROUP];
-};
-// size: 0xB8
-
struct Main
{
/*0x00*/ u8 filler0[0x2];
@@ -115,18 +81,20 @@ extern StateFunc gMainFuncs[];
extern struct OamData gOamBuffer[128];
extern u16 gUnknown_03005C00[0x600];
-void SetMainGameState(u16);
void sub_24C(void);
void sub_2B4(void);
void sub_490(void);
void sub_518(void);
void sub_578(void);
u32 Random(void);
+void HBlankIntr(void);
+void VCountIntr(void);
+void SerialIntr(void);
+void Timer3Intr(void);
void sub_CBC(void);
void sub_D10(void);
void sub_D74(void);
-void SerialIntr(void);
-void Timer3Intr(void);
-s16 LoadSpriteSets(const struct SpriteSet* const*, u16, struct SpriteGroup*);
+void sub_DC4(void);
+
#endif // GUARD_MAIN_H
diff --git a/include/types.h b/include/types.h
new file mode 100644
index 0000000..af7a749
--- /dev/null
+++ b/include/types.h
@@ -0,0 +1,37 @@
+#ifndef GUARD_TYPES_H
+#define GUARD_TYPES_H
+
+// Place all discovered types (structs, unions, etc.) in this file.
+
+typedef void (*StateFunc)(void);
+typedef void (*IntrFunc)(void);
+
+struct MainUnk2E8
+{
+ u16 unk0;
+ u16 unk2;
+};
+
+struct SpriteSet
+{
+ u16 count;
+ u8 oamData[0];
+};
+
+struct OamDataSimple
+{
+ u16 oamId;
+ s16 xOffset;
+ s16 yOffset;
+};
+
+struct SpriteGroup
+{
+ u16 available;
+ s16 baseX;
+ s16 baseY;
+ struct OamDataSimple oam[MAX_SPRITES_IN_GROUP];
+};
+// size: 0xB8
+
+#endif // GUARD_TYPES_H
diff --git a/include/variables.h b/include/variables.h
new file mode 100644
index 0000000..6a74cb7
--- /dev/null
+++ b/include/variables.h
@@ -0,0 +1,167 @@
+#ifndef GUARD_VARIABLES_H
+#define GUARD_VARIABLES_H
+
+// Place all external variable declarations in this file
+
+extern u8 gUnknown_03000000[];
+//extern ? gOamBuffer;
+//extern ? IntrMain_Buffer;
+//extern ? gUnknown_03005C00;
+//extern ? SoundMainRAM_Buffer;
+extern u16 sGbPlayerCurKeys;
+extern u16 sGbPlayerPrevKeys;
+//extern ? gUnknown_02002008;
+extern u8 gUnknown_02002808[];
+//extern ? gTitlescreen;
+//extern ? gEraseSaveDataAccessStep;
+//extern ? gEraseSaveDataAccessCounter;
+//extern ? gEReaderAccessStep;
+//extern ? gEReaderAccessCounter;
+//extern ? gUnknown_020028A4;
+//extern ? gUnknown_020028A5;
+//extern ? gUnknown_02002958;
+//extern ? gIntrTable;
+//extern ? gMain;
+//extern ? gUnknown_0200B134;
+//extern ? gUnknown_0200B3B8;
+//extern ? gUnknown_0200FB98;
+//extern ? gUnknown_0200FB9C;
+//extern ? gUnknown_0200FBA0;
+//extern ? gUnknown_02017BD0;
+//extern ? gUnknown_02017BD4;
+//extern ? gUnknown_02017BE0;
+//extern ? gUnknown_02019BE0;
+//extern ? gUnknown_02019BE4;
+//extern ? gUnknown_02019BE8;
+//extern ? gUnknown_02019BEC;
+//extern ? gUnknown_02019BF0;
+//extern ? gUnknown_02019BF4;
+//extern ? gUnknown_02019BF8;
+//extern ? gUnknown_02019BFC;
+//extern ? gUnknown_02019C00;
+//extern ? gUnknown_02019C04;
+//extern ? gUnknown_02019C08;
+//extern ? gGameBoyPlayerEnabled;
+//extern ? gUnknown_02019C10;
+//extern ? gAutoDisplayTitlescreenMenu;
+//extern ? gUnknown_0201C190;
+//extern ? gUnknown_0202BE00;
+//extern ? gUnknown_202BE24;
+//extern ? gUnknown_0202C588;
+//extern ? gUnknown_020314E0;
+//extern ? gUnknown_02031520;
+//extern ? gSoundInfo;
+//extern ? gPokemonCryMusicPlayers;
+//extern ? gMPlayJumpTable;
+//extern ? gCgbChans;
+//extern ? gPokemonCryTracks;
+//extern ? gPokemonCrySong;
+//extern ? gMPlayInfo_BGM;
+//extern ? gMPlayMemAccArea;
+extern const u16 gWildMonLocations[][2][8];
+extern const s16 gUnknown_08055C44[];
+extern const struct OamData gEmptyOamData[128];
+extern const u8 gUnknown_08058048[];
+extern const u8 gUnknown_08058248[];
+extern const u8 gUnknown_0805C248[];
+extern StateFunc gTitlescreenStateFuncs[];
+//extern ? gIntroCopyright_Gfx;
+//extern ? gIntroCopyright_Pal;
+//extern ? gIntroScene1Sprites_Pals;
+//extern ? gIntroScene1Sprites_Gfx;
+extern const u8 gGBAButtonIcons_Pals[];
+extern const u8 gOptionsSprites_Gfx[];
+extern const IntrFunc gIntrTableTemplate[14];
+//extern ? gMainFuncs;
+//extern ? gUnknown_086A4B08;
+//extern ? gUnknown_086A4B14;
+//extern ? gUnknown_086A4B20;
+//extern ? gUnknown_086A4B30;
+//extern ? gUnknown_086A4B40;
+//extern ? gUnknown_086A4B54;
+//extern ? gUnknown_086A4B70;
+//extern ? gUnknown_086A4B80;
+//extern ? gUnknown_086A4B94;
+//extern ? gUnknown_086A4BAC;
+//extern ? gUnknown_086A4BC8;
+//extern ? gUnknown_086A4BE8;
+//extern ? gUnknown_086A4BFC;
+//extern ? gUnknown_086A4C18;
+//extern ? gUnknown_086A4C2C;
+extern const int *gUnknown_086A4C44[];
+extern const s16 gUnknown_086A964C[];
+extern const s8 gUnknown_086A9662[];
+extern const s8 gUnknown_086A9666[6][2];
+extern const s8 gUnknown_086A9672[9][2];
+extern const u16 gUnknown_086A96A4[];
+extern const u16 gUnknown_086A96D4[];
+extern const struct SpriteSet *const gUnknown_086A96E4[];
+extern const u8 *const gUnknown_086A96F8[7];
+extern const u8 *const gUnknown_086A9714[];
+extern const s8 gUnknown_086A9748[];
+extern const u8 *const gUnknown_086A975C[7];
+extern const u8 *const gUnknown_086A9778[];
+extern const s16 gEReaderAccessButtonSequence[];
+//extern ? gMonHatchSpriteGroupPals;
+//extern ? gMonPortraitGroupPals;
+//extern ? gMonHatchSpriteGroupGfx;
+//extern ? gMonPortraitGroupGfx;
+//extern ? gMonHatchSpriteGroup0_Gfx;
+//extern ? gMonHatchSpriteGroup1_Gfx;
+//extern ? gMonHatchSpriteGroup2_Gfx;
+//extern ? gMonHatchSpriteGroup3_Gfx;
+//extern ? gMonHatchSpriteGroup4_Gfx;
+//extern ? gMonHatchSpriteGroup5_Gfx;
+//extern ? gFieldSelectWindow_Gfx;
+//extern ? gUnknown_080A4000;
+//extern ? gFieldSelectFrameShadowTilemap;
+//extern ? gFieldSelectMiniFields_Gfx;
+//extern ? gUnknown_080A8020;
+//extern ? gFieldSelectWindowTilemap;
+//extern ? gFieldSelectBGPals;
+//extern ? gFieldSelectSpritePals;
+//extern ? gFieldSelectSpriteGfx;
+extern const u8 gTitlescreenBgTilemap[];
+extern const u16 gTitlescreenBg_Pals[];
+extern const u8 gTitlescreenBg_Gfx[];
+extern const u8 gTitlescreenSpritesNoSavedGame_Gfx[];
+//extern ? gUnknown_081306C0;
+extern const u8 gTitlescreenSpritesSavedGame_Gfx[];
+//extern ? gUnknown_081376E0;
+extern const u16 gTitlescreenSprites_Pals[];
+//extern ? gMonHatchSpriteGroup0_Pals;
+//extern ? gMonHatchSpriteGroup1_Pals;
+//extern ? gMonHatchSpriteGroup2_Pals;
+//extern ? gMonHatchSpriteGroup3_Pals;
+//extern ? gMonHatchSpriteGroup4_Pals;
+//extern ? gMonHatchSpriteGroup5_Pals;
+//extern ? gMonPortraitsGroup0_Gfx;
+//extern ? gMonPortraitsGroup1_Gfx;
+//extern ? gMonPortraitsGroup2_Gfx;
+//extern ? gMonPortraitsGroup3_Gfx;
+//extern ? gMonPortraitsGroup4_Gfx;
+//extern ? gMonPortraitsGroup5_Gfx;
+//extern ? gMonPortraitsGroup6_Gfx;
+//extern ? gMonPortraitsGroup7_Gfx;
+//extern ? gMonPortraitsGroup8_Gfx;
+//extern ? gMonPortraitsGroup9_Gfx;
+//extern ? gMonPortraitsGroup10_Gfx;
+//extern ? gMonPortraitsGroup11_Gfx;
+//extern ? gMonPortraitsGroup12_Gfx;
+//extern ? gMonPortraitsGroup13_Gfx;
+//extern ? gMonPortraitsGroup0_Pals;
+//extern ? gMonPortraitsGroup1_Pals;
+//extern ? gMonPortraitsGroup2_Pals;
+//extern ? gMonPortraitsGroup3_Pals;
+//extern ? gMonPortraitsGroup4_Pals;
+//extern ? gMonPortraitsGroup5_Pals;
+//extern ? gMonPortraitsGroup6_Pals;
+//extern ? gMonPortraitsGroup7_Pals;
+//extern ? gMonPortraitsGroup8_Pals;
+//extern ? gMonPortraitsGroup9_Pals;
+//extern ? gMonPortraitsGroup10_Pals;
+//extern ? gMonPortraitsGroup11_Pals;
+//extern ? gMonPortraitsGroup12_Pals;
+//extern ? gMonPortraitsGroup13_Pals;
+
+#endif // GUARD_VARIABLES_H \ No newline at end of file
diff --git a/ld_script.txt b/ld_script.txt
index f939164..c0a0e64 100755
--- a/ld_script.txt
+++ b/ld_script.txt
@@ -6,7 +6,8 @@ SECTIONS
ALIGN(4)
{
<EWRAM>
- . = 0x40000;
+ /* COMMON starts at ??? */
+<COMMON>
}
/* start of iwram */
@@ -14,11 +15,11 @@ SECTIONS
iwram (NOLOAD) :
ALIGN(4)
{
- /* .bss starts at 0x3000000 */
+ /* .bss starts at 0x3000000 */
<BSS>
+ /* .bss.code starts at 0x3007400 */
+ src/m4a.o(.bss.code);
- /* COMMON starts at ??? */
-<COMMON>
. = 0x8000;
}
@@ -47,9 +48,7 @@ SECTIONS
asm/options.o(.text);
asm/rom_528AC.o(.text);
asm/m4a_1.o(.text);
- src/m4a_2.o(.text);
- asm/m4a_3.o(.text);
- src/m4a_4.o(.text);
+ src/m4a.o(.text);
asm/libagbsyscall.o(.text);
asm/unknown_lib.o(.text);
*libgcc.a:_call_via_rX.o(.text);
diff --git a/src/gbplayer.c b/src/gbplayer.c
index 5e4ad19..00d30d5 100755
--- a/src/gbplayer.c
+++ b/src/gbplayer.c
@@ -2,18 +2,6 @@
#include "gbplayer.h"
#include "main.h"
-extern void sub_1340(void);
-extern void sub_13FC(void);
-extern void sub_1828(void);
-extern u8 gUnknown_02002808[];
-extern u16 sGbPlayerCurKeys;
-extern u16 sGbPlayerPrevKeys;
-extern const u8 gUnknown_08058048[];
-extern const u8 gUnknown_08058248[];
-extern const u8 gUnknown_0805C248[];
-
-extern const int *gUnknown_086A4C44[];
-
/*static*/ void ReadGbPlayerKeys(void)
{
u16 keyInput = REG_KEYINPUT ^ KEYS_MASK;
diff --git a/src/m4a.c b/src/m4a.c
new file mode 100755
index 0000000..2c70083
--- /dev/null
+++ b/src/m4a.c
@@ -0,0 +1,1791 @@
+#include <string.h>
+#include "gba/m4a_internal.h"
+
+extern const u8 gCgb3Vol[];
+
+#define BSS_CODE __attribute__((section(".bss.code")))
+
+asm(".set gScaleTable, 0x0852D928"); // TODO:
+asm(".set gFreqTable, 0x0852D9DC"); // TODO:
+asm(".set gMPlayTable, 0x08534DD4"); // TODO:
+asm(".set gPokemonCrySongTemplate, 0x0852DB40"); // TODO:
+asm(".set gSongTable, 0x08534E04"); // TODO:
+asm(".set gMaxLines, 0x3C"); // TODO:
+asm(".set gPcmSamplesPerVBlankTable, 0x0852DA0C"); // TODO:
+asm(".set gNoiseTable, 0x0852DAC0"); // TODO:
+asm(".set gCgbScaleTable, 0x0852DA24"); // TODO:
+asm(".set gCgbFreqTable, 0x0852DAA8"); // TODO:
+asm(".set gNumMusicPlayers, 0x4"); // TODO:
+asm(".set gCgb3Vol, 0x0852DAFC"); // TODO:
+asm(".set gXcmdTable, 0x0852DB74"); // TODO:
+
+BSS_CODE ALIGNED(4) char SoundMainRAM_Buffer[0x800] = {0};
+
+struct SoundInfo gSoundInfo;
+struct PokemonCrySong gPokemonCrySongs[MAX_POKEMON_CRIES];
+struct MusicPlayerInfo gPokemonCryMusicPlayers[MAX_POKEMON_CRIES];
+void *gMPlayJumpTable[36];
+struct CgbChannel gCgbChans[4];
+struct MusicPlayerTrack gPokemonCryTracks[MAX_POKEMON_CRIES * 2];
+struct PokemonCrySong gPokemonCrySong;
+struct MusicPlayerInfo gMPlayInfo_BGM;
+struct MusicPlayerInfo gMPlayInfo_SE1;
+struct MusicPlayerInfo gMPlayInfo_SE2;
+u8 gMPlayMemAccArea[0x10];
+
+u32 MidiKeyToFreq(struct WaveData *wav, u8 key, u8 fineAdjust)
+{
+ u32 val1;
+ u32 val2;
+ u32 fineAdjustShifted = fineAdjust << 24;
+
+ if (key > 178)
+ {
+ key = 178;
+ fineAdjustShifted = 255 << 24;
+ }
+
+ val1 = gScaleTable[key];
+ val1 = gFreqTable[val1 & 0xF] >> (val1 >> 4);
+
+ val2 = gScaleTable[key + 1];
+ val2 = gFreqTable[val2 & 0xF] >> (val2 >> 4);
+
+ return umul3232H32(wav->freq, val1 + umul3232H32(val2 - val1, fineAdjustShifted));
+}
+
+void UnusedDummyFunc(void)
+{
+}
+
+void MPlayContinue(struct MusicPlayerInfo *mplayInfo)
+{
+ if (mplayInfo->ident == ID_NUMBER)
+ {
+ mplayInfo->ident++;
+ mplayInfo->status &= ~MUSICPLAYER_STATUS_PAUSE;
+ mplayInfo->ident = ID_NUMBER;
+ }
+}
+
+void MPlayFadeOut(struct MusicPlayerInfo *mplayInfo, u16 speed)
+{
+ if (mplayInfo->ident == ID_NUMBER)
+ {
+ mplayInfo->ident++;
+ mplayInfo->fadeOC = speed;
+ mplayInfo->fadeOI = speed;
+ mplayInfo->fadeOV = (64 << FADE_VOL_SHIFT);
+ mplayInfo->ident = ID_NUMBER;
+ }
+}
+
+void m4aSoundInit(void)
+{
+ s32 i;
+
+ CpuCopy32((void *)((s32)SoundMainRAM & ~1), SoundMainRAM_Buffer, sizeof(SoundMainRAM_Buffer));
+
+ SoundInit(&gSoundInfo);
+ MPlayExtender(gCgbChans);
+ m4aSoundMode(SOUND_MODE_DA_BIT_8
+ | SOUND_MODE_FREQ_13379
+ | (14 << SOUND_MODE_MASVOL_SHIFT)
+ | (6 << SOUND_MODE_MAXCHN_SHIFT));
+
+ for (i = 0; i < NUM_MUSIC_PLAYERS; i++)
+ {
+ struct MusicPlayerInfo *mplayInfo = gMPlayTable[i].info;
+ MPlayOpen(mplayInfo, gMPlayTable[i].track, gMPlayTable[i].unk_8);
+ mplayInfo->unk_B = gMPlayTable[i].unk_A;
+ mplayInfo->memAccArea = gMPlayMemAccArea;
+ }
+
+ memcpy(&gPokemonCrySong, &gPokemonCrySongTemplate, sizeof(struct PokemonCrySong));
+
+ for (i = 0; i < MAX_POKEMON_CRIES; i++)
+ {
+ struct MusicPlayerInfo *mplayInfo = &gPokemonCryMusicPlayers[i];
+ struct MusicPlayerTrack *track = &gPokemonCryTracks[i * 2];
+ MPlayOpen(mplayInfo, track, 2);
+ track->chan = 0;
+ }
+}
+
+void m4aSoundMain(void)
+{
+ SoundMain();
+}
+
+void m4aSongNumStart(u16 n)
+{
+ const struct MusicPlayer *mplayTable = gMPlayTable;
+ const struct Song *songTable = gSongTable;
+ const struct Song *song = &songTable[n];
+ const struct MusicPlayer *mplay = &mplayTable[song->ms];
+
+ MPlayStart(mplay->info, song->header);
+}
+
+void m4aSongNumStartOrChange(u16 n)
+{
+ const struct MusicPlayer *mplayTable = gMPlayTable;
+ const struct Song *songTable = gSongTable;
+ const struct Song *song = &songTable[n];
+ const struct MusicPlayer *mplay = &mplayTable[song->ms];
+
+ if (mplay->info->songHeader != song->header)
+ {
+ MPlayStart(mplay->info, song->header);
+ }
+ else
+ {
+ if ((mplay->info->status & MUSICPLAYER_STATUS_TRACK) == 0
+ || (mplay->info->status & MUSICPLAYER_STATUS_PAUSE))
+ {
+ MPlayStart(mplay->info, song->header);
+ }
+ }
+}
+
+void m4aSongNumStartOrContinue(u16 n)
+{
+ const struct MusicPlayer *mplayTable = gMPlayTable;
+ const struct Song *songTable = gSongTable;
+ const struct Song *song = &songTable[n];
+ const struct MusicPlayer *mplay = &mplayTable[song->ms];
+
+ if (mplay->info->songHeader != song->header)
+ MPlayStart(mplay->info, song->header);
+ else if ((mplay->info->status & MUSICPLAYER_STATUS_TRACK) == 0)
+ MPlayStart(mplay->info, song->header);
+ else if (mplay->info->status & MUSICPLAYER_STATUS_PAUSE)
+ MPlayContinue(mplay->info);
+}
+
+void m4aSongNumStop(u16 n)
+{
+ const struct MusicPlayer *mplayTable = gMPlayTable;
+ const struct Song *songTable = gSongTable;
+ const struct Song *song = &songTable[n];
+ const struct MusicPlayer *mplay = &mplayTable[song->ms];
+
+ if (mplay->info->songHeader == song->header)
+ m4aMPlayStop(mplay->info);
+}
+
+void m4aSongNumContinue(u16 n)
+{
+ const struct MusicPlayer *mplayTable = gMPlayTable;
+ const struct Song *songTable = gSongTable;
+ const struct Song *song = &songTable[n];
+ const struct MusicPlayer *mplay = &mplayTable[song->ms];
+
+ if (mplay->info->songHeader == song->header)
+ MPlayContinue(mplay->info);
+}
+
+void m4aMPlayAllStop(void)
+{
+ s32 i;
+
+ for (i = 0; i < NUM_MUSIC_PLAYERS; i++)
+ m4aMPlayStop(gMPlayTable[i].info);
+
+ for (i = 0; i < MAX_POKEMON_CRIES; i++)
+ m4aMPlayStop(&gPokemonCryMusicPlayers[i]);
+}
+
+void m4aMPlayContinue(struct MusicPlayerInfo *mplayInfo)
+{
+ MPlayContinue(mplayInfo);
+}
+
+void m4aMPlayAllContinue(void)
+{
+ s32 i;
+
+ for (i = 0; i < NUM_MUSIC_PLAYERS; i++)
+ MPlayContinue(gMPlayTable[i].info);
+
+ for (i = 0; i < MAX_POKEMON_CRIES; i++)
+ MPlayContinue(&gPokemonCryMusicPlayers[i]);
+}
+
+void m4aMPlayFadeOut(struct MusicPlayerInfo *mplayInfo, u16 speed)
+{
+ MPlayFadeOut(mplayInfo, speed);
+}
+
+void m4aMPlayFadeOutTemporarily(struct MusicPlayerInfo *mplayInfo, u16 speed)
+{
+ if (mplayInfo->ident == ID_NUMBER)
+ {
+ mplayInfo->ident++;
+ mplayInfo->fadeOC = speed;
+ mplayInfo->fadeOI = speed;
+ mplayInfo->fadeOV = (64 << FADE_VOL_SHIFT) | TEMPORARY_FADE;
+ mplayInfo->ident = ID_NUMBER;
+ }
+}
+
+void m4aMPlayFadeIn(struct MusicPlayerInfo *mplayInfo, u16 speed)
+{
+ if (mplayInfo->ident == ID_NUMBER)
+ {
+ mplayInfo->ident++;
+ mplayInfo->fadeOC = speed;
+ mplayInfo->fadeOI = speed;
+ mplayInfo->fadeOV = (0 << FADE_VOL_SHIFT) | FADE_IN;
+ mplayInfo->status &= ~MUSICPLAYER_STATUS_PAUSE;
+ mplayInfo->ident = ID_NUMBER;
+ }
+}
+
+void m4aMPlayImmInit(struct MusicPlayerInfo *mplayInfo)
+{
+ s32 trackCount = mplayInfo->trackCount;
+ struct MusicPlayerTrack *track = mplayInfo->tracks;
+
+ while (trackCount > 0)
+ {
+ if (track->flags & MPT_FLG_EXIST)
+ {
+ if (track->flags & MPT_FLG_START)
+ {
+ Clear64byte(track);
+ track->flags = MPT_FLG_EXIST;
+ track->bendRange = 2;
+ track->volX = 64;
+ track->lfoSpeed = 22;
+ track->tone.type = 1;
+ }
+ }
+
+ trackCount--;
+ track++;
+ }
+}
+
+void MPlayExtender(struct CgbChannel *cgbChans)
+{
+ struct SoundInfo *soundInfo;
+ u32 ident;
+
+ REG_SOUNDCNT_X = SOUND_MASTER_ENABLE
+ | SOUND_4_ON
+ | SOUND_3_ON
+ | SOUND_2_ON
+ | SOUND_1_ON;
+ REG_SOUNDCNT_L = 0; // set master volume to zero
+ REG_NR12 = 0x8;
+ REG_NR22 = 0x8;
+ REG_NR42 = 0x8;
+ REG_NR14 = 0x80;
+ REG_NR24 = 0x80;
+ REG_NR44 = 0x80;
+ REG_NR30 = 0;
+ REG_NR50 = 0x77;
+
+ soundInfo = SOUND_INFO_PTR;
+
+ ident = soundInfo->ident;
+
+ if (ident != ID_NUMBER)
+ return;
+
+ soundInfo->ident++;
+
+ gMPlayJumpTable[8] = ply_memacc;
+ gMPlayJumpTable[17] = ply_lfos;
+ gMPlayJumpTable[19] = ply_mod;
+ gMPlayJumpTable[28] = ply_xcmd;
+ gMPlayJumpTable[29] = ply_endtie;
+ gMPlayJumpTable[30] = SampleFreqSet;
+ gMPlayJumpTable[31] = TrackStop;
+ gMPlayJumpTable[32] = FadeOutBody;
+ gMPlayJumpTable[33] = TrkVolPitSet;
+
+ soundInfo->cgbChans = (struct CgbChannel *)cgbChans;
+ soundInfo->CgbSound = CgbSound;
+ soundInfo->CgbOscOff = CgbOscOff;
+ soundInfo->MidiKeyToCgbFreq = MidiKeyToCgbFreq;
+ soundInfo->maxLines = MAX_LINES;
+
+ CpuFill32(0, cgbChans, sizeof(struct CgbChannel) * 4);
+
+ cgbChans[0].ty = 1;
+ cgbChans[0].panMask = 0x11;
+ cgbChans[1].ty = 2;
+ cgbChans[1].panMask = 0x22;
+ cgbChans[2].ty = 3;
+ cgbChans[2].panMask = 0x44;
+ cgbChans[3].ty = 4;
+ cgbChans[3].panMask = 0x88;
+
+ soundInfo->ident = ident;
+}
+
+void MusicPlayerJumpTableCopy(void)
+{
+ asm("swi 0x2A");
+}
+
+void ClearChain(void *x)
+{
+ void (*func)(void *) = *(&gMPlayJumpTable[34]);
+ func(x);
+}
+
+void Clear64byte(void *x)
+{
+ void (*func)(void *) = *(&gMPlayJumpTable[35]);
+ func(x);
+}
+
+void SoundInit(struct SoundInfo *soundInfo)
+{
+ soundInfo->ident = 0;
+
+ if (REG_DMA1CNT & (DMA_REPEAT << 16))
+ REG_DMA1CNT = ((DMA_ENABLE | DMA_START_NOW | DMA_32BIT | DMA_SRC_INC | DMA_DEST_FIXED) << 16) | 4;
+
+ if (REG_DMA2CNT & (DMA_REPEAT << 16))
+ REG_DMA2CNT = ((DMA_ENABLE | DMA_START_NOW | DMA_32BIT | DMA_SRC_INC | DMA_DEST_FIXED) << 16) | 4;
+
+ REG_DMA1CNT_H = DMA_32BIT;
+ REG_DMA2CNT_H = DMA_32BIT;
+ REG_SOUNDCNT_X = SOUND_MASTER_ENABLE
+ | SOUND_4_ON
+ | SOUND_3_ON
+ | SOUND_2_ON
+ | SOUND_1_ON;
+ REG_SOUNDCNT_H = SOUND_B_FIFO_RESET | SOUND_B_TIMER_0 | SOUND_B_LEFT_OUTPUT
+ | SOUND_A_FIFO_RESET | SOUND_A_TIMER_0 | SOUND_A_RIGHT_OUTPUT
+ | SOUND_ALL_MIX_FULL;
+ REG_SOUNDBIAS_H = (REG_SOUNDBIAS_H & 0x3F) | 0x40;
+
+ REG_DMA1SAD = (s32)soundInfo->pcmBuffer;
+ REG_DMA1DAD = (s32)&REG_FIFO_A;
+ REG_DMA2SAD = (s32)soundInfo->pcmBuffer + PCM_DMA_BUF_SIZE;
+ REG_DMA2DAD = (s32)&REG_FIFO_B;
+
+ SOUND_INFO_PTR = soundInfo;
+ CpuFill32(0, soundInfo, sizeof(struct SoundInfo));
+
+ soundInfo->maxChans = 8;
+ soundInfo->masterVolume = 15;
+ soundInfo->plynote = (u32)ply_note;
+ soundInfo->CgbSound = DummyFunc;
+ soundInfo->CgbOscOff = (void (*)(u8))DummyFunc;
+ soundInfo->MidiKeyToCgbFreq = (u32 (*)(u8, u8, u8))DummyFunc;
+ soundInfo->ExtVolPit = (u32)DummyFunc;
+
+ MPlayJumpTableCopy(gMPlayJumpTable);
+
+ soundInfo->MPlayJumpTable = (u32)gMPlayJumpTable;
+
+ SampleFreqSet(SOUND_MODE_FREQ_13379);
+
+ soundInfo->ident = ID_NUMBER;
+}
+
+void SampleFreqSet(u32 freq)
+{
+ struct SoundInfo *soundInfo = SOUND_INFO_PTR;
+
+ freq = (freq & 0xF0000) >> 16;
+ soundInfo->freq = freq;
+ soundInfo->pcmSamplesPerVBlank = gPcmSamplesPerVBlankTable[freq - 1];
+ soundInfo->pcmDmaPeriod = PCM_DMA_BUF_SIZE / soundInfo->pcmSamplesPerVBlank;
+
+ // LCD refresh rate 59.7275Hz
+ soundInfo->pcmFreq = (597275 * soundInfo->pcmSamplesPerVBlank + 5000) / 10000;
+
+ // CPU frequency 16.78Mhz
+ soundInfo->divFreq = (16777216 / soundInfo->pcmFreq + 1) >> 1;
+
+ // Turn off timer 0.
+ REG_TM0CNT_H = 0;
+
+ // cycles per LCD fresh 280896
+ REG_TM0CNT_L = -(280896 / soundInfo->pcmSamplesPerVBlank);
+
+ m4aSoundVSyncOn();
+
+ while (*(vu8 *)REG_ADDR_VCOUNT == 159)
+ ;
+
+ while (*(vu8 *)REG_ADDR_VCOUNT != 159)
+ ;
+
+ REG_TM0CNT_H = TIMER_ENABLE | TIMER_1CLK;
+}
+
+void m4aSoundMode(u32 mode)
+{
+ struct SoundInfo *soundInfo = SOUND_INFO_PTR;
+ u32 temp;
+
+ if (soundInfo->ident != ID_NUMBER)
+ return;
+
+ soundInfo->ident++;
+
+ temp = mode & (SOUND_MODE_REVERB_SET | SOUND_MODE_REVERB_VAL);
+
+ if (temp)
+ soundInfo->reverb = temp & SOUND_MODE_REVERB_VAL;
+
+ temp = mode & SOUND_MODE_MAXCHN;
+
+ if (temp)
+ {
+ struct SoundChannel *chan;
+
+ soundInfo->maxChans = temp >> SOUND_MODE_MAXCHN_SHIFT;
+
+ temp = MAX_DIRECTSOUND_CHANNELS;
+ chan = &soundInfo->chans[0];
+
+ while (temp != 0)
+ {
+ chan->status = 0;
+ temp--;
+ chan++;
+ }
+ }
+
+ temp = mode & SOUND_MODE_MASVOL;
+
+ if (temp)
+ soundInfo->masterVolume = temp >> SOUND_MODE_MASVOL_SHIFT;
+
+ temp = mode & SOUND_MODE_DA_BIT;
+
+ if (temp)
+ {
+ temp = (temp & 0x300000) >> 14;
+ REG_SOUNDBIAS_H = (REG_SOUNDBIAS_H & 0x3F) | temp;
+ }
+
+ temp = mode & SOUND_MODE_FREQ;
+
+ if (temp)
+ {
+ m4aSoundVSyncOff();
+ SampleFreqSet(temp);
+ }
+
+ soundInfo->ident = ID_NUMBER;
+}
+
+void SoundClear(void)
+{
+ struct SoundInfo *soundInfo = SOUND_INFO_PTR;
+ s32 i;
+ void *chan;
+
+ if (soundInfo->ident != ID_NUMBER)
+ return;
+
+ soundInfo->ident++;
+
+ i = MAX_DIRECTSOUND_CHANNELS;
+ chan = &soundInfo->chans[0];
+
+ while (i > 0)
+ {
+ ((struct SoundChannel *)chan)->status = 0;
+ i--;
+ chan = (void *)((s32)chan + sizeof(struct SoundChannel));
+ }
+
+ chan = soundInfo->cgbChans;
+
+ if (chan)
+ {
+ i = 1;
+
+ while (i <= 4)
+ {
+ soundInfo->CgbOscOff(i);
+ ((struct CgbChannel *)chan)->sf = 0;
+ i++;
+ chan = (void *)((s32)chan + sizeof(struct CgbChannel));
+ }
+ }
+
+ soundInfo->ident = ID_NUMBER;
+}
+
+void m4aSoundVSyncOff(void)
+{
+ struct SoundInfo *soundInfo = SOUND_INFO_PTR;
+
+ if (soundInfo->ident >= ID_NUMBER && soundInfo->ident <= ID_NUMBER + 1)
+ {
+ soundInfo->ident += 10;
+
+ if (REG_DMA1CNT & (DMA_REPEAT << 16))
+ REG_DMA1CNT = ((DMA_ENABLE | DMA_START_NOW | DMA_32BIT | DMA_SRC_INC | DMA_DEST_FIXED) << 16) | 4;
+
+ if (REG_DMA2CNT & (DMA_REPEAT << 16))
+ REG_DMA2CNT = ((DMA_ENABLE | DMA_START_NOW | DMA_32BIT | DMA_SRC_INC | DMA_DEST_FIXED) << 16) | 4;
+
+ REG_DMA1CNT_H = DMA_32BIT;
+ REG_DMA2CNT_H = DMA_32BIT;
+
+ CpuFill32(0, soundInfo->pcmBuffer, sizeof(soundInfo->pcmBuffer));
+ }
+}
+
+void m4aSoundVSyncOn(void)
+{
+ struct SoundInfo *soundInfo = SOUND_INFO_PTR;
+ u32 ident = soundInfo->ident;
+
+ if (ident == ID_NUMBER)
+ return;
+
+ REG_DMA1CNT_H = DMA_ENABLE | DMA_START_SPECIAL | DMA_32BIT | DMA_REPEAT;
+ REG_DMA2CNT_H = DMA_ENABLE | DMA_START_SPECIAL | DMA_32BIT | DMA_REPEAT;
+
+ soundInfo->pcmDmaCounter = 0;
+ soundInfo->ident = ident - 10;
+}
+
+void MPlayOpen(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *tracks, u8 trackCount)
+{
+ struct SoundInfo *soundInfo;
+
+ if (trackCount == 0)
+ return;
+
+ if (trackCount > MAX_MUSICPLAYER_TRACKS)
+ trackCount = MAX_MUSICPLAYER_TRACKS;
+
+ soundInfo = SOUND_INFO_PTR;
+
+ if (soundInfo->ident != ID_NUMBER)
+ return;
+
+ soundInfo->ident++;
+
+ Clear64byte(mplayInfo);
+
+ mplayInfo->tracks = tracks;
+ mplayInfo->trackCount = trackCount;
+ mplayInfo->status = MUSICPLAYER_STATUS_PAUSE;
+
+ while (trackCount != 0)
+ {
+ tracks->flags = 0;
+ trackCount--;
+ tracks++;
+ }
+
+ if (soundInfo->func != 0)
+ {
+ mplayInfo->func = soundInfo->func;
+ mplayInfo->intp = soundInfo->intp;
+ soundInfo->func = 0;
+ }
+
+ soundInfo->intp = (u32)mplayInfo;
+ soundInfo->func = (u32)MPlayMain;
+ soundInfo->ident = ID_NUMBER;
+ mplayInfo->ident = ID_NUMBER;
+}
+
+void MPlayStart(struct MusicPlayerInfo *mplayInfo, struct SongHeader *songHeader)
+{
+ s32 i;
+ u8 unk_B;
+ struct MusicPlayerTrack *track;
+
+ if (mplayInfo->ident != ID_NUMBER)
+ return;
+
+ unk_B = mplayInfo->unk_B;
+
+ if (!unk_B
+ || ((!mplayInfo->songHeader || !(mplayInfo->tracks[0].flags & MPT_FLG_START))
+ && ((mplayInfo->status & MUSICPLAYER_STATUS_TRACK) == 0
+ || (mplayInfo->status & MUSICPLAYER_STATUS_PAUSE)))
+ || (mplayInfo->priority <= songHeader->priority))
+ {
+ mplayInfo->ident++;
+ mplayInfo->status = 0;
+ mplayInfo->songHeader = songHeader;
+ mplayInfo->tone = songHeader->tone;
+ mplayInfo->priority = songHeader->priority;
+ mplayInfo->clock = 0;
+ mplayInfo->tempoD = 150;
+ mplayInfo->tempoI = 150;
+ mplayInfo->tempoU = 0x100;
+ mplayInfo->tempoC = 0;
+ mplayInfo->fadeOI = 0;
+
+ i = 0;
+ track = mplayInfo->tracks;
+
+ while (i < songHeader->trackCount && i < mplayInfo->trackCount)
+ {
+ TrackStop(mplayInfo, track);
+ track->flags = MPT_FLG_EXIST | MPT_FLG_START;
+ track->chan = 0;
+ track->cmdPtr = songHeader->part[i];
+ i++;
+ track++;
+ }
+
+ while (i < mplayInfo->trackCount)
+ {
+ TrackStop(mplayInfo, track);
+ track->flags = 0;
+ i++;
+ track++;
+ }
+
+ if (songHeader->reverb & 0x80)
+ m4aSoundMode(songHeader->reverb);
+
+ mplayInfo->ident = ID_NUMBER;
+ }
+}
+
+void m4aMPlayStop(struct MusicPlayerInfo *mplayInfo)
+{
+ s32 i;
+ struct MusicPlayerTrack *track;
+
+ if (mplayInfo->ident != ID_NUMBER)
+ return;
+
+ mplayInfo->ident++;
+ mplayInfo->status |= MUSICPLAYER_STATUS_PAUSE;
+
+ i = mplayInfo->trackCount;
+ track = mplayInfo->tracks;
+
+ while (i > 0)
+ {
+ TrackStop(mplayInfo, track);
+ i--;
+ track++;
+ }
+
+ mplayInfo->ident = ID_NUMBER;
+}
+
+void FadeOutBody(struct MusicPlayerInfo *mplayInfo)
+{
+ s32 i;
+ struct MusicPlayerTrack *track;
+ u16 fadeOI = mplayInfo->fadeOI;
+ register u32 temp asm("r3");
+ register u16 mask asm("r2");
+
+ if (fadeOI == 0)
+ return;
+
+ mplayInfo->fadeOC--;
+
+ temp = 0xFFFF;
+ mask = temp;
+
+ if (mplayInfo->fadeOC != 0)
+ return;
+
+ mplayInfo->fadeOC = fadeOI;
+
+ if (mplayInfo->fadeOV & FADE_IN)
+ {
+ mplayInfo->fadeOV += (4 << FADE_VOL_SHIFT);
+
+ if ((u16)(mplayInfo->fadeOV & mask) >= (64 << FADE_VOL_SHIFT))
+ {
+ mplayInfo->fadeOV = (64 << FADE_VOL_SHIFT);
+ mplayInfo->fadeOI = 0;
+ }
+ }
+ else
+ {
+ mplayInfo->fadeOV -= (4 << FADE_VOL_SHIFT);
+
+ if ((s16)(mplayInfo->fadeOV & mask) <= 0)
+ {
+ i = mplayInfo->trackCount;
+ track = mplayInfo->tracks;
+
+ while (i > 0)
+ {
+ register u32 fadeOV asm("r7");
+ u32 val;
+
+ TrackStop(mplayInfo, track);
+
+ val = TEMPORARY_FADE;
+ fadeOV = mplayInfo->fadeOV;
+ val &= fadeOV;
+
+ if (!val)
+ track->flags = 0;
+
+ i--;
+ track++;
+ }
+
+ if (mplayInfo->fadeOV & TEMPORARY_FADE)
+ mplayInfo->status |= MUSICPLAYER_STATUS_PAUSE;
+ else
+ mplayInfo->status = MUSICPLAYER_STATUS_PAUSE;
+
+ mplayInfo->fadeOI = 0;
+ return;
+ }
+ }
+
+ i = mplayInfo->trackCount;
+ track = mplayInfo->tracks;
+
+ while (i > 0)
+ {
+ if (track->flags & MPT_FLG_EXIST)
+ {
+ track->volX = (mplayInfo->fadeOV >> FADE_VOL_SHIFT);
+ track->flags |= MPT_FLG_VOLCHG;
+ }
+
+ i--;
+ track++;
+ }
+}
+
+void TrkVolPitSet(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *track)
+{
+ if (track->flags & MPT_FLG_VOLSET)
+ {
+ s32 x;
+ s32 y;
+
+ x = (u32)(track->vol * track->volX) >> 5;
+
+ if (track->modT == 1)
+ x = (u32)(x * (track->modM + 128)) >> 7;
+
+ y = 2 * track->pan + track->panX;
+
+ if (track->modT == 2)
+ y += track->modM;
+
+ if (y < -128)
+ y = -128;
+ else if (y > 127)
+ y = 127;
+
+ track->volMR = (u32)((y + 128) * x) >> 8;
+ track->volML = (u32)((127 - y) * x) >> 8;
+ }
+
+ if (track->flags & MPT_FLG_PITSET)
+ {
+ s32 bend = track->bend * track->bendRange;
+ s32 x = (track->tune + bend)
+ * 4
+ + (track->keyShift << 8)
+ + (track->keyShiftX << 8)
+ + track->pitX;
+
+ if (track->modT == 0)
+ x += 16 * track->modM;
+
+ track->keyM = x >> 8;
+ track->pitM = x;
+ }
+
+ track->flags &= ~(MPT_FLG_PITSET | MPT_FLG_VOLSET);
+}
+
+u32 MidiKeyToCgbFreq(u8 chanNum, u8 key, u8 fineAdjust)
+{
+ if (chanNum == 4)
+ {
+ if (key <= 20)
+ {
+ key = 0;
+ }
+ else
+ {
+ key -= 21;
+ if (key > 59)
+ key = 59;
+ }
+
+ return gNoiseTable[key];
+ }
+ else
+ {
+ s32 val1;
+ s32 val2;
+
+ if (key <= 35)
+ {
+ fineAdjust = 0;
+ key = 0;
+ }
+ else
+ {
+ key -= 36;
+ if (key > 130)
+ {
+ key = 130;
+ fineAdjust = 255;
+ }
+ }
+
+ val1 = gCgbScaleTable[key];
+ val1 = gCgbFreqTable[val1 & 0xF] >> (val1 >> 4);
+
+ val2 = gCgbScaleTable[key + 1];
+ val2 = gCgbFreqTable[val2 & 0xF] >> (val2 >> 4);
+
+ return val1 + ((fineAdjust * (val2 - val1)) >> 8) + 2048;
+ }
+}
+
+void CgbOscOff(u8 chanNum)
+{
+ switch (chanNum)
+ {
+ case 1:
+ REG_NR12 = 8;
+ REG_NR14 = 0x80;
+ break;
+ case 2:
+ REG_NR22 = 8;
+ REG_NR24 = 0x80;
+ break;
+ case 3:
+ REG_NR30 = 0;
+ break;
+ default:
+ REG_NR42 = 8;
+ REG_NR44 = 0x80;
+ }
+}
+
+static inline int CgbPan(struct CgbChannel *chan)
+{
+ u32 rightVolume = chan->rightVolume;
+ u32 leftVolume = chan->leftVolume;
+
+ if ((rightVolume = (u8)rightVolume) >= (leftVolume = (u8)leftVolume))
+ {
+ if (rightVolume / 2 >= leftVolume)
+ {
+ chan->pan = 0x0F;
+ return 1;
+ }
+ }
+ else
+ {
+ if (leftVolume / 2 >= rightVolume)
+ {
+ chan->pan = 0xF0;
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+void CgbModVol(struct CgbChannel *chan)
+{
+ struct SoundInfo *soundInfo = SOUND_INFO_PTR;
+
+ if ((soundInfo->mode & 1) || !CgbPan(chan))
+ {
+ chan->pan = 0xFF;
+ chan->eg = (u32)(chan->rightVolume + chan->leftVolume) >> 4;
+ }
+ else
+ {
+ // Force chan->rightVolume and chan->leftVolume to be read from memory again,
+ // even though there is no reason to do so.
+ // The command line option "-fno-gcse" achieves the same result as this.
+ asm("" : : : "memory");
+
+ chan->eg = (u32)(chan->rightVolume + chan->leftVolume) >> 4;
+ if (chan->eg > 15)
+ chan->eg = 15;
+ }
+
+ chan->sg = (chan->eg * chan->su + 15) >> 4;
+ chan->pan &= chan->panMask;
+}
+
+void CgbSound(void)
+{
+ s32 ch;
+ struct CgbChannel *channels;
+ s32 evAdd;
+ s32 prevC15;
+ struct SoundInfo *soundInfo = SOUND_INFO_PTR;
+ vu8 *nrx0ptr;
+ vu8 *nrx1ptr;
+ vu8 *nrx2ptr;
+ vu8 *nrx3ptr;
+ vu8 *nrx4ptr;
+
+ // Most comparision operations that cast to s8 perform 'and' by 0xFF.
+ int mask = 0xff;
+
+ if (soundInfo->c15)
+ soundInfo->c15--;
+ else
+ soundInfo->c15 = 14;
+
+ for (ch = 1, channels = soundInfo->cgbChans; ch <= 4; ch++, channels++)
+ {
+ if (!(channels->sf & 0xc7))
+ continue;
+
+ switch (ch)
+ {
+ case 1:
+ nrx0ptr = (vu8 *)(REG_ADDR_NR10);
+ nrx1ptr = (vu8 *)(REG_ADDR_NR11);
+ nrx2ptr = (vu8 *)(REG_ADDR_NR12);
+ nrx3ptr = (vu8 *)(REG_ADDR_NR13);
+ nrx4ptr = (vu8 *)(REG_ADDR_NR14);
+ break;
+ case 2:
+ nrx0ptr = (vu8 *)(REG_ADDR_NR10+1);
+ nrx1ptr = (vu8 *)(REG_ADDR_NR21);
+ nrx2ptr = (vu8 *)(REG_ADDR_NR22);
+ nrx3ptr = (vu8 *)(REG_ADDR_NR23);
+ nrx4ptr = (vu8 *)(REG_ADDR_NR24);
+ break;
+ case 3:
+ nrx0ptr = (vu8 *)(REG_ADDR_NR30);
+ nrx1ptr = (vu8 *)(REG_ADDR_NR31);
+ nrx2ptr = (vu8 *)(REG_ADDR_NR32);
+ nrx3ptr = (vu8 *)(REG_ADDR_NR33);
+ nrx4ptr = (vu8 *)(REG_ADDR_NR34);
+ break;
+ default:
+ nrx0ptr = (vu8 *)(REG_ADDR_NR30+1);
+ nrx1ptr = (vu8 *)(REG_ADDR_NR41);
+ nrx2ptr = (vu8 *)(REG_ADDR_NR42);
+ nrx3ptr = (vu8 *)(REG_ADDR_NR43);
+ nrx4ptr = (vu8 *)(REG_ADDR_NR44);
+ break;
+ }
+
+ prevC15 = soundInfo->c15;
+ evAdd = *nrx2ptr;
+
+ if (channels->sf & 0x80)
+ {
+ if (!(channels->sf & 0x40))
+ {
+ channels->sf = 3;
+ channels->mo = 3;
+ CgbModVol(channels);
+ switch (ch)
+ {
+ case 1:
+ *nrx0ptr = channels->sw;
+ // fallthrough
+ case 2:
+ *nrx1ptr = ((u32)channels->wp << 6) + channels->le;
+ goto loc_82E0E30;
+ case 3:
+ if ((u32)channels->wp != channels->cp)
+ {
+ *nrx0ptr = 0x40;
+ REG_WAVE_RAM0 = channels->wp[0];
+ REG_WAVE_RAM1 = channels->wp[1];
+ REG_WAVE_RAM2 = channels->wp[2];
+ REG_WAVE_RAM3 = channels->wp[3];
+ channels->cp = (u32)channels->wp;
+ }
+ *nrx0ptr = 0;
+ *nrx1ptr = channels->le;
+ if (channels->le)
+ channels->n4 = -64;
+ else
+ channels->n4 = -128;
+ break;
+ default:
+ *nrx1ptr = channels->le;
+ *nrx3ptr = (u32)channels->wp << 3;
+ loc_82E0E30:
+ evAdd = channels->at + 8;
+ if (channels->le)
+ channels->n4 = 64;
+ else
+ channels->n4 = 0;
+ break;
+ }
+ channels->ec = channels->at;
+ if ((s8)(channels->at & mask))
+ {
+ channels->ev = 0;
+ goto EC_MINUS;
+ }
+ else
+ {
+ goto loc_82E0F96;
+ }
+ }
+ else
+ {
+ goto loc_82E0E82;
+ }
+ }
+ else if (channels->sf & 0x04)
+ {
+ channels->echoLength--;
+ if ((s8)(channels->echoLength & mask) <= 0)
+ {
+ loc_82E0E82:
+ CgbOscOff(ch);
+ channels->sf = 0;
+ goto LAST_LABEL;
+ }
+ goto loc_82E0FD6;
+ }
+ else if ((channels->sf & 0x40) && (channels->sf & 0x03))
+ {
+ channels->sf &= 0xfc;
+ channels->ec = channels->re;
+ if ((s8)(channels->re & mask))
+ {
+ channels->mo |= 1;
+ if (ch != 3)
+ {
+ evAdd = channels->re;
+ }
+ goto EC_MINUS;
+ }
+ else
+ {
+ goto loc_82E0F02;
+ }
+ }
+ else
+ {
+ loc_82E0ED0:
+ if (channels->ec == 0)
+ {
+ if (ch == 3)
+ {
+ channels->mo |= 1;
+ }
+ CgbModVol(channels);
+ if ((channels->sf & 0x3) == 0)
+ {
+ channels->ev--;
+ if ((s8)(channels->ev & mask) <= 0)
+ {
+ loc_82E0F02:
+ channels->ev = ((channels->eg * channels->echoVolume) + 0xFF) >> 8;
+ if (channels->ev)
+ {
+ channels->sf |= 0x4;
+ channels->mo |= 1;
+ if (ch != 3)
+ {
+ evAdd = 8;
+ }
+ goto loc_82E0FD6;
+ }
+ else
+ {
+ goto loc_82E0E82;
+ }
+ }
+ else
+ {
+ channels->ec = channels->re;
+ }
+ }
+ else if ((channels->sf & 0x3) == 1)
+ {
+ loc_82E0F3A:
+ channels->ev = channels->sg;
+ channels->ec = 7;
+ }
+ else if ((channels->sf & 0x3) == 2)
+ {
+ int ev, sg;
+
+ channels->ev--;
+ ev = (s8)(channels->ev & mask);
+ sg = (s8)(channels->sg);
+ if (ev <= sg)
+ {
+ loc_82E0F5A:
+ if (channels->su == 0)
+ {
+ channels->sf &= 0xfc;
+ goto loc_82E0F02;
+ }
+ else
+ {
+ channels->sf--;
+ channels->mo |= 1;
+ if (ch != 3)
+ {
+ evAdd = 8;
+ }
+ goto loc_82E0F3A;
+ }
+ }
+ else
+ {
+ channels->ec = channels->de;
+ }
+ }
+ else
+ {
+ channels->ev++;
+ if ((u8)(channels->ev & mask) >= channels->eg)
+ {
+ loc_82E0F96:
+ channels->sf--;
+ channels->ec = channels->de;
+ if ((u8)(channels->ec & mask))
+ {
+ channels->mo |= 1;
+ channels->ev = channels->eg;
+ if (ch != 3)
+ {
+ evAdd = channels->de;
+ }
+ }
+ else
+ {
+ goto loc_82E0F5A;
+ }
+ }
+ else
+ {
+ channels->ec = channels->at;
+ }
+ }
+ }
+ }
+
+ EC_MINUS:
+ channels->ec--;
+ if (prevC15 == 0)
+ {
+ prevC15--;
+ goto loc_82E0ED0;
+ }
+
+ loc_82E0FD6:
+ if (channels->mo & 0x2)
+ {
+ if (ch < 4 && (channels->ty & 0x08))
+ {
+ int biasH = REG_SOUNDBIAS_H;
+
+ if (biasH < 64)
+ {
+ channels->fr = (channels->fr + 2) & 0x7fc;
+ }
+ else if (biasH < 128)
+ {
+ channels->fr = (channels->fr + 1) & 0x7fe;
+ }
+ }
+ if (ch != 4)
+ {
+ *nrx3ptr = channels->fr;
+ }
+ else
+ {
+ *nrx3ptr = (*nrx3ptr & 0x08) | channels->fr;
+ }
+ channels->n4 = (channels->n4 & 0xC0) + (*((u8*)(&channels->fr) + 1));
+ *nrx4ptr = (s8)(channels->n4 & mask);
+ }
+
+ if (channels->mo & 1)
+ {
+ REG_NR51 = (REG_NR51 & ~channels->panMask) | channels->pan;
+ if (ch == 3)
+ {
+ *nrx2ptr = gCgb3Vol[channels->ev];
+ if (channels->n4 & 0x80)
+ {
+ *nrx0ptr = 0x80;
+ *nrx4ptr = channels->n4;
+ channels->n4 &= 0x7f;
+ }
+ }
+ else
+ {
+ evAdd &= 0xf;
+ *nrx2ptr = (channels->ev << 4) + evAdd;
+ *nrx4ptr = channels->n4 | 0x80;
+ if (ch == 1 && !(*nrx0ptr & 0x08))
+ {
+ *nrx4ptr = channels->n4 | 0x80;
+ }
+ }
+ }
+
+ LAST_LABEL:
+ channels->mo = 0;
+ }
+}
+
+void m4aMPlayTempoControl(struct MusicPlayerInfo *mplayInfo, u16 tempo)
+{
+ if (mplayInfo->ident == ID_NUMBER)
+ {
+ mplayInfo->ident++;
+ mplayInfo->tempoU = tempo;
+ mplayInfo->tempoI = (mplayInfo->tempoD * mplayInfo->tempoU) >> 8;
+ mplayInfo->ident = ID_NUMBER;
+ }
+}
+
+void m4aMPlayVolumeControl(struct MusicPlayerInfo *mplayInfo, u16 trackBits, u16 volume)
+{
+ s32 i;
+ u32 bit;
+ struct MusicPlayerTrack *track;
+
+ if (mplayInfo->ident != ID_NUMBER)
+ return;
+
+ mplayInfo->ident++;
+
+ i = mplayInfo->trackCount;
+ track = mplayInfo->tracks;
+ bit = 1;
+
+ while (i > 0)
+ {
+ if (trackBits & bit)
+ {
+ if (track->flags & MPT_FLG_EXIST)
+ {
+ track->volX = volume / 4;
+ track->flags |= MPT_FLG_VOLCHG;
+ }
+ }
+
+ i--;
+ track++;
+ bit <<= 1;
+ }
+
+ mplayInfo->ident = ID_NUMBER;
+}
+
+void m4aMPlayPitchControl(struct MusicPlayerInfo *mplayInfo, u16 trackBits, s16 pitch)
+{
+ s32 i;
+ u32 bit;
+ struct MusicPlayerTrack *track;
+
+ if (mplayInfo->ident != ID_NUMBER)
+ return;
+
+ mplayInfo->ident++;
+
+ i = mplayInfo->trackCount;
+ track = mplayInfo->tracks;
+ bit = 1;
+
+ while (i > 0)
+ {
+ if (trackBits & bit)
+ {
+ if (track->flags & MPT_FLG_EXIST)
+ {
+ track->keyShiftX = pitch >> 8;
+ track->pitX = pitch;
+ track->flags |= MPT_FLG_PITCHG;
+ }
+ }
+
+ i--;
+ track++;
+ bit <<= 1;
+ }
+
+ mplayInfo->ident = ID_NUMBER;
+}
+
+void m4aMPlayPanpotControl(struct MusicPlayerInfo *mplayInfo, u16 trackBits, s8 pan)
+{
+ s32 i;
+ u32 bit;
+ struct MusicPlayerTrack *track;
+
+ if (mplayInfo->ident != ID_NUMBER)
+ return;
+
+ mplayInfo->ident++;
+
+ i = mplayInfo->trackCount;
+ track = mplayInfo->tracks;
+ bit = 1;
+
+ while (i > 0)
+ {
+ if (trackBits & bit)
+ {
+ if (track->flags & MPT_FLG_EXIST)
+ {
+ track->panX = pan;
+ track->flags |= MPT_FLG_VOLCHG;
+ }
+ }
+
+ i--;
+ track++;
+ bit <<= 1;
+ }
+
+ mplayInfo->ident = ID_NUMBER;
+}
+
+void ClearModM(struct MusicPlayerTrack *track)
+{
+ track->lfoSpeedC = 0;
+ track->modM = 0;
+
+ if (track->modT == 0)
+ track->flags |= MPT_FLG_PITCHG;
+ else
+ track->flags |= MPT_FLG_VOLCHG;
+}
+
+void m4aMPlayModDepthSet(struct MusicPlayerInfo *mplayInfo, u16 trackBits, u8 modDepth)
+{
+ s32 i;
+ u32 bit;
+ struct MusicPlayerTrack *track;
+
+ if (mplayInfo->ident != ID_NUMBER)
+ return;
+
+ mplayInfo->ident++;
+
+ i = mplayInfo->trackCount;
+ track = mplayInfo->tracks;
+ bit = 1;
+
+ while (i > 0)
+ {
+ if (trackBits & bit)
+ {
+ if (track->flags & MPT_FLG_EXIST)
+ {
+ track->mod = modDepth;
+
+ if (!track->mod)
+ ClearModM(track);
+ }
+ }
+
+ i--;
+ track++;
+ bit <<= 1;
+ }
+
+ mplayInfo->ident = ID_NUMBER;
+}
+
+void m4aMPlayLFOSpeedSet(struct MusicPlayerInfo *mplayInfo, u16 trackBits, u8 lfoSpeed)
+{
+ s32 i;
+ u32 bit;
+ struct MusicPlayerTrack *track;
+
+ if (mplayInfo->ident != ID_NUMBER)
+ return;
+
+ mplayInfo->ident++;
+
+ i = mplayInfo->trackCount;
+ track = mplayInfo->tracks;
+ bit = 1;
+
+ while (i > 0)
+ {
+ if (trackBits & bit)
+ {
+ if (track->flags & MPT_FLG_EXIST)
+ {
+ track->lfoSpeed = lfoSpeed;
+
+ if (!track->lfoSpeed)
+ ClearModM(track);
+ }
+ }
+
+ i--;
+ track++;
+ bit <<= 1;
+ }
+
+ mplayInfo->ident = ID_NUMBER;
+}
+
+#define MEMACC_COND_JUMP(cond) \
+if (cond) \
+ goto cond_true; \
+else \
+ goto cond_false; \
+
+void ply_memacc(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *track)
+{
+ u32 op;
+ u8 *addr;
+ u8 data;
+
+ op = *track->cmdPtr;
+ track->cmdPtr++;
+
+ addr = mplayInfo->memAccArea + *track->cmdPtr;
+ track->cmdPtr++;
+
+ data = *track->cmdPtr;
+ track->cmdPtr++;
+
+ switch (op)
+ {
+ case 0:
+ *addr = data;
+ return;
+ case 1:
+ *addr += data;
+ return;
+ case 2:
+ *addr -= data;
+ return;
+ case 3:
+ *addr = mplayInfo->memAccArea[data];
+ return;
+ case 4:
+ *addr += mplayInfo->memAccArea[data];
+ return;
+ case 5:
+ *addr -= mplayInfo->memAccArea[data];
+ return;
+ case 6:
+ MEMACC_COND_JUMP(*addr == data)
+ return;
+ case 7:
+ MEMACC_COND_JUMP(*addr != data)
+ return;
+ case 8:
+ MEMACC_COND_JUMP(*addr > data)
+ return;
+ case 9:
+ MEMACC_COND_JUMP(*addr >= data)
+ return;
+ case 10:
+ MEMACC_COND_JUMP(*addr <= data)
+ return;
+ case 11:
+ MEMACC_COND_JUMP(*addr < data)
+ return;
+ case 12:
+ MEMACC_COND_JUMP(*addr == mplayInfo->memAccArea[data])
+ return;
+ case 13:
+ MEMACC_COND_JUMP(*addr != mplayInfo->memAccArea[data])
+ return;
+ case 14:
+ MEMACC_COND_JUMP(*addr > mplayInfo->memAccArea[data])
+ return;
+ case 15:
+ MEMACC_COND_JUMP(*addr >= mplayInfo->memAccArea[data])
+ return;
+ case 16:
+ MEMACC_COND_JUMP(*addr <= mplayInfo->memAccArea[data])
+ return;
+ case 17:
+ MEMACC_COND_JUMP(*addr < mplayInfo->memAccArea[data])
+ return;
+ default:
+ return;
+ }
+
+cond_true:
+ {
+ void (*func)(struct MusicPlayerInfo *, struct MusicPlayerTrack *) = *(&gMPlayJumpTable[1]);
+ func(mplayInfo, track);
+ return;
+ }
+
+cond_false:
+ track->cmdPtr += 4;
+}
+
+void ply_xcmd(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *track)
+{
+ u32 n = *track->cmdPtr;
+ track->cmdPtr++;
+
+ gXcmdTable[n](mplayInfo, track);
+}
+
+void ply_xxx(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *track)
+{
+ void (*func)(struct MusicPlayerInfo *, struct MusicPlayerTrack *) = *(&gMPlayJumpTable[0]);
+ func(mplayInfo, track);
+}
+
+#define READ_XCMD_BYTE(var, n) \
+{ \
+ u32 byte = track->cmdPtr[(n)]; \
+ byte <<= n * 8; \
+ (var) &= ~(0xFF << (n * 8)); \
+ (var) |= byte; \
+}
+
+void ply_xwave(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *track)
+{
+ u32 wav;
+
+ READ_XCMD_BYTE(wav, 0) // UB: uninitialized variable
+ READ_XCMD_BYTE(wav, 1)
+ READ_XCMD_BYTE(wav, 2)
+ READ_XCMD_BYTE(wav, 3)
+
+ track->tone.wav = (struct WaveData *)wav;
+ track->cmdPtr += 4;
+}
+
+void ply_xtype(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *track)
+{
+ track->tone.type = *track->cmdPtr;
+ track->cmdPtr++;
+}
+
+void ply_xatta(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *track)
+{
+ track->tone.attack = *track->cmdPtr;
+ track->cmdPtr++;
+}
+
+void ply_xdeca(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *track)
+{
+ track->tone.decay = *track->cmdPtr;
+ track->cmdPtr++;
+}
+
+void ply_xsust(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *track)
+{
+ track->tone.sustain = *track->cmdPtr;
+ track->cmdPtr++;
+}
+
+void ply_xrele(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *track)
+{
+ track->tone.release = *track->cmdPtr;
+ track->cmdPtr++;
+}
+
+void ply_xiecv(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *track)
+{
+ track->echoVolume = *track->cmdPtr;
+ track->cmdPtr++;
+}
+
+void ply_xiecl(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *track)
+{
+ track->echoLength = *track->cmdPtr;
+ track->cmdPtr++;
+}
+
+void ply_xleng(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *track)
+{
+ track->tone.length = *track->cmdPtr;
+ track->cmdPtr++;
+}
+
+void ply_xswee(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *track)
+{
+ track->tone.pan_sweep = *track->cmdPtr;
+ track->cmdPtr++;
+}
+
+void ply_xcmd_0C(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *track)
+{
+ u32 unk;
+
+ READ_XCMD_BYTE(unk, 0) // UB: uninitialized variable
+ READ_XCMD_BYTE(unk, 1)
+
+ if (track->unk_3A < (u16)unk)
+ {
+ track->unk_3A++;
+ track->cmdPtr -= 2;
+ track->wait = 1;
+ }
+ else
+ {
+ track->unk_3A = 0;
+ track->cmdPtr += 2;
+ }
+}
+
+void ply_xcmd_0D(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *track)
+{
+ u32 unk;
+
+ READ_XCMD_BYTE(unk, 0) // UB: uninitialized variable
+ READ_XCMD_BYTE(unk, 1)
+ READ_XCMD_BYTE(unk, 2)
+ READ_XCMD_BYTE(unk, 3)
+
+ track->unk_3C = unk;
+ track->cmdPtr += 4;
+}
+
+void DummyFunc(void)
+{
+}
+
+struct MusicPlayerInfo *SetPokemonCryTone(struct ToneData *tone)
+{
+ u32 maxClock = 0;
+ s32 maxClockIndex = 0;
+ s32 i;
+ struct MusicPlayerInfo *mplayInfo;
+
+ for (i = 0; i < MAX_POKEMON_CRIES; i++)
+ {
+ struct MusicPlayerTrack *track = &gPokemonCryTracks[i * 2];
+
+ if (!track->flags && (!track->chan || track->chan->track != track))
+ goto start_song;
+
+ if (maxClock < gPokemonCryMusicPlayers[i].clock)
+ {
+ maxClock = gPokemonCryMusicPlayers[i].clock;
+ maxClockIndex = i;
+ }
+ }
+
+ i = maxClockIndex;
+
+start_song:
+ mplayInfo = &gPokemonCryMusicPlayers[i];
+ mplayInfo->ident++;
+
+#define CRY ((s32)&gPokemonCrySongs + i * sizeof(struct PokemonCrySong))
+#define CRY_OFS(field) offsetof(struct PokemonCrySong, field)
+
+ memcpy((void *)CRY, &gPokemonCrySong, sizeof(struct PokemonCrySong));
+
+ *(u32 *)(CRY + CRY_OFS(tone)) = (u32)tone;
+ *(u32 *)(CRY + CRY_OFS(part)) = CRY + CRY_OFS(part0);
+ *(u32 *)(CRY + CRY_OFS(part) + 4) = CRY + CRY_OFS(part1);
+ *(u32 *)(CRY + CRY_OFS(gotoTarget)) = CRY + CRY_OFS(cont);
+
+#undef CRY_OFS
+#undef CRY
+
+ mplayInfo->ident = ID_NUMBER;
+
+ MPlayStart(mplayInfo, (struct SongHeader *)(&gPokemonCrySongs[i]));
+
+ return mplayInfo;
+}
+
+void SetPokemonCryVolume(u8 val)
+{
+ gPokemonCrySong.volumeValue = val & 0x7F;
+}
+
+void SetPokemonCryPanpot(s8 val)
+{
+ gPokemonCrySong.panValue = (val + C_V) & 0x7F;
+}
+
+void SetPokemonCryPitch(s16 val)
+{
+ s16 b = val + 0x80;
+ u8 a = gPokemonCrySong.tuneValue2 - gPokemonCrySong.tuneValue;
+ gPokemonCrySong.tieKeyValue = (b >> 8) & 0x7F;
+ gPokemonCrySong.tuneValue = (b >> 1) & 0x7F;
+ gPokemonCrySong.tuneValue2 = (a + ((b >> 1) & 0x7F)) & 0x7F;
+}
+
+void SetPokemonCryLength(u16 val)
+{
+ gPokemonCrySong.unkCmd0CParam = val;
+}
+
+void SetPokemonCryRelease(u8 val)
+{
+ gPokemonCrySong.releaseValue = val;
+}
+
+void SetPokemonCryProgress(u32 val)
+{
+ gPokemonCrySong.unkCmd0DParam = val;
+}
+
+int IsPokemonCryPlaying(struct MusicPlayerInfo *mplayInfo)
+{
+ struct MusicPlayerTrack *track = mplayInfo->tracks;
+
+ if (track->chan && track->chan->track == track)
+ return 1;
+ else
+ return 0;
+}
+
+void SetPokemonCryChorus(s8 val)
+{
+ if (val)
+ {
+ gPokemonCrySong.trackCount = 2;
+ gPokemonCrySong.tuneValue2 = (val + gPokemonCrySong.tuneValue) & 0x7F;
+ }
+ else
+ {
+ gPokemonCrySong.trackCount = 1;
+ }
+}
+
+void SetPokemonCryStereo(u32 val)
+{
+ struct SoundInfo *soundInfo = SOUND_INFO_PTR;
+
+ if (val)
+ {
+ REG_SOUNDCNT_H = SOUND_B_TIMER_0 | SOUND_B_LEFT_OUTPUT
+ | SOUND_A_TIMER_0 | SOUND_A_RIGHT_OUTPUT
+ | SOUND_ALL_MIX_FULL;
+ soundInfo->mode &= ~1;
+ }
+ else
+ {
+ REG_SOUNDCNT_H = SOUND_B_TIMER_0 | SOUND_B_LEFT_OUTPUT | SOUND_B_RIGHT_OUTPUT
+ | SOUND_A_TIMER_0 | SOUND_A_LEFT_OUTPUT | SOUND_A_RIGHT_OUTPUT
+ | SOUND_B_MIX_HALF | SOUND_A_MIX_HALF | SOUND_CGB_MIX_FULL;
+ soundInfo->mode |= 1;
+ }
+}
+
+void SetPokemonCryPriority(u8 val)
+{
+ gPokemonCrySong.priority = val;
+}
diff --git a/src/m4a_2.c b/src/m4a_2.c
deleted file mode 100755
index 0dc5f6c..0000000
--- a/src/m4a_2.c
+++ /dev/null
@@ -1,931 +0,0 @@
-#include "gba/m4a_internal.h"
-
-// #define BSS_CODE __attribute__((section(".bss.code")))
-
-asm(".set gScaleTable, 0x0852D928"); // TODO:
-asm(".set gFreqTable, 0x0852D9DC"); // TODO:
-asm(".set gMPlayTable, 0x08534DD4"); // TODO:
-asm(".set gPokemonCrySongTemplate, 0x0852DB40"); // TODO:
-asm(".set gSongTable, 0x08534E04"); // TODO:
-asm(".set gMaxLines, 0x3C"); // TODO:
-asm(".set gPcmSamplesPerVBlankTable, 0x0852DA0C"); // TODO:
-asm(".set gNoiseTable, 0x0852DAC0"); // TODO:
-asm(".set gCgbScaleTable, 0x0852DA24"); // TODO:
-asm(".set gCgbFreqTable, 0x0852DAA8"); // TODO:
-asm(".set gNumMusicPlayers, 0x4"); // TODO:
-
-extern char SoundMainRAM_Buffer[0x800];
-extern struct SoundInfo gSoundInfo;
-extern struct MusicPlayerInfo gPokemonCryMusicPlayers[MAX_POKEMON_CRIES];
-extern void *gMPlayJumpTable[36];
-extern struct CgbChannel gCgbChans[4];
-extern struct MusicPlayerTrack gPokemonCryTracks[MAX_POKEMON_CRIES * 2];
-extern struct PokemonCrySong gPokemonCrySong;
-extern u8 gMPlayMemAccArea[0x10];
-
-// BSS_CODE ALIGNED(4) char SoundMainRAM_Buffer[0x800] = {0};
-// struct PokemonCrySong gPokemonCrySongs[MAX_POKEMON_CRIES];
-// struct MusicPlayerInfo gPokemonCryMusicPlayers[MAX_POKEMON_CRIES];
-// void *gMPlayJumpTable[36];
-// struct CgbChannel gCgbChans[4];
-// struct MusicPlayerTrack gPokemonCryTracks[MAX_POKEMON_CRIES * 2];
-// struct PokemonCrySong gPokemonCrySong;
-// struct MusicPlayerInfo gMPlayInfo_BGM;
-// struct MusicPlayerInfo gMPlayInfo_SE1;
-// struct MusicPlayerInfo gMPlayInfo_SE2;
-// struct MusicPlayerInfo gMPlayInfo_SE3;
-// u8 gMPlayMemAccArea[0x10];
-
-u32 MidiKeyToFreq(struct WaveData *wav, u8 key, u8 fineAdjust)
-{
- u32 val1;
- u32 val2;
- u32 fineAdjustShifted = fineAdjust << 24;
-
- if (key > 178)
- {
- key = 178;
- fineAdjustShifted = 255 << 24;
- }
-
- val1 = gScaleTable[key];
- val1 = gFreqTable[val1 & 0xF] >> (val1 >> 4);
-
- val2 = gScaleTable[key + 1];
- val2 = gFreqTable[val2 & 0xF] >> (val2 >> 4);
-
- return umul3232H32(wav->freq, val1 + umul3232H32(val2 - val1, fineAdjustShifted));
-}
-
-void UnusedDummyFunc()
-{
-}
-
-void MPlayContinue(struct MusicPlayerInfo *mplayInfo)
-{
- if (mplayInfo->ident == ID_NUMBER)
- {
- mplayInfo->ident++;
- mplayInfo->status &= ~MUSICPLAYER_STATUS_PAUSE;
- mplayInfo->ident = ID_NUMBER;
- }
-}
-
-void MPlayFadeOut(struct MusicPlayerInfo *mplayInfo, u16 speed)
-{
- if (mplayInfo->ident == ID_NUMBER)
- {
- mplayInfo->ident++;
- mplayInfo->fadeOC = speed;
- mplayInfo->fadeOI = speed;
- mplayInfo->fadeOV = (64 << FADE_VOL_SHIFT);
- mplayInfo->ident = ID_NUMBER;
- }
-}
-
-void m4aSoundInit(void)
-{
- s32 i;
-
- CpuCopy32((void *)((s32)SoundMainRAM & ~1), SoundMainRAM_Buffer, sizeof(SoundMainRAM_Buffer));
-
- SoundInit(&gSoundInfo);
- MPlayExtender(gCgbChans);
- m4aSoundMode(SOUND_MODE_DA_BIT_8
- | SOUND_MODE_FREQ_13379
- | (14 << SOUND_MODE_MASVOL_SHIFT)
- | (6 << SOUND_MODE_MAXCHN_SHIFT));
-
- for (i = 0; i < NUM_MUSIC_PLAYERS; i++)
- {
- struct MusicPlayerInfo *mplayInfo = gMPlayTable[i].info;
- MPlayOpen(mplayInfo, gMPlayTable[i].track, gMPlayTable[i].unk_8);
- mplayInfo->unk_B = gMPlayTable[i].unk_A;
- mplayInfo->memAccArea = gMPlayMemAccArea;
- }
-
- memcpy(&gPokemonCrySong, &gPokemonCrySongTemplate, sizeof(struct PokemonCrySong));
-
- for (i = 0; i < MAX_POKEMON_CRIES; i++)
- {
- struct MusicPlayerInfo *mplayInfo = &gPokemonCryMusicPlayers[i];
- struct MusicPlayerTrack *track = &gPokemonCryTracks[i * 2];
- MPlayOpen(mplayInfo, track, 2);
- track->chan = 0;
- }
-}
-
-void m4aSoundMain(void)
-{
- SoundMain();
-}
-
-void m4aSongNumStart(u16 n)
-{
- const struct MusicPlayer *mplayTable = gMPlayTable;
- const struct Song *songTable = gSongTable;
- const struct Song *song = &songTable[n];
- const struct MusicPlayer *mplay = &mplayTable[song->ms];
-
- MPlayStart(mplay->info, song->header);
-}
-
-void m4aSongNumStartOrChange(u16 n)
-{
- const struct MusicPlayer *mplayTable = gMPlayTable;
- const struct Song *songTable = gSongTable;
- const struct Song *song = &songTable[n];
- const struct MusicPlayer *mplay = &mplayTable[song->ms];
-
- if (mplay->info->songHeader != song->header)
- {
- MPlayStart(mplay->info, song->header);
- }
- else
- {
- if ((mplay->info->status & MUSICPLAYER_STATUS_TRACK) == 0
- || (mplay->info->status & MUSICPLAYER_STATUS_PAUSE))
- {
- MPlayStart(mplay->info, song->header);
- }
- }
-}
-
-void m4aSongNumStartOrContinue(u16 n)
-{
- const struct MusicPlayer *mplayTable = gMPlayTable;
- const struct Song *songTable = gSongTable;
- const struct Song *song = &songTable[n];
- const struct MusicPlayer *mplay = &mplayTable[song->ms];
-
- if (mplay->info->songHeader != song->header)
- MPlayStart(mplay->info, song->header);
- else if ((mplay->info->status & MUSICPLAYER_STATUS_TRACK) == 0)
- MPlayStart(mplay->info, song->header);
- else if (mplay->info->status & MUSICPLAYER_STATUS_PAUSE)
- MPlayContinue(mplay->info);
-}
-
-void m4aSongNumStop(u16 n)
-{
- const struct MusicPlayer *mplayTable = gMPlayTable;
- const struct Song *songTable = gSongTable;
- const struct Song *song = &songTable[n];
- const struct MusicPlayer *mplay = &mplayTable[song->ms];
-
- if (mplay->info->songHeader == song->header)
- m4aMPlayStop(mplay->info);
-}
-
-void m4aSongNumContinue(u16 n)
-{
- const struct MusicPlayer *mplayTable = gMPlayTable;
- const struct Song *songTable = gSongTable;
- const struct Song *song = &songTable[n];
- const struct MusicPlayer *mplay = &mplayTable[song->ms];
-
- if (mplay->info->songHeader == song->header)
- MPlayContinue(mplay->info);
-}
-
-void m4aMPlayAllStop(void)
-{
- s32 i;
-
- for (i = 0; i < NUM_MUSIC_PLAYERS; i++)
- m4aMPlayStop(gMPlayTable[i].info);
-
- for (i = 0; i < MAX_POKEMON_CRIES; i++)
- m4aMPlayStop(&gPokemonCryMusicPlayers[i]);
-}
-
-void m4aMPlayContinue(struct MusicPlayerInfo *mplayInfo)
-{
- MPlayContinue(mplayInfo);
-}
-
-void m4aMPlayAllContinue(void)
-{
- s32 i;
-
- for (i = 0; i < NUM_MUSIC_PLAYERS; i++)
- MPlayContinue(gMPlayTable[i].info);
-
- for (i = 0; i < MAX_POKEMON_CRIES; i++)
- MPlayContinue(&gPokemonCryMusicPlayers[i]);
-}
-
-void m4aMPlayFadeOut(struct MusicPlayerInfo *mplayInfo, u16 speed)
-{
- MPlayFadeOut(mplayInfo, speed);
-}
-
-void m4aMPlayFadeOutTemporarily(struct MusicPlayerInfo *mplayInfo, u16 speed)
-{
- if (mplayInfo->ident == ID_NUMBER)
- {
- mplayInfo->ident++;
- mplayInfo->fadeOC = speed;
- mplayInfo->fadeOI = speed;
- mplayInfo->fadeOV = (64 << FADE_VOL_SHIFT) | TEMPORARY_FADE;
- mplayInfo->ident = ID_NUMBER;
- }
-}
-
-void m4aMPlayFadeIn(struct MusicPlayerInfo *mplayInfo, u16 speed)
-{
- if (mplayInfo->ident == ID_NUMBER)
- {
- mplayInfo->ident++;
- mplayInfo->fadeOC = speed;
- mplayInfo->fadeOI = speed;
- mplayInfo->fadeOV = (0 << FADE_VOL_SHIFT) | FADE_IN;
- mplayInfo->status &= ~MUSICPLAYER_STATUS_PAUSE;
- mplayInfo->ident = ID_NUMBER;
- }
-}
-
-void m4aMPlayImmInit(struct MusicPlayerInfo *mplayInfo)
-{
- s32 trackCount = mplayInfo->trackCount;
- struct MusicPlayerTrack *track = mplayInfo->tracks;
-
- while (trackCount > 0)
- {
- if (track->flags & MPT_FLG_EXIST)
- {
- if (track->flags & MPT_FLG_START)
- {
- Clear64byte(track);
- track->flags = MPT_FLG_EXIST;
- track->bendRange = 2;
- track->volX = 64;
- track->lfoSpeed = 22;
- track->tone.type = 1;
- }
- }
-
- trackCount--;
- track++;
- }
-}
-
-void MPlayExtender(struct CgbChannel *cgbChans)
-{
- struct SoundInfo *soundInfo;
- u32 ident;
-
- REG_SOUNDCNT_X = SOUND_MASTER_ENABLE
- | SOUND_4_ON
- | SOUND_3_ON
- | SOUND_2_ON
- | SOUND_1_ON;
- REG_SOUNDCNT_L = 0; // set master volume to zero
- REG_NR12 = 0x8;
- REG_NR22 = 0x8;
- REG_NR42 = 0x8;
- REG_NR14 = 0x80;
- REG_NR24 = 0x80;
- REG_NR44 = 0x80;
- REG_NR30 = 0;
- REG_NR50 = 0x77;
-
- soundInfo = SOUND_INFO_PTR;
-
- ident = soundInfo->ident;
-
- if (ident != ID_NUMBER)
- return;
-
- soundInfo->ident++;
-
- gMPlayJumpTable[8] = ply_memacc;
- gMPlayJumpTable[17] = ply_lfos;
- gMPlayJumpTable[19] = ply_mod;
- gMPlayJumpTable[28] = ply_xcmd;
- gMPlayJumpTable[29] = ply_endtie;
- gMPlayJumpTable[30] = SampleFreqSet;
- gMPlayJumpTable[31] = TrackStop;
- gMPlayJumpTable[32] = FadeOutBody;
- gMPlayJumpTable[33] = TrkVolPitSet;
-
- soundInfo->cgbChans = (struct CgbChannel *)cgbChans;
- soundInfo->CgbSound = CgbSound;
- soundInfo->CgbOscOff = CgbOscOff;
- soundInfo->MidiKeyToCgbFreq = MidiKeyToCgbFreq;
- soundInfo->maxLines = MAX_LINES;
-
- CpuFill32(0, cgbChans, sizeof(struct CgbChannel) * 4);
-
- cgbChans[0].ty = 1;
- cgbChans[0].panMask = 0x11;
- cgbChans[1].ty = 2;
- cgbChans[1].panMask = 0x22;
- cgbChans[2].ty = 3;
- cgbChans[2].panMask = 0x44;
- cgbChans[3].ty = 4;
- cgbChans[3].panMask = 0x88;
-
- soundInfo->ident = ident;
-}
-
-void MusicPlayerJumpTableCopy(void)
-{
- asm("swi 0x2A");
-}
-
-void ClearChain(void *x)
-{
- void (*func)(void *) = *(&gMPlayJumpTable[34]);
- func(x);
-}
-
-void Clear64byte(void *x)
-{
- void (*func)(void *) = *(&gMPlayJumpTable[35]);
- func(x);
-}
-
-void SoundInit(struct SoundInfo *soundInfo)
-{
- soundInfo->ident = 0;
-
- if (REG_DMA1CNT & (DMA_REPEAT << 16))
- REG_DMA1CNT = ((DMA_ENABLE | DMA_START_NOW | DMA_32BIT | DMA_SRC_INC | DMA_DEST_FIXED) << 16) | 4;
-
- if (REG_DMA2CNT & (DMA_REPEAT << 16))
- REG_DMA2CNT = ((DMA_ENABLE | DMA_START_NOW | DMA_32BIT | DMA_SRC_INC | DMA_DEST_FIXED) << 16) | 4;
-
- REG_DMA1CNT_H = DMA_32BIT;
- REG_DMA2CNT_H = DMA_32BIT;
- REG_SOUNDCNT_X = SOUND_MASTER_ENABLE
- | SOUND_4_ON
- | SOUND_3_ON
- | SOUND_2_ON
- | SOUND_1_ON;
- REG_SOUNDCNT_H = SOUND_B_FIFO_RESET | SOUND_B_TIMER_0 | SOUND_B_LEFT_OUTPUT
- | SOUND_A_FIFO_RESET | SOUND_A_TIMER_0 | SOUND_A_RIGHT_OUTPUT
- | SOUND_ALL_MIX_FULL;
- REG_SOUNDBIAS_H = (REG_SOUNDBIAS_H & 0x3F) | 0x40;
-
- REG_DMA1SAD = (s32)soundInfo->pcmBuffer;
- REG_DMA1DAD = (s32)&REG_FIFO_A;
- REG_DMA2SAD = (s32)soundInfo->pcmBuffer + PCM_DMA_BUF_SIZE;
- REG_DMA2DAD = (s32)&REG_FIFO_B;
-
- SOUND_INFO_PTR = soundInfo;
- CpuFill32(0, soundInfo, sizeof(struct SoundInfo));
-
- soundInfo->maxChans = 8;
- soundInfo->masterVolume = 15;
- soundInfo->plynote = (u32)ply_note;
- soundInfo->CgbSound = DummyFunc;
- soundInfo->CgbOscOff = (void (*)(u8))DummyFunc;
- soundInfo->MidiKeyToCgbFreq = (u32 (*)(u8, u8, u8))DummyFunc;
- soundInfo->ExtVolPit = (u32)DummyFunc;
-
- MPlayJumpTableCopy(gMPlayJumpTable);
-
- soundInfo->MPlayJumpTable = (u32)gMPlayJumpTable;
-
- SampleFreqSet(SOUND_MODE_FREQ_13379);
-
- soundInfo->ident = ID_NUMBER;
-}
-
-void SampleFreqSet(u32 freq)
-{
- struct SoundInfo *soundInfo = SOUND_INFO_PTR;
-
- freq = (freq & 0xF0000) >> 16;
- soundInfo->freq = freq;
- soundInfo->pcmSamplesPerVBlank = gPcmSamplesPerVBlankTable[freq - 1];
- soundInfo->pcmDmaPeriod = PCM_DMA_BUF_SIZE / soundInfo->pcmSamplesPerVBlank;
-
- // LCD refresh rate 59.7275Hz
- soundInfo->pcmFreq = (597275 * soundInfo->pcmSamplesPerVBlank + 5000) / 10000;
-
- // CPU frequency 16.78Mhz
- soundInfo->divFreq = (16777216 / soundInfo->pcmFreq + 1) >> 1;
-
- // Turn off timer 0.
- REG_TM0CNT_H = 0;
-
- // cycles per LCD fresh 280896
- REG_TM0CNT_L = -(280896 / soundInfo->pcmSamplesPerVBlank);
-
- m4aSoundVSyncOn();
-
- while (*(vu8 *)REG_ADDR_VCOUNT == 159)
- ;
-
- while (*(vu8 *)REG_ADDR_VCOUNT != 159)
- ;
-
- REG_TM0CNT_H = TIMER_ENABLE | TIMER_1CLK;
-}
-
-void m4aSoundMode(u32 mode)
-{
- struct SoundInfo *soundInfo = SOUND_INFO_PTR;
- u32 temp;
-
- if (soundInfo->ident != ID_NUMBER)
- return;
-
- soundInfo->ident++;
-
- temp = mode & (SOUND_MODE_REVERB_SET | SOUND_MODE_REVERB_VAL);
-
- if (temp)
- soundInfo->reverb = temp & SOUND_MODE_REVERB_VAL;
-
- temp = mode & SOUND_MODE_MAXCHN;
-
- if (temp)
- {
- struct SoundChannel *chan;
-
- soundInfo->maxChans = temp >> SOUND_MODE_MAXCHN_SHIFT;
-
- temp = MAX_DIRECTSOUND_CHANNELS;
- chan = &soundInfo->chans[0];
-
- while (temp != 0)
- {
- chan->status = 0;
- temp--;
- chan++;
- }
- }
-
- temp = mode & SOUND_MODE_MASVOL;
-
- if (temp)
- soundInfo->masterVolume = temp >> SOUND_MODE_MASVOL_SHIFT;
-
- temp = mode & SOUND_MODE_DA_BIT;
-
- if (temp)
- {
- temp = (temp & 0x300000) >> 14;
- REG_SOUNDBIAS_H = (REG_SOUNDBIAS_H & 0x3F) | temp;
- }
-
- temp = mode & SOUND_MODE_FREQ;
-
- if (temp)
- {
- m4aSoundVSyncOff();
- SampleFreqSet(temp);
- }
-
- soundInfo->ident = ID_NUMBER;
-}
-
-void SoundClear(void)
-{
- struct SoundInfo *soundInfo = SOUND_INFO_PTR;
- s32 i;
- void *chan;
-
- if (soundInfo->ident != ID_NUMBER)
- return;
-
- soundInfo->ident++;
-
- i = MAX_DIRECTSOUND_CHANNELS;
- chan = &soundInfo->chans[0];
-
- while (i > 0)
- {
- ((struct SoundChannel *)chan)->status = 0;
- i--;
- chan = (void *)((s32)chan + sizeof(struct SoundChannel));
- }
-
- chan = soundInfo->cgbChans;
-
- if (chan)
- {
- i = 1;
-
- while (i <= 4)
- {
- soundInfo->CgbOscOff(i);
- ((struct CgbChannel *)chan)->sf = 0;
- i++;
- chan = (void *)((s32)chan + sizeof(struct CgbChannel));
- }
- }
-
- soundInfo->ident = ID_NUMBER;
-}
-
-void m4aSoundVSyncOff(void)
-{
- struct SoundInfo *soundInfo = SOUND_INFO_PTR;
-
- if (soundInfo->ident >= ID_NUMBER && soundInfo->ident <= ID_NUMBER + 1)
- {
- soundInfo->ident += 10;
-
- if (REG_DMA1CNT & (DMA_REPEAT << 16))
- REG_DMA1CNT = ((DMA_ENABLE | DMA_START_NOW | DMA_32BIT | DMA_SRC_INC | DMA_DEST_FIXED) << 16) | 4;
-
- if (REG_DMA2CNT & (DMA_REPEAT << 16))
- REG_DMA2CNT = ((DMA_ENABLE | DMA_START_NOW | DMA_32BIT | DMA_SRC_INC | DMA_DEST_FIXED) << 16) | 4;
-
- REG_DMA1CNT_H = DMA_32BIT;
- REG_DMA2CNT_H = DMA_32BIT;
-
- CpuFill32(0, soundInfo->pcmBuffer, sizeof(soundInfo->pcmBuffer));
- }
-}
-
-void m4aSoundVSyncOn(void)
-{
- struct SoundInfo *soundInfo = SOUND_INFO_PTR;
- u32 ident = soundInfo->ident;
-
- if (ident == ID_NUMBER)
- return;
-
- REG_DMA1CNT_H = DMA_ENABLE | DMA_START_SPECIAL | DMA_32BIT | DMA_REPEAT;
- REG_DMA2CNT_H = DMA_ENABLE | DMA_START_SPECIAL | DMA_32BIT | DMA_REPEAT;
-
- soundInfo->pcmDmaCounter = 0;
- soundInfo->ident = ident - 10;
-}
-
-void MPlayOpen(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *tracks, u8 trackCount)
-{
- struct SoundInfo *soundInfo;
-
- if (trackCount == 0)
- return;
-
- if (trackCount > MAX_MUSICPLAYER_TRACKS)
- trackCount = MAX_MUSICPLAYER_TRACKS;
-
- soundInfo = SOUND_INFO_PTR;
-
- if (soundInfo->ident != ID_NUMBER)
- return;
-
- soundInfo->ident++;
-
- Clear64byte(mplayInfo);
-
- mplayInfo->tracks = tracks;
- mplayInfo->trackCount = trackCount;
- mplayInfo->status = MUSICPLAYER_STATUS_PAUSE;
-
- while (trackCount != 0)
- {
- tracks->flags = 0;
- trackCount--;
- tracks++;
- }
-
- if (soundInfo->func != 0)
- {
- mplayInfo->func = soundInfo->func;
- mplayInfo->intp = soundInfo->intp;
- soundInfo->func = 0;
- }
-
- soundInfo->intp = (u32)mplayInfo;
- soundInfo->func = (u32)MPlayMain;
- soundInfo->ident = ID_NUMBER;
- mplayInfo->ident = ID_NUMBER;
-}
-
-void MPlayStart(struct MusicPlayerInfo *mplayInfo, struct SongHeader *songHeader)
-{
- s32 i;
- u8 unk_B;
- struct MusicPlayerTrack *track;
-
- if (mplayInfo->ident != ID_NUMBER)
- return;
-
- unk_B = mplayInfo->unk_B;
-
- if (!unk_B
- || ((!mplayInfo->songHeader || !(mplayInfo->tracks[0].flags & MPT_FLG_START))
- && ((mplayInfo->status & MUSICPLAYER_STATUS_TRACK) == 0
- || (mplayInfo->status & MUSICPLAYER_STATUS_PAUSE)))
- || (mplayInfo->priority <= songHeader->priority))
- {
- mplayInfo->ident++;
- mplayInfo->status = 0;
- mplayInfo->songHeader = songHeader;
- mplayInfo->tone = songHeader->tone;
- mplayInfo->priority = songHeader->priority;
- mplayInfo->clock = 0;
- mplayInfo->tempoD = 150;
- mplayInfo->tempoI = 150;
- mplayInfo->tempoU = 0x100;
- mplayInfo->tempoC = 0;
- mplayInfo->fadeOI = 0;
-
- i = 0;
- track = mplayInfo->tracks;
-
- while (i < songHeader->trackCount && i < mplayInfo->trackCount)
- {
- TrackStop(mplayInfo, track);
- track->flags = MPT_FLG_EXIST | MPT_FLG_START;
- track->chan = 0;
- track->cmdPtr = songHeader->part[i];
- i++;
- track++;
- }
-
- while (i < mplayInfo->trackCount)
- {
- TrackStop(mplayInfo, track);
- track->flags = 0;
- i++;
- track++;
- }
-
- if (songHeader->reverb & 0x80)
- m4aSoundMode(songHeader->reverb);
-
- mplayInfo->ident = ID_NUMBER;
- }
-}
-
-void m4aMPlayStop(struct MusicPlayerInfo *mplayInfo)
-{
- s32 i;
- struct MusicPlayerTrack *track;
-
- if (mplayInfo->ident != ID_NUMBER)
- return;
-
- mplayInfo->ident++;
- mplayInfo->status |= MUSICPLAYER_STATUS_PAUSE;
-
- i = mplayInfo->trackCount;
- track = mplayInfo->tracks;
-
- while (i > 0)
- {
- TrackStop(mplayInfo, track);
- i--;
- track++;
- }
-
- mplayInfo->ident = ID_NUMBER;
-}
-
-void FadeOutBody(struct MusicPlayerInfo *mplayInfo)
-{
- s32 i;
- struct MusicPlayerTrack *track;
- u16 fadeOI = mplayInfo->fadeOI;
- register u32 temp asm("r3");
- register u16 mask asm("r2");
-
- if (fadeOI == 0)
- return;
-
- mplayInfo->fadeOC--;
-
- temp = 0xFFFF;
- mask = temp;
-
- if (mplayInfo->fadeOC != 0)
- return;
-
- mplayInfo->fadeOC = fadeOI;
-
- if (mplayInfo->fadeOV & FADE_IN)
- {
- mplayInfo->fadeOV += (4 << FADE_VOL_SHIFT);
-
- if ((u16)(mplayInfo->fadeOV & mask) >= (64 << FADE_VOL_SHIFT))
- {
- mplayInfo->fadeOV = (64 << FADE_VOL_SHIFT);
- mplayInfo->fadeOI = 0;
- }
- }
- else
- {
- mplayInfo->fadeOV -= (4 << FADE_VOL_SHIFT);
-
- if ((s16)(mplayInfo->fadeOV & mask) <= 0)
- {
- i = mplayInfo->trackCount;
- track = mplayInfo->tracks;
-
- while (i > 0)
- {
- register u32 fadeOV asm("r7");
- u32 val;
-
- TrackStop(mplayInfo, track);
-
- val = TEMPORARY_FADE;
- fadeOV = mplayInfo->fadeOV;
- val &= fadeOV;
-
- if (!val)
- track->flags = 0;
-
- i--;
- track++;
- }
-
- if (mplayInfo->fadeOV & TEMPORARY_FADE)
- mplayInfo->status |= MUSICPLAYER_STATUS_PAUSE;
- else
- mplayInfo->status = MUSICPLAYER_STATUS_PAUSE;
-
- mplayInfo->fadeOI = 0;
- return;
- }
- }
-
- i = mplayInfo->trackCount;
- track = mplayInfo->tracks;
-
- while (i > 0)
- {
- if (track->flags & MPT_FLG_EXIST)
- {
- track->volX = (mplayInfo->fadeOV >> FADE_VOL_SHIFT);
- track->flags |= MPT_FLG_VOLCHG;
- }
-
- i--;
- track++;
- }
-}
-
-void TrkVolPitSet(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *track)
-{
- if (track->flags & MPT_FLG_VOLSET)
- {
- s32 x;
- s32 y;
-
- x = (u32)(track->vol * track->volX) >> 5;
-
- if (track->modT == 1)
- x = (u32)(x * (track->modM + 128)) >> 7;
-
- y = 2 * track->pan + track->panX;
-
- if (track->modT == 2)
- y += track->modM;
-
- if (y < -128)
- y = -128;
- else if (y > 127)
- y = 127;
-
- track->volMR = (u32)((y + 128) * x) >> 8;
- track->volML = (u32)((127 - y) * x) >> 8;
- }
-
- if (track->flags & MPT_FLG_PITSET)
- {
- s32 bend = track->bend * track->bendRange;
- register s32 x asm("r1") = track->tune;
- x += bend;
- x *= 4;
- x += (track->keyShift << 8);
- x += (track->keyShiftX << 8);
- x += track->pitX;
-
- if (track->modT == 0)
- x += 16 * track->modM;
-
- track->keyM = x >> 8;
- track->pitM = x;
- }
-
- track->flags &= ~(MPT_FLG_PITSET | MPT_FLG_VOLSET);
-}
-
-u32 MidiKeyToCgbFreq(u8 chanNum, u8 key, u8 fineAdjust)
-{
- if (chanNum == 4)
- {
- if (key <= 20)
- {
- key = 0;
- }
- else
- {
- key -= 21;
- if (key > 59)
- key = 59;
- }
-
- return gNoiseTable[key];
- }
- else
- {
- s32 val1;
- s32 val2;
-
- if (key <= 35)
- {
- fineAdjust = 0;
- key = 0;
- }
- else
- {
- key -= 36;
- if (key > 130)
- {
- key = 130;
- fineAdjust = 255;
- }
- }
-
- val1 = gCgbScaleTable[key];
- val1 = gCgbFreqTable[val1 & 0xF] >> (val1 >> 4);
-
- val2 = gCgbScaleTable[key + 1];
- val2 = gCgbFreqTable[val2 & 0xF] >> (val2 >> 4);
-
- return val1 + ((fineAdjust * (val2 - val1)) >> 8) + 2048;
- }
-}
-
-void CgbOscOff(u8 chanNum)
-{
- switch (chanNum)
- {
- case 1:
- REG_NR12 = 8;
- REG_NR14 = 0x80;
- break;
- case 2:
- REG_NR22 = 8;
- REG_NR24 = 0x80;
- break;
- case 3:
- REG_NR30 = 0;
- break;
- default:
- REG_NR42 = 8;
- REG_NR44 = 0x80;
- }
-}
-
-static inline int CgbPan(struct CgbChannel *chan)
-{
- u32 rightVolume = chan->rightVolume;
- u32 leftVolume = chan->leftVolume;
-
- if ((rightVolume = (u8)rightVolume) >= (leftVolume = (u8)leftVolume))
- {
- if (rightVolume / 2 >= leftVolume)
- {
- chan->pan = 0x0F;
- return 1;
- }
- }
- else
- {
- if (leftVolume / 2 >= rightVolume)
- {
- chan->pan = 0xF0;
- return 1;
- }
- }
-
- return 0;
-}
-
-void CgbModVol(struct CgbChannel *chan)
-{
- struct SoundInfo *soundInfo = SOUND_INFO_PTR;
-
- if ((soundInfo->mode & 1) || !CgbPan(chan))
- {
- chan->pan = 0xFF;
- chan->eg = (u32)(chan->rightVolume + chan->leftVolume) >> 4;
- }
- else
- {
- // Force chan->rightVolume and chan->leftVolume to be read from memory again,
- // even though there is no reason to do so.
- // The command line option "-fno-gcse" achieves the same result as this.
- asm("" : : : "memory");
-
- chan->eg = (u32)(chan->rightVolume + chan->leftVolume) >> 4;
- if (chan->eg > 15)
- chan->eg = 15;
- }
-
- chan->sg = (chan->eg * chan->su + 15) >> 4;
- chan->pan &= chan->panMask;
-}
diff --git a/src/m4a_4.c b/src/m4a_4.c
deleted file mode 100755
index 32f7a29..0000000
--- a/src/m4a_4.c
+++ /dev/null
@@ -1,548 +0,0 @@
-#include "gba/m4a_internal.h"
-
-asm(".set gXcmdTable, 0x0852DB74"); // TODO:
-asm(".set gPokemonCrySongs, 0x02032AE0"); // TODO:
-
-void m4aMPlayTempoControl(struct MusicPlayerInfo *mplayInfo, u16 tempo)
-{
- if (mplayInfo->ident == ID_NUMBER)
- {
- mplayInfo->ident++;
- mplayInfo->tempoU = tempo;
- mplayInfo->tempoI = (mplayInfo->tempoD * mplayInfo->tempoU) >> 8;
- mplayInfo->ident = ID_NUMBER;
- }
-}
-
-void m4aMPlayVolumeControl(struct MusicPlayerInfo *mplayInfo, u16 trackBits, u16 volume)
-{
- s32 i;
- u32 bit;
- struct MusicPlayerTrack *track;
-
- if (mplayInfo->ident != ID_NUMBER)
- return;
-
- mplayInfo->ident++;
-
- i = mplayInfo->trackCount;
- track = mplayInfo->tracks;
- bit = 1;
-
- while (i > 0)
- {
- if (trackBits & bit)
- {
- if (track->flags & MPT_FLG_EXIST)
- {
- track->volX = volume / 4;
- track->flags |= MPT_FLG_VOLCHG;
- }
- }
-
- i--;
- track++;
- bit <<= 1;
- }
-
- mplayInfo->ident = ID_NUMBER;
-}
-
-void m4aMPlayPitchControl(struct MusicPlayerInfo *mplayInfo, u16 trackBits, s16 pitch)
-{
- s32 i;
- u32 bit;
- struct MusicPlayerTrack *track;
-
- if (mplayInfo->ident != ID_NUMBER)
- return;
-
- mplayInfo->ident++;
-
- i = mplayInfo->trackCount;
- track = mplayInfo->tracks;
- bit = 1;
-
- while (i > 0)
- {
- if (trackBits & bit)
- {
- if (track->flags & MPT_FLG_EXIST)
- {
- track->keyShiftX = pitch >> 8;
- track->pitX = pitch;
- track->flags |= MPT_FLG_PITCHG;
- }
- }
-
- i--;
- track++;
- bit <<= 1;
- }
-
- mplayInfo->ident = ID_NUMBER;
-}
-
-void m4aMPlayPanpotControl(struct MusicPlayerInfo *mplayInfo, u16 trackBits, s8 pan)
-{
- s32 i;
- u32 bit;
- struct MusicPlayerTrack *track;
-
- if (mplayInfo->ident != ID_NUMBER)
- return;
-
- mplayInfo->ident++;
-
- i = mplayInfo->trackCount;
- track = mplayInfo->tracks;
- bit = 1;
-
- while (i > 0)
- {
- if (trackBits & bit)
- {
- if (track->flags & MPT_FLG_EXIST)
- {
- track->panX = pan;
- track->flags |= MPT_FLG_VOLCHG;
- }
- }
-
- i--;
- track++;
- bit <<= 1;
- }
-
- mplayInfo->ident = ID_NUMBER;
-}
-
-void ClearModM(struct MusicPlayerTrack *track)
-{
- track->lfoSpeedC = 0;
- track->modM = 0;
-
- if (track->modT == 0)
- track->flags |= MPT_FLG_PITCHG;
- else
- track->flags |= MPT_FLG_VOLCHG;
-}
-
-void m4aMPlayModDepthSet(struct MusicPlayerInfo *mplayInfo, u16 trackBits, u8 modDepth)
-{
- s32 i;
- u32 bit;
- struct MusicPlayerTrack *track;
-
- if (mplayInfo->ident != ID_NUMBER)
- return;
-
- mplayInfo->ident++;
-
- i = mplayInfo->trackCount;
- track = mplayInfo->tracks;
- bit = 1;
-
- while (i > 0)
- {
- if (trackBits & bit)
- {
- if (track->flags & MPT_FLG_EXIST)
- {
- track->mod = modDepth;
-
- if (!track->mod)
- ClearModM(track);
- }
- }
-
- i--;
- track++;
- bit <<= 1;
- }
-
- mplayInfo->ident = ID_NUMBER;
-}
-
-void m4aMPlayLFOSpeedSet(struct MusicPlayerInfo *mplayInfo, u16 trackBits, u8 lfoSpeed)
-{
- s32 i;
- u32 bit;
- struct MusicPlayerTrack *track;
-
- if (mplayInfo->ident != ID_NUMBER)
- return;
-
- mplayInfo->ident++;
-
- i = mplayInfo->trackCount;
- track = mplayInfo->tracks;
- bit = 1;
-
- while (i > 0)
- {
- if (trackBits & bit)
- {
- if (track->flags & MPT_FLG_EXIST)
- {
- track->lfoSpeed = lfoSpeed;
-
- if (!track->lfoSpeed)
- ClearModM(track);
- }
- }
-
- i--;
- track++;
- bit <<= 1;
- }
-
- mplayInfo->ident = ID_NUMBER;
-}
-
-#define MEMACC_COND_JUMP(cond) \
-if (cond) \
- goto cond_true; \
-else \
- goto cond_false; \
-
-void ply_memacc(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *track)
-{
- u32 op;
- u8 *addr;
- u8 data;
-
- op = *track->cmdPtr;
- track->cmdPtr++;
-
- addr = mplayInfo->memAccArea + *track->cmdPtr;
- track->cmdPtr++;
-
- data = *track->cmdPtr;
- track->cmdPtr++;
-
- switch (op)
- {
- case 0:
- *addr = data;
- return;
- case 1:
- *addr += data;
- return;
- case 2:
- *addr -= data;
- return;
- case 3:
- *addr = mplayInfo->memAccArea[data];
- return;
- case 4:
- *addr += mplayInfo->memAccArea[data];
- return;
- case 5:
- *addr -= mplayInfo->memAccArea[data];
- return;
- case 6:
- MEMACC_COND_JUMP(*addr == data)
- return;
- case 7:
- MEMACC_COND_JUMP(*addr != data)
- return;
- case 8:
- MEMACC_COND_JUMP(*addr > data)
- return;
- case 9:
- MEMACC_COND_JUMP(*addr >= data)
- return;
- case 10:
- MEMACC_COND_JUMP(*addr <= data)
- return;
- case 11:
- MEMACC_COND_JUMP(*addr < data)
- return;
- case 12:
- MEMACC_COND_JUMP(*addr == mplayInfo->memAccArea[data])
- return;
- case 13:
- MEMACC_COND_JUMP(*addr != mplayInfo->memAccArea[data])
- return;
- case 14:
- MEMACC_COND_JUMP(*addr > mplayInfo->memAccArea[data])
- return;
- case 15:
- MEMACC_COND_JUMP(*addr >= mplayInfo->memAccArea[data])
- return;
- case 16:
- MEMACC_COND_JUMP(*addr <= mplayInfo->memAccArea[data])
- return;
- case 17:
- MEMACC_COND_JUMP(*addr < mplayInfo->memAccArea[data])
- return;
- default:
- return;
- }
-
-cond_true:
- {
- void (*func)(struct MusicPlayerInfo *, struct MusicPlayerTrack *) = *(&gMPlayJumpTable[1]);
- func(mplayInfo, track);
- return;
- }
-
-cond_false:
- track->cmdPtr += 4;
-}
-
-void ply_xcmd(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *track)
-{
- u32 n = *track->cmdPtr;
- track->cmdPtr++;
-
- gXcmdTable[n](mplayInfo, track);
-}
-
-void ply_xxx(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *track)
-{
- void (*func)(struct MusicPlayerInfo *, struct MusicPlayerTrack *) = *(&gMPlayJumpTable[0]);
- func(mplayInfo, track);
-}
-
-#define READ_XCMD_BYTE(var, n) \
-{ \
- u32 byte = track->cmdPtr[(n)]; \
- byte <<= n * 8; \
- (var) &= ~(0xFF << (n * 8)); \
- (var) |= byte; \
-}
-
-void ply_xwave(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *track)
-{
- u32 wav;
-
- READ_XCMD_BYTE(wav, 0) // UB: uninitialized variable
- READ_XCMD_BYTE(wav, 1)
- READ_XCMD_BYTE(wav, 2)
- READ_XCMD_BYTE(wav, 3)
-
- track->tone.wav = (struct WaveData *)wav;
- track->cmdPtr += 4;
-}
-
-void ply_xtype(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *track)
-{
- track->tone.type = *track->cmdPtr;
- track->cmdPtr++;
-}
-
-void ply_xatta(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *track)
-{
- track->tone.attack = *track->cmdPtr;
- track->cmdPtr++;
-}
-
-void ply_xdeca(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *track)
-{
- track->tone.decay = *track->cmdPtr;
- track->cmdPtr++;
-}
-
-void ply_xsust(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *track)
-{
- track->tone.sustain = *track->cmdPtr;
- track->cmdPtr++;
-}
-
-void ply_xrele(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *track)
-{
- track->tone.release = *track->cmdPtr;
- track->cmdPtr++;
-}
-
-void ply_xiecv(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *track)
-{
- track->echoVolume = *track->cmdPtr;
- track->cmdPtr++;
-}
-
-void ply_xiecl(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *track)
-{
- track->echoLength = *track->cmdPtr;
- track->cmdPtr++;
-}
-
-void ply_xleng(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *track)
-{
- track->tone.length = *track->cmdPtr;
- track->cmdPtr++;
-}
-
-void ply_xswee(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *track)
-{
- track->tone.pan_sweep = *track->cmdPtr;
- track->cmdPtr++;
-}
-
-void ply_xcmd_0C(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *track)
-{
- u32 unk;
-
- READ_XCMD_BYTE(unk, 0) // UB: uninitialized variable
- READ_XCMD_BYTE(unk, 1)
-
- if (track->unk_3A < (u16)unk)
- {
- track->unk_3A++;
- track->cmdPtr -= 2;
- track->wait = 1;
- }
- else
- {
- track->unk_3A = 0;
- track->cmdPtr += 2;
- }
-}
-
-void ply_xcmd_0D(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *track)
-{
- u32 unk;
-
- READ_XCMD_BYTE(unk, 0) // UB: uninitialized variable
- READ_XCMD_BYTE(unk, 1)
- READ_XCMD_BYTE(unk, 2)
- READ_XCMD_BYTE(unk, 3)
-
- track->unk_3C = unk;
- track->cmdPtr += 4;
-}
-
-void DummyFunc(void)
-{
-}
-
-struct MusicPlayerInfo *SetPokemonCryTone(struct ToneData *tone)
-{
- u32 maxClock = 0;
- s32 maxClockIndex = 0;
- s32 i;
- struct MusicPlayerInfo *mplayInfo;
-
- for (i = 0; i < MAX_POKEMON_CRIES; i++)
- {
- struct MusicPlayerTrack *track = &gPokemonCryTracks[i * 2];
-
- if (!track->flags && (!track->chan || track->chan->track != track))
- goto start_song;
-
- if (maxClock < gPokemonCryMusicPlayers[i].clock)
- {
- maxClock = gPokemonCryMusicPlayers[i].clock;
- maxClockIndex = i;
- }
- }
-
- i = maxClockIndex;
-
-start_song:
- mplayInfo = &gPokemonCryMusicPlayers[i];
- mplayInfo->ident++;
-
-#define CRY ((s32)&gPokemonCrySongs + i * sizeof(struct PokemonCrySong))
-#define CRY_OFS(field) offsetof(struct PokemonCrySong, field)
-
- memcpy((void *)CRY, &gPokemonCrySong, sizeof(struct PokemonCrySong));
-
- *(u32 *)(CRY + CRY_OFS(tone)) = (u32)tone;
- *(u32 *)(CRY + CRY_OFS(part)) = CRY + CRY_OFS(part0);
- *(u32 *)(CRY + CRY_OFS(part) + 4) = CRY + CRY_OFS(part1);
- *(u32 *)(CRY + CRY_OFS(gotoTarget)) = CRY + CRY_OFS(cont);
-
-#undef CRY_OFS
-#undef CRY
-
- mplayInfo->ident = ID_NUMBER;
-
- MPlayStart(mplayInfo, (struct SongHeader *)(&gPokemonCrySongs[i]));
-
- return mplayInfo;
-}
-
-void SetPokemonCryVolume(u8 val)
-{
- gPokemonCrySong.volumeValue = val & 0x7F;
-}
-
-void SetPokemonCryPanpot(s8 val)
-{
- gPokemonCrySong.panValue = (val + C_V) & 0x7F;
-}
-
-void SetPokemonCryPitch(s16 val)
-{
- s16 b = val + 0x80;
- u8 a = gPokemonCrySong.tuneValue2 - gPokemonCrySong.tuneValue;
- gPokemonCrySong.tieKeyValue = (b >> 8) & 0x7F;
- gPokemonCrySong.tuneValue = (b >> 1) & 0x7F;
- gPokemonCrySong.tuneValue2 = (a + ((b >> 1) & 0x7F)) & 0x7F;
-}
-
-void SetPokemonCryLength(u16 val)
-{
- gPokemonCrySong.unkCmd0CParam = val;
-}
-
-void SetPokemonCryRelease(u8 val)
-{
- gPokemonCrySong.releaseValue = val;
-}
-
-void SetPokemonCryProgress(u32 val)
-{
- gPokemonCrySong.unkCmd0DParam = val;
-}
-
-int IsPokemonCryPlaying(struct MusicPlayerInfo *mplayInfo)
-{
- struct MusicPlayerTrack *track = mplayInfo->tracks;
-
- if (track->chan && track->chan->track == track)
- return 1;
- else
- return 0;
-}
-
-void SetPokemonCryChorus(s8 val)
-{
- if (val)
- {
- gPokemonCrySong.trackCount = 2;
- gPokemonCrySong.tuneValue2 = (val + gPokemonCrySong.tuneValue) & 0x7F;
- }
- else
- {
- gPokemonCrySong.trackCount = 1;
- }
-}
-
-void SetPokemonCryStereo(u32 val)
-{
- struct SoundInfo *soundInfo = SOUND_INFO_PTR;
-
- if (val)
- {
- REG_SOUNDCNT_H = SOUND_B_TIMER_0 | SOUND_B_LEFT_OUTPUT
- | SOUND_A_TIMER_0 | SOUND_A_RIGHT_OUTPUT
- | SOUND_ALL_MIX_FULL;
- soundInfo->mode &= ~1;
- }
- else
- {
- REG_SOUNDCNT_H = SOUND_B_TIMER_0 | SOUND_B_LEFT_OUTPUT | SOUND_B_RIGHT_OUTPUT
- | SOUND_A_TIMER_0 | SOUND_A_LEFT_OUTPUT | SOUND_A_RIGHT_OUTPUT
- | SOUND_B_MIX_HALF | SOUND_A_MIX_HALF | SOUND_CGB_MIX_FULL;
- soundInfo->mode |= 1;
- }
-}
-
-void SetPokemonCryPriority(u8 val)
-{
- gPokemonCrySong.priority = val;
-}
diff --git a/src/main.c b/src/main.c
index 62b6b14..de8d269 100755
--- a/src/main.c
+++ b/src/main.c
@@ -3,23 +3,11 @@
#include "gbplayer.h"
#include "m4a.h"
-extern void sub_438(void);
-extern void sub_8BC(void);
-extern void sub_8FC(void);
-extern void sub_940(void);
-extern void sub_1F4C(void);
-extern void sub_1F5C(void);
-extern void sub_1090C(void);
-extern void sub_52A18(void);
-
static void sub_B54(void);
static void sub_B8C(void);
static void InitIntrHandlers(void);
static void ReadKeys(void);
-extern const IntrFunc gIntrTableTemplate[14];
-extern const s16 gUnknown_08055C44[];
-
void AgbMain(void)
{
RegisterRamReset(0xFF);
diff --git a/src/rom_850.c b/src/rom_850.c
index 97fed1f..56a4914 100755
--- a/src/rom_850.c
+++ b/src/rom_850.c
@@ -1,16 +1,6 @@
#include "global.h"
#include "main.h"
-extern IntrFunc *gUnknown_0200FB98;
-extern IntrFunc *gUnknown_02019BE0;
-extern void (*gUnknown_0200FB9C)(void);
-extern void (*gUnknown_0200FBA0)(void);
-extern void (*gUnknown_02017BD0)(void);
-extern void (*gUnknown_02017BD4)(void);
-extern void HBlankIntr(void);
-extern void VCountIntr(void);
-extern void sub_DC4(void);
-
u16 sub_850(void)
{
if (REG_IME & INTR_FLAG_VBLANK
diff --git a/src/titlescreen.c b/src/titlescreen.c
index 315c3e6..b013c2f 100755
--- a/src/titlescreen.c
+++ b/src/titlescreen.c
@@ -3,48 +3,9 @@
#include "m4a.h"
#include "main.h"
-extern u8 gUnknown_03000000[];
-
-
-extern StateFunc gTitlescreenStateFuncs[];
-extern const u8 gTitlescreenBg_Gfx[];
-extern const u16 gTitlescreenBg_Pals[];
-extern const u8 gTitlescreenBgTilemap[];
-extern const u16 gTitlescreenSprites_Pals[];
-extern const u8 gTitlescreenSpritesSavedGame_Gfx[];
-extern const u8 gTitlescreenSpritesNoSavedGame_Gfx[];
-extern const u8 gGBAButtonIcons_Pals[];
-extern const u8 gOptionsSprites_Gfx[];
-extern const u8 *const gUnknown_086A975C[7];
-extern const u8 *const gUnknown_086A96F8[7];
-extern const s16 gUnknown_086A964C[];
-extern const s8 gUnknown_086A9662[];
-extern const s8 gUnknown_086A9666[6][2];
-extern const s8 gUnknown_086A9748[];
-extern const u8 *const gUnknown_086A9714[];
-extern const u8 *const gUnknown_086A9778[];
-extern const s8 gUnknown_086A9672[9][2];
-extern const u16 gUnknown_086A96A4[];
-extern const u16 gUnknown_086A96D4[];
-extern const s16 gEReaderAccessButtonSequence[];
-extern const struct SpriteSet *const gUnknown_086A96E4[];
-
-extern void sub_438(void);
-extern void sub_CBC(void);
-extern void sub_D10(void);
-extern void sub_FE04(void (*func)(void));
-extern void sub_FD5C(void (*func)(void));
-extern void sub_10708(void*, void*, u16, s16);
-extern void sub_52C44(void);
-
-extern void sub_10AC0(void);
-extern void sub_1175C(void);
-extern void sub_11968(void);
-extern void sub_11B74(void);
-
static void sub_114FC(void);
static void sub_1157C(void);
-extern void sub_11640(void);
+/*static*/ extern void sub_11640(void);
// If the user doesn't press any buttons at the title screen,
// it will transition to a demo gameplay experience.
@@ -208,7 +169,7 @@ void sub_10BB8(void)
if (gTitlescreen.idleFramesCounter % 10 == 0)
{
gTitlescreen.idleFadeoutCounter++;
- m4aMPlayVolumeControl(&gMPlayInfo_02032EE0, 0xFFFF, 0x100 / gTitlescreen.idleFadeoutCounter);
+ m4aMPlayVolumeControl(&gMPlayInfo_BGM, 0xFFFF, 0x100 / gTitlescreen.idleFadeoutCounter);
}
if (gTitlescreen.idleFadeoutCounter > 9)
diff --git a/src/util.c b/src/util.c
index b1af27b..f0d0b05 100755
--- a/src/util.c
+++ b/src/util.c
@@ -1,9 +1,6 @@
#include "global.h"
#include "main.h"
-extern const struct OamData gEmptyOamData[128];
-extern int sub_55A24(u8*); // Rumble Pak?
-
static u8 *sub_734(u32, u8*, u32);
static int sub_780(int, int);
diff --git a/sym_bss.txt b/sym_bss.txt
index f282d64..fc81cd3 100755
--- a/sym_bss.txt
+++ b/sym_bss.txt
@@ -12,6 +12,3 @@ gUnknown_03005C00: @ 0x3005C00
.space 0xC00
.space 0xC00
-
-SoundMainRAM_Buffer: @ 0x3007400
- .space 0x800
diff --git a/sym_common.txt b/sym_common.txt
index 8b13789..9df7200 100755
--- a/sym_common.txt
+++ b/sym_common.txt
@@ -1 +1 @@
-
+ .include "m4a.o"
diff --git a/sym_ewram.txt b/sym_ewram.txt
index e3060f6..7ae3d99 100755
--- a/sym_ewram.txt
+++ b/sym_ewram.txt
@@ -159,33 +159,3 @@ gUnknown_020314E0: @ 0x20314E0
gUnknown_02031520: @ 0x2031520
.space 0x610
-
-gSoundInfo: @ 0x2031B30
-
- .space 0x1020
-
-gPokemonCryMusicPlayers: @ 0x2032B50
-
- .space 0x80
-
-gMPlayJumpTable: @ 0x2032BD0
-
- .space 0x90
-
-gCgbChans: @ 0x2032C60
-
- .space 0x100
-
-gPokemonCryTracks: @ 0x2032D60
-
- .space 0x140
-
-gPokemonCrySong: @ 0x2032EA0
-
- .space 0x40
-
-gMPlayInfo_02032EE0: @ 0x2032EE0
-
- .space 0xC0
-
-gMPlayMemAccArea: @ 0x2032FA0