Sonic and Sega Retro Message Board: Adding >$1F songs (Sonic 2) - Sonic and Sega Retro Message Board

Jump to content

Hey there, Guest!  (Log In · Register) Help
Page 1 of 1
    Locked
    Locked Forum

Adding >$1F songs (Sonic 2) About to give up...

#1 User is offline Tamkis 

  Posted 27 June 2011 - 04:52 PM

  • Posts: 116
  • Joined: 19-November 10
  • Gender:Male
  • Location:Pennsylvania
  • Project:Megaman 2: The Robotnik Wars, Unnamed S3&K hack
  • Wiki edits:16
For the past 2 months, I have been struggling to add even more music into my sonic 2 hack, Sonic Loco 2. I need this featuer implemented into my hack before I submit it into the hacking contest. I plan on using different songs per boss (like in Megamix), and having a music monitor like in S1Nineko for a hidden song per zone. These new songs will total more than the original limit of Sonic 2 of $1F songs.

Below is the code for my attempt of adding more than $1F songs. FYI, I am using the Sonic 2 clone driver, which is based upon the simpler Sonic 1 Sound driver, and one of the latest .svn disasms for Sonic 2. What am I doing wrong, and could anybody help me fix it?

s2.constants.asm:

Syntax Highlighted Code: ASM
 
; Music IDs
offset := zMasterPlaylist
ptrsize := 1
idstart := $68
; $80 is reserved for silence, so if you make idstart $80 or less,
; you may need to insert a dummy zMusIDPtr in the $80 slot
 
MusID__First = idstart
MUsID_EHZH = id(zMusIDPtr_EHZH) ; 68** "H" stands for "hidden"
MUsID_CPZH = id(zMusIDPtr_CPZH) ; 69
MUsID_ARZH = id(zMusIDPtr_ARZH) ; 70
MUsID_CNZH = id(zMusIDPtr_CNZH) ; 71
MUsID_HTZH = id(zMusIDPtr_HTZH) ; 72
MusID_MCZH = id(zMusIDPtr_MCZH) ; 73
MusID_OOZH = id(zMusIDPtr_OOZH) ; 74
MusID_MTZH = id(zMusIDPtr_MTZH) ; 75
MusID_Boss1 = id(zMusIDPtr_Boss1) ; 76
MusID_Boss2 = id(zMusIDPtr_Boss2) ; 77
MusID_Boss3 = id(zMusIDPtr_Boss3) ; 78
MusID_Boss4 = id(zMusIDPtr_Boss4) ; 79
MusID_Boss5 = id(zMusIDPtr_Boss5) ; 7a
MusID_Boss6 = id(zMusIDPtr_Boss6) ; 7b
MusID_Boss7 = id(zMusIDPtr_Boss7) ; 7c
MusID_Boss8 = id(zMusIDPtr_Boss8) ; 7d
MusID_Boss9 = id(zMusIDPtr_Boss9) ; 7e
MusID_Boss10 = id(zMusIDPtr_Boss10) ; 7f
MusID_Dum = id(zMusIDPtr_Dum) ; 80
 
MusID_2PResult = id(zMusIDPtr_2PResult) ; 81
MusID_EHZ = id(zMusIDPtr_EHZ) ; 82
MusID_MCZ_2P = id(zMusIDPtr_MCZ_2P) ; 83
MusID_OOZ = id(zMusIDPtr_OOZ) ; 84
MusID_MTZ = id(zMusIDPtr_MTZ) ; 85
MusID_HTZ = id(zMusIDPtr_HTZ) ; 86
MusID_ARZ = id(zMusIDPtr_ARZ) ; 87
MusID_CNZ_2P = id(zMusIDPtr_CNZ_2P) ; 88
MusID_CNZ = id(zMusIDPtr_CNZ) ; 89
MusID_DEZ = id(zMusIDPtr_DEZ) ; 8A
MusID_MCZ = id(zMusIDPtr_MCZ) ; 8B
MusID_EHZ_2P = id(zMusIDPtr_EHZ_2P) ; 8C
MusID_SCZ = id(zMusIDPtr_SCZ) ; 8D
MusID_CPZ = id(zMusIDPtr_CPZ) ; 8E
MusID_WFZ = id(zMusIDPtr_WFZ) ; 8F
MusID_HPZ = id(zMusIDPtr_HPZ) ; 90
MusID_Options = id(zMusIDPtr_Options) ; 91
MusID_SpecStage = id(zMusIDPtr_SpecStage) ; 92
MusID_Boss = id(zMusIDPtr_Boss) ; 93
MusID_EndBoss = id(zMusIDPtr_EndBoss) ; 94
MusID_Ending = id(zMusIDPtr_Ending) ; 95
MusID_SuperSonic = id(zMusIDPtr_SuperSonic); 96
MusID_Invincible = id(zMusIDPtr_Invincible); 97
MusID_ExtraLife = id(zMusIDPtr_ExtraLife) ; 98
MusID_Title = id(zMusIDPtr_Title) ; 99
MusID_EndLevel = id(zMusIDPtr_EndLevel) ; 9A
MusID_GameOver = id(zMusIDPtr_GameOver) ; 9B
MusID_Continue = id(zMusIDPtr_Continue) ; 9C
MusID_Emerald = id(zMusIDPtr_Emerald) ; 9D
MusID_Credits = id(zMusIDPtr_Credits) ; 9E
MusID_Countdown = id(zMusIDPtr_Countdown) ; 9F
MusID__End = id(zMusIDPtr__End) ; a0
 


