Compare commits

..

2 Commits

Author SHA1 Message Date
Randy Thiemann 71054b6c9d Add Analogue Pocket version. 2023-10-25 10:54:33 +02:00
Randy Thiemann 6d980285e3 Menu music and DAS on menu items. 2023-10-25 09:21:06 +02:00
15 changed files with 4564 additions and 2051 deletions

Binary file not shown.

BIN
bin/DMGTRIS.pocket Normal file

Binary file not shown.

5
patch_pocket.py Normal file
View File

@ -0,0 +1,5 @@
logo = b"\x01\x10\xCE\xEF\x00\x00\x44\xAA\x00\x74\x00\x18\x11\x95\x00\x34\x00\x1A\x00\xD5\x00\x22\x00\x69\x6F\xF6\xF7\x73\x09\x90\xE1\x10\x44\x40\x9A\x90\xD5\xD0\x44\x30\xA9\x21\x5D\x48\x22\xE0\xF8\x60"
with open('bin/DMGTRIS.GBC', 'rb+') as f:
f.seek(0x104)
f.write(logo)

View File

@ -37,5 +37,11 @@ SECTION "Bank ID 2", ROMX[$4000], BANK[2]
ENDR
db $02
SECTION "Bank ID 3", ROMX[$4000], BANK[3]
REPT 7
rst $00
ENDR
db $03
ENDC

View File

@ -35,7 +35,7 @@ INCLUDE "structs.asm"
MACRO wait_vram
ld hl, rSTAT
.wvr\@
bit 1, [hl]
bit STATB_BUSY, [hl]
jr nz, .wvr\@
ENDM
@ -143,6 +143,7 @@ DEF SFX_LEVELLOCK EQU 14
DEF SFX_LEVELUP EQU 15
DEF SFX_RANKUP EQU 16
DEF SFX_READYGO EQU 17
DEF MUSIC_MENU EQU $EE
DEF STACK_SIZE EQU 64
DEF GAME_OVER_R10 EQU 133

View File

