From f3a852edc3d00978006c17b146d3877d9b5696a7 Mon Sep 17 00:00:00 2001 From: shoofle Date: Sun, 6 Apr 2025 11:16:30 -0400 Subject: [PATCH] a lot of refactors, and waffling on audio engines. --- 21TheWorld.inc | 2 + Async.inc | 21 +- Audio.inc | 861 ++++++---- CardHelpers.inc | 24 +- CopyRangeSafe.inc => CopyRange.inc | 15 - CopyTilesSafe.inc => CopyTiles.inc | 0 Random.inc | 10 +- ScreenCardBrowse.inc | 1 - ScreenCardRead.inc | 6 +- ScreenMainMenu.inc | 30 +- ScreenShuffle.inc | 15 +- ScreenSpreadSelect.inc | 6 +- .../00thefool.aseprite | Bin .../01themagician.aseprite | Bin .../01themagician.asm | 0 .../02thehighpriestess.aseprite | Bin .../02thehighpriestess.asm | 0 .../03theempress.aseprite | Bin 03theempress.asm => card_art/03theempress.asm | 0 .../04theemperor.aseprite | Bin 04theemperor.asm => card_art/04theemperor.asm | 0 .../05thehierophant.aseprite | Bin .../05thehierophant.asm | 0 .../06thelovers.aseprite | Bin 06thelovers.asm => card_art/06thelovers.asm | 0 .../07thechariot.aseprite | Bin 07thechariot.asm => card_art/07thechariot.asm | 0 .../08strength.aseprite | Bin 08strength.asm => card_art/08strength.asm | 0 .../09thehermit.aseprite | Bin 09thehermit.asm => card_art/09thehermit.asm | 0 .../10wheeloffortune.aseprite | Bin .../10wheeloffortune.asm | 0 .../11justice.aseprite | Bin 11justice.asm => card_art/11justice.asm | 0 .../12thehangedman.aseprite | Bin .../12thehangedman.asm | 0 13death.aseprite => card_art/13death.aseprite | Bin 13death.asm => card_art/13death.asm | 0 .../14temperance.aseprite | Bin 14temperance.asm => card_art/14temperance.asm | 0 .../15thedevil.aseprite | Bin 15thedevil.asm => card_art/15thedevil.asm | 0 .../16thetower.aseprite | Bin 16thetower.asm => card_art/16thetower.asm | 0 .../17thestar.aseprite | Bin 17thestar.asm => card_art/17thestar.asm | 0 .../18themoon.aseprite | Bin 18themoon.asm => card_art/18themoon.asm | 0 .../19thesun.aseprite | Bin 19thesun.asm => card_art/19thesun.asm | 0 .../20judgement.aseprite | Bin 20judgement.asm => card_art/20judgement.asm | 0 .../21theworld.aseprite | Bin 21theworld.asm => card_art/21theworld.asm | 0 KeyArtTiles.asm => card_art/KeyArtTiles.asm | 0 SpriteTiles.asm => card_art/SpriteTiles.asm | 0 Sprites.asm => card_art/Sprites.asm | 0 SpritesLayer.asm => card_art/SpritesLayer.asm | 0 .../screendesigns.aseprite | Bin .../screendesigns.asm | 0 carillon.sav | Bin 0 -> 32768 bytes gb_tarot_theme_2.mod | Bin 0 -> 50186 bytes gb_tarot_theme_2.mod~ | Bin 0 -> 52234 bytes gb_tarot_theme_2.s3m | Bin 0 -> 55880 bytes gbt_player.inc | 643 ++++++++ gbt_player_bank1.inc | 1389 +++++++++++++++++ justice.asm | 101 -- main.asm | 19 +- mod2gbt | Bin 0 -> 22624 bytes pythonrangetest.c | 217 +++ pythonrangetest.inc | 222 +++ range_test.s3m | Bin 0 -> 50160 bytes rangetest.mod | Bin 0 -> 69616 bytes rangetest.s3m | Bin 0 -> 76718 bytes s3m2gbt.py | 375 ++++- s3m2shoofmt.py | 627 ++++++++ source.zip | Bin 427157 -> 475958 bytes 78 files changed, 3992 insertions(+), 592 deletions(-) rename CopyRangeSafe.inc => CopyRange.inc (51%) rename CopyTilesSafe.inc => CopyTiles.inc (100%) rename 00thefool.aseprite => card_art/00thefool.aseprite (100%) rename 01themagician.aseprite => card_art/01themagician.aseprite (100%) rename 01themagician.asm => card_art/01themagician.asm (100%) rename 02thehighpriestess.aseprite => card_art/02thehighpriestess.aseprite (100%) rename 02thehighpriestess.asm => card_art/02thehighpriestess.asm (100%) rename 03theempress.aseprite => card_art/03theempress.aseprite (100%) rename 03theempress.asm => card_art/03theempress.asm (100%) rename 04theemperor.aseprite => card_art/04theemperor.aseprite (100%) rename 04theemperor.asm => card_art/04theemperor.asm (100%) rename 05thehierophant.aseprite => card_art/05thehierophant.aseprite (100%) rename 05thehierophant.asm => card_art/05thehierophant.asm (100%) rename 06thelovers.aseprite => card_art/06thelovers.aseprite (100%) rename 06thelovers.asm => card_art/06thelovers.asm (100%) rename 07thechariot.aseprite => card_art/07thechariot.aseprite (100%) rename 07thechariot.asm => card_art/07thechariot.asm (100%) rename 08strength.aseprite => card_art/08strength.aseprite (100%) rename 08strength.asm => card_art/08strength.asm (100%) rename 09thehermit.aseprite => card_art/09thehermit.aseprite (100%) rename 09thehermit.asm => card_art/09thehermit.asm (100%) rename 10wheeloffortune.aseprite => card_art/10wheeloffortune.aseprite (100%) rename 10wheeloffortune.asm => card_art/10wheeloffortune.asm (100%) rename 11justice.aseprite => card_art/11justice.aseprite (100%) rename 11justice.asm => card_art/11justice.asm (100%) rename 12thehangedman.aseprite => card_art/12thehangedman.aseprite (100%) rename 12thehangedman.asm => card_art/12thehangedman.asm (100%) rename 13death.aseprite => card_art/13death.aseprite (100%) rename 13death.asm => card_art/13death.asm (100%) rename 14temperance.aseprite => card_art/14temperance.aseprite (100%) rename 14temperance.asm => card_art/14temperance.asm (100%) rename 15thedevil.aseprite => card_art/15thedevil.aseprite (100%) rename 15thedevil.asm => card_art/15thedevil.asm (100%) rename 16thetower.aseprite => card_art/16thetower.aseprite (100%) rename 16thetower.asm => card_art/16thetower.asm (100%) rename 17thestar.aseprite => card_art/17thestar.aseprite (100%) rename 17thestar.asm => card_art/17thestar.asm (100%) rename 18themoon.aseprite => card_art/18themoon.aseprite (100%) rename 18themoon.asm => card_art/18themoon.asm (100%) rename 19thesun.aseprite => card_art/19thesun.aseprite (100%) rename 19thesun.asm => card_art/19thesun.asm (100%) rename 20judgement.aseprite => card_art/20judgement.aseprite (100%) rename 20judgement.asm => card_art/20judgement.asm (100%) rename 21theworld.aseprite => card_art/21theworld.aseprite (100%) rename 21theworld.asm => card_art/21theworld.asm (100%) rename KeyArtTiles.asm => card_art/KeyArtTiles.asm (100%) rename SpriteTiles.asm => card_art/SpriteTiles.asm (100%) rename Sprites.asm => card_art/Sprites.asm (100%) rename SpritesLayer.asm => card_art/SpritesLayer.asm (100%) rename screendesigns.aseprite => card_art/screendesigns.aseprite (100%) rename screendesigns.asm => card_art/screendesigns.asm (100%) create mode 100644 carillon.sav create mode 100644 gb_tarot_theme_2.mod create mode 100644 gb_tarot_theme_2.mod~ create mode 100644 gb_tarot_theme_2.s3m create mode 100644 gbt_player.inc create mode 100644 gbt_player_bank1.inc delete mode 100644 justice.asm create mode 100755 mod2gbt create mode 100644 pythonrangetest.c create mode 100644 pythonrangetest.inc create mode 100644 range_test.s3m create mode 100644 rangetest.mod create mode 100644 rangetest.s3m mode change 100644 => 100755 s3m2gbt.py create mode 100644 s3m2shoofmt.py diff --git a/21TheWorld.inc b/21TheWorld.inc index 2bb4522..418dbc1 100644 --- a/21TheWorld.inc +++ b/21TheWorld.inc @@ -285,6 +285,8 @@ TheWorld: ld hl, MY_OAM ; go through MY_OAM and, for any which aren't still visible, set their ; y value to zero. + ; this could probably be rewritten as a simpler lookup table if we rewrote it + ; using jp hl and pointer math rather than explicitly listing all the possibilities .cleanUpLoop ld a, [hl] ; a is the y value and hl points to y : cp a, (2+1+5)*8 diff --git a/Async.inc b/Async.inc index 6a2ab67..bd51d43 100644 --- a/Async.inc +++ b/Async.inc @@ -1,15 +1,13 @@ ; async variables somewhere in RAM -def vAsyncAF equ ASYNC_VARS_START -def vAsyncHL EQU vAsyncAF+2 -def vAsyncDE EQU vAsyncHL+2 -def vAsyncBC equ vAsyncDE+2 -def vAsyncPC equ vAsyncBC+2 -def vAsyncNext equ vAsyncPC+2 -def vAsyncAfter equ vAsyncNext+2 -def vAsyncProgress equ vAsyncAfter+2 -def vAsyncMainSP equ vAsyncProgress+2 -def vAsyncThreadSP equ vAsyncMainSP+2 - +PUSHS "Async Variables", WRAM0[ASYNC_VARS_START] +vAsyncAF: dw +vAsyncHL: dw +vAsyncDE: dw +vAsyncBC: dw +vAsyncPC: dw +vAsyncMainSP: dw +vAsyncThreadSP: dw +POPS ; canonical ordering to push should be: AF, BC, DE, HL, def ASYNC_STACK_TOP equ $ffc0 @@ -18,6 +16,7 @@ def ASYNC_STACK_TOP equ $ffc0 ; second value is the destination of the async call, at ffbc = ffbe-2 = ffc0-2-2 def ASYNC_THREAD_CALL equ ASYNC_STACK_TOP - 2 - 2 +; timing for async execution, in scanlines def SAFE_ASYNC_START EQU 148 def SAFE_ASYNC_END EQU 153 diff --git a/Audio.inc b/Audio.inc index 150fa24..07db592 100644 --- a/Audio.inc +++ b/Audio.inc @@ -1,347 +1,534 @@ -PUSHS "Sound Variables", WRAM0[AUDIO_VARS_START] -ordersStart: dw -println "orders start is ", ordersStart -ordersLength: db - - -; audio player state -currentOrderNumber: db -currentRowNumber: db -println "currentRowNumber is ", currentRowNumber -currentTickNumber: db -currentPattern: dw -println "current pattern is ", currentPattern -audioReadHead: dw - -AUDIO_VARIABLES_BEGIN: - -speed: db - -macro channel ; macro to define all the channell data in parallel -channel_\1_note: db -channel_\1_duty: db -channel_\1_volume: db -channel_\1_slide: db -channel_\1_arp: db -channel_\1_pan: db -channel_\1_vibrato: db -channel_\1_trigger: db -endm - -channel 1 -channel 2 -channel 3 -channel 4 - -println "channel 1 note is ", channel_1_note -AUDIO_VARIABLES_END: -POPS - SoundSetup: - ld a, LOW(gbtarottheme) - ld [ordersStart], a - ld a, HIGH(gbtarottheme) - ld [ordersStart+1], a - - ld a, 0 - ld [currentOrderNumber], a - ld [currentRowNumber], a - ld [currentTickNumber], a - - ld a, $FF - ld [currentRowNumber], a - - ld a, [ordersStart] - ld l, a - ld a, [ordersStart+1] - ld h, a - inc hl - - ld a, [hl+] - ld [currentPattern], a - ld [audioReadHead], a - ld a, [hl+] - ld [currentPattern+1], a - ld [audioReadHead+1], a - - ld hl, ZEROES - ld de, AUDIO_VARIABLES_BEGIN - ld bc, AUDIO_VARIABLES_END - AUDIO_VARIABLES_BEGIN - call CopyRange - - ld a, 6 - ld [speed], a - - ld a, %1000_1111 - ld [rNR52], a - ld a, $ff - ld [rNR51], a - ld a, $11 - ld [rNR50], a + ld a, BANK(gbt_play) + ld [rROMB0], a + ld de,pythonrangetest + ld bc,BANK(instr_test_data) + ld a,$05 + call gbt_play ; Play song + + ld a, 1 + call gbt_loop + + ld a, [cvCardBank] + ld [rROMB0], a ret + SoundUpdate: - ld a, [speed] - ld b, a - ld a, [currentTickNumber] - inc a - call ArrayClampLoopingB - ld [currentTickNumber], a + ld a, BANK(gbt_play) + ld [rROMB0], a - cp a, 0 - jp nz, .doneAllPackets ; if we're not zero, then just update the things + call gbt_update - ld b, 64 - ld a, [currentRowNumber] - inc a - call ArrayClampLoopingB - ld [currentRowNumber], a - - cp a, 0 - jp nz, :+ ; if the new row number is zero, then we go to the next pattern. - ld a, AUDHIGH_RESTART - ld [rNR14], a - - - ; TODO: update for song orders - ld a, [currentPattern] - ld [audioReadHead], a - ld a, [currentPattern+1] - ld [audioReadHead+1], a -: - ld a, [audioReadHead] - ld l, a - ld a, [audioReadHead+1] - ld h, a - - ld a, [currentRowNumber] - ld b, a - ld a, [hl+] - and a, $F0 - cp a, 0 - ret nz - ld a, [hl+] - cp a, b - jp nz, .doneAllPackets ; return if the current row doesn't equal the row we're looking at - - ; else we're looking at packets -.packetExamine - ld a, l - ld [audioReadHead], a - ld a, h - ld [audioReadHead+1], a - - ld d, h - ld e, l - - ld hl, channel_1_note - - ld a, [de] - and a, $0F - cp a, 1 - jp nz, :+ - ld hl, channel_1_note -: cp a, 2 - jp nz, :+ - ld hl, channel_2_note -: cp a, 3 - jp nz, :+ - ld hl, channel_3_note -: cp a, 4 - jp nz, :+ - ld hl, channel_4_note -: - - ld a, [de] - and a, $F0 ; grab the top nibble of [hl], which holds the effect. - - ; if nibble is zero, then update our read head (already done) and return. - cp a, $00 - jp z, .doneAllPackets - - ld bc, channel_1_note - channel_1_note - cp a, $10 - jp z, .updateValue - - ld bc, channel_1_volume - channel_1_note - cp a, $20 - jp z, .updateVolume - - ld bc, channel_1_duty - channel_1_note - cp a, $30 - jp z, .updateValue - - ld bc, channel_1_pan - channel_1_note - cp a, $40 - jp z, .updateValue - - ld bc, channel_1_arp - channel_1_note - cp a, $50 - jp z, .updateValue - - ld bc, channel_1_vibrato - channel_1_note - cp a, $60 - jp z, .updateValue - - ld bc, channel_1_slide - channel_1_note - cp a, $70 - jp z, .updateValue - - ld bc, channel_1_volume - channel_1_note - cp a, $80 - jp z, .noteCut - - cp a, $90 - jp z, .patternJump - - cp a, $a0 - jp z, .breakSetStep - - cp a, $b0 - jp z, .setSpeed - - cp a, $c0 - jp z, .event - ; and now a bunch of code for handling all those cases! - -.updateVolume: - inc de - add hl, bc - ld a, 0 - ld [channel_1_trigger], a - ld a, [hl] - cp a, 0 - jp nz, :+ - ; if the volume is zero to start with, - ; and the new volume is nonzero, - ld a, [de] - ; set the trigger flag - cp a, 0 - jp z, :+ - ld a, AUDHIGH_RESTART - ld [channel_1_trigger], a -: - - ld a, [de] - ld [hl], a - - inc de - ld h, d - ld l, e - jp .packetExamine - -.updateValue: - inc de - - add hl, bc -: ld a, [de] - ld [hl], a - - inc de - ld h, d - ld l, e - - jp .packetExamine - -.noteCut: - inc de - add hl, bc - - ld [hl], 0 - - ld a, AUDHIGH_RESTART - ld [channel_1_trigger], a - - inc de - ld h, d - ld l, e - jp .packetExamine -.patternJump: - ; TODO - inc de - inc de - ld h, d - ld l, e - jp .packetExamine -.breakSetStep: - ; TODO - inc de - inc de - ld h, d - ld l, e - jp .packetExamine -.setSpeed: - inc de - ld a, [de] - ld [speed], a - - inc de - ld h, d - ld l, e - jp .packetExamine -.event: - ; TODO - inc de - inc de - ld h, d - ld l, e - jp .packetExamine - - -.doneAllPackets: - call Channel_1_Update - call Channel_2_Update - call Channel_3_Update - call Channel_4_Update + ld a, [cvCardBank] + ld [rROMB0], a ret - -Channel_1_Update: - ld a, [channel_1_duty] - or a, $0a - ld [rNR11], a - - ld a, [channel_1_volume] - sla a - sla a - sla a - sla a - and a, $F0 - ld [rNR12], a - - ld a, [channel_1_note] - ld hl, note_periods - ld b, 0 - ld c, a - add hl, bc - add hl, bc ; double width values - - ld a, [hl+] - ld [rNR13], a - - - ld a, [channel_1_trigger] - or a, [hl] - or a, AUDHIGH_LENGTH_OFF - ld [rNR14], a - - ld a, 0 - ld [channel_1_trigger], a - ret - -Channel_2_Update: -Channel_3_Update: -Channel_4_Update: - ret - -note_periods: - dw 44, 156, 262, 363, 457, 547, 631, 710, 786, 854, 923, 986, ; C3 to B3 - dw 1046,1102,1155,1205,1253,1297,1339,1379,1417,1452,1486,1517, ; C4 to B4 - dw 1546,1575,1602,1627,1650,1673,1694,1714,1732,1750,1767,1783, ; C5 to B5 - dw 1798,1812,1825,1837,1849,1860,1871,1881,1890,1899,1907,1915, ; C6 to B6 - dw 1923,1930,1936,1943,1949,1954,1959,1964,1969,1974,1978,1982, ; C7 to B7 - dw 1985,1988,1992,1995,1998,2001,2004,2006,2009,2011,2013,2015 ; C8 to B8 - -INCLUDE "theme.inc" +; File created by mod2gbt +; s3m2gbt modified by shoofle to output rgbds-compatible asm files +SECTION "pythonrangetest_0", ROMX +pythonrangetest_0: + db $BF,$00,$30,$10,$10,$10, + db $00,$00,$00,$00, + db $BF,$01,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$02,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$03,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$04,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$05,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$06,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$07,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$08,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$09,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$0A,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$0B,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$0C,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$0D,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$0E,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$0F,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$10,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$11,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$12,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$13,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$14,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$15,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$16,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$17,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$18,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$19,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$1A,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$1B,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$1C,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$1D,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$1E,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$1F,$30,$00,$00,$00, + db $00,$00,$00,$00, + + +SECTION "pythonrangetest_1", ROMX +pythonrangetest_1: + db $BF,$20,$30,$10,$10,$10, + db $00,$00,$00,$00, + db $BF,$21,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$22,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$23,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$24,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$25,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$26,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$27,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$28,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$29,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$2A,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$2B,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$2C,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$2D,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$2E,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$2F,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$30,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$31,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$32,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$33,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$34,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$35,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$36,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$37,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$38,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$39,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$3A,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$3B,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$3C,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$3D,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$3E,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$3F,$30,$00,$00,$00, + db $00,$00,$00,$00, + + +SECTION "pythonrangetest_2", ROMX +pythonrangetest_2: + db $BF,$40,$30,$10,$10,$10, + db $00,$00,$00,$00, + db $BF,$41,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$42,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$43,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$44,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$45,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$46,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$47,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + + +pythonrangetest_init_state: + db 0x01,0x06,0x02,0x11,0x22,0x44,0x88,0x00, + +SECTION "pythonrangetest", ROMX +pythonrangetest: + db BANK(pythonrangetest_0) + dw pythonrangetest_0 + + db BANK(pythonrangetest_1) + dw pythonrangetest_1 + + db BANK(pythonrangetest_2) + dw pythonrangetest_2 + + db $00 + dw $0000 + + + SECTION "instr_test_0", ROMX +instr_test_0: + DB $98, $1F, $20, $20, $4A, $07 + DB $2F, $00, $00, $20 + DB $2F, $00, $00, $00 + DB $2F, $00, $00, $00 + DB $2F, $00, $00, $00 + DB $2F, $00, $00, $00 + DB $2F, $00, $00, $00 + DB $2F, $00, $00, $00 + DB $98, $2F, $00, $00, $00 + DB $2F, $00, $00, $00 + DB $2F, $00, $00, $00 + DB $2F, $00, $00, $00 + DB $2F, $00, $00, $00 + DB $2F, $00, $00, $00 + DB $2F, $00, $00, $00 + DB $2F, $00, $00, $00 + DB $98, $3F, $00, $00, $00 + DB $2F, $00, $00, $00 + DB $2F, $00, $00, $00 + DB $2F, $00, $00, $00 + DB $2F, $00, $00, $00 + DB $2F, $00, $00, $00 + DB $2F, $00, $00, $00 + DB $2F, $00, $00, $00 + DB $98, $0F, $00, $00, $00 + DB $2F, $00, $00, $00 + DB $2F, $00, $00, $00 + DB $2F, $00, $00, $00 + DB $2F, $00, $00, $00 + DB $2F, $00, $00, $00 + DB $2F, $00, $00, $00 + DB $2F, $00, $00, $00 + DB $20, $00, $98, $10, $00 + DB $00, $00, $21, $00 + DB $00, $00, $21, $00 + DB $00, $00, $21, $00 + DB $00, $00, $21, $00 + DB $00, $00, $21, $00 + DB $00, $00, $21, $00 + DB $00, $00, $21, $00 + DB $00, $00, $98, $11, $00 + DB $00, $00, $21, $00 + DB $00, $00, $21, $00 + DB $00, $00, $21, $00 + DB $00, $00, $21, $00 + DB $00, $00, $21, $00 + DB $00, $00, $21, $00 + DB $00, $00, $21, $00 + DB $00, $00, $98, $12, $00 + DB $00, $00, $21, $00 + DB $00, $00, $21, $00 + DB $00, $00, $21, $00 + DB $00, $00, $21, $00 + DB $00, $00, $21, $00 + DB $00, $00, $21, $00 + DB $00, $00, $21, $00 + DB $00, $00, $98, $13, $00 + DB $00, $00, $21, $00 + DB $00, $00, $21, $00 + DB $00, $00, $21, $00 + DB $00, $00, $21, $00 + DB $00, $00, $21, $00 + DB $00, $00, $21, $00 + DB $00, $00, $21, $00 + + SECTION "instr_test_1", ROMX +instr_test_1: + DB $00, $00, $98, $14, $00 + DB $00, $00, $21, $00 + DB $00, $00, $21, $00 + DB $00, $00, $21, $00 + DB $00, $00, $21, $00 + DB $00, $00, $21, $00 + DB $00, $00, $21, $00 + DB $00, $00, $21, $00 + DB $00, $00, $98, $15, $00 + DB $00, $00, $21, $00 + DB $00, $00, $21, $00 + DB $00, $00, $21, $00 + DB $00, $00, $21, $00 + DB $00, $00, $21, $00 + DB $00, $00, $21, $00 + DB $00, $00, $21, $00 + DB $00, $00, $98, $16, $00 + DB $00, $00, $21, $00 + DB $00, $00, $21, $00 + DB $00, $00, $21, $00 + DB $00, $00, $21, $00 + DB $00, $00, $21, $00 + DB $00, $00, $21, $00 + DB $00, $00, $21, $00 + DB $00, $00, $98, $17, $00 + DB $00, $00, $21, $00 + DB $00, $00, $21, $00 + DB $00, $00, $21, $00 + DB $00, $00, $21, $00 + DB $00, $00, $21, $00 + DB $00, $00, $21, $00 + DB $00, $00, $21, $00 + DB $00, $00, $20, $80, $0F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $81, $0F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $82, $0F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $83, $0F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + + SECTION "instr_test_2", ROMX +instr_test_2: + DB $00, $00, $00, $84, $0F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $85, $0F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $86, $0F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $87, $0F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $88, $0F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $89, $0F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $8A, $0F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $8B, $0F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + + SECTION "instr_test_3", ROMX +instr_test_3: + DB $00, $00, $00, $8C, $0F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $8D, $0F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $8E, $0F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $8F, $0F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $2F + DB $00, $00, $00, $20 + DB $00, $00, $00, $00 + DB $00, $00, $00, $00 + DB $00, $00, $00, $00 + DB $00, $00, $00, $00 + DB $00, $00, $00, $00 + DB $00, $00, $00, $00 + DB $00, $00, $00, $00 + DB $00, $00, $00, $00 + DB $00, $00, $00, $00 + DB $00, $00, $00, $00 + DB $00, $00, $00, $00 + DB $00, $00, $00, $00 + DB $00, $00, $00, $00 + DB $00, $00, $00, $00 + DB $00, $00, $00, $00 + DB $00, $00, $00, $00 + DB $00, $00, $00, $00 + DB $00, $00, $00, $00 + DB $00, $00, $00, $00 + DB $00, $00, $00, $00 + DB $00, $00, $00, $00 + DB $00, $00, $00, $00 + DB $00, $00, $00, $00 + DB $00, $00, $00, $00 + DB $00, $00, $00, $00 + DB $00, $00, $00, $00 + DB $00, $00, $00, $00 + DB $00, $00, $00, $00 + DB $00, $00, $00, $00 + DB $00, $00, $00, $00 + DB $00, $00, $00, $00 + + SECTION "instr_test_data", ROM0 +instr_test_data:: + DB BANK(instr_test_0) + DW instr_test_0 + DB BANK(instr_test_1) + DW instr_test_1 + DB BANK(instr_test_2) + DW instr_test_2 + DB BANK(instr_test_3) + DW instr_test_3 + DB $00 + DW $0000 + + diff --git a/CardHelpers.inc b/CardHelpers.inc index 31985ca..6fc42a8 100644 --- a/CardHelpers.inc +++ b/CardHelpers.inc @@ -1,6 +1,8 @@ ; CARD_HELPER_VARS_START defines the beginning of the $100 bytes set aside for system usage -def cvCardBank equ 0 -def cvCardAddress equ 1 ; location of the current card's struct +PUSHS "Card Helper Vars", WRAM0[CARD_HELPER_VARS_START] +cvCardBank: db +cvCardAddress: dw +POPS LoadCardData: LoadCardDataAsync: @@ -33,14 +35,14 @@ LoadCardDataAsync: add hl, bc ; triple add bc entries are bank, addr, addr ld a, [hl+] - ld [CARD_HELPER_VARS_START + cvCardBank], a + ld [cvCardBank], a ld [rROMB0], a ; select the specified bank ; follow the pointer we're looking at, and write it to cvCardAddress ld a, [hl+] - ld [CARD_HELPER_VARS_START + cvCardAddress], a + ld [cvCardAddress], a ld c, a ld a, [hl+] - ld [CARD_HELPER_VARS_START + cvCardAddress + 1], a + ld [cvCardAddress + 1], a ld b, a ld h, b @@ -82,9 +84,9 @@ LoadCardDataAsync: call CopyTilesToMap - ld a, [CARD_HELPER_VARS_START + cvCardAddress] + ld a, [cvCardAddress] ld l, a - ld a, [CARD_HELPER_VARS_START + cvCardAddress + 1] + ld a, [cvCardAddress + 1] ld h, a ; hl now contains the address of the card data. ld b, 0 @@ -110,9 +112,9 @@ LoadCardDataAsync: call CardInit - ld a, [CARD_HELPER_VARS_START + cvCardAddress] + ld a, [cvCardAddress] ld l, a - ld a, [CARD_HELPER_VARS_START + cvCardAddress + 1] + ld a, [cvCardAddress + 1] ld h, a ; hl now contains the address of the card data. ld b, 0 @@ -135,9 +137,9 @@ LoadCardDataAsync: call CopyRange - ld a, [CARD_HELPER_VARS_START + cvCardAddress] + ld a, [cvCardAddress] ld l, a - ld a, [CARD_HELPER_VARS_START + cvCardAddress + 1] + ld a, [cvCardAddress + 1] ld h, a ; hl now contains the address of the card data. ld b, 0 diff --git a/CopyRangeSafe.inc b/CopyRange.inc similarity index 51% rename from CopyRangeSafe.inc rename to CopyRange.inc index 89ef549..b855437 100644 --- a/CopyRangeSafe.inc +++ b/CopyRange.inc @@ -1,18 +1,3 @@ -; variables for safe transfer async function -DEF vSafeCopySource EQU $ff80 -DEF vSafeCopyDest EQU vSafeCopySource + 2 -DEF vSafeCopyCount EQU vSafeCopyDest + 2 ; check this for safe transfer being complete -DEF vSafeCopyOriginalCount EQU vSafeCopyCount + 2 -; stash previous interrupt state before using the interrupts -DEF vSafeCopyLYC EQU vSafeCopyOriginalCount + 2 ; stashes $FF45, the LYC register -DEF vSafeCopySTAT EQU vSafeCopyLYC + 1 ; stashes $FF41, the STAT register -DEF vSafeCopyInterrupt EQU vSafeCopySTAT + 1 ; stashes the previous LCD interrupt -DEF vSafeCopyInterruptEnable EQU vSafeCopyInterrupt + 2 ; stashes $FFFF, which interrupts are enabled - -DEF SAFE_TRANSFER_START EQU 145 -DEF SAFE_TRANSFER_END EQU 153 - - CopyRange: CopyRangeUnsafe: ; hl is source diff --git a/CopyTilesSafe.inc b/CopyTiles.inc similarity index 100% rename from CopyTilesSafe.inc rename to CopyTiles.inc diff --git a/Random.inc b/Random.inc index 3e6dc2d..f0546f5 100644 --- a/Random.inc +++ b/Random.inc @@ -101,8 +101,7 @@ RandomUnderD: ; takes d as limit (inclusive) ret z ret c jr .inOne - - + SwapCards: ; takes hl as array, c and e as indices to swap (uses b and d) inc hl ; first element of array push hl ; save it for later @@ -122,10 +121,3 @@ SwapCards: ; takes hl as array, c and e as indices to swap (uses b and d) add hl, bc ld [hl], d ; put old [hl+0e] in [hl+0c] ret - - - - - - - \ No newline at end of file diff --git a/ScreenCardBrowse.inc b/ScreenCardBrowse.inc index ecdfe5e..6cc97ab 100644 --- a/ScreenCardBrowse.inc +++ b/ScreenCardBrowse.inc @@ -1,5 +1,4 @@ ; screen variables shared with screencardread -;DEF vPreviousCardIndex EQU VARIABLES_START ScreenCardBrowse: dw CardBrowseSetup diff --git a/ScreenCardRead.inc b/ScreenCardRead.inc index 1f374c1..c5f73eb 100644 --- a/ScreenCardRead.inc +++ b/ScreenCardRead.inc @@ -1,5 +1,7 @@ -; screen variables -DEF vPreviousCardIndex EQU SCREEN_VARS_START+16 +PUSHS UNION "Screen Variables", WRAM0[SCREEN_VARS_START] +ds 16 ; why are we putting this so far in? +vPreviousCardIndex: db +POPS ScreenCardRead: dw CardReadSetup diff --git a/ScreenMainMenu.inc b/ScreenMainMenu.inc index ba2e7bd..68b9aee 100644 --- a/ScreenMainMenu.inc +++ b/ScreenMainMenu.inc @@ -1,20 +1,22 @@ -; global variables at the start of hram -DEF vCurrentSpread EQU GLOBAL_VARS_START ; 16bit address of current spread, ff90 -DEF vSelectedSpreadIndex equ vCurrentSpread + 2 ; ff92 -def vSelectedSpreadCard equ vSelectedSpreadIndex + 1 ; ff93 -def vSelectedCardIndex equ vSelectedSpreadCard+1 ; ff94 -DEF vFrameCountSquares EQU vSelectedCardIndex+1 ; ff95 -DEF vTime EQU vFrameCountSquares+1 ; 16bit ; ff96 -def vBlocked EQU vTime+2 +PUSHS UNION "Global Variables", WRAM0[GLOBAL_VARS_START] +vCurrentSpread: dw +vSelectedSpreadIndex: db +vSelectedSpreadCard: db +vSelectedCardIndex: db +vFrameCountSquares: db +vTime: dw +vBlocked: db println "vBlocked is ", vBlocked ; - +POPS ; screen-specific variables -DEF vFrameCount1 EQU SCREEN_VARS_START -DEF vFrameCount2 equ vFrameCount1+1 -DEF vFrameCount3 EQU vFrameCount2+1 -DEF vMenuIndex equ vFrameCount3+1 -DEF vMenuIndexPrevious equ vMenuIndex + 1 +PUSHS UNION "Screen Variables", WRAM0[SCREEN_VARS_START] +vFrameCount1: db +vFrameCount2: db +vFrameCount3: db +vMenuIndex: db +vMenuIndexPrevious: db +POPS ScreenMainMenu: dw MainMenuSetup diff --git a/ScreenShuffle.inc b/ScreenShuffle.inc index ee95ef1..7b2a2cc 100644 --- a/ScreenShuffle.inc +++ b/ScreenShuffle.inc @@ -1,11 +1,10 @@ -; screen variables already ddefined in screencardread -;DEF vPreviousCardIndex EQU VARIABLES_START -;def vBlocked equ vPreviousCardIndex + 1 -def vAnimationFrame EQU SCREEN_VARS_START -def vState EQU vAnimationFrame+1 -def vCurrentAnimation EQU vState+1 ; 2 bytes -def vShuffleIndex equ vCurrentAnimation+2 -def vShuffleTime equ vShuffleIndex+1 ; 2 bytes +PUSHS UNION "Screen Variables", WRAM0[SCREEN_VARS_START] +vAnimationFrame: db ;def vAnimationFrame EQU SCREEN_VARS_START +vState: db ;def vState EQU vAnimationFrame+1 +vCurrentAnimation: dw ;def vCurrentAnimation EQU vState+1 ; 2 bytes +vShuffleIndex: db ;def vShuffleIndex equ vCurrentAnimation+2 +vShuffleTime: dw ;def vShuffleTime equ vShuffleIndex+1 ; 2 bytes +POPS def S_Center = 0 def S_RightOut = 1 diff --git a/ScreenSpreadSelect.inc b/ScreenSpreadSelect.inc index c12594a..517a4dc 100644 --- a/ScreenSpreadSelect.inc +++ b/ScreenSpreadSelect.inc @@ -1,5 +1,7 @@ -DEF vPreviousSpreadIndex EQU SCREEN_VARS_START -def vPreviousSpreadCard equ vPreviousSpreadIndex + 1 +PUSHS UNION "Screen Variables", WRAM0[SCREEN_VARS_START] +vPreviousSpreadIndex: db ; EQU SCREEN_VARS_START +vPreviousSpreadCard: db ; equ vPreviousSpreadIndex + 1 +POPS ScreenSpreadSelect: dw SpreadSelectSetup diff --git a/00thefool.aseprite b/card_art/00thefool.aseprite similarity index 100% rename from 00thefool.aseprite rename to card_art/00thefool.aseprite diff --git a/01themagician.aseprite b/card_art/01themagician.aseprite similarity index 100% rename from 01themagician.aseprite rename to card_art/01themagician.aseprite diff --git a/01themagician.asm b/card_art/01themagician.asm similarity index 100% rename from 01themagician.asm rename to card_art/01themagician.asm diff --git a/02thehighpriestess.aseprite b/card_art/02thehighpriestess.aseprite similarity index 100% rename from 02thehighpriestess.aseprite rename to card_art/02thehighpriestess.aseprite diff --git a/02thehighpriestess.asm b/card_art/02thehighpriestess.asm similarity index 100% rename from 02thehighpriestess.asm rename to card_art/02thehighpriestess.asm diff --git a/03theempress.aseprite b/card_art/03theempress.aseprite similarity index 100% rename from 03theempress.aseprite rename to card_art/03theempress.aseprite diff --git a/03theempress.asm b/card_art/03theempress.asm similarity index 100% rename from 03theempress.asm rename to card_art/03theempress.asm diff --git a/04theemperor.aseprite b/card_art/04theemperor.aseprite similarity index 100% rename from 04theemperor.aseprite rename to card_art/04theemperor.aseprite diff --git a/04theemperor.asm b/card_art/04theemperor.asm similarity index 100% rename from 04theemperor.asm rename to card_art/04theemperor.asm diff --git a/05thehierophant.aseprite b/card_art/05thehierophant.aseprite similarity index 100% rename from 05thehierophant.aseprite rename to card_art/05thehierophant.aseprite diff --git a/05thehierophant.asm b/card_art/05thehierophant.asm similarity index 100% rename from 05thehierophant.asm rename to card_art/05thehierophant.asm diff --git a/06thelovers.aseprite b/card_art/06thelovers.aseprite similarity index 100% rename from 06thelovers.aseprite rename to card_art/06thelovers.aseprite diff --git a/06thelovers.asm b/card_art/06thelovers.asm similarity index 100% rename from 06thelovers.asm rename to card_art/06thelovers.asm diff --git a/07thechariot.aseprite b/card_art/07thechariot.aseprite similarity index 100% rename from 07thechariot.aseprite rename to card_art/07thechariot.aseprite diff --git a/07thechariot.asm b/card_art/07thechariot.asm similarity index 100% rename from 07thechariot.asm rename to card_art/07thechariot.asm diff --git a/08strength.aseprite b/card_art/08strength.aseprite similarity index 100% rename from 08strength.aseprite rename to card_art/08strength.aseprite diff --git a/08strength.asm b/card_art/08strength.asm similarity index 100% rename from 08strength.asm rename to card_art/08strength.asm diff --git a/09thehermit.aseprite b/card_art/09thehermit.aseprite similarity index 100% rename from 09thehermit.aseprite rename to card_art/09thehermit.aseprite diff --git a/09thehermit.asm b/card_art/09thehermit.asm similarity index 100% rename from 09thehermit.asm rename to card_art/09thehermit.asm diff --git a/10wheeloffortune.aseprite b/card_art/10wheeloffortune.aseprite similarity index 100% rename from 10wheeloffortune.aseprite rename to card_art/10wheeloffortune.aseprite diff --git a/10wheeloffortune.asm b/card_art/10wheeloffortune.asm similarity index 100% rename from 10wheeloffortune.asm rename to card_art/10wheeloffortune.asm diff --git a/11justice.aseprite b/card_art/11justice.aseprite similarity index 100% rename from 11justice.aseprite rename to card_art/11justice.aseprite diff --git a/11justice.asm b/card_art/11justice.asm similarity index 100% rename from 11justice.asm rename to card_art/11justice.asm diff --git a/12thehangedman.aseprite b/card_art/12thehangedman.aseprite similarity index 100% rename from 12thehangedman.aseprite rename to card_art/12thehangedman.aseprite diff --git a/12thehangedman.asm b/card_art/12thehangedman.asm similarity index 100% rename from 12thehangedman.asm rename to card_art/12thehangedman.asm diff --git a/13death.aseprite b/card_art/13death.aseprite similarity index 100% rename from 13death.aseprite rename to card_art/13death.aseprite diff --git a/13death.asm b/card_art/13death.asm similarity index 100% rename from 13death.asm rename to card_art/13death.asm diff --git a/14temperance.aseprite b/card_art/14temperance.aseprite similarity index 100% rename from 14temperance.aseprite rename to card_art/14temperance.aseprite diff --git a/14temperance.asm b/card_art/14temperance.asm similarity index 100% rename from 14temperance.asm rename to card_art/14temperance.asm diff --git a/15thedevil.aseprite b/card_art/15thedevil.aseprite similarity index 100% rename from 15thedevil.aseprite rename to card_art/15thedevil.aseprite diff --git a/15thedevil.asm b/card_art/15thedevil.asm similarity index 100% rename from 15thedevil.asm rename to card_art/15thedevil.asm diff --git a/16thetower.aseprite b/card_art/16thetower.aseprite similarity index 100% rename from 16thetower.aseprite rename to card_art/16thetower.aseprite diff --git a/16thetower.asm b/card_art/16thetower.asm similarity index 100% rename from 16thetower.asm rename to card_art/16thetower.asm diff --git a/17thestar.aseprite b/card_art/17thestar.aseprite similarity index 100% rename from 17thestar.aseprite rename to card_art/17thestar.aseprite diff --git a/17thestar.asm b/card_art/17thestar.asm similarity index 100% rename from 17thestar.asm rename to card_art/17thestar.asm diff --git a/18themoon.aseprite b/card_art/18themoon.aseprite similarity index 100% rename from 18themoon.aseprite rename to card_art/18themoon.aseprite diff --git a/18themoon.asm b/card_art/18themoon.asm similarity index 100% rename from 18themoon.asm rename to card_art/18themoon.asm diff --git a/19thesun.aseprite b/card_art/19thesun.aseprite similarity index 100% rename from 19thesun.aseprite rename to card_art/19thesun.aseprite diff --git a/19thesun.asm b/card_art/19thesun.asm similarity index 100% rename from 19thesun.asm rename to card_art/19thesun.asm diff --git a/20judgement.aseprite b/card_art/20judgement.aseprite similarity index 100% rename from 20judgement.aseprite rename to card_art/20judgement.aseprite diff --git a/20judgement.asm b/card_art/20judgement.asm similarity index 100% rename from 20judgement.asm rename to card_art/20judgement.asm diff --git a/21theworld.aseprite b/card_art/21theworld.aseprite similarity index 100% rename from 21theworld.aseprite rename to card_art/21theworld.aseprite diff --git a/21theworld.asm b/card_art/21theworld.asm similarity index 100% rename from 21theworld.asm rename to card_art/21theworld.asm diff --git a/KeyArtTiles.asm b/card_art/KeyArtTiles.asm similarity index 100% rename from KeyArtTiles.asm rename to card_art/KeyArtTiles.asm diff --git a/SpriteTiles.asm b/card_art/SpriteTiles.asm similarity index 100% rename from SpriteTiles.asm rename to card_art/SpriteTiles.asm diff --git a/Sprites.asm b/card_art/Sprites.asm similarity index 100% rename from Sprites.asm rename to card_art/Sprites.asm diff --git a/SpritesLayer.asm b/card_art/SpritesLayer.asm similarity index 100% rename from SpritesLayer.asm rename to card_art/SpritesLayer.asm diff --git a/screendesigns.aseprite b/card_art/screendesigns.aseprite similarity index 100% rename from screendesigns.aseprite rename to card_art/screendesigns.aseprite diff --git a/screendesigns.asm b/card_art/screendesigns.asm similarity index 100% rename from screendesigns.asm rename to card_art/screendesigns.asm diff --git a/carillon.sav b/carillon.sav new file mode 100644 index 0000000000000000000000000000000000000000..6ec3dbf62e7a0205d6766946b61d4cb447fd8afd GIT binary patch literal 32768 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%0D-&$wYbu>A6lVWzyVjy)rhB46MpDT`M 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 IzI^q+0aEcZ@&Et; literal 0 HcmV?d00001 diff --git a/gbt_player.inc b/gbt_player.inc new file mode 100644 index 0000000..ddd96a2 --- /dev/null +++ b/gbt_player.inc @@ -0,0 +1,643 @@ +;############################################################################### +; +; GBT Player v3.1.0 +; +; SPDX-License-Identifier: MIT +; +; Copyright (c) 2009-2021, Antonio Niño Díaz +; +;############################################################################### + + INCLUDE "hardware.inc" +;############################################################################### +; +; GBT Player v3.1.0 +; +; SPDX-License-Identifier: MIT +; +; Copyright (c) 2009-2020, Antonio Niño Díaz +; +;############################################################################### + + IF !DEF(GBT_PLAYER_INC) + DEF GBT_PLAYER_INC = 1 + +;############################################################################### + + EXPORT gbt_play ; Starts playing a song. + ; de = pointer to song data + ; a = default speed. Careful, 0 = 256! + ; bc = data bank (b ignored if ROM with < 256 banks) + ; THIS WILL CHANGE ROM BANK!!! + + EXPORT gbt_pause ; Pauses or unpauses the song. + ; a = 0 to pause, anything else to unpause. + + EXPORT gbt_loop ; Enables/disables looping at the end of the song. + ; a = 0 to stop at the end, anything else to loop + + EXPORT gbt_stop ; Stops the song. + + EXPORT gbt_enable_channels ; Enables given channels. + ; a = channel flags ORed: + ; channel 1 = 1 + ; channel 2 = 2 + ; channel 3 = 4 + ; channel 4 = 8 + + EXPORT gbt_update ; Updates the player, must be called each VBL. + ; Note: This will change the active ROM bank! + +; - If the following value is uncomented, the total of banks allowed is 512 +; (or more), but it's a bit slower. MBC5 ONLY, DOESN'T WORK WITH OTHERS!!! +; YOU MUST USE THE -512-banks OPTION WHEN CONVERTING A SONG WITH mod2gbt!!! +; - If it's commented, only 256 banks are allowed, it's a little bit faster +; and saves a few bytes. MBC1, MBC3 and MBC5 (and others). + +; DEF GBT_USE_MBC5_512BANKS = 1 + +;############################################################################### + + ENDC ; GBT_PLAYER_INC + +;############################################################################### + + +;############################################################################### + + SECTION "GBT_VAR_1",WRAMX[$d800] + +;------------------------------------------------------------------------------- + +gbt_playing: DS 1 + +; pointer to the pattern pointer array +gbt_pattern_array_ptr: DS 2 ; LSB first +IF DEF(GBT_USE_MBC5_512BANKS) +gbt_pattern_array_bank: DS 2 ; LSB first +ELSE +gbt_pattern_array_bank: DS 1 +ENDC + +; playing speed +gbt_speed:: DS 1 + +; Up to 12 bytes per step are copied here to be handled in functions in bank 1 +gbt_temp_play_data:: DS 12 + +gbt_loop_enabled: DS 1 +gbt_ticks_elapsed:: DS 1 +gbt_current_step:: DS 1 +gbt_current_pattern:: DS 1 +gbt_current_step_data_ptr:: DS 2 ; pointer to next step data - LSB first +IF DEF(GBT_USE_MBC5_512BANKS) +gbt_current_step_data_bank:: DS 2 ; bank of current pattern data - LSB first +ELSE +gbt_current_step_data_bank:: DS 1 ; bank of current pattern data +ENDC + +gbt_channels_enabled:: DS 1 + +gbt_pan:: DS 4*1 ; Ch 1-4 +gbt_vol:: DS 4*1 ; Ch 1-4 +gbt_instr:: DS 4*1 ; Ch 1-4 +gbt_freq:: DS 3*2 ; Ch 1-3 + +gbt_channel3_loaded_instrument:: DS 1 ; current loaded instrument ($FF if none) + +; Arpeggio -> Ch 1-3 +gbt_arpeggio_freq_index:: DS 3*3 ; {base index, base index+x, base index+y} * 3 +gbt_arpeggio_enabled:: DS 3*1 ; if 0, disabled +gbt_arpeggio_tick:: DS 3*1 + +; Cut note +gbt_cut_note_tick:: DS 4*1 ; If tick == gbt_cut_note_tick, stop note. + +; Last step of last pattern this is set to 1 +gbt_have_to_stop_next_step:: DS 1 + +gbt_update_pattern_pointers:: DS 1 ; set to 1 by jump effects + +;############################################################################### + + SECTION "GBT_BANK0",ROM0 + +;------------------------------------------------------------------------------- + +gbt_get_pattern_ptr:: ; a = pattern number + + ; loads a pointer to pattern a into gbt_current_step_data_ptr and + ; gbt_current_step_data_bank + + ld e,a + ld d,0 + +IF DEF(GBT_USE_MBC5_512BANKS) + ld a,[gbt_pattern_array_bank+0] + ld [rROMB0],a ; MBC5 - Set bank + ld a,[gbt_pattern_array_bank+1] + ld [rROMB1],a ; MBC5 - Set bank +ELSE + ld a,[gbt_pattern_array_bank] + ld [rROMB0],a ; MBC1, MBC3, MBC5 - Set bank +ENDC + + ld hl,gbt_pattern_array_ptr + ld a,[hl+] + ld h,[hl] + ld l,a + + ; hl = pointer to list of pointers + ; de = pattern number + +IF DEF(GBT_USE_MBC5_512BANKS) + add hl,de +ENDC + add hl,de + add hl,de + add hl,de + + ; hl = pointer to pattern bank + + ld a,[hl+] + ld [gbt_current_step_data_bank+0],a +IF DEF(GBT_USE_MBC5_512BANKS) + ld a,[hl+] + ld [gbt_current_step_data_bank+1],a +ENDC + + ; hl = pointer to pattern data + + ld a,[hl+] + ld h,[hl] + ld l,a + + ld a,l + ld [gbt_current_step_data_ptr],a + ld a,h + ld [gbt_current_step_data_ptr+1],a + + ret + +;------------------------------------------------------------------------------- + +gbt_get_pattern_ptr_banked:: ; a = pattern number + + push de + call gbt_get_pattern_ptr + pop de + + ld hl,gbt_current_step_data_ptr + ld a,[hl+] + ld b,a + ld a,[hl] + or a,b + jr nz,.dont_loop + xor a,a + ld [gbt_current_pattern], a +.dont_loop: + +IF DEF(GBT_USE_MBC5_512BANKS) + xor a,a + ld [rROMB1],a +ENDC + ld a,$01 + ld [rROMB0],a ; MBC1, MBC3, MBC5 - Set bank 1 + + ret + +;------------------------------------------------------------------------------- + +gbt_play:: ; de = data, bc = bank, a = speed + + ld hl,gbt_pattern_array_ptr + ld [hl],e + inc hl + ld [hl],d + + ld [gbt_speed],a + + ld a,c + ld [gbt_pattern_array_bank+0],a +IF DEF(GBT_USE_MBC5_512BANKS) + ld a,b + ld [gbt_pattern_array_bank+1],a +ENDC + + ld a,0 + call gbt_get_pattern_ptr + + xor a,a + ld [gbt_current_step],a + ld [gbt_current_pattern],a + ld [gbt_ticks_elapsed],a + ld [gbt_loop_enabled],a + ld [gbt_have_to_stop_next_step],a + ld [gbt_update_pattern_pointers],a + + ld a,$FF + ld [gbt_channel3_loaded_instrument],a + + ld a,$0F + ld [gbt_channels_enabled],a + + ld hl,gbt_pan + ld a,$11 ; L and R + ld [hl+],a + add a,a + ld [hl+],a + add a,a + ld [hl+],a + add a,a + ld [hl],a + + ld hl,gbt_vol + ld a,$F0 ; 100% + ld [hl+],a + ld [hl+],a + ld a,$20 ; 100% + ld [hl+],a + ld a,$F0 ; 100% + ld [hl+],a + + ld a,0 + + ld hl,gbt_instr + ld [hl+],a + ld [hl+],a + ld [hl+],a + ld [hl+],a + + ld hl,gbt_freq + ld [hl+],a + ld [hl+],a + ld [hl+],a + ld [hl+],a + ld [hl+],a + ld [hl+],a + + ld [gbt_arpeggio_enabled+0],a + ld [gbt_arpeggio_enabled+1],a + ld [gbt_arpeggio_enabled+2],a + + ld a,$FF + ld [gbt_cut_note_tick+0],a + ld [gbt_cut_note_tick+1],a + ld [gbt_cut_note_tick+2],a + ld [gbt_cut_note_tick+3],a + + ld a,$80 + ld [rNR52],a + ld a,$00 + ld [rNR51],a + ld a,$00 ; 0% + ld [rNR50],a + + xor a,a + ld [rNR10],a + ld [rNR11],a + ld [rNR12],a + ld [rNR13],a + ld [rNR14],a + ld [rNR21],a + ld [rNR22],a + ld [rNR23],a + ld [rNR24],a + ld [rNR30],a + ld [rNR31],a + ld [rNR32],a + ld [rNR33],a + ld [rNR34],a + ld [rNR41],a + ld [rNR42],a + ld [rNR43],a + ld [rNR44],a + + ld a,$77 ; 100% + ld [rNR50],a + + ld a,$01 + ld [gbt_playing],a + + ret + +;------------------------------------------------------------------------------- + +gbt_pause:: ; a = pause/unpause + ld [gbt_playing],a + or a,a + jr nz,.gbt_pause_unmute + + ; Silence all channels + xor a,a + ld [rNR51],a + + ret + +.gbt_pause_unmute: ; Unmute sound if playback is resumed + + ; Restore panning status + ld hl,gbt_pan + ld a,[hl+] + or a,[hl] + inc hl + or a,[hl] + inc hl + or a,[hl] + ld [rNR51],a + + ret + +;------------------------------------------------------------------------------- + +gbt_loop:: ; a = loop/don't loop + ld [gbt_loop_enabled],a + ret + +;------------------------------------------------------------------------------- + +gbt_stop:: + xor a,a + ld [gbt_playing],a + ld [rNR50],a + ld [rNR51],a + ld [rNR52],a + ret + +;------------------------------------------------------------------------------- + +gbt_enable_channels:: ; a = channel flags (channel flag = (1<<(channel_num-1))) + ld [gbt_channels_enabled],a + ret + +;------------------------------------------------------------------------------- + + EXPORT gbt_update_bank1 + +gbt_update:: + + ld a,[gbt_playing] + or a,a + ret z ; If not playing, return + + ; Handle tick counter + + ld hl,gbt_ticks_elapsed + ld a,[gbt_speed] ; a = total ticks + ld b,[hl] ; b = ticks elapsed + inc b + ld [hl],b + cp a,b + jr z,.dontexit + + ; Tick != Speed, update effects and exit +IF DEF(GBT_USE_MBC5_512BANKS) + xor a,a + ld [rROMB1],a +ENDC + ld a,$01 + ld [rROMB0],a ; MBC1, MBC3, MBC5 - Set bank 1 + ; Call update function in bank 1 (in gbt_player_bank1.s) + call gbt_update_effects_bank1 + + ret + +.dontexit: + ld [hl],$00 ; reset tick counter + + ; Clear tick-based effects + ; ------------------------ + + xor a,a + ld hl,gbt_arpeggio_enabled ; Disable arpeggio + ld [hl+],a + ld [hl+],a + ld [hl],a + dec a ; a = $FF + ld hl,gbt_cut_note_tick ; Disable cut note + ld [hl+],a + ld [hl+],a + ld [hl+],a + ld [hl],a + + ; Update effects + ; -------------- + +IF DEF(GBT_USE_MBC5_512BANKS) + xor a,a + ld [rROMB1],a +ENDC + ld a,$01 + ld [rROMB0],a ; MBC1, MBC3, MBC5 - Set bank 1 + ; Call update function in bank 1 (in gbt_player_bank1.s) + call gbt_update_effects_bank1 + + ; Check if last step + ; ------------------ + + ld a,[gbt_have_to_stop_next_step] + or a,a + jr z,.dont_stop + + call gbt_stop + ld a,0 + ld [gbt_have_to_stop_next_step],a + ret + +.dont_stop: + + ; Get this step data + ; ------------------ + + ; Change to bank with song data + +IF DEF(GBT_USE_MBC5_512BANKS) + ld a,[gbt_current_step_data_bank+0] + ld [rROMB0],a ; MBC5 - Set bank + ld a,[gbt_current_step_data_bank+1] + ld [rROMB1],a ; MBC5 - Set bank +ELSE + ld a,[gbt_current_step_data_bank] + ld [rROMB0],a ; MBC1, MBC3, MBC5 - Set bank +ENDC + + ; Get step data + + ld a,[gbt_current_step_data_ptr] + ld l,a + ld a,[gbt_current_step_data_ptr+1] + ld h,a ; hl = pointer to data + + ld de,gbt_temp_play_data + + ld b,4 +.copy_loop: ; copy as bytes as needed for this step + + ld a,[hl+] + ld [de],a + inc de + bit 7,a + jr nz,.more_bytes + bit 6,a + jr z,.no_more_bytes_this_channel + + jr .one_more_byte + +.more_bytes: + + ld a,[hl+] + ld [de],a + inc de + bit 7,a + jr z,.no_more_bytes_this_channel + +.one_more_byte: + + ld a,[hl+] + ld [de],a + inc de + +.no_more_bytes_this_channel: + dec b + jr nz,.copy_loop + + ld a,l + ld [gbt_current_step_data_ptr],a + ld a,h + ld [gbt_current_step_data_ptr+1],a ; save pointer to data + + ; Increment step/pattern + ; ---------------------- + + ; Increment step + + ld a,[gbt_current_step] + inc a + ld [gbt_current_step],a + cp a,64 + jr nz,.dont_increment_pattern + + ; Increment pattern + + ld a,0 + ld [gbt_current_step],a ; Step 0 + + ld a,[gbt_current_pattern] + inc a + ld [gbt_current_pattern],a + + call gbt_get_pattern_ptr + + ld a,[gbt_current_step_data_ptr] + ld b,a + ld a,[gbt_current_step_data_ptr+1] + or a,b + jr nz,.not_ended ; if pointer is 0, song has ended + + ld a,[gbt_loop_enabled] + and a,a + + jr z,.loop_disabled + + ; If loop is enabled, jump to pattern 0 + + ld a,0 + ld [gbt_current_pattern],a + + call gbt_get_pattern_ptr + + jr .end_handling_steps_pattern + +.loop_disabled: + + ; If loop is disabled, stop song + ; Stop it next step, if not this step won't be played + + ld a,1 + ld [gbt_have_to_stop_next_step],a + +.not_ended: + +.dont_increment_pattern: + +.end_handling_steps_pattern: + +IF DEF(GBT_USE_MBC5_512BANKS) + xor a,a + ld [rROMB1],a ; MBC5 +ENDC + ld a,$01 + ld [rROMB0],a ; MBC1, MBC3, MBC5 - Set bank 1 + ; Call update function in bank 1 (in gbt_player_bank1.s) + call gbt_update_bank1 + + ; Check if any effect has changed the pattern or step + + ld a,[gbt_update_pattern_pointers] + and a,a + ret z + ; if any effect has changed the pattern or step, update + + xor a,a + ld [gbt_update_pattern_pointers],a ; clear update flag + + ld [gbt_have_to_stop_next_step],a ; clear stop flag + + ld a,[gbt_current_pattern] + call gbt_get_pattern_ptr ; set ptr to start of the pattern + + ; Search the step + + ; Change to bank with song data + +IF DEF(GBT_USE_MBC5_512BANKS) + ld a,[gbt_pattern_array_bank+1] + ld [rROMB1],a ; MBC5 +ENDC + ld a,[gbt_pattern_array_bank+0] + ld [rROMB0],a ; MBC1, MBC3, MBC5 + + ld a,[gbt_current_step_data_ptr] + ld l,a + ld a,[gbt_current_step_data_ptr+1] + ld h,a ; hl = pointer to data + + ld a,[gbt_current_step] + and a,a + ret z ; if changing to step 0, exit + + add a,a + add a,a + ld b,a ; b = iterations = step * 4 (number of channels) +.next_channel: + + ld a,[hl+] + bit 7,a + jr nz,.next_channel_more_bytes + bit 6,a + jr z,.next_channel_no_more_bytes_this_channel + + jr .next_channel_one_more_byte + +.next_channel_more_bytes: + + ld a,[hl+] + bit 7,a + jr z,.next_channel_no_more_bytes_this_channel + +.next_channel_one_more_byte: + + ld a,[hl+] + +.next_channel_no_more_bytes_this_channel: + dec b + jr nz,.next_channel + + ld a,l + ld [gbt_current_step_data_ptr],a + ld a,h + ld [gbt_current_step_data_ptr+1],a ; save pointer to data + + ret + +;############################################################################### diff --git a/gbt_player_bank1.inc b/gbt_player_bank1.inc new file mode 100644 index 0000000..14093ba --- /dev/null +++ b/gbt_player_bank1.inc @@ -0,0 +1,1389 @@ +;############################################################################### +; +; GBT Player v3.1.0 +; +; SPDX-License-Identifier: MIT +; +; Copyright (c) 2009-2020 Antonio Niño Díaz +; +;############################################################################### + + INCLUDE "hardware.inc" + INCLUDE "gbt_player.inc" + +;############################################################################### + + SECTION "GBT_BANK1",ROMX,BANK[1] + +;------------------------------------------------------------------------------- + +gbt_wave: ; 8 sounds +DB $A5,$D7,$C9,$E1,$BC,$9A,$76,$31,$0C,$BA,$DE,$60,$1B,$CA,$03,$93 ; random +DB $F0,$E1,$D2,$C3,$B4,$A5,$96,$87,$78,$69,$5A,$4B,$3C,$2D,$1E,$0F +DB $FD,$EC,$DB,$CA,$B9,$A8,$97,$86,$79,$68,$57,$46,$35,$24,$13,$02 ; up-downs +DB $DE,$FE,$DC,$BA,$9A,$A9,$87,$77,$88,$87,$65,$56,$54,$32,$10,$12 +DB $AB,$CD,$EF,$ED,$CB,$A0,$12,$3E,$DC,$BA,$BC,$DE,$FE,$DC,$32,$10 ; tri. broken +DB $FF,$EE,$DD,$CC,$BB,$AA,$99,$88,$77,$66,$55,$44,$33,$22,$11,$00 ; triangular +DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$00,$00,$00,$00,$00,$00,$00,$00 ; square +DB $79,$BC,$DE,$EF,$FF,$EE,$DC,$B9,$75,$43,$21,$10,$00,$11,$23,$45 ; sine + +gbt_noise: ; 16 sounds + ; 7 bit + DB $5F,$5B,$4B,$2F,$3B,$58,$1F,$0F + ; 15 bit + DB $90,$80,$70,$50,$00 + DB $67,$63,$53 + +gbt_frequencies: + DW 44, 156, 262, 363, 457, 547, 631, 710, 786, 854, 923, 986 + DW 1046, 1102, 1155, 1205, 1253, 1297, 1339, 1379, 1417, 1452, 1486, 1517 + DW 1546, 1575, 1602, 1627, 1650, 1673, 1694, 1714, 1732, 1750, 1767, 1783 + DW 1798, 1812, 1825, 1837, 1849, 1860, 1871, 1881, 1890, 1899, 1907, 1915 + DW 1923, 1930, 1936, 1943, 1949, 1954, 1959, 1964, 1969, 1974, 1978, 1982 + DW 1985, 1988, 1992, 1995, 1998, 2001, 2004, 2006, 2009, 2011, 2013, 2015 + +;------------------------------------------------------------------------------- + +_gbt_get_freq_from_index: ; a = index, bc = returned freq + ld hl,gbt_frequencies + ld c,a + ld b,$00 + add hl,bc + add hl,bc + ld c,[hl] + inc hl + ld b,[hl] + ret + +;------------------------------------------------------------------------------- +; ---------------------------------- Channel 1 --------------------------------- +;------------------------------------------------------------------------------- + +gbt_channel_1_handle:: ; de = info + + ld a,[gbt_channels_enabled] + and a,$01 + jr nz,.channel1_enabled + + ; Channel is disabled. Increment pointer as needed + + ld a,[de] + inc de + bit 7,a + jr nz,.more_bytes + bit 6,a + jr z,.no_more_bytes_this_channel + + jr .one_more_byte + +.more_bytes: + + ld a,[de] + inc de + bit 7,a + jr z,.no_more_bytes_this_channel + +.one_more_byte: + + inc de + +.no_more_bytes_this_channel: + + ret + +.channel1_enabled: + + ; Channel 1 is enabled + + ld a,[de] + inc de + + bit 7,a + jr nz,.has_frequency + + ; Not frequency + + bit 6,a + jr nz,.instr_effects + + ; Set volume or NOP + + bit 5,a + jr nz,.just_set_volume + + ; NOP + + ret + +.just_set_volume: + + ; Set volume + + and a,$0F + swap a + ld [gbt_vol+0],a + + jr .refresh_channel1_regs + +.instr_effects: + + ; Set instrument and effect + + ld b,a ; save byte + + and a,$30 + add a,a + add a,a + ld [gbt_instr+0],a ; Instrument + + ld a,b ; restore byte + + and a,$0F ; a = effect + + call gbt_channel_1_set_effect + + jr .refresh_channel1_regs + +.has_frequency: + + ; Has frequency + + and a,$7F + ld [gbt_arpeggio_freq_index+0*3],a + ; This destroys hl and a. Returns freq in bc + call _gbt_get_freq_from_index + + ld a,c + ld [gbt_freq+0*2+0],a + ld a,b + ld [gbt_freq+0*2+1],a ; Get frequency + + ld a,[de] + inc de + + bit 7,a + jr nz,.freq_instr_and_effect + + ; Freq + Instr + Volume + + ld b,a ; save byte + + and a,$30 + add a,a + add a,a + ld [gbt_instr+0],a ; Instrument + + ld a,b ; restore byte + + and a,$0F ; a = volume + + swap a + ld [gbt_vol+0],a + + jr .refresh_channel1_regs + +.freq_instr_and_effect: + + ; Freq + Instr + Effect + + ld b,a ; save byte + + and a,$30 + add a,a + add a,a + ld [gbt_instr+0],a ; Instrument + + ld a,b ; restore byte + + and a,$0F ; a = effect + + call gbt_channel_1_set_effect + + ;jr .refresh_channel1_regs + +.refresh_channel1_regs: + + ; fall through!!!!! + +; ----------------- + +channel1_refresh_registers: + + xor a,a + ld [rNR10],a + ld a,[gbt_instr+0] + ld [rNR11],a + ld a,[gbt_vol+0] + ld [rNR12],a + ld a,[gbt_freq+0*2+0] + ld [rNR13],a + ld a,[gbt_freq+0*2+1] + or a,$80 ; start + ld [rNR14],a + + ret + +; ------------------ + +channel1_update_effects: ; returns 1 in a if it needed to update sound registers + + ; Cut note + ; -------- + + ld a,[gbt_cut_note_tick+0] + ld hl,gbt_ticks_elapsed + cp a,[hl] + jp nz,.dont_cut + + dec a ; a = $FF + ld [gbt_cut_note_tick+0],a ; disable cut note + + xor a,a ; vol = 0 + ld [rNR12],a + ld a,$80 ; start + ld [rNR14],a + +.dont_cut: + + ; Arpeggio + ; -------- + + ld a,[gbt_arpeggio_enabled+0] + and a,a + ret z ; a is 0, return 0 + + ; If enabled arpeggio, handle it + + ld a,[gbt_arpeggio_tick+0] + and a,a + jr nz,.not_tick_0 + + ; Tick 0 - Set original frequency + + ld a,[gbt_arpeggio_freq_index+0*3+0] + + call _gbt_get_freq_from_index + + ld a,c + ld [gbt_freq+0*2+0],a + ld a,b + ld [gbt_freq+0*2+1],a ; Set frequency + + ld a,1 + ld [gbt_arpeggio_tick+0],a + + ret ; ret 1 + +.not_tick_0: + + cp a,1 + jr nz,.not_tick_1 + + ; Tick 1 + + ld a,[gbt_arpeggio_freq_index+0*3+1] + + call _gbt_get_freq_from_index + + ld a,c + ld [gbt_freq+0*2+0],a + ld a,b + ld [gbt_freq+0*2+1],a ; Set frequency + + ld a,2 + ld [gbt_arpeggio_tick+0],a + + dec a + ret ; ret 1 + +.not_tick_1: + + ; Tick 2 + + ld a,[gbt_arpeggio_freq_index+0*3+2] + + call _gbt_get_freq_from_index + + ld a,c + ld [gbt_freq+0*2+0],a + ld a,b + ld [gbt_freq+0*2+1],a ; Set frequency + + xor a,a + ld [gbt_arpeggio_tick+0],a + + inc a ; ret 1 + ret + +; ----------------- + +; returns a = 1 if needed to update registers, 0 if not +gbt_channel_1_set_effect: ; a = effect, de = pointer to data. + + ld hl,.gbt_ch1_jump_table + ld c,a + ld b,0 + add hl,bc + add hl,bc + + ld a,[hl+] + ld h,[hl] + ld l,a + + ld a,[de] ; load args + inc de + + jp hl + +.gbt_ch1_jump_table: + DW .gbt_ch1_pan + DW .gbt_ch1_arpeggio + DW .gbt_ch1_cut_note + DW gbt_ch1234_nop + DW gbt_ch1234_nop + DW gbt_ch1234_nop + DW gbt_ch1234_nop + DW gbt_ch1234_nop + DW gbt_ch1234_jump_pattern + DW gbt_ch1234_jump_position + DW gbt_ch1234_speed + DW gbt_ch1234_nop + DW gbt_ch1234_nop + DW gbt_ch1234_nop + DW gbt_ch1234_nop + DW gbt_ch1234_nop + +.gbt_ch1_pan: + and a,$11 + ld [gbt_pan+0],a + xor a,a + ret ; ret 0 do not update registers, only NR51 at end. + +.gbt_ch1_arpeggio: + ld b,a ; b = params + + ld hl,gbt_arpeggio_freq_index+0*3 + ld c,[hl] ; c = base index + inc hl + + ld a,b + swap a + and a,$0F + add a,c + + ld [hl+],a ; save first increment + + ld a,b + and a,$0F + add a,c + + ld [hl],a ; save second increment + + ld a,1 + ld [gbt_arpeggio_enabled+0],a + ld [gbt_arpeggio_tick+0],a + + ret ; ret 1 + +.gbt_ch1_cut_note: + ld [gbt_cut_note_tick+0],a + xor a,a ; ret 0 + ret + +;------------------------------------------------------------------------------- +; ---------------------------------- Channel 2 --------------------------------- +;------------------------------------------------------------------------------- + +gbt_channel_2_handle:: ; de = info + + ld a,[gbt_channels_enabled] + and a,$02 + jr nz,.channel2_enabled + + ; Channel is disabled. Increment pointer as needed + + ld a,[de] + inc de + bit 7,a + jr nz,.more_bytes + bit 6,a + jr z,.no_more_bytes_this_channel + + jr .one_more_byte + +.more_bytes: + + ld a,[de] + inc de + bit 7,a + jr z,.no_more_bytes_this_channel + +.one_more_byte: + + inc de + +.no_more_bytes_this_channel: + + ret + +.channel2_enabled: + + ; Channel 2 is enabled + + ld a,[de] + inc de + + bit 7,a + jr nz,.has_frequency + + ; Not frequency + + bit 6,a + jr nz,.instr_effects + + ; Set volume or NOP + + bit 5,a + jr nz,.just_set_volume + + ; NOP + + ret + +.just_set_volume: + + ; Set volume + + and a,$0F + swap a + ld [gbt_vol+1],a + + jr .refresh_channel2_regs + +.instr_effects: + + ; Set instrument and effect + + ld b,a ; save byte + + and a,$30 + add a,a + add a,a + ld [gbt_instr+1],a ; Instrument + + ld a,b ; restore byte + + and a,$0F ; a = effect + + call gbt_channel_2_set_effect + + jr .refresh_channel2_regs + +.has_frequency: + + ; Has frequency + + and a,$7F + ld [gbt_arpeggio_freq_index+1*3],a + ; This destroys hl and a. Returns freq in bc + call _gbt_get_freq_from_index + + ld a,c + ld [gbt_freq+1*2+0],a + ld a,b + ld [gbt_freq+1*2+1],a ; Get frequency + + ld a,[de] + inc de + + bit 7,a + jr nz,.freq_instr_and_effect + + ; Freq + Instr + Volume + + ld b,a ; save byte + + and a,$30 + add a,a + add a,a + ld [gbt_instr+1],a ; Instrument + + ld a,b ; restore byte + + and a,$0F ; a = volume + + swap a + ld [gbt_vol+1],a + + jr .refresh_channel2_regs + +.freq_instr_and_effect: + + ; Freq + Instr + Effect + + ld b,a ; save byte + + and a,$30 + add a,a + add a,a + ld [gbt_instr+1],a ; Instrument + + ld a,b ; restore byte + + and a,$0F ; a = effect + + call gbt_channel_2_set_effect + + ;jr .refresh_channel2_regs + +.refresh_channel2_regs: + + ; fall through!!!!! + +; ----------------- + +channel2_refresh_registers: + + ld a,[gbt_instr+1] + ld [rNR21],a + ld a,[gbt_vol+1] + ld [rNR22],a + ld a,[gbt_freq+1*2+0] + ld [rNR23],a + ld a,[gbt_freq+1*2+1] + or a,$80 ; start + ld [rNR24],a + + ret + +; ------------------ + +channel2_update_effects: ; returns 1 in a if it needed to update sound registers + + ; Cut note + ; -------- + + ld a,[gbt_cut_note_tick+1] + ld hl,gbt_ticks_elapsed + cp a,[hl] + jp nz,.dont_cut + + dec a ; a = $FF + ld [gbt_cut_note_tick+1],a ; disable cut note + + xor a,a ; vol = 0 + ld [rNR22],a + ld a,$80 ; start + ld [rNR24],a + +.dont_cut: + + ; Arpeggio + ; -------- + + ld a,[gbt_arpeggio_enabled+1] + and a,a + ret z ; a is 0, return 0 + + ; If enabled arpeggio, handle it + + ld a,[gbt_arpeggio_tick+1] + and a,a + jr nz,.not_tick_0 + + ; Tick 0 - Set original frequency + + ld a,[gbt_arpeggio_freq_index+1*3+0] + + call _gbt_get_freq_from_index + + ld a,c + ld [gbt_freq+1*2+0],a + ld a,b + ld [gbt_freq+1*2+1],a ; Set frequency + + ld a,1 + ld [gbt_arpeggio_tick+1],a + + ret ; ret 1 + +.not_tick_0: + + cp a,1 + jr nz,.not_tick_1 + + ; Tick 1 + + ld a,[gbt_arpeggio_freq_index+1*3+1] + + call _gbt_get_freq_from_index + + ld a,c + ld [gbt_freq+1*2+0],a + ld a,b + ld [gbt_freq+1*2+1],a ; Set frequency + + ld a,2 + ld [gbt_arpeggio_tick+1],a + + dec a + ret ; ret 1 + +.not_tick_1: + + ; Tick 2 + + ld a,[gbt_arpeggio_freq_index+1*3+2] + + call _gbt_get_freq_from_index + + ld a,c + ld [gbt_freq+1*2+0],a + ld a,b + ld [gbt_freq+1*2+1],a ; Set frequency + + xor a,a + ld [gbt_arpeggio_tick+1],a + + inc a ; ret 1 + ret + +; ----------------- + +; returns a = 1 if needed to update registers, 0 if not +gbt_channel_2_set_effect: ; a = effect, de = pointer to data + + ld hl,.gbt_ch2_jump_table + ld c,a + ld b,0 + add hl,bc + add hl,bc + + ld a,[hl+] + ld h,[hl] + ld l,a + + ld a,[de] ; load args + inc de + + jp hl + +.gbt_ch2_jump_table: + DW .gbt_ch2_pan + DW .gbt_ch2_arpeggio + DW .gbt_ch2_cut_note + DW gbt_ch1234_nop + DW gbt_ch1234_nop + DW gbt_ch1234_nop + DW gbt_ch1234_nop + DW gbt_ch1234_nop + DW gbt_ch1234_jump_pattern + DW gbt_ch1234_jump_position + DW gbt_ch1234_speed + DW gbt_ch1234_nop + DW gbt_ch1234_nop + DW gbt_ch1234_nop + DW gbt_ch1234_nop + DW gbt_ch1234_nop + +.gbt_ch2_pan: + and a,$22 + ld [gbt_pan+1],a + xor a,a + ret ; ret 0 do not update registers, only NR51 at end. + +.gbt_ch2_arpeggio: + ld b,a ; b = params + + ld hl,gbt_arpeggio_freq_index+1*3 + ld c,[hl] ; c = base index + inc hl + + ld a,b + swap a + and a,$0F + add a,c + + ld [hl+],a ; save first increment + + ld a,b + and a,$0F + add a,c + + ld [hl],a ; save second increment + + ld a,1 + ld [gbt_arpeggio_enabled+1],a + ld [gbt_arpeggio_tick+1],a + + ret ; ret 1 + +.gbt_ch2_cut_note: + ld [gbt_cut_note_tick+1],a + xor a,a ; ret 0 + ret + +;------------------------------------------------------------------------------- +; ---------------------------------- Channel 3 --------------------------------- +;------------------------------------------------------------------------------- + +gbt_channel_3_handle:: ; de = info + + ld a,[gbt_channels_enabled] + and a,$04 + jr nz,.channel3_enabled + + ; Channel is disabled. Increment pointer as needed + + ld a,[de] + inc de + bit 7,a + jr nz,.more_bytes + bit 6,a + jr z,.no_more_bytes_this_channel + + jr .one_more_byte + +.more_bytes: + + ld a,[de] + inc de + bit 7,a + jr z,.no_more_bytes_this_channel + +.one_more_byte: + + inc de + +.no_more_bytes_this_channel: + + ret + +.channel3_enabled: + + ; Channel 3 is enabled + + ld a,[de] + inc de + + bit 7,a + jr nz,.has_frequency + + ; Not frequency + + bit 6,a + jr nz,.effects + + ; Set volume or NOP + + bit 5,a + jr nz,.just_set_volume + + ; NOP + + ret + +.just_set_volume: + + ; Set volume + + and a,$0F + swap a + ld [gbt_vol+2],a + + jr .refresh_channel3_regs + +.effects: + + ; Set effect + + and a,$0F ; a = effect + + call gbt_channel_3_set_effect + and a,a + ret z ; if 0, don't refresh registers + + jr .refresh_channel3_regs + +.has_frequency: + + ; Has frequency + + and a,$7F + ld [gbt_arpeggio_freq_index+2*3],a + ; This destroys hl and a. Returns freq in bc + call _gbt_get_freq_from_index + + ld a,c + ld [gbt_freq+2*2+0],a + ld a,b + ld [gbt_freq+2*2+1],a ; Get frequency + + ld a,[de] + inc de + + bit 7,a + jr nz,.freq_instr_and_effect + + ; Freq + Instr + Volume + + ld b,a ; save byte + + and a,$0F + ld [gbt_instr+2],a ; Instrument + + ld a,b ; restore byte + + and a,$30 ; a = volume + add a,a + ld [gbt_vol+2],a + + jr .refresh_channel3_regs + +.freq_instr_and_effect: + + ; Freq + Instr + Effect + + ld b,a ; save byte + + and a,$0F + ld [gbt_instr+2],a ; Instrument + + ld a,b ; restore byte + + and a,$70 + swap a ; a = effect (only 0-7 allowed here) + + call gbt_channel_3_set_effect + + ;jr .refresh_channel3_regs + +.refresh_channel3_regs: + + ; fall through!!!!! + +; ----------------- + +channel3_refresh_registers: + + xor a,a + ld [rNR30],a ; disable + + ld a,[gbt_channel3_loaded_instrument] + ld b,a + ld a,[gbt_instr+2] + cp a,b + call nz,gbt_channel3_load_instrument ; a = instrument + + ld a,$80 + ld [rNR30],a ; enable + + xor a,a + ld [rNR31],a + ld a,[gbt_vol+2] + ld [rNR32],a + ld a,[gbt_freq+2*2+0] + ld [rNR33],a + ld a,[gbt_freq+2*2+1] + or a,$80 ; start + ld [rNR34],a + + ret + +; ------------------ + +gbt_channel3_load_instrument: + + ld [gbt_channel3_loaded_instrument],a + + swap a ; a = a * 16 + ld c,a + ld b,0 + ld hl,gbt_wave + add hl,bc + + ld c,$30 + ld b,16 +.loop: + ld a,[hl+] + ld [$FF00+c],a + inc c + dec b + jr nz,.loop + + ret + +; ------------------ + +channel3_update_effects: ; returns 1 in a if it needed to update sound registers + + ; Cut note + ; -------- + + ld a,[gbt_cut_note_tick+2] + ld hl,gbt_ticks_elapsed + cp a,[hl] + jp nz,.dont_cut + + dec a ; a = $FF + ld [gbt_cut_note_tick+2],a ; disable cut note + + ld a,$80 + ld [rNR30],a ; enable + + xor a,a ; vol = 0 + ld [rNR32],a + ld a,$80 ; start + ld [rNR34],a + +.dont_cut: + + ; Arpeggio + ; -------- + + ld a,[gbt_arpeggio_enabled+2] + and a,a + ret z ; a is 0, return 0 + + ; If enabled arpeggio, handle it + + ld a,[gbt_arpeggio_tick+2] + and a,a + jr nz,.not_tick_0 + + ; Tick 0 - Set original frequency + + ld a,[gbt_arpeggio_freq_index+2*3+0] + + call _gbt_get_freq_from_index + + ld a,c + ld [gbt_freq+2*2+0],a + ld a,b + ld [gbt_freq+2*2+1],a ; Set frequency + + ld a,1 + ld [gbt_arpeggio_tick+2],a + + ret ; ret 1 + +.not_tick_0: + + cp a,1 + jr nz,.not_tick_1 + + ; Tick 1 + + ld a,[gbt_arpeggio_freq_index+2*3+1] + + call _gbt_get_freq_from_index + + ld a,c + ld [gbt_freq+2*2+0],a + ld a,b + ld [gbt_freq+2*2+1],a ; Set frequency + + ld a,2 + ld [gbt_arpeggio_tick+2],a + + dec a + ret ; ret 1 + +.not_tick_1: + + ; Tick 2 + + ld a,[gbt_arpeggio_freq_index+2*3+2] + + call _gbt_get_freq_from_index + + ld a,c + ld [gbt_freq+2*2+0],a + ld a,b + ld [gbt_freq+2*2+1],a ; Set frequency + + xor a,a + ld [gbt_arpeggio_tick+2],a + + inc a + ret ; ret 1 + +; ----------------- + +; returns a = 1 if needed to update registers, 0 if not +gbt_channel_3_set_effect: ; a = effect, de = pointer to data + + ld hl,.gbt_ch3_jump_table + ld c,a + ld b,0 + add hl,bc + add hl,bc + + ld a,[hl+] + ld h,[hl] + ld l,a + + ld a,[de] ; load args + inc de + + jp hl + +.gbt_ch3_jump_table: + DW .gbt_ch3_pan + DW .gbt_ch3_arpeggio + DW .gbt_ch3_cut_note + DW gbt_ch1234_nop + DW gbt_ch1234_nop + DW gbt_ch1234_nop + DW gbt_ch1234_nop + DW gbt_ch1234_nop + DW gbt_ch1234_jump_pattern + DW gbt_ch1234_jump_position + DW gbt_ch1234_speed + DW gbt_ch1234_nop + DW gbt_ch1234_nop + DW gbt_ch1234_nop + DW gbt_ch1234_nop + DW gbt_ch1234_nop + +.gbt_ch3_pan: + and a,$44 + ld [gbt_pan+2],a + xor a,a + ret ; ret 0 do not update registers, only NR51 at end. + +.gbt_ch3_arpeggio: + ld b,a ; b = params + + ld hl,gbt_arpeggio_freq_index+2*3 + ld c,[hl] ; c = base index + inc hl + + ld a,b + swap a + and a,$0F + add a,c + + ld [hl+],a ; save first increment + + ld a,b + and a,$0F + add a,c + + ld [hl],a ; save second increment + + ld a,1 + ld [gbt_arpeggio_enabled+2],a + ld [gbt_arpeggio_tick+2],a + + ret ; ret 1 + +.gbt_ch3_cut_note: + ld [gbt_cut_note_tick+2],a + xor a,a ; ret 0 + ret + +;------------------------------------------------------------------------------- +; ---------------------------------- Channel 4 --------------------------------- +;------------------------------------------------------------------------------- + +gbt_channel_4_handle:: ; de = info + + ld a,[gbt_channels_enabled] + and a,$08 + jr nz,.channel4_enabled + + ; Channel is disabled. Increment pointer as needed + + ld a,[de] + inc de + bit 7,a + jr nz,.more_bytes + bit 6,a + jr z,.no_more_bytes_this_channel + + jr .one_more_byte + +.more_bytes: + + ld a,[de] + inc de + bit 7,a + jr z,.no_more_bytes_this_channel + +.one_more_byte: + + inc de + +.no_more_bytes_this_channel: + + ret + +.channel4_enabled: + + ; Channel 4 is enabled + + ld a,[de] + inc de + + bit 7,a + jr nz,.has_instrument + + ; Not instrument + + bit 6,a + jr nz,.effects + + ; Set volume or NOP + + bit 5,a + jr nz,.just_set_volume + + ; NOP + + ret + +.just_set_volume: + + ; Set volume + + and a,$0F + swap a + ld [gbt_vol+3],a + + jr .refresh_channel4_regs + +.effects: + + ; Set effect + + and a,$0F ; a = effect + + call gbt_channel_4_set_effect + and a,a + ret z ; if 0, don't refresh registers + + jr .refresh_channel4_regs + +.has_instrument: + + ; Has instrument + + and a,$0F + ld hl,gbt_noise + ld c,a + ld b,0 + add hl,bc + ld a,[hl] ; a = instrument data + + ld [gbt_instr+3],a + + ld a,[de] + inc de + + bit 7,a + jr nz,.instr_and_effect + + ; Instr + Volume + + and a,$0F ; a = volume + + swap a + ld [gbt_vol+3],a + + jr .refresh_channel4_regs + +.instr_and_effect: + + ; Instr + Effect + + and a,$0F ; a = effect + + call gbt_channel_4_set_effect + + ;jr .refresh_channel4_regs + +.refresh_channel4_regs: + + ; fall through!!!!! + +; ----------------- + +channel4_refresh_registers: + + xor a,a + ld [rNR41],a + ld a,[gbt_vol+3] + ld [rNR42],a + ld a,[gbt_instr+3] + ld [rNR43],a + ld a,$80 ; start + ld [rNR44],a + + ret + +; ------------------ + +channel4_update_effects: ; returns 1 in a if it needed to update sound registers + + ; Cut note + ; -------- + + ld a,[gbt_cut_note_tick+3] + ld hl,gbt_ticks_elapsed + cp a,[hl] + jp nz,.dont_cut + + dec a ; a = $FF + ld [gbt_cut_note_tick+3],a ; disable cut note + + xor a,a ; vol = 0 + ld [rNR42],a + ld a,$80 ; start + ld [rNR44],a + +.dont_cut: + + xor a,a + ret ; a is 0, return 0 + +; ----------------- + +; returns a = 1 if needed to update registers, 0 if not +gbt_channel_4_set_effect: ; a = effect, de = pointer to data + + ld hl,.gbt_ch4_jump_table + ld c,a + ld b,0 + add hl,bc + add hl,bc + + ld a,[hl+] + ld h,[hl] + ld l,a + + ld a,[de] ; load args + inc de + + jp hl + +.gbt_ch4_jump_table: + DW .gbt_ch4_pan + DW gbt_ch1234_nop ; gbt_ch4_arpeggio + DW .gbt_ch4_cut_note + DW gbt_ch1234_nop + DW gbt_ch1234_nop + DW gbt_ch1234_nop + DW gbt_ch1234_nop + DW gbt_ch1234_nop + DW gbt_ch1234_jump_pattern + DW gbt_ch1234_jump_position + DW gbt_ch1234_speed + DW gbt_ch1234_nop + DW gbt_ch1234_nop + DW gbt_ch1234_nop + DW gbt_ch1234_nop + DW gbt_ch1234_nop + +.gbt_ch4_pan: + and a,$88 + ld [gbt_pan+3],a + xor a,a + ret ; ret 0 do not update registers, only NR51 at end. + +.gbt_ch4_cut_note: + ld [gbt_cut_note_tick+3],a + xor a,a ; ret 0 + ret + +;------------------------------------------------------------------------------- +;------------------------------------------------------------------------------- +;------------------------------------------------------------------------------- + +; Common effects go here: + +gbt_ch1234_nop: + xor a,a ;ret 0 + ret + +gbt_ch1234_jump_pattern: + ld [gbt_current_pattern],a + xor a,a + ld [gbt_current_step],a + ld [gbt_have_to_stop_next_step],a ; clear stop flag + ld a,1 + ld [gbt_update_pattern_pointers],a + xor a,a ;ret 0 + ret + +gbt_ch1234_jump_position: + ld [gbt_current_step],a + ld hl,gbt_current_pattern + inc [hl] + + ; Check to see if jump puts us past end of song + ld a,[hl] + call gbt_get_pattern_ptr_banked + ld a,1 + ld [gbt_update_pattern_pointers],a + xor a,a ;ret 0 + ret + +gbt_ch1234_speed: + ld [gbt_speed],a + xor a,a + ld [gbt_ticks_elapsed],a + ret ;ret 0 + +;------------------------------------------------------------------------------- + +gbt_update_bank1:: + + ld de,gbt_temp_play_data + + ; each function will return in de the pointer to next byte + + call gbt_channel_1_handle + + call gbt_channel_2_handle + + call gbt_channel_3_handle + + call gbt_channel_4_handle + + ; end of channel handling + + ld hl,gbt_pan + ld a,[hl+] + or a,[hl] + inc hl + or a,[hl] + inc hl + or a,[hl] + ld [rNR51],a ; handle panning... + + ret + +;------------------------------------------------------------------------------- + +gbt_update_effects_bank1:: + + call channel1_update_effects + and a,a + call nz,channel1_refresh_registers + + call channel2_update_effects + and a,a + call nz,channel2_refresh_registers + + call channel3_update_effects + and a,a + call nz,channel3_refresh_registers + + call channel4_update_effects + and a,a + call nz,channel4_refresh_registers + + ret + +;############################################################################### diff --git a/justice.asm b/justice.asm deleted file mode 100644 index dd90e6e..0000000 --- a/justice.asm +++ /dev/null @@ -1,101 +0,0 @@ - ; original export script by gabriel reis, modified by shoofle - - -KeyArtTiles: - - db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 - db $00,$00,$00,$60,$20,$5c,$3c,$43,$3c,$43,$20,$5c,$00,$60,$00,$00 - db $3f,$40,$3f,$40,$3f,$40,$3f,$40,$3f,$40,$3f,$40,$3f,$40,$3f,$40 - db $ff,$00,$ff,$00,$ff,$00,$ff,$00,$ff,$00,$ff,$00,$ff,$00,$ff,$00 - db $fc,$02,$fc,$02,$fc,$02,$fc,$02,$fc,$02,$fc,$02,$fc,$02,$fc,$02 - db $00,$00,$00,$06,$04,$3a,$3c,$c2,$3c,$c2,$04,$3a,$00,$06,$00,$00 - db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$03,$03 - db $1f,$20,$0f,$30,$07,$18,$03,$0c,$01,$06,$00,$03,$00,$01,$00,$00 - db $ff,$00,$ff,$00,$ff,$00,$ff,$00,$ff,$00,$ff,$00,$7f,$80,$00,$ff - db $ff,$00,$ff,$00,$ff,$00,$ff,$00,$ff,$00,$ff,$00,$fc,$03,$00,$ff - db $f8,$04,$f0,$0c,$e0,$18,$c0,$30,$80,$60,$00,$c0,$00,$80,$00,$00 - db $04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04 - db $80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80 - db $00,$04,$00,$1c,$08,$74,$78,$84,$38,$44,$08,$34,$00,$0c,$00,$04 - db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$0f,$0f - db $00,$00,$00,$18,$08,$14,$0c,$12,$1c,$22,$18,$27,$00,$38,$c1,$c1 - db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$0f,$3f,$f8,$ff - db $00,$00,$00,$00,$00,$00,$00,$00,$03,$03,$fe,$ff,$03,$ff,$1c,$fc - db $00,$00,$00,$00,$00,$00,$00,$00,$f8,$f8,$18,$f8,$f8,$f8,$08,$08 - db $18,$1f,$33,$3c,$67,$78,$43,$7c,$4f,$71,$7f,$7f,$7f,$7f,$78,$7f - db $67,$ef,$f3,$33,$f3,$13,$f3,$13,$f3,$f3,$f3,$f3,$f4,$f4,$f4,$34 - db $1f,$ff,$fa,$fb,$82,$83,$02,$03,$01,$01,$01,$01,$81,$81,$81,$81 - db $f0,$f0,$10,$f0,$10,$f0,$10,$f0,$10,$f0,$10,$f0,$10,$f0,$10,$f0 - db $14,$14,$14,$14,$14,$14,$14,$14,$14,$14,$22,$22,$22,$22,$22,$22 - db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01 - db $7f,$60,$5f,$60,$38,$27,$2f,$30,$17,$18,$08,$0f,$00,$0f,$00,$ff - db $f4,$14,$f4,$14,$78,$98,$d8,$38,$a8,$68,$48,$c8,$10,$d0,$1f,$ff - db $81,$81,$80,$80,$40,$40,$40,$40,$40,$40,$40,$40,$20,$20,$e0,$e0 - db $10,$f0,$90,$f0,$90,$f0,$90,$f0,$50,$70,$50,$70,$48,$78,$48,$78 - db $22,$22,$21,$21,$41,$41,$41,$41,$7f,$7f,$41,$7f,$3e,$3e,$00,$00 - db $04,$04,$04,$04,$3c,$3c,$3f,$3f,$07,$07,$02,$1d,$0f,$30,$18,$27 - db $80,$80,$80,$80,$f0,$f0,$f0,$f0,$80,$80,$00,$c0,$00,$c0,$80,$40 - db $00,$07,$00,$04,$00,$08,$00,$08,$00,$18,$00,$10,$00,$10,$00,$30 - db $10,$1f,$0f,$0f,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 - db $20,$f0,$c0,$dc,$00,$04,$00,$06,$00,$02,$00,$02,$00,$03,$00,$03 - db $48,$78,$28,$38,$28,$38,$28,$38,$28,$38,$24,$3c,$14,$1c,$14,$1c - db $1f,$20,$18,$27,$1f,$20,$18,$27,$0f,$10,$00,$0f,$07,$07,$07,$07 - db $80,$40,$80,$40,$00,$e3,$00,$ff,$70,$8f,$fc,$83,$ff,$80,$ff,$80 - db $00,$20,$00,$40,$00,$c1,$00,$81,$00,$e1,$c0,$21,$c0,$21,$c0,$31 - db $00,$01,$00,$21,$00,$21,$00,$21,$00,$21,$00,$23,$01,$22,$01,$22 - db $14,$1c,$14,$9c,$14,$9c,$12,$9e,$0a,$de,$00,$ff,$8f,$70,$c1,$3e - db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$80,$00,$c0 - db $7f,$80,$3f,$c0,$3f,$c0,$3f,$c0,$0f,$f0,$00,$ff,$00,$7f,$00,$7f - db $e0,$11,$e0,$11,$e0,$11,$e0,$11,$c0,$31,$00,$f1,$00,$f1,$00,$f2 - db $01,$22,$01,$22,$01,$22,$01,$22,$01,$22,$00,$23,$00,$23,$00,$23 - db $9f,$60,$83,$7c,$bf,$40,$c2,$3d,$de,$23,$0a,$fe,$0a,$fe,$0a,$fe - db $80,$40,$80,$40,$00,$c0,$00,$80,$00,$00,$00,$00,$00,$00,$00,$00 - db $00,$7f,$00,$7f,$00,$7f,$00,$7f,$00,$7f,$00,$3f,$00,$3f,$00,$3f - db $00,$f2,$00,$e2,$00,$e6,$00,$ec,$00,$dc,$00,$f4,$00,$e4,$00,$c4 - db $00,$33,$00,$31,$00,$39,$00,$2d,$00,$25,$00,$27,$00,$23,$00,$23 - db $0a,$fe,$0a,$fe,$0a,$fe,$0a,$fe,$09,$ff,$09,$ff,$09,$ff,$09,$ff - db $00,$04,$00,$04,$00,$04,$00,$04,$00,$04,$00,$0c,$00,$08,$00,$08 - db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$60,$00,$30 - db $00,$21,$00,$20,$00,$31,$00,$11,$00,$10,$00,$10,$00,$10,$00,$10 - db $09,$ff,$09,$ff,$09,$ff,$09,$8f,$0f,$0f,$00,$06,$00,$00,$00,$00 - db $00,$08,$00,$08,$00,$08,$00,$08,$00,$18,$00,$10,$00,$10,$00,$10 - db $00,$1c,$00,$06,$00,$01,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 - db $00,$00,$00,$00,$00,$80,$00,$c0,$00,$00,$00,$00,$00,$00,$00,$00 - db $00,$08,$00,$08,$00,$08,$00,$0c,$00,$04,$00,$06,$00,$0e,$00,$1a - db $00,$10,$00,$10,$00,$30,$00,$38,$00,$24,$00,$22,$00,$21,$00,$21 - db $00,$00,$00,$00,$00,$01,$00,$07,$00,$00,$00,$00,$00,$00,$00,$00 - db $00,$32,$00,$c2,$00,$82,$00,$03,$00,$01,$00,$01,$00,$00,$00,$00 - db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$80,$00,$80,$00,$c0 - db $00,$21,$00,$20,$00,$20,$00,$20,$00,$20,$00,$20,$00,$40,$00,$40 - db $00,$80,$00,$80,$00,$40,$00,$60,$00,$30,$00,$18,$00,$07,$00,$00 - db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$c0,$00,$00 - db $00,$80,$00,$80,$00,$80,$00,$40,$00,$40,$00,$40,$00,$60,$00,$20 - db $00,$40,$00,$40,$00,$40,$00,$40,$00,$60,$00,$3c,$00,$3f,$00,$39 - db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$c0,$00,$ff - db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$ff,$00,$01 - db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$07,$00,$fc,$00,$bf - db $00,$20,$00,$10,$00,$10,$00,$10,$00,$f0,$00,$b0,$00,$30,$00,$f0 - db $00,$00,$00,$7f,$00,$30,$00,$18,$00,$0c,$00,$06,$00,$03,$00,$03 - db $00,$00,$00,$ff,$00,$1a,$00,$32,$00,$62,$00,$c2,$00,$82,$00,$82 - db $00,$03,$00,$06,$00,$0c,$00,$18,$00,$30,$00,$20,$00,$7f,$00,$00 - db $00,$82,$00,$c2,$00,$62,$00,$32,$00,$12,$00,$1a,$00,$ff,$00,$00 - - - -BackgroundCopy: ; tiles start at 27 - db $1b, $1c, $1d, $1e, $1e, $1f, $20, $1b - db $21, $1b, $22, $23, $24, $25, $1b, $1b - db $26, $27, $28, $29, $2a, $2b, $2c, $2d - db $26, $27, $1b, $2e, $2f, $30, $31, $32 - db $26, $27, $33, $34, $35, $36, $37, $38 - db $39, $3a, $3b, $1b, $3c, $3d, $3e, $1b - db $3f, $40, $41, $1b, $1b, $42, $43, $44 - db $1b, $45, $46, $1b, $1b, $47, $48, $49 - db $1b, $4a, $4b, $1b, $1b, $4c, $4d, $1b - db $1b, $1b, $4e, $4f, $1b, $50, $51, $1b - db $1b, $1b, $52, $53, $54, $55, $1b, $1b - db $1b, $1b, $56, $1b, $57, $58, $59, $1b - db $1b, $1b, $5a, $5b, $5c, $1b, $5d, $1b - db $1b, $1b, $5e, $5f, $60, $61, $62, $1b - db $1b, $1b, $1b, $63, $64, $1b, $1b, $1b - db $1b, $1b, $1b, $65, $66, $1b, $1b, $1b diff --git a/main.asm b/main.asm index 2cef85f..e7b2b6f 100644 --- a/main.asm +++ b/main.asm @@ -42,16 +42,20 @@ def ZEROES equ $D000 def ONES equ $D200 ; allocating $8 spaces for system variables, currently only using $4 bytes -DEF rMYBTN EQU SYSTEM_VARS_START -DEF rMYBTNP EQU rMYBTN + 1 -DEF rDELTAT EQU rMYBTNP + 1 ; delta_t where $1000 = 1 second -def rLFSR equ rDELTAT + 1 ; 16 bit +PUSHS "System Variables", WRAM0[SYSTEM_VARS_START] +rMYBTN: db ; EQU SYSTEM_VARS_START +rMYBTNP: db ;EQU rMYBTN + 1 +rDELTAT: db ; EQU rMYBTNP + 1 ; delta_t where $1000 = 1 second +rLFSR: dw ; equ rDELTAT + 1 ; 16 bit +POPS def SAFE_DMA_LOCATION equ $ffc0 -def VARIABLE_TILES_START equ 26 +def VARIABLE_TILES_START equ 26 ; where in VRAM the variable tiles start +; (i.e. we allocate VARIABLE_TILES_START-1 slots out of that block of 128 +; for ever-present ui tiles) @@ -558,8 +562,8 @@ LetterTiles: INCLUDE "Async.inc" INCLUDE "Audio.inc" INCLUDE "Random.inc" -INCLUDE "CopyRangeSafe.inc" -INCLUDE "CopyTilesSafe.inc" +INCLUDE "CopyRange.inc" +INCLUDE "CopyTiles.inc" INCLUDE "ScreenMainMenu.inc" INCLUDE "ScreenSpreadSelect.inc" INCLUDE "CardHelpers.inc" @@ -569,3 +573,4 @@ INCLUDE "ScreenShuffle.inc" INCLUDE "CardLibrary.inc" +include "gbt_player_bank1.inc" \ No newline at end of file diff --git a/mod2gbt b/mod2gbt new file mode 100755 index 0000000000000000000000000000000000000000..09ae777cbfddd068a72a5f9919b57937b9a0f872 GIT binary patch literal 22624 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 MFg#uUvn`+h2e2c|G5`Po literal 0 HcmV?d00001 diff --git a/pythonrangetest.c b/pythonrangetest.c new file mode 100644 index 0000000..1cad6b3 --- /dev/null +++ b/pythonrangetest.c @@ -0,0 +1,217 @@ +; s3m2gbt modified by shoofle to output rgbds-compatible asm filespythonrangetest_0: + db 0xBF,0x00,0x30,0x10,0x10,0x10, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x01,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x02,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x03,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x04,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x05,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x06,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x07,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x08,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x09,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x0A,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x0B,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x0C,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x0D,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x0E,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x0F,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x10,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x11,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x12,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x13,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x14,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x15,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x16,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x17,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x18,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x19,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x1A,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x1B,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x1C,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x1D,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x1E,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x1F,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + + +pythonrangetest_1: + db 0xBF,0x20,0x30,0x10,0x10,0x10, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x21,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x22,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x23,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x24,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x25,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x26,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x27,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x28,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x29,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x2A,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x2B,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x2C,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x2D,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x2E,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x2F,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x30,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x31,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x32,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x33,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x34,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x35,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x36,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x37,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x38,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x39,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x3A,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x3B,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x3C,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x3D,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x3E,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x3F,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + + +pythonrangetest_2: + db 0xBF,0x40,0x30,0x10,0x10,0x10, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x41,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x42,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x43,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x44,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x45,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x46,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0xBF,0x47,0x30,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + db 0x00,0x00,0x00,0x00, + + +pythonrangetest_init_state: + db 0x01,0x06,0x02,0x11,0x22,0x44,0x88,0x00, + +pythonrangetest: + db BANK(pythonrangetest_0) + dw pythonrangetest_0 + + db BANK(pythonrangetest_1) + dw pythonrangetest_1 + + db BANK(pythonrangetest_2) + dw pythonrangetest_2 + + db $00 + dw $0000 + diff --git a/pythonrangetest.inc b/pythonrangetest.inc new file mode 100644 index 0000000..354236b --- /dev/null +++ b/pythonrangetest.inc @@ -0,0 +1,222 @@ +; s3m2gbt modified by shoofle to output rgbds-compatible asm files +SECTION "pythonrangetest_0", ROMX +pythonrangetest_0: + db $BF,$00,$30,$10,$10,$10, + db $00,$00,$00,$00, + db $BF,$01,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$02,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$03,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$04,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$05,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$06,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$07,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$08,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$09,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$0A,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$0B,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$0C,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$0D,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$0E,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$0F,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$10,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$11,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$12,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$13,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$14,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$15,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$16,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$17,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$18,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$19,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$1A,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$1B,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$1C,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$1D,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$1E,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$1F,$30,$00,$00,$00, + db $00,$00,$00,$00, + + +SECTION "pythonrangetest_1", ROMX +pythonrangetest_1: + db $BF,$20,$30,$10,$10,$10, + db $00,$00,$00,$00, + db $BF,$21,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$22,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$23,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$24,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$25,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$26,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$27,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$28,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$29,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$2A,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$2B,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$2C,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$2D,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$2E,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$2F,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$30,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$31,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$32,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$33,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$34,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$35,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$36,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$37,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$38,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$39,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$3A,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$3B,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$3C,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$3D,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$3E,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$3F,$30,$00,$00,$00, + db $00,$00,$00,$00, + + +SECTION "pythonrangetest_2", ROMX +pythonrangetest_2: + db $BF,$40,$30,$10,$10,$10, + db $00,$00,$00,$00, + db $BF,$41,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$42,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$43,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$44,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$45,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$46,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $BF,$47,$30,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + db $00,$00,$00,$00, + + +pythonrangetest_init_state: + db 0x01,0x06,0x02,0x11,0x22,0x44,0x88,0x00, + +SECTION "pythonrangetest", ROMX +pythonrangetest: + db BANK(pythonrangetest_0) + dw pythonrangetest_0 + + db BANK(pythonrangetest_1) + dw pythonrangetest_1 + + db BANK(pythonrangetest_2) + dw pythonrangetest_2 + + db $00 + dw $0000 + diff --git a/range_test.s3m b/range_test.s3m new file mode 100644 index 0000000000000000000000000000000000000000..a55bcb25992d0312dcac113caddd2bd9f645eff9 GIT binary patch literal 50160 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 literal 0 HcmV?d00001 diff --git a/rangetest.s3m b/rangetest.s3m new file mode 100644 index 0000000000000000000000000000000000000000..a3d188dc18df9f1d98b04d4aa01f48388fe9051c GIT binary patch literal 76718 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