After I tried to compile that, I got errors such as "zMusIDPtr_EHZH, symbol undefined". So, after more searching, in the s2.sounddriver.asm, I changed this:

Syntax Highlighted Code: ASM
 
; Music IDs
offset := MusicPoint2
ptrsize := 2
idstart := 68h ;Is this correct?
; note: +20h means uncompressed, here
 
 
ZMusIDPtr_EHZH: db id(MusPtr_EHZH) ;??
ZMusIDPtr_cPZH: db id(MusPtr_CPZH) ;??
ZMusIDPtr_ARZH: db id(MusPtr_ARZH) ;??
ZMusIDPtr_CNZH: db id(MusPtr_CNZH) ;??
ZMusIDPtr_HTZH: db id(MusPtr_HTZH) ;
ZMusIDPtr_MCZH: db id(MusPtr_MCZH) ;
ZMusIDPtr_OOZH: db id(MusPtr_OOZH) ;
ZMusIDPtr_MTZH: db id(MusPtr_MTZH) ;
ZMusIDPtr_Boss1: db id(MusPtr_Boss1) ;
ZMusIDPtr_Boss2: db id(MusPtr_Boss2) ;
ZMusIDPtr_Boss3: db id(MusPtr_Boss3) ;
ZMusIDPtr_Boss4: db id(MusPtr_Boss4) ;
ZMusIDPtr_Boss5: db id(MusPtr_Boss5) ;
ZMusIDPtr_Boss6: db id(MusPtr_Boss6) ;
ZMusIDPtr_Boss7: db id(MusPtr_Boss7) ;
ZMusIDPtr_Boss8: db id(MusPtr_Boss8) ;
ZMusIDPtr_Boss9: db id(MusPtr_Boss9) ;
ZMusIDPtr_Boss10: db id(MusPtr_Boss10) ;
ZMusIDPtr_Dum: db id(MusPtr_Dum) ;
 
;WTF is with these psuedo-random music IDs??
 
zMusIDPtr_2PResult: db id(MusPtr_2PResult) ; 92
zMusIDPtr_EHZ: db id(MusPtr_EHZ) ; 81
zMusIDPtr_MCZ_2P: db id(MusPtr_MCZ_2P) ; 85
zMusIDPtr_OOZ: db id(MusPtr_OOZ) ; 8F
zMusIDPtr_MTZ: db id(MusPtr_MTZ) ; 82
zMusIDPtr_HTZ: db id(MusPtr_HTZ) ; 94
zMusIDPtr_ARZ: db id(MusPtr_ARZ) ; 86
zMusIDPtr_CNZ_2P: db id(MusPtr_CNZ_2P) ; 80
zMusIDPtr_CNZ: db id(MusPtr_CNZ) ; 83
zMusIDPtr_DEZ: db id(MusPtr_DEZ) ; 87
zMusIDPtr_MCZ: db id(MusPtr_MCZ) ; 84
zMusIDPtr_EHZ_2P: db id(MusPtr_EHZ_2P) ; 91
zMusIDPtr_SCZ: db id(MusPtr_SCZ) ; 8E
zMusIDPtr_CPZ: db id(MusPtr_CPZ) ; 8C
zMusIDPtr_WFZ: db id(MusPtr_WFZ) ; 90
zMusIDPtr_HPZ: db id(MusPtr_HPZ) ; 9B
zMusIDPtr_Options: db id(MusPtr_Options) ; 89
zMusIDPtr_SpecStage: db id(MusPtr_SpecStage) ; 88
zMusIDPtr_Boss: db id(MusPtr_Boss) ; 8D
zMusIDPtr_EndBoss: db id(MusPtr_EndBoss) ; 8B
zMusIDPtr_Ending: db id(MusPtr_Ending) ; 8A
zMusIDPtr_SuperSonic: db id(MusPtr_SuperSonic) ; 93
zMusIDPtr_Invincible: db id(MusPtr_Invincible) ; 99
zMusIDPtr_ExtraLife: db id(MusPtr_ExtraLife)+20h; B5
zMusIDPtr_Title: db id(MusPtr_Title) ; 96
zMusIDPtr_EndLevel: db id(MusPtr_EndLevel) ; 97
zMusIDPtr_GameOver: db id(MusPtr_GameOver)+20h ; B8
zMusIDPtr_Continue: db (MusPtr_Continue-MusicPoint1)/ptrsize ; 0
zMusIDPtr_Emerald: db id(MusPtr_Emerald)+20h ; BA
zMusIDPtr_Credits: db id(MusPtr_Credits)+20h ; BD
zMusIDPtr_Countdown: db id(MusPtr_Drowning)+40h ; DC
zMusIDPtr__End:
 