@ -59,6 +59,10 @@ ENDC
IF !DEF(HARDWARE_INC)
DEF HARDWARE_INC EQU 1
; Uncomment this line to build a rom with the registers scrambled for the analogue pocket.
;DEF BUILD_POCKET EQU 1
; Usage: rev_Check_hardware_inc <min_ver>
; Examples: rev_Check_hardware_inc 4.1.2
; rev_Check_hardware_inc 4.1 (equivalent to 4.1.0)
@ -534,8 +538,30 @@ DEF AUDENA_OFF EQU %00000000 ; sets all audio regs to 0!
; -- LCDC ($FF40)
; -- LCD Control (R/W)
; --
if def(BUILD_POCKET)
DEF rLCDC EQU $FF4E
else
DEF rLCDC EQU $FF40
endc
if def(BUILD_POCKET)
DEF LCDCF_OFF EQU %00000000 ; LCD Control Operation
DEF LCDCF_ON EQU %00000001 ; LCD Control Operation
DEF LCDCF_WIN9800 EQU %00000000 ; Window Tile Map Display Select
DEF LCDCF_WIN9C00 EQU %00000010 ; Window Tile Map Display Select
DEF LCDCF_WINOFF EQU %00000000 ; Window Display
DEF LCDCF_WINON EQU %00000100 ; Window Display
DEF LCDCF_BLK21 EQU %00000000 ; BG & Window Tile Data Select
DEF LCDCF_BLK01 EQU %00001000 ; BG & Window Tile Data Select
DEF LCDCF_BG9800 EQU %00000000 ; BG Tile Map Display Select
DEF LCDCF_BG9C00 EQU %00010000 ; BG Tile Map Display Select
DEF LCDCF_OBJ8 EQU %00000000 ; OBJ Construction
DEF LCDCF_OBJ16 EQU %00100000 ; OBJ Construction
DEF LCDCF_OBJOFF EQU %00000000 ; OBJ Display
DEF LCDCF_OBJON EQU %01000000 ; OBJ Display
DEF LCDCF_BGOFF EQU %00000000 ; BG Display
DEF LCDCF_BGON EQU %10000000 ; BG Display
else
DEF LCDCF_OFF EQU %00000000 ; LCD Control Operation
DEF LCDCF_ON EQU %10000000 ; LCD Control Operation
DEF LCDCF_WIN9800 EQU %00000000 ; Window Tile Map Display Select
@ -552,7 +578,18 @@ DEF LCDCF_OBJOFF EQU %00000000 ; OBJ Display
DEF LCDCF_OBJON EQU %00000010 ; OBJ Display
DEF LCDCF_BGOFF EQU %00000000 ; BG Display
DEF LCDCF_BGON EQU %00000001 ; BG Display
endc
if def(BUILD_POCKET)
DEF LCDCB_ON EQU 0 ; LCD Control Operation
DEF LCDCB_WIN9C00 EQU 1 ; Window Tile Map Display Select
DEF LCDCB_WINON EQU 2 ; Window Display
DEF LCDCB_BLKS EQU 3 ; BG & Window Tile Data Select
DEF LCDCB_BG9C00 EQU 4 ; BG Tile Map Display Select
DEF LCDCB_OBJ16 EQU 5 ; OBJ Construction
DEF LCDCB_OBJON EQU 6; OBJ Display
DEF LCDCB_BGON EQU 7 ; BG Display
else
DEF LCDCB_ON EQU 7 ; LCD Control Operation
DEF LCDCB_WIN9C00 EQU 6 ; Window Tile Map Display Select
DEF LCDCB_WINON EQU 5 ; Window Display
@ -561,6 +598,7 @@ DEF LCDCB_BG9C00 EQU 3 ; BG Tile Map Display Select
DEF LCDCB_OBJ16 EQU 2 ; OBJ Construction
DEF LCDCB_OBJON EQU 1 ; OBJ Display
DEF LCDCB_BGON EQU 0 ; BG Display
endc
; "Window Character Data Select" follows BG
@ -570,6 +608,18 @@ DEF LCDCB_BGON EQU 0 ; BG Display
; --
DEF rSTAT EQU $FF41
if def(BUILD_POCKET)
DEF STATF_LYC EQU %00000010 ; LYC=LY Coincidence (Selectable)
DEF STATF_MODE10 EQU %00000100 ; Mode 10
DEF STATF_MODE01 EQU %00001000 ; Mode 01 (V-Blank)
DEF STATF_MODE00 EQU %00010000 ; Mode 00 (H-Blank)
DEF STATF_LYCF EQU %00100000 ; Coincidence Flag
DEF STATF_HBL EQU %00000000 ; H-Blank
DEF STATF_VBL EQU %10000000 ; V-Blank
DEF STATF_OAM EQU %01000000 ; OAM-RAM is used by system
DEF STATF_LCD EQU %11000000 ; Both OAM and VRAM used by system
DEF STATF_BUSY EQU %01000000 ; When set, VRAM access is unsafe
else
DEF STATF_LYC EQU %01000000 ; LYC=LY Coincidence (Selectable)
DEF STATF_MODE10 EQU %00100000 ; Mode 10
DEF STATF_MODE01 EQU %00010000 ; Mode 01 (V-Blank)
@ -580,13 +630,23 @@ DEF STATF_VBL EQU %00000001 ; V-Blank
DEF STATF_OAM EQU %00000010 ; OAM-RAM is used by system
DEF STATF_LCD EQU %00000011 ; Both OAM and VRAM used by system
DEF STATF_BUSY EQU %00000010 ; When set, VRAM access is unsafe
endc
if def(BUILD_POCKET)
DEF STATB_LYC EQU 1
DEF STATB_MODE10 EQU 2
DEF STATB_MODE01 EQU 3
DEF STATB_MODE00 EQU 4
DEF STATB_LYCF EQU 5
DEF STATB_BUSY EQU 6
else
DEF STATB_LYC EQU 6
DEF STATB_MODE10 EQU 5
DEF STATB_MODE01 EQU 4
DEF STATB_MODE00 EQU 3
DEF STATB_LYCF EQU 2
DEF STATB_BUSY EQU 1
endc
; --
; -- SCY ($FF42)

View File

@ -1,30 +0,0 @@
; DMGTRIS
; Copyright (C) 2023 - Randy Thiemann <randy.thiemann@gmail.com>
; This program is free software: you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation, either version 3 of the License, or
; (at your option) any later version.
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
; You should have received a copy of the GNU General Public License
; along with this program. If not, see <https://www.gnu.org/licenses/>.
IF !DEF(BUILD_DATE_ASM)
DEF BUILD_DATE_ASM EQU 1
SECTION "Build date", ROM0
db "Built "
BuildDate::
db __ISO_8601_UTC__
db 0
ENDC

2178
src/res/music_data.inc Normal file

File diff suppressed because it is too large Load Diff

2019
src/res/sfx_data.inc Normal file

File diff suppressed because it is too large Load Diff

BIN
src/res/sources/menu.fur Normal file

Binary file not shown.

BIN
src/res/sources/menu.vgm Normal file

Binary file not shown.

View File