Avd77GP(lJo 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 literal 0 HcmV?d00001 diff --git a/s3m2gbt.py b/s3m2gbt.py old mode 100644 new mode 100755 index d7f03a8..71d74c6 --- a/s3m2gbt.py +++ b/s3m2gbt.py @@ -1,39 +1,11 @@ #!/usr/bin/env python3 -# i (shoofle) have heavily modified this script to output a totally different format -# in order to use it with my tarot project. much credit to the original author, -# whose intro title/copyright block is preserved below. -# sourced this from https://github.com/AntonioND/gbt-player/tree/master/gba/s3m2gbt -# in april of 2025 - # s3m2gbt v4.4.1 (Part of GBT Player) # # SPDX-License-Identifier: MIT # # Copyright (c) 2022 Antonio Niño Díaz -""" - SAMPLE PERIOD LUT - MOD values - C C# D D# E F F# G G# A A# B -Octave 0:1712,1616,1525,1440,1357,1281,1209,1141,1077,1017, 961, 907 // C3 to B3 -Octave 1: 856, 808, 762, 720, 678, 640, 604, 570, 538, 508, 480, 453 // C4 to B4 -Octave 2: 428, 404, 381, 360, 339, 320, 302, 285, 269, 254, 240, 226 // C5 to B5 -Octave 3: 214, 202, 190, 180, 170, 160, 151, 143, 135, 127, 120, 113 // C6 to B6 -Octave 4: 107, 101, 95, 90, 85, 80, 76, 71, 67, 64, 60, 57 // C7 to B7 -Octave 5: 53, 50, 47, 45, 42, 40, 37, 35, 33, 31, 30, 28 // C8 to B8 - -//From C3 to B8 | A5 = 1750 = 440.00Hz | C5 = 1546 -const UWORD GB_frequencies[] = { - 44, 156, 262, 363, 457, 547, 631, 710, 786, 854, 923, 986, // C3 to B3 - 1046,1102,1155,1205,1253,1297,1339,1379,1417,1452,1486,1517, // C4 to B4 - 1546,1575,1602,1627,1650,1673,1694,1714,1732,1750,1767,1783, // C5 to B5 - 1798,1812,1825,1837,1849,1860,1871,1881,1890,1899,1907,1915, // C6 to B6 - 1923,1930,1936,1943,1949,1954,1959,1964,1969,1974,1978,1982, // C7 to B7 - 1985,1988,1992,1995,1998,2001,2004,2006,2009,2011,2013,2015 // C8 to B8 -}; - -""" - class RowConversionError(Exception): def __init__(self, message, pattern = -1, row = -1, channel = -1): self.pattern = pattern @@ -313,13 +285,8 @@ def s3m_note_to_gb(note): # Note cut with ^^ if note == 0xFE: return 0xFE - if note == 0xFF: - return 0xFF # Note off and ^^ note cut should be handled before reaching this point - #note = note & 0x7F - if note > 0x7F: - print(note) assert note <= 0x7F note -= 32 @@ -351,16 +318,15 @@ def s3m_pan_to_gb(pan, channel): return val -# masks for how to define an effect -EFFECT_PAN = 0x40 -EFFECT_ARPEGGIO = 0x50 -EFFECT_VIBRATO = 0x60 -EFFECT_VOLUME_SLIDE = 0x70 -EFFECT_NOTE_CUT = 0x80 -EFFECT_PATTERN_JUMP = 0x90 -EFFECT_BREAK_SET_STEP = 0xA0 -EFFECT_SPEED = 0xB0 -EFFECT_EVENT = 0xC0 +EFFECT_PAN = 0 +EFFECT_ARPEGGIO = 1 +EFFECT_NOTE_CUT = 2 +EFFECT_VIBRATO = 3 +EFFECT_VOLUME_SLIDE = 4 +EFFECT_PATTERN_JUMP = 8 +EFFECT_BREAK_SET_STEP = 9 +EFFECT_SPEED = 10 +EFFECT_EVENT = 15 # Returns (converted_num, converted_params) if there was a valid effect. If # there is none, it returns (None, None). Note that it is needed to pass the @@ -443,31 +409,229 @@ def effect_s3m_to_gb(channel, effectnum, effectparams): raise RowConversionError(f"Unsupported effect: {effectnum}{effectparams:02X}") -def convert_channel(channel, note_index, samplenum, volume, effectnum, effectparams): - commands = [] +HAS_VOLUME = 1 << 4 +HAS_INSTRUMENT = 1 << 5 +HAS_EFFECT = 1 << 6 +HAS_NOTE = 1 << 7 +HAS_KIT = 1 << 7 + +def convert_channel1(note_index, samplenum, volume, effectnum, effectparams): + command = [ 0, 0, 0, 0 ] # NOP + command_ptr = 1 # Check if it's needed to add a note - if note_index != -1 and note_index != 0xFF and note_index != 0xFE: + if note_index != -1: note_index = s3m_note_to_gb(note_index) - commands.append([0x10 | channel, note_index]) - if note_index == 0xFF or note_index == 0xFE: - commands.append([0x80 | channel, note_index]) - - if volume > -1: - commands.append([0x20 | channel, s3m_volume_to_gb(volume) & 0x0F]) + command[0] |= HAS_NOTE + command[command_ptr] = note_index + command_ptr = command_ptr + 1 # Check if there is a sample defined if samplenum > 0: instrument = samplenum & 3 - commands.append([0x30 | channel, instrument << 6]) + + command[0] |= HAS_INSTRUMENT + command[command_ptr] = (instrument << 4) & 0x30 if effectnum is not None: [num, params] = effect_s3m_to_gb(1, effectnum, effectparams) if num is not None: - commands.append([num | channel, params]) + command[0] |= HAS_EFFECT + command[command_ptr] |= num & 0x0F + command_ptr += 1 + command[command_ptr] = params & 0xFF - return commands + # Check if it's needed to add a volume + if volume > -1: + command[0] |= HAS_VOLUME + command[0] |= s3m_volume_to_gb(volume) & 0x0F + + # Note: The volume bit doesn't affect the final size. + sizes = [ 1, 2, 3, 3, 2, 3, 4, 4 ] + command_size = sizes[command[0] >> 5] + + return command[:command_size] + +def convert_channel2(note_index, samplenum, volume, effectnum, effectparams): + command = [ 0, 0, 0, 0 ] # NOP + command_ptr = 1 + + # Check if it's needed to add a note + if note_index != -1: + note_index = s3m_note_to_gb(note_index) + command[0] |= HAS_NOTE + command[command_ptr] = note_index + command_ptr = command_ptr + 1 + + # Check if there is a sample defined + if samplenum > 0: + instrument = samplenum & 3 + + command[0] |= HAS_INSTRUMENT + command[command_ptr] = (instrument << 4) & 0x30 + + if effectnum is not None: + [num, params] = effect_s3m_to_gb(2, effectnum, effectparams) + + if num is not None: + command[0] |= HAS_EFFECT + command[command_ptr] |= num & 0x0F + command_ptr += 1 + command[command_ptr] = params & 0xFF + + # Check if it's needed to add a volume + if volume > -1: + command[0] |= HAS_VOLUME + command[0] |= s3m_volume_to_gb(volume) & 0x0F + + # Note: The volume bit doesn't affect the final size. + sizes = [ 1, 2, 3, 3, 2, 3, 4, 4 ] + command_size = sizes[command[0] >> 5] + + return command[:command_size] + +def convert_channel3(note_index, samplenum, volume, effectnum, effectparams): + command = [ 0, 0, 0, 0 ] # NOP + command_ptr = 1 + + # Check if it's needed to add a note + if note_index != -1: + note_index = s3m_note_to_gb(note_index) + command[0] |= HAS_NOTE + command[command_ptr] = note_index + command_ptr = command_ptr + 1 + + # Check if there is a sample defined + if samplenum > 0: + instrument = samplenum & 7 + + command[0] |= HAS_INSTRUMENT + command[command_ptr] = (instrument << 4) & 0xF0 + + if effectnum is not None: + [num, params] = effect_s3m_to_gb(3, effectnum, effectparams) + + if num is not None: + command[0] |= HAS_EFFECT + command[command_ptr] |= num & 0x0F + command_ptr += 1 + command[command_ptr] = params & 0xFF + + # Check if it's needed to add a volume + if volume > -1: + command[0] |= HAS_VOLUME + command[0] |= s3m_volume_to_gb_ch3(volume) & 0x0F + + # Note: The volume bit doesn't affect the final size. + sizes = [ 1, 2, 3, 3, 2, 3, 4, 4 ] + command_size = sizes[command[0] >> 5] + + return command[:command_size] + +def convert_channel4(note_index, samplenum, volume, effectnum, effectparams): + command = [ 0, 0, 0, 0 ] # NOP + command_ptr = 1 + + # Note cut using ^^ as note + if note_index == 0xFE: + if samplenum > 0: + # This limitation is only for channel 4. It should never happen in a + # regular song. + raise("Note cut + Sample in same row: Not supported in channel 4") + samplenum = 0xFE + + # Check if there is a sample defined + if samplenum > 0: + if samplenum == 0xFE: + kit = 0xFE; + else: + kit = samplenum & 0xF; + command[0] |= HAS_KIT + command[command_ptr] = kit + command_ptr += 1 + + if effectnum is not None: + [num, params] = effect_s3m_to_gb(4, effectnum, effectparams) + + if num is not None: + command[0] |= HAS_EFFECT + command[command_ptr] |= num & 0x0F + command_ptr += 1 + command[command_ptr] = params & 0xFF + + # Check if it's needed to add a volume + if volume > -1: + command[0] |= HAS_VOLUME + command[0] |= s3m_volume_to_gb(volume) & 0x0F + + # Note: The volume bit doesn't affect the final size. + sizes = [ 1, 2, 3, 3, 2, 3, 4, 4 ] + command_size = sizes[command[0] >> 5] + + return command[:command_size] + +STARTUP_CMD_DONE = 0 +STARTUP_CMD_SPEED = 1 +STARTUP_CMD_PANING = 2 +STARTUP_CMD_CHANNEL3_INSTRUMENT = 3 + +SAMPLE_64_ENTRIES = 1 << 7 + +def initial_state_array(speed, panning_array, instruments): + array = [] + + # Initial speed + # ------------- + + array.extend([STARTUP_CMD_SPEED, speed]) + + # Initial panning + # --------------- + + array.extend([STARTUP_CMD_PANING]) + array.extend(panning_array) + + # Channel 3 instruments + # --------------------- + + if instruments is not None: + print("Exporting instruments...") + count = 0 + for inst in instruments: + # In the tracker, instruments start at index 1, but they start at + # index 0 in the S3M file. + count += 1 + + # Only handle instruments assigned to channel 3 + if count < 8 or count > 15: + continue + + name = inst.sample_name + + size = inst.length + if size != 32 and size != 64: + raise S3MFormatError(f"Sample '{name}': Invalid sample length: {size}") + else: + flags = count - 8 # The low bits are the instrument index + if size == 64: + flags |= SAMPLE_64_ENTRIES + + array.extend([STARTUP_CMD_CHANNEL3_INSTRUMENT, flags]) + + # Convert from 8 bit to 4 bit + for i in range(0, size, 2): + sample_hi = inst.sample_data[i + 0] >> 4 + sample_lo = inst.sample_data[i + 1] >> 4 + value = (sample_hi << 4) | sample_lo + array.extend([value]) + + # End commands + # ------------ + + array.extend([STARTUP_CMD_DONE]) + + return array def convert_file(module_path, song_name, output_path, export_instruments): @@ -481,7 +645,7 @@ def convert_file(module_path, song_name, output_path, export_instruments): with open(output_path, "w") as fileout: - fileout.write("; File created by shoofle's s3m2gbt edit\n\n") + fileout.write("; s3m2gbt modified by shoofle to output rgbds-compatible asm files\n") # Export patterns # --------------- @@ -498,15 +662,18 @@ def convert_file(module_path, song_name, output_path, export_instruments): print(f"Pattern {pattern} not exported: Not in the order list") continue + fileout.write(f"SECTION \"{song_name}_{pattern}\", ROMX\n") fileout.write(f"{song_name}_{pattern}:\n") row = 0 - commands = [[0x00, 0x00]] + cmd1 = [0] + cmd2 = [0] + cmd3 = [0] + cmd4 = [0] for c in p.cells: - # If an end of row marker is reached, print the previous row. # Trust that the S3M file is generated in a valid way and it # doesn't have markers at weird positions, and that there is one @@ -514,19 +681,21 @@ def convert_file(module_path, song_name, output_path, export_instruments): if c.empty: # Write row - fileout.write(" ") + fileout.write(" db ") - for cmd in commands: - fileout.write("db ") - for b in cmd: - fileout.write(f"${b:02X}, ") - fileout.write("\n") + cmd = cmd1 + cmd2 + cmd3 + cmd4 + for b in cmd: + fileout.write(f"${b:02X},") fileout.write("\n") row = row + 1 - commands = [[0x0F, row & 0xFF]] + # Clear commands + cmd1 = [0] + cmd2 = [0] + cmd3 = [0] + cmd4 = [0] # Next iteration continue @@ -557,11 +726,19 @@ def convert_file(module_path, song_name, output_path, export_instruments): channel = c.channel + 1 try: - commands.extend(convert_channel(channel, - note, instrument, volume, - effectnum, effectparams)) - - if channel > 4: + if channel == 1: + cmd1 = convert_channel1(note, instrument, volume, + effectnum, effectparams) + elif channel == 2: + cmd2 = convert_channel2(note, instrument, volume, + effectnum, effectparams) + elif channel == 3: + cmd3 = convert_channel3(note, instrument, volume, + effectnum, effectparams) + elif channel == 4: + cmd4 = convert_channel4(note, instrument, volume, + effectnum, effectparams) + else: raise S3MFormatError(f"Too many channels: {channel}") except RowConversionError as e: e.row = row @@ -569,27 +746,77 @@ def convert_file(module_path, song_name, output_path, export_instruments): e.channel = channel raise e + fileout.write("\n") + fileout.write("\n") # Export initial state # -------------------- - print(f"Exporting initial state... or not...") + print(f"Exporting initial state...") + + fileout.write(f"{song_name}_init_state:\n") + + default_pan = [8, 8, 8, 8] + for i in range(0, 4): + default_pan[i] = s3m.channel_pan[i] + + gb_default_pan = [ + s3m_pan_to_gb(default_pan[0], 1), + s3m_pan_to_gb(default_pan[1], 2), + s3m_pan_to_gb(default_pan[2], 3), + s3m_pan_to_gb(default_pan[3], 4) + ] + + instr = None + if export_instruments: + instr = s3m.instruments + + state_array = initial_state_array(s3m.initial_speed, gb_default_pan, instr) + + # Write rows of 8 bytes until the end of the array + while True: + left = len(state_array) + + write = [] + if left == 0: + break + elif left <= 8: + write = state_array + state_array = [] + else: + write = state_array[0:8] + state_array = state_array[8:] + + fileout.write(" db ") + for s in write: + fileout.write(f"0x{s:02X},") + fileout.write("\n") + + fileout.write("\n") - # Export orders # ------------- print(f"Exporting orders...") + fileout.write(f"SECTION \"{song_name}\", ROMX\n") fileout.write(f"{song_name}:\n") - fileout.write(f"\tdb {len(s3m.song_orders)}\n") + #fileout.write(f" {song_name}_init_state,") + #fileout.write("\n") + for o in s3m.song_orders: pattern = int(o) if pattern >= s3m.num_patterns: # TODO: Warn if the pattern goes over the limit? continue - fileout.write(f"\tdw {song_name}_{pattern}\n") + fileout.write(f" db BANK({song_name}_{pattern})\n") + fileout.write(f" dw {song_name}_{pattern}\n") + fileout.write("\n") + + fileout.write(" db $00\n") + fileout.write(" dw $0000\n") + fileout.write("\n") if __name__ == "__main__": diff --git a/s3m2shoofmt.py b/s3m2shoofmt.py new file mode 100644 index 0000000..d7f03a8 --- /dev/null +++ b/s3m2shoofmt.py @@ -0,0 +1,627 @@ +#!/usr/bin/env python3 + +# i (shoofle) have heavily modified this script to output a totally different format +# in order to use it with my tarot project. much credit to the original author, +# whose intro title/copyright block is preserved below. +# sourced this from https://github.com/AntonioND/gbt-player/tree/master/gba/s3m2gbt +# in april of 2025 + +# s3m2gbt v4.4.1 (Part of GBT Player) +# +# SPDX-License-Identifier: MIT +# +# Copyright (c) 2022 Antonio Niño Díaz + +""" + SAMPLE PERIOD LUT - MOD values + C C# D D# E F F# G G# A A# B +Octave 0:1712,1616,1525,1440,1357,1281,1209,1141,1077,1017, 961, 907 // C3 to B3 +Octave 1: 856, 808, 762, 720, 678, 640, 604, 570, 538, 508, 480, 453 // C4 to B4 +Octave 2: 428, 404, 381, 360, 339, 320, 302, 285, 269, 254, 240, 226 // C5 to B5 +Octave 3: 214, 202, 190, 180, 170, 160, 151, 143, 135, 127, 120, 113 // C6 to B6 +Octave 4: 107, 101, 95, 90, 85, 80, 76, 71, 67, 64, 60, 57 // C7 to B7 +Octave 5: 53, 50, 47, 45, 42, 40, 37, 35, 33, 31, 30, 28 // C8 to B8 + +//From C3 to B8 | A5 = 1750 = 440.00Hz | C5 = 1546 +const UWORD GB_frequencies[] = { + 44, 156, 262, 363, 457, 547, 631, 710, 786, 854, 923, 986, // C3 to B3 + 1046,1102,1155,1205,1253,1297,1339,1379,1417,1452,1486,1517, // C4 to B4 + 1546,1575,1602,1627,1650,1673,1694,1714,1732,1750,1767,1783, // C5 to B5 + 1798,1812,1825,1837,1849,1860,1871,1881,1890,1899,1907,1915, // C6 to B6 + 1923,1930,1936,1943,1949,1954,1959,1964,1969,1974,1978,1982, // C7 to B7 + 1985,1988,1992,1995,1998,2001,2004,2006,2009,2011,2013,2015 // C8 to B8 +}; + +""" + +class RowConversionError(Exception): + def __init__(self, message, pattern = -1, row = -1, channel = -1): + self.pattern = pattern + self.row = row + self.channel = channel + 1 + self.message = message + + def __str__(self): + return f"Pattern {self.pattern} | Row {self.row} | Channel {self.channel} | {self.message}" + +class S3MFormatError(Exception): + pass + +class S3MFormatReader: + + def read_u8(self): + offset = self.read_ptr + self.read_ptr += 1 + return int(self.data[offset]) + + def read_u16(self): + offset = self.read_ptr + self.read_ptr += 2 + return int((self.data[offset + 1] << 8) | self.data[offset]) + + def read_memseg(self): + offset = self.read_ptr + self.read_ptr += 3 + part1 = self.data[offset + 0] + part2 = self.data[offset + 1] + part3 = self.data[offset + 2] + return int((part1 << 16) | (part3 << 8) | part2) + + def read_string(self, size): + offset = self.read_ptr + self.read_ptr += size + return self.data[offset:offset+size] + +class S3MFileInstrument(S3MFormatReader): + + def __init__(self, data, offset): + self.data = data + self.read_ptr = offset + + instrument_type = self.read_u8() + if instrument_type != 1: + self.exists = False + return + self.exists = True + + self.dos_filename = self.read_string(12).decode("utf-8") + + self.sample_data_offset = self.read_memseg() * 16 + + self.length = self.read_u16() + self.length |= self.read_u16() << 16 + + self.read_ptr += 4 + 4 # Skip loop begin and loop end + + self.default_volume = self.read_u8() + + self.read_ptr = offset + 0x30 + + self.sample_name = self.read_string(28).decode("utf-8") + + if self.read_string(4) != b'SCRS': + raise S3MFormatError("Invalid magic string in instrument") + + start = self.sample_data_offset + end = start + self.length + self.sample_data = self.data[start:end] + +class S3MFilePatternCell(): + + def __init__(self, header, channel, note, instrument, volume, + effect, effect_args): + + if header == 0: + self.empty = True + return + + self.empty = False + + self.channel = channel + + if (note != None) or (instrument != None): + self.has_note_and_instrument = True + self.note = note + self.instrument = instrument + else: + self.has_note_and_instrument = False + + if volume != None: + self.has_volume = True + self.volume = volume + else: + self.has_volume = False + + if (effect != None) or (effect_args != None): + self.has_effect = True + self.effect = effect + self.effect_args = effect_args + else: + self.has_effect = False + +class S3MFilePattern(S3MFormatReader): + + def __init__(self, data, offset): + + # Check if we have asked to generate an empty pattern + if data == None: + cell = S3MFilePatternCell(0, 0, 0, 0, 0, 0, 0) + self.cells = [] + for i in range(0, 64): + self.cells.append(cell) + return + + self.data = data + self.read_ptr = offset + + length = self.read_u16() - 2 + + self.cells = [] + + while length > 0: + header = self.read_u8() + length -= 1 + + channel = header & 31 + + note = None + instrument = None + volume = None + effect = None + effect_args = None + + if (header & (1 << 5)) != 0: # Has note and instrument + note = self.read_u8() + instrument = self.read_u8() + length -= 2 + + if (header & (1 << 6)) != 0: # Has volume + volume = self.read_u8() + length -= 1 + + if (header & (1 << 7)) != 0: # Has effect + effect = self.read_u8() + effect_args = self.read_u8() + length -= 2 + + cell = S3MFilePatternCell(header, channel, note, instrument, volume, + effect, effect_args) + self.cells.append(cell) + +class S3MFile(S3MFormatReader): + + def __init__(self, data): + + # Save data for now + + self.data = data + self.read_ptr = 0 + + self.name = self.read_string(28).decode("utf-8") + print(f"Song Name: '{self.name}'") + + self.read_ptr += 1 + 1 + 2 # Ignore fields + + self.song_length = self.read_u16() + print(f"Song Length: {self.song_length}") + + self.num_instruments = self.read_u16() + self.num_patterns = self.read_u16() + + self.read_ptr += 6 # Ignore fields + + if self.read_string(4) != b'SCRM': + raise S3MFormatError("Invalid magic string in file") + + self.read_ptr += 1 # Ignore global volume + + self.initial_speed = self.read_u8() + + if self.read_u8() != 150: + raise S3MFormatError("Invalid tempo: It must be 150") + + self.read_ptr += 2 # Ignore master volume and ultraclick removal + + # Save this for later + has_custom_pan = False + if self.read_u8() == 252: + has_custom_pan = True + + self.read_ptr = 0x40 + channel_settings = self.read_string(4) + if channel_settings[0] >= 16 or channel_settings[1] >= 16 or \ + channel_settings[2] >= 16 or channel_settings[3] >= 16: + raise S3MFormatError("Invalid channel settings: Channels 0-3 must be enabled") + + # Read orders + + self.read_ptr = 0x60 + + self.song_orders = self.read_string(self.song_length) + if self.song_length % 2 == 1: + self.read_ptr += 1 # Align to 2 + + # Read instrument parapointers + + self.instrument_offsets = [None] * self.num_instruments + for i in range(0, self.num_instruments): + self.instrument_offsets[i] = self.read_u16() * 16 + + # Read pattern parapointers + + self.pattern_offsets = [None] * self.num_patterns + for i in range(0, self.num_patterns): + self.pattern_offsets[i] = self.read_u16() * 16 + + # Read default panning + + if has_custom_pan: + self.channel_pan = [b & 0xF for b in self.read_string(4)] + else: + self.channel_pan = [8, 8, 8, 8] + + # Load instruments + + self.instruments = [None] * self.num_instruments + for i in range(0, len(self.instrument_offsets)): + offset = self.instrument_offsets[i] + if offset != 0: + instr = S3MFileInstrument(self.data, offset) + if instr.exists: + self.instruments[i] = instr + + # Load patterns + + self.patterns = [None] * self.num_patterns + for i in range(0, len(self.pattern_offsets)): + offset = self.pattern_offsets[i] + if offset != 0: + self.patterns[i] = S3MFilePattern(self.data, offset) + else: + # A NULL pointer means that the pattern is empty + self.patterns[i] = S3MFilePattern(None, 0) + + # The file data is no longer needed + + self.data = [] + +# Channels 1, 2, 4 +def s3m_volume_to_gb(s3m_vol): + if s3m_vol >= 64: + return 15 + else: + return s3m_vol >> 2; + +# Channel 3 +def s3m_volume_to_gb_ch3(s3m_vol): + vol = s3m_volume_to_gb(s3m_vol) + + if vol >= 0 and vol <= 3: + return 0 # 0% + elif vol >= 4 and vol <= 6: + return 3 # 25% + elif vol >= 7 and vol <= 9: + return 2 # 50% + elif vol >= 10 and vol <= 12: + return 4 # 75% + elif vol >= 13 and vol <= 15: + return 1 # 100% + else: + return 0 + +def s3m_note_to_gb(note): + # Note cut with ^^ + if note == 0xFE: + return 0xFE + if note == 0xFF: + return 0xFF + + # Note off and ^^ note cut should be handled before reaching this point + #note = note & 0x7F + if note > 0x7F: + print(note) + assert note <= 0x7F + + note -= 32 + if note < 0: + raise RowConversionError("Note too low") + elif note > 32 + 16 * 6: + raise RowConversionError("Note too high") + + note = (note & 0xF) + ((note & 0xF0) >> 4) * 12 + return note + +def s3m_pan_to_gb(pan, channel): + left = False + right = False + + if pan >= 0 and pan <= 3: + left = True + elif pan >= 4 and pan <= 11: + left = True + right = True + elif pan >= 12 and pan <= 15: + right = True + + val = 0 + if left: + val |= 1 << (3 + channel) + if right: + val |= 1 << (channel - 1) + + return val + +# masks for how to define an effect +EFFECT_PAN = 0x40 +EFFECT_ARPEGGIO = 0x50 +EFFECT_VIBRATO = 0x60 +EFFECT_VOLUME_SLIDE = 0x70 +EFFECT_NOTE_CUT = 0x80 +EFFECT_PATTERN_JUMP = 0x90 +EFFECT_BREAK_SET_STEP = 0xA0 +EFFECT_SPEED = 0xB0 +EFFECT_EVENT = 0xC0 + +# Returns (converted_num, converted_params) if there was a valid effect. If +# there is none, it returns (None, None). Note that it is needed to pass the +# channel to this function because some effects behave differently depending on +# the channel (like panning). +def effect_s3m_to_gb(channel, effectnum, effectparams): + + if effectnum == 'A': # Set Speed + if effectparams == 0: + raise RowConversionError("Speed must not be zero") + + return (EFFECT_SPEED, effectparams) + + if effectnum == 'B': # Pattern jump + # TODO: Fail if this jumps out of bounds + return (EFFECT_PATTERN_JUMP, effectparams) + + elif effectnum == 'C': # Break + Set row + # Effect value is BCD, convert to integer + val = (((effectparams & 0xF0) >> 4) * 10) + (effectparams & 0x0F) + return (EFFECT_BREAK_SET_STEP, val) + + elif effectnum == 'D': # Volume Slide + if channel == 3: + raise RowConversionError("Volume slide not supported in channel 3") + + if effectparams == 0: + # Ignore volume slide commands that just continue the effect, + # they are only needed for the S3M player. + return (None, None) + + upper = (effectparams >> 4) & 0xF + lower = effectparams & 0xF + + if upper == 0xF or lower == 0xF: + raise RowConversionError("Fine volume slide not supported") + + elif lower == 0: # Volume goes up + params = 1 << 3 # Increase + delay = 7 - upper + 1 + if delay <= 0: + raise RowConversionError("Volume slide too steep") + params |= delay + return (EFFECT_VOLUME_SLIDE, params) + elif upper == 0: # Volume goes down + params = 0 << 3 # Decrease + delay = 7 - lower + 1 + if delay <= 0: + raise RowConversionError("Volume slide too steep") + params = delay + return (EFFECT_VOLUME_SLIDE, params) + else: + raise RowConversionError("Invalid volume slide arguments") + + return (EFFECT_VOLUME_SLIDE, effectparams) + + elif effectnum == 'H': # Vibrato + return (EFFECT_VIBRATO, effectparams) + + elif effectnum == 'J': # Arpeggio + return (EFFECT_ARPEGGIO, effectparams) + + elif effectnum == 'S': # This effect is subdivided into many + + subeffectnum = (effectparams & 0xF0) >> 4 + subeffectparams = effectparams & 0x0F + + if subeffectnum == 0x8: # Pan position + val = s3m_pan_to_gb(subeffectparams, channel) + return (EFFECT_PAN, val) + + elif subeffectnum == 0xC: # Notecut + return (EFFECT_NOTE_CUT, subeffectparams) + + elif subeffectnum == 0xF: # Funkrepeat? Set active macro? + # This effect is either unused, or it's the "set active macro" + # command, which doesn't have any effect if you don't use the macro + # afterwards. It can safely be overloaded for event callbacks. + return (EFFECT_EVENT, subeffectparams) + + raise RowConversionError(f"Unsupported effect: {effectnum}{effectparams:02X}") + +def convert_channel(channel, note_index, samplenum, volume, effectnum, effectparams): + commands = [] + + # Check if it's needed to add a note + if note_index != -1 and note_index != 0xFF and note_index != 0xFE: + note_index = s3m_note_to_gb(note_index) + commands.append([0x10 | channel, note_index]) + if note_index == 0xFF or note_index == 0xFE: + commands.append([0x80 | channel, note_index]) + + if volume > -1: + commands.append([0x20 | channel, s3m_volume_to_gb(volume) & 0x0F]) + + # Check if there is a sample defined + if samplenum > 0: + instrument = samplenum & 3 + commands.append([0x30 | channel, instrument << 6]) + + if effectnum is not None: + [num, params] = effect_s3m_to_gb(1, effectnum, effectparams) + + if num is not None: + commands.append([num | channel, params]) + + return commands + +def convert_file(module_path, song_name, output_path, export_instruments): + + with open(module_path, "rb") as file: + file_byte_array = bytearray(file.read()) + + s3m = S3MFile(file_byte_array) + + if output_path == None: + output_path = song_name + ".inc" + + with open(output_path, "w") as fileout: + + fileout.write("; File created by shoofle's s3m2gbt edit\n\n") + + # Export patterns + # --------------- + + print(f"Exporting patterns...") + + pattern = -1 + for p in s3m.patterns: + pattern += 1 + + # Check if pattern is actually used in the order list. If it isn't + # used, don't export it. + if pattern not in s3m.song_orders: + print(f"Pattern {pattern} not exported: Not in the order list") + continue + + fileout.write(f"{song_name}_{pattern}:\n") + + row = 0 + + commands = [[0x00, 0x00]] + + for c in p.cells: + + + # If an end of row marker is reached, print the previous row. + # Trust that the S3M file is generated in a valid way and it + # doesn't have markers at weird positions, and that there is one + # marker right at the end of each pattern. + if c.empty: + + # Write row + fileout.write(" ") + + for cmd in commands: + fileout.write("db ") + for b in cmd: + fileout.write(f"${b:02X}, ") + fileout.write("\n") + + fileout.write("\n") + + row = row + 1 + + commands = [[0x0F, row & 0xFF]] + + # Next iteration + continue + + volume = -1 + if c.has_volume: + volume = c.volume + + note = -1 + instrument = 0 + if c.has_note_and_instrument: + note = c.note + instrument = c.instrument + + # Rows with note and instrument but no volume use the + # default volume of the sample. + if instrument > 0 and volume == -1: + this_instr = s3m.instruments[instrument - 1] + volume = this_instr.default_volume + + effectnum = None + effectparams = None + if c.has_effect: + # Convert type to ASCII to match the documentation + effectnum = chr(c.effect + ord('A') - 1) + effectparams = c.effect_args + + channel = c.channel + 1 + + try: + commands.extend(convert_channel(channel, + note, instrument, volume, + effectnum, effectparams)) + + if channel > 4: + raise S3MFormatError(f"Too many channels: {channel}") + except RowConversionError as e: + e.row = row + e.pattern = pattern + e.channel = channel + raise e + + + # Export initial state + # -------------------- + + print(f"Exporting initial state... or not...") + + + # Export orders + # ------------- + + print(f"Exporting orders...") + + fileout.write(f"{song_name}:\n") + + fileout.write(f"\tdb {len(s3m.song_orders)}\n") + for o in s3m.song_orders: + pattern = int(o) + if pattern >= s3m.num_patterns: + # TODO: Warn if the pattern goes over the limit? + continue + fileout.write(f"\tdw {song_name}_{pattern}\n") + +if __name__ == "__main__": + + import argparse + import sys + + print("s3m2gbt v4.4.1 (part of GBT Player)") + print("Copyright (c) 2022 Antonio Niño Díaz ") + print("All rights reserved") + print("") + + parser = argparse.ArgumentParser(description='Convert S3M files into GBT format.') + parser.add_argument("--input", default=None, required=True, + help="input file") + parser.add_argument("--name", default=None, required=True, + help="output song name") + parser.add_argument("--output", default=None, required=False, + help="output file") + parser.add_argument("--instruments", default=False, required=False, + action='store_true', help="export channel 3 instruments") + + args = parser.parse_args() + + try: + convert_file(args.input, args.name, args.output, args.instruments) + except RowConversionError as e: + print("ERROR: " + str(e)) + sys.exit(1) + except S3MFormatError as e: + print("ERROR: Invalid S3M file: " + str(e)) + sys.exit(1) + + print("Done!") + + sys.exit(0) diff --git a/source.zip b/source.zip index 2f25319eced3bc4dd68468b8103e540044892066..dde3c625ba4dd74687e7620b3607928ae1352605 100644 GIT binary patch delta 57303 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 delta 9847 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