Even after this, some symbols were still "undefined". After more searching, I changed this in s2.asm:

Syntax Highlighted Code: ASM
 
; ------------------------------------------------------------------------------
; Music pointers
; ------------------------------------------------------------------------------
align $8000
soundBankStart := *
 
; loc_F8000:
MusicPoint2:
;**
MusPtr_EHZH: rom_ptr_z80 Mus_EHZH
MusPtr_CPZH: rom_ptr_z80 Mus_CPZH
MusPtr_ARZH: rom_ptr_z80 Mus_ARZH
MusPtr_CNZH: rom_ptr_z80 Mus_CNZH
MusPtr_HTZH: rom_ptr_z80 Mus_HTZH
MusPtr_MCZH: rom_ptr_z80 Mus_MCZH
MusPtr_OOZH: rom_ptr_z80 Mus_OOZH
MusPtr_MTZH: rom_ptr_z80 Mus_MTZH
MusPtr_Boss1: rom_ptr_z80 Mus_Boss1
MusPtr_Boss2: rom_ptr_z80 Mus_Boss2
MusPtr_Boss3: rom_ptr_z80 Mus_Boss3
MusPtr_Boss4: rom_ptr_z80 Mus_Boss4
MusPtr_Boss5: rom_ptr_z80 Mus_Boss5
MusPtr_Boss6: rom_ptr_z80 Mus_Boss6
MusPtr_Boss7: rom_ptr_z80 Mus_Boss7
MusPtr_Boss8: rom_ptr_z80 Mus_Boss8
MusPtr_Boss9: rom_ptr_z80 Mus_Boss9
MusPtr_Boss10: rom_ptr_z80 Mus_Boss10
MusPtr_Dum: rom_ptr_z80 Mus_Dum
 
MusPtr_CNZ_2P: rom_ptr_z80 Mus_CNZ_2P
MusPtr_EHZ: rom_ptr_z80 Mus_EHZ
MusPtr_MTZ: rom_ptr_z80 Mus_MTZ
MusPtr_CNZ: rom_ptr_z80 Mus_CNZ
MusPtr_MCZ: rom_ptr_z80 Mus_MCZ
MusPtr_MCZ_2P: rom_ptr_z80 Mus_MCZ_2P
MusPtr_ARZ: rom_ptr_z80 Mus_ARZ
MusPtr_DEZ: rom_ptr_z80 Mus_DEZ
MusPtr_SpecStage: rom_ptr_z80 Mus_SpecStage
MusPtr_Options: rom_ptr_z80 Mus_Options
MusPtr_Ending: rom_ptr_z80 Mus_Ending
MusPtr_EndBoss: rom_ptr_z80 Mus_EndBoss
MusPtr_CPZ: rom_ptr_z80 Mus_CPZ
MusPtr_Boss: rom_ptr_z80 Mus_Boss
MusPtr_SCZ: rom_ptr_z80 Mus_SCZ
MusPtr_OOZ: rom_ptr_z80 Mus_OOZ
MusPtr_WFZ: rom_ptr_z80 Mus_WFZ
MusPtr_EHZ_2P: rom_ptr_z80 Mus_EHZ_2P
MusPtr_2PResult: rom_ptr_z80 Mus_2PResult
MusPtr_SuperSonic: rom_ptr_z80 Mus_SuperSonic
MusPtr_HTZ: rom_ptr_z80 Mus_HTZ
MusPtr_ExtraLife: rom_ptr_z80 Mus_ExtraLife
MusPtr_Title: rom_ptr_z80 Mus_Title
MusPtr_EndLevel: rom_ptr_z80 Mus_EndLevel
MusPtr_GameOver: rom_ptr_z80 Mus_GameOver
MusPtr_Invincible: rom_ptr_z80 Mus_Invincible
MusPtr_Emerald: rom_ptr_z80 Mus_Emerald
MusPtr_HPZ: rom_ptr_z80 Mus_HPZ
MusPtr_Drowning: rom_ptr_z80 Mus_Drowning
MusPtr_Credits: rom_ptr_z80 Mus_Credits
 