@ -0,0 +1,241 @@
# DMGTRIS
# Copyright (C) 2023 - Randy Thiemann <randy.thiemann@gmail.com>
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
from construct import Struct, Const, Int32ul, Int16ul, Int8ul, Bytes
vgm_header = Struct(
"magic" / Const(b"Vgm "),
"eof_offset" / Int32ul,
"version" / Int32ul,
"sn76489_clock" / Int32ul,
"ym2413_clock" / Int32ul,
"gd3_offset" / Int32ul,
"total_samples" / Int32ul,
"loop_offset" / Int32ul,
"loop_samples" / Int32ul,
"rate" / Int32ul,
"sn_fb" / Int16ul,
"sn_w" / Int8ul,
"sn_c" / Int8ul,
"ym2612_clock" / Int32ul,
"ym2151_clock" / Int32ul,
"vgm_data_offset" / Int32ul,
"seg_pcm_clock" / Int32ul,
"seg_pcm_intf_reg" / Int32ul,
"rf5c68_clock" / Int32ul,
"ym2203_clock" / Int32ul,
"ym2608_clock" / Int32ul,
"ym2610_clock" / Int32ul,
"ym3812_clock" / Int32ul,
"ym3526_clock" / Int32ul,
"y8950_clock" / Int32ul,
"ymf262_clock" / Int32ul,
"ymf278b_clock" / Int32ul,
"ymf271_clock" / Int32ul,
"ymz280b_clock" / Int32ul,
"rf5c164_clock" / Int32ul,
"pwm_clock" / Int32ul,
"ay8910_clock" / Int32ul,
"ay8910_type" / Int8ul,
"ay8910_flags" / Int8ul,
"ym2203_ay8910_flags" / Int8ul,
"ym2608_ay8910_flags" / Int8ul,
"volume_mod" / Int8ul,
"reserved_0" / Bytes(1),
"loop_base" / Int8ul,
"loop_modifier" / Int8ul,
"dmg_clock" / Int32ul,
"nes_apu_clock" / Int32ul,
"multi_pcm_clock" / Int32ul,
"upd7759_clock" / Int32ul,
"okim6258_clock" / Int32ul,
"okim6258_flags" / Int8ul,
"k054539_flags" / Int8ul,
"c140_chip_type" / Int8ul,
"reserved_1" / Bytes(1),
"okim6295_clock" / Int32ul,
"k051649_k052539_clock" / Int32ul,
"k054539_clock" / Int32ul,
"huc6280_clock" / Int32ul,
"c140_clock" / Int32ul,
"k053260_clock" / Int32ul,
"pokey_clock" / Int32ul,
"qsound_clock" / Int32ul,
"scsp_clock" / Int32ul,
"extra_hdr_offset" / Int32ul,
"wonder_swan_clock" / Int32ul,
"vsu_clock" / Int32ul,
"saa1099_clock" / Int32ul,
"es5503_clock" / Int32ul,
"es5505_es5506_clock" / Int32ul,
"es5503_num_channels" / Int8ul,
"es5505_es5506_num_channels" / Int8ul,
"c352_clock_div" / Int8ul,
"reserved_2" / Bytes(1),
"x1_010_clock" / Int32ul,
"c352_clock" / Int32ul,
"ga20_clock" / Int32ul,
"reserved_3" / Bytes(28)
)
b3_command = Struct(
"command" / Const(b'\xB3'),
"reg" / Int8ul,
"data" / Int8ul
)
register_names = [
"REG_UNK", # 0x00
"REG_UNK", # 0x01
"REG_UNK", # 0x02
"REG_UNK", # 0x03
"REG_UNK", # 0x04
"REG_UNK", # 0x05
"REG_UNK", # 0x06
"REG_UNK", # 0x07
"REG_UNK", # 0x08
"REG_UNK", # 0x09
"REG_UNK", # 0x0A
"REG_UNK", # 0x0B
"REG_UNK", # 0x0C
"REG_UNK", # 0x0D
"REG_UNK", # 0x0E
"REG_UNK", # 0x0F
"REG_NR10_CH1_SWEEP", # 0x10
"REG_NR11_CH1_LENDT", # 0x11
"REG_NR12_CH1_VOLEV", # 0x12
"REG_NR13_CH1_FRQLO", # 0x13
"REG_NR14_CH1_FRQHI", # 0x14
"REG_UNK", # 0x15
"REG_NR21_CH2_LENDT", # 0x16
"REG_NR22_CH2_VOLEV", # 0x17
"REG_NR23_CH2_FRQLO", # 0x18
"REG_NR24_CH2_FRQHI", # 0x19
"REG_NR30_CH3_DACEN", # 0x1A
"REG_NR31_CH3_LENGT", # 0x1B
"REG_NR32_CH3_VOLUM", # 0x1C
"REG_NR33_CH3_FRQLO", # 0x1D
"REG_NR34_CH3_FRQHI", # 0x1E
"REG_UNK", # 0x1F
"REG_NR41_CH4_LENGT", # 0x20
"REG_NR42_CH4_VOLEV", # 0x21
"REG_NR43_CH4_FQRND", # 0x22
"REG_NR44_CH4_CNTRL", # 0x23
"REG_NR50_MVOLVINPN", # 0x24
"REG_NR51_MASTERPAN", # 0x25
"REG_NR52_MASTERCTL", # 0x26
"REG_UNK", # 0x27
"REG_UNK", # 0x28
"REG_UNK", # 0x29
"REG_UNK", # 0x2A
"REG_UNK", # 0x2B
"REG_UNK", # 0x2C
"REG_UNK", # 0x2D
"REG_UNK", # 0x2E
"REG_UNK", # 0x2F
"REG_WAVE_PATTERN_0", # 0x30
"REG_WAVE_PATTERN_1", # 0x31
"REG_WAVE_PATTERN_2", # 0x32
"REG_WAVE_PATTERN_3", # 0x33
"REG_WAVE_PATTERN_4", # 0x34
"REG_WAVE_PATTERN_5", # 0x35
"REG_WAVE_PATTERN_6", # 0x36
"REG_WAVE_PATTERN_7", # 0x37
"REG_WAVE_PATTERN_8", # 0x38
"REG_WAVE_PATTERN_9", # 0x39
"REG_WAVE_PATTERN_A", # 0x3A
"REG_WAVE_PATTERN_B", # 0x3B
"REG_WAVE_PATTERN_C", # 0x3C
"REG_WAVE_PATTERN_D", # 0x3D
"REG_WAVE_PATTERN_E", # 0x3E
"REG_WAVE_PATTERN_F", # 0x3F
]
def chunks(lst, n):
for i in range(0, len(lst), n):
yield lst[i:i + n]
class DB:
l = []
def __init__(self):
self.l = []
def __str__(self):
out = []
for chunk in chunks(self.l, 8):
out.append(f" db {', '.join(chunk)}")
return "\n".join(out) + "\n"
def __repr__(self):
return str(self)
def __len__(self):
return len(self.l)
def add(self, *args):
if len(args) == 1:
self.l.append(f"${args[0]:02X}")
else:
self.l.append(register_names[args[0]])
self.l.append(f"${args[1]:02X}")
def trim(self):
while self.l[-1] == "$FF":
self.l.pop()
for c, v in enumerate(register_names):
if v != "REG_UNK":
print(f"DEF {v} EQU ${c:02X}")
print()
print("sMusicMenu::")
with open("menu.vgm", "rb") as f:
data = f.read()
header = vgm_header.parse(data)
data_offset = 0x34 + header.vgm_data_offset
data = data[data_offset:]
db = DB()
ctr = 0
last = None
while len(data) > 0:
if data.startswith(b'\x67\x66'):
data = data[3:]
data = data[Int32ul.parse(data) + 4:]
elif data.startswith(b'\xB3'):
b3 = b3_command.parse(data)
if last == 0x62:
print(db)
db = DB()
db.add(b3.reg + 0x10, b3.data)
last = 0xB3
data = data[3:]
elif data.startswith(b'\x62'):
db.add(0xFF)
last = 0x62
data = data[1:]
elif data.startswith(b'\x66'):
if len(db) > 0:
db.trim()
db.add(0xFE)
print(db, end="")
break
else:
print(f"Unknown command: ${data[0]:02X}")
data = data[1:]
print("sMusicMenuEnd::")

File diff suppressed because it is too large Load Diff

View File

@ -121,6 +121,9 @@ SwitchToGameplay::
ld a, LCDCF_ON | LCDCF_BGON | LCDCF_OBJON | LCDCF_BLK01
ldh [rLCDC], a
; Music end
call SFXKill
; Make sure the first game loop starts just like all the future ones.
wait_vblank
wait_vblank_end

View File

@ -123,6 +123,11 @@ SwitchToTitle::
ld a, LCDCF_ON | LCDCF_BGON | LCDCF_BLK01
ldh [rLCDC], a
; Music start
call SFXKill
ld a, MUSIC_MENU
call SFXEnqueue
; Make sure the first game loop starts just like all the future ones.
wait_vblank
wait_vblank_end
@ -178,12 +183,24 @@ TitleEventLoopHandler::
.left
ldh a, [hLeftState]
cp a, 1
jp z, DecrementOption
cp a, 16
jr c, .right
ldh a, [hFrameCtr]
and 3
cp a, 3
jr nz, .right
jp DecrementOption
.right
ldh a, [hRightState]
cp a, 1
jp z, IncrementOption
cp a, 16
jr c, .done
ldh a, [hFrameCtr]
and 3
cp a, 3
jr nz, .done
jp IncrementOption