Even after that, I got a new error:

"> > >s2.asm(88541): error: soundBank must fit in $8000 bytes but was $8012. Try moving something to the other bank.
> > > fatal "soundBank must fit in $8000 bytes but was $\{*-soundBankStart}. Try moving something to the other bank."
fatal error, assembly terminated"

As suggested in the Q&A thread, I commented out this fatal error to see what would happen. What happened was that the new songs were inserted, BUT any of the old songs that were shifted past sound test ID $1F were omitted! Any value >=$20 in the sound test was still sfx. How can I add more songs? I believe that the game still thinks that the music is banked, even though the S1Snd driver was ported...


Below are some useful resources, including my hack disasm, which you can use to try to fix the problem. It isn't the latest version of my disasm, so you will need to give me steps to implement the fix into the latest version of my hack. Also below is my OST, complete with the new songs (boss songs and hidden songs) for testing.

S2 z80 sound driver info (if you want to fix this problem in z80)
lMy hack disasm for testing purposes (password is "Loco")
Sonic 2 Loco OST
This post has been edited by Tamkis: 27 June 2011 - 04:53 PM

#2 User is offline Spanner 

Posted 27 June 2011 - 06:35 PM

  • Not much I can do on here nowadays...
  • Posts: 2873
  • Joined: 02-June 07
  • Gender:Male
  • Location:United Kingdom
  • Project:Sonic the Hedgehog Hacking Contest, Other Stuff
  • Wiki edits:2,193
SCHG How-to:Expand the music index to start at $00 instead of $80 (Sonic 2 Clone Driver version)

This should help you in extending the music list.

#3 User is offline Tamkis 

Posted 27 June 2011 - 07:02 PM

  • Posts: 116
  • Joined: 19-November 10
  • Gender:Male
  • Location:Pennsylvania
  • Project:Megaman 2: The Robotnik Wars, Unnamed S3&K hack
  • Wiki edits:16
I knew about this guide, haven't tried it yet, but doesn't all this guide does is enumerate the pointers? I will try it in a bit and get back if I have problems. Hope it works

#4 User is offline SegaLoco 

Posted 27 June 2011 - 11:48 PM

  • W)(at did you say?
  • Posts: 999
  • Joined: 16-August 06
  • Gender:Male
  • Location:Corpus Christi, TX
  • Wiki edits:79
Sonic Loco......shouldn't that be a name I would be expected to use for a hack?

#5 User is offline flamewing 

  Posted 28 June 2011 - 11:35 AM

  • Emerald Hunter
  • Posts: 831
  • Joined: 11-October 10
  • Gender:Male
  • Location:Brasil
  • Project:Sonic Classic Heroes; Sonic 2 Special Stage Editor; Sonic 3&K Heroes (on hold)
  • Wiki edits:12
There is a whole lot that needs to be changed to be able to add more than 1F songs to the S2 sound driver, or more than 120 songs+SFX. There is also the work that needs to be done to get bank switching working right to deal with bank size issues correctly -- in your case, for example, the $12 bytes past the end of the bank will never be reachable by the z80 and hence will be "lost".

Here is the full guide on how to extend the S2 sound driver to have better bank switching for music, more space for SFX, easier maintenance of song lists and more than $1F songs (or more than 120 songs + SFX). I do not, however, explain how to fix sound test; you will have to do that yourself.

Lets start by moving SFX to a sound bank of their own:
  1. in s2.sounddriver.asm, look for zsub_600 and replace the following 'bankswitch MusicPoint2' by 'bankswitch SoundIndex';
  2. in s2.sounddriver.asm, look for zloc_F1D and do the same replacement;
  3. In s2.asm, just above label 'SoundIndex', add code as needed to make it look like this:
    Syntax Highlighted Code: ASM
    	if * > soundBankStart + $8000
    fatal "soundBank must fit in $8000 bytes but was ${*-soundBankStart}. Try moving something to the other bank."
    elseif MOMPASS=2
    message "soundBank has ${$8000+soundBankStart-*} bytes free at end."
    endif
     
    ; ------------------------------------------------------------------------------------------
    ; Sound effect pointers
    ; ------------------------------------------------------------------------------------------
    align $8000
    soundBankStart := *
    ; WARNING the sound driver treats certain sounds specially
    ; going by the ID of the sound.
    ; SndID_Ring, SndID_RingLeft, SndID_Gloop, SndID_SpindashRev
    ; are referenced by the sound driver directly.
    ; If needed you can change this in s2.sounddriver.asm
     
     
    ; NOTE: the exact order of this list determines the priority of each sound, since it determines the sound's SndID.
    ; a sound can get dropped if a higher-priority sound is already playing.
    ; the rules for sound priority are currently unknown, but you can generally swap pointer lines around to resolve priority conflicts.
    ; loc_FEE91: SoundPoint:
    SoundIndex:

Doing that will give you some space for the songs and SFX. And please, after you do these, restore the warning you deleted at the end of the file. BTW, I just applied items 1 and 2 to the SVN version because it makes no difference for it without also doing item 3.

From now on, I will be assuming the SVN version of s2.sounddriver.asm due to the much better labels and comments. You can use it as reference, as it keeps the old labels. At this point, I will be improving the workings of the master playlist in the S2 sound driver so that it behaves more like the S&K sound driver (I.e., better) with regards to song banks. This will essentially allow you to add as many songs as you can without worrying about bank sizes.

First, scroll down to zMasterPlaylist definition on s2.sounddriver.asm. Before it, define the following macros:
Syntax Highlighted Code: Z80
zmake68kBank function addr,(((addr&3F8000h)/zROMWindow))
zmakePlaylistEntry macro addr,val
db zmake68kBank(addr),val
dw zmake68kPtr(addr)
endm

You will have to edit the master playlist; here are 3 examples of how to do it: edit this:
Syntax Highlighted Code: Z80
zMusIDPtr_EndLevel:	db	id(MusPtr_EndLevel); 97
zMusIDPtr_GameOver: db id(MusPtr_GameOver)+20h; B8
zMusIDPtr_Continue: db (MusPtr_Continue-MusicPoint1)/ptrsize; 0

into this:
Syntax Highlighted Code: Z80
zMusIDPtr_EndLevel:	zmakePlaylistEntry Mus_EndLevel,0
zMusIDPtr_GameOver: zmakePlaylistEntry Mus_GameOver,20h
zMusIDPtr_Continue: zmakePlaylistEntry Mus_Continue,0

Basically, the +20h (or +40h) gets shunted to after the comma, while a zero is there if neither is present, also removing the 'Ptr' from 'MusPtr'. You can also delete the comments at the end of the line, as they are misleading now. The continue music was an exception, so I fixed it in the example. You can also delete these lines:
Syntax Highlighted Code: ASM
; Music IDs
offset := MusicPoint2
ptrsize := 2
idstart := 80h

We now have a table that has, as entries: bank ID (byte); song flags (1 byte); song pointer, relative to bank start (2 bytes). We must now make the game use this. So now find the line after label zBGMLoad that refers to zMasterPlaylist. You can just search for zMasterPlaylist, it is the only line other than the definition that has it. Modify it so that this:
Syntax Highlighted Code: Z80
	ld	hl,zMasterPlaylist; Get address of the zMasterPlaylist
add hl,de ; Add the 16-bit offset here
ld a,(hl) ; Get "fixed" index
ld b,a ; 'a' -> 'b'
; The following instructions enable a bankswitch routine
and 80h ; Clear 'a' back to an index
ld (zComRange+16h),a; Store this ??? (Is used to enable alternate bank)
ld a,b ; Restore 'a' to +80h version
add a,a ; Adding a+a+a causes an overflow and a multiplication by 2
add a,a ; Now multiplied by 4
ld c,a ; Result -> 'c'
ccf ; Clear carry flag...
sbc a,a ; ... reverse subtract with carry that was set to zero ... umm.. a=0 in a funny way?
ld (zIsPalFlag),a ; Clear zIsPalFlag?
ld a,c ; Put prior multiply result back in
add a,a ; Now multiplied by 8!
sbc a,a ; This is nonzero if bit 5 of original a is set, zero otherwise (uncompressed song flag)
push af ; Backing up result...?
ld a,b ; Put 80h based index -> 'a'
and zFirstSound-1 ; Caps maximum number of BGMs
add a,a; multiply by 2; now 'a' is offset into music table, save for the $8000
ld e,a
ld d,0; de = a
ld hl,zROMWindow
add hl,de; "hl" now contains 2-byte offset for music address table lookup
call zBankSwitchToMusic; Bank switch to start of music in ROM!
pop hl; Restore 'hl'
ld e,(hl)
inc hl
ld d,(hl); Getting offset within bank to music -> de

becomes this
Syntax Highlighted Code: Z80
	ld	hl,zMasterPlaylist; Get address of the zMasterPlaylist
add hl,de ; Add the 16-bit offset here
add hl,de ; Add the 16-bit offset here
add hl,de ; Add the 16-bit offset here
add hl,de ; Add the 16-bit offset here
ld a,(hl) ; Get bank index
inc hl ; Advance pointer
ld (zComRange+16h),a; Store bank index
ld a,(hl) ; Get song flags
inc hl ; Advance pointer
add a,a ; Adding a+a causes an overflow and a multiplication by 2
add a,a ; Now multiplied by 4
ld c,a ; Result -> 'c'
ccf ; Clear carry flag...
sbc a,a ; ... reverse subtract with carry that was set to zero ... umm.. a=0 in a funny way?
ld (zIsPalFlag),a ; Clear zIsPalFlag?
ld a,c ; Put prior multiply result back in
add a,a ; Now multiplied by 8!
sbc a,a ; This is nonzero if bit 5 of original a is set, zero otherwise (uncompressed song flag)
push af ; Backing up result...?
ld e, (hl) ; Read low byte of pointer into e
inc hl ; Advance pointer
ld d, (hl) ; Read high byte of pointer into d
push hl; Save 'hl' (will be damaged by bank switch)
call zBankSwitchToMusic; Bank switch to start of music in ROM!
pop hl; Restore 'hl'

This is because we went from 1 byte per entry to 4 bytes per entry. We also skipped several steps due to the new organization, including one that caps the number of songs to $1F (the limit is still there, in another place, though). We now have to fix the zBankSwitchToMusic routine to work with the new index. So go to it, and replace this:
Syntax Highlighted Code: Z80
zBankSwitchToMusic:
ld a,(zComRange+16h)
or a
jr nz,+
 
bankswitch MusicPoint1
ret
+
bankswitch MusicPoint2
ret

with this:
Syntax Highlighted Code: Z80
zBankSwitchToMusic:
ld a,(zComRange+16h)
ld hl, zBankRegister
ld (hl), a
rept 7
rra
ld (hl), a
endm
xor a
ld (hl), a
ret

Now go to s2.constants.asm and search for zMasterPlaylist. Right under it, change ptrsize to 4. Now go to s2.asm. Find MusicPoint1 and delete the line starting as 'MusPtr_Continue:' then go to MusicPoint2 and delete all lines starting as 'MusPtr_'; none of that is needed now. You are now free to move songs to different banks as you please, and can create new banks at will.

To create a new bank, go anywhere you want (except the middle of another bank) and add the following lines:
Syntax Highlighted Code: ASM
	align $8000
soundBankStart := *
; songs
; go
; here
if * > soundBankStart + $8000
fatal "soundBank must fit in $8000 bytes but was $\{*-soundBankStart}. Try moving something to the other bank."
elseif MOMPASS=2
message "soundBank has $\{$8000+soundBankStart-*} bytes free at end."
endif

Add the songs in the indicated location on the new bank.

If you build the ROM right now and test, everything should be working correctly.

To add songs now is rather simple:
  1. add the music in any bank you want, creating one if needed;
  2. add the entry for the song in zMasterPlaylist;
  3. add an entry to zSpedUpTempoTable for the new song, in the same order as it is found on the master playlist (it is right below the master playlist);
  4. add the entry in the music ID list in s2.constants.asm.

It is so easy now to get space for songs that you can, if you want, decompress all songs and split them into banks as you see fit (as long as you change the second parameter to have bit 5 (20h) set in the second entry on the master playlist).

All we need to do now is lift the song + SFX limit. We already took care of one problem. Starting here, things are minimally tested; I moved song IDs around to test and it worked, but I would love to know if it works in a more extreme case.
  1. If you are using the SVN disassembly, this is done already, so skip to step 2; otherwise, go to s2.sounddriver.asm, find sub zPlaySoundByIndex and replace the first line 'ret p' by this:
    Syntax Highlighted Code: Z80
    	cp	MusID__First
    ret c
  2. in s2.constants.asm, find the line containing zMasterPlaylist; you will edit idstart to be the value you want;
  3. back to s2.sounddriver.asm, go to the master playlist and add a dummy entry for music ID $80 (you will have to find where it goes on your own). You should also not use a music ID of $00 (you won't be able to, anyway). Here is a suitable dummy entry:
    Syntax Highlighted Code: Z80
    dw 0,0

To have more SFX ids allowed, go to line 'offset := SoundIndex' in s2.constants.asm and change the value of idstart below to what you want. A good value is 'idstart := MusID__End', as this will always allow you to add SFX and songs as you please. You must also watch for SFX ID of $80 depending on when exactly music ends (you will have to add a dummy entry to SoundIndex table in s2.asm instead of in zMasterPlaylist if ID $80 falls on SFX range).

That sums it all, I think.

Edit: Fixed mistake in master playlist format.

Edit 2: code->asm,z80 tags.
This post has been edited by flamewing: 29 June 2011 - 10:27 PM

#6 User is offline Tamkis 

Posted 29 June 2011 - 04:04 PM

  • Posts: 116
  • Joined: 19-November 10
  • Gender:Male
  • Location:Pennsylvania
  • Project:Megaman 2: The Robotnik Wars, Unnamed S3&K hack
  • Wiki edits:16
Wow, you are right, there is a lot that needs to be changed for >$1F songs. How much research did you have to do to code this? This is amazing; no wonder why you are a tech member! I've followed most of the steps at this point, but am having some minor problems:

QUOTE
First, scroll down to zMasterPlaylist definition on s2.sounddriver.asm. Before it, define the following macros:
CODE
zmake68kBank function addr,(((addr&3F8000h)/zROMWindow))
zmakePlaylistEntry macro addr,val
    db    zmake68kBank(addr),val
    dw    zmake68kPtr(addr)
    endm


Even though I added this macro above zmasterplaylist, the assembler is ignoring it and generating errors like (in the s2.log)

CODE
> > >s2.sounddriver.asm(3118): error: unknown opcode
> > > ZMAKEPLAYLISTENTRY(MUS_2PRESULT,0)
> > > zMusIDPtr_2PResult:    zmakePlaylistEntry(Mus_2PResult,0)
> > >s2.sounddriver.asm(3119): error: unknown opcode
> > > ZMAKEPLAYLISTENTRY(MUS_EHZ,0)
> > > zMusIDPtr_EHZ:        zmakePlaylistEntry(Mus_EHZ,0)


QUOTE
Now go to s2.constants.asm and search for zMasterPlaylist. Right under it, change ptrsize to 4. Now go to s2.asm. Find MusicPoint1 and delete the line starting as 'MusPtr_Continue:' then go to MusicPoint2 and delete all lines starting as 'MusPtr_'; none of that is needed now. You are now free to move songs to different banks as you please, and can create new banks at will.

To create a new bank, go anywhere you want (except the middle of another bank) and add the following lines:
CODE
    align $8000
soundBankStart    := *
; songs
; go
; here
    if * > soundBankStart + $8000
        fatal "soundBank must fit in $8000 bytes but was $\{*-soundBankStart}. Try moving something to the other bank."
    elseif MOMPASS=2
        message "soundBank has $\{$8000+soundBankStart-*} bytes free at end."
    endif

Add the songs in the indicated location on the new bank.

If you build the ROM right now and test, everything should be working correctly.

To add songs now is rather simple:
  1. add the music in any bank you want, creating one if needed;
  2. add the entry for the song in zMasterPlaylist;
  3. add an entry to zSpedUpTempoTable for the new song, in the same order as it is found on the master playlist (it is right below the master playlist);
  4. add the entry in the music ID list in s2.constants.asm.


Dumb question, but what is the new format of the songs in the bank under "songs go here"? Could you give me some examples? This is as far as I have gotten so far, but other than those few errors, everything is working.


#7 User is offline flamewing 

Posted 29 June 2011 - 05:25 PM

  • Emerald Hunter
  • Posts: 831
  • Joined: 11-October 10
  • Gender:Male
  • Location:Brasil
  • Project:Sonic Classic Heroes; Sonic 2 Special Stage Editor; Sonic 3&K Heroes (on hold)
  • Wiki edits:12
QUOTE (Tamkis @ Jun 29 2011, 06:04 PM)
Wow, you are right, there is a lot that needs to be changed for >$1F songs. How much research did you have to do to code this? This is amazing; no wonder why you are a tech member!

Quite a bit. Things got a bit faster since I found out Rob Jinnai had done a lot of research on the S2 sound driver; his work (which I merged to SVN recently) gave me quite a head start for figuring out the S&K sound driver (still going on); both of these combined led to the changes I wrote about on my previous post.

QUOTE (Tamkis @ Jun 29 2011, 06:04 PM)
QUOTE
First, scroll down to zMasterPlaylist definition on s2.sounddriver.asm. Before it, define the following macros:
CODE
zmake68kBank function addr,(((addr&3F8000h)/zROMWindow))
zmakePlaylistEntry macro addr,val
    db    zmake68kBank(addr),val
    dw    zmake68kPtr(addr)
    endm

Even though I added this macro above zmasterplaylist, the assembler is ignoring it and generating errors like (in the s2.log)

Ah, sorry; that is my fault: macros like that do not use parenthesis. So instead of what I said earlier, use this format for the master playlist instead:
Syntax Highlighted Code: Z80
zMusIDPtr_EndLevel:	zmakePlaylistEntry Mus_EndLevel,0
zMusIDPtr_GameOver: zmakePlaylistEntry Mus_GameOver,20h
zMusIDPtr_Continue: zmakePlaylistEntry Mus_Continue,0

(basically, remove the parenthesis) I fixed it in my previous post.

QUOTE
Dumb question, but what is the new format of the songs in the bank under "songs go here"? Could you give me some examples? This is as far as I have gotten so far, but other than those few errors, everything is working.

If you mean the format of the entries, then it is one of the following:
Syntax Highlighted Code: ASM
Mus_DoomsdayZone:	BINCLUDE	"sound/music/DoomsdayZone.bin"
Mus_FinalZone: include "sound/music/FinalZone.asm"
; Since following is uncompressed, master playlist entry must have a 20h
Mus_GameOver: dc.w z80_ptr(MusGO_Voices),$0603,$02F2
dc.w z80_ptr(MusGOver_DAC),$0000
dc.w z80_ptr(MusGOver_FM1),$E80A
dc.w z80_ptr(MusGOver_FM2),$F40F
dc.w z80_ptr(MusGOver_FM3),$F40F
dc.w z80_ptr(MusGOver_FM4),$F40D
dc.w z80_ptr(MusGOver_FM5),$DC16
dc.w z80_ptr(MusGOver_PSG),$D003,$0005
dc.w z80_ptr(MusGOver_PSG),$DC06,$0005
dc.w z80_ptr(MusGOver_PSG),$DC00,$0004
MusGOver_FM1: dc.b $EF,$00
dc.b $F0,$20,$01,$04,$05
dc.b $80,$0C,$CA,$12,$80,$06,$CA,$80,$CB,$12,$C8,$1E
dc.b $CA,$06,$80,$CA,$80,$CA,$80,$C6,$80,$C4,$12,$C8
dc.b $0C,$80,$12,$C9,$04,$80,$C9,$C8,$06,$80,$C7,$80
dc.b $C6,$80
dc.b $F0,$28,$01,$18,$05
dc.b $C5,$60,$F2
MusGOver_FM2: dc.b $EF,$01,$80,$01,$D9,$06,$80,$D9,$80,$D6,$80,$D6
dc.b $80,$D7,$15,$D7,$1B,$D9,$06,$80,$D9,$80,$D6,$80
dc.b $D6,$80,$DC,$15,$DC,$1B,$F2
MusGOver_FM3: dc.b $EF,$01,$D6,$0C,$D6,$D2,$D2,$D4,$15,$D4,$1B,$D6
dc.b $0C,$D6,$D2,$D2,$D7,$15,$D7,$1B,$F2
MusGOver_FM4: dc.b $EF,$02,$E2,$01,$AE,$06,$80,$AE,$80,$A9,$80,$A9
dc.b $80,$AC,$15,$AB,$0C,$AC,$03,$AB,$0C,$AE,$06,$80
dc.b $AE,$80,$A9,$80,$A9,$80,$B3,$15,$B2,$0C,$B3,$03
dc.b $B2,$0C,$AE,$04,$80,$AE,$AD,$06,$80,$AC,$80,$AB
dc.b $80,$AB,$60,$E2,$01,$F2
MusGOver_FM5: dc.b $EF,$03,$80,$30,$D7,$12,$80,$03,$D7,$1B,$80,$30
dc.b $DC,$12,$80,$03,$DC,$1B
MusGOver_PSG: dc.b $F2
MusGOver_DAC: dc.b $80,$18,$81
dc.b $F7,$00,$04
dc.w z80_ptr(MusGOver_DAC)
dc.b $F2
MusGO_Voices: dc.b $3A,$51,$51,$08,$02,$1E,$1E,$1E,$10,$1F,$1F,$1F
dc.b $0F,$00,$00,$00,$02,$0F,$0F,$0F,$1F,$18,$22,$24,$81
dc.b $3C,$33,$73,$30,$70,$94,$96,$9F,$9F,$12,$14,$00
dc.b $0F,$04,$04,$0A,$0D,$2F,$4F,$0F,$2F,$33,$1A,$80,$80
dc.b $3A,$01,$01,$07,$01,$8E,$8D,$8E,$53,$0E,$0E,$0E
dc.b $03,$00,$00,$00,$07,$1F,$1F,$FF,$0F,$1C,$27,$28,$80
dc.b $1F,$66,$53,$31,$22,$1C,$1F,$98,$1F,$12,$0F,$0F
dc.b $0F,$00,$00,$00,$00,$FF,$0F,$0F,$0F,$8C,$8A,$8D,$8B

If you mean the format of the songs: these would be normal S2 SMPS format. You can put the song compressed or uncompressed, it is your choice -- if uncompressed, the song's entry in the master playlist must have a 20h instead of a 0, if compressed, it must be Kosinskisaxman-compressed, with all pointers assuming that the song starts at offset $1380.

Edit: fixed stupid mistake. What was I thinking, 'Kosinski'?
This post has been edited by flamewing: 29 June 2011 - 10:24 PM

Page 1 of 1
    Locked
    Locked Forum

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users