don't click here

How to play different songs on different acts (Sonic 1)

Discussion in 'Engineering & Reverse Engineering' started by nineko, Jan 2, 2008.

Thread Status:
Not open for further replies.
  1. nineko

    nineko

    I am the Holy Cat Tech Member
    6,308
    486
    63
    italy
    Everyone's hack was using different songs in different acts (think Sonic 1 Megamix and Sonic 1 Remastered, just to name two), and I wanted to add this feature to my soniNeko as well, so I searched the forums and the wiki for a guide or something. With much surprise, I found nothing. So I tried to do it by myself, and I'm happy to say that I succeeded! Yep guys, my first ASM edit all by myself! To be honest, I had to ask Puto what bhi.s does (since I didn't know if it was involved in the music process), but that's pretty much it, ASM isn't as hard as it seems!

    So here is the result of my work, to use with the ASM68K version of Hivebrain's split disassembly.

    STEP 1: REORGANIZE THE PLAYLISTS
    In the disassembly, misc\muslist1.bin is used as the "normal playlist", while misc\muslist2.bin is used when invincibility wears off. This is redundant, not to mention gay, since those playlist are identical, but muslist1.bin has an extra byte for Final Zone + a 00 to make it even. Try to put an invincibility monitor in Final Zone, and when it's done you'll get Scrap Brain music. We don't want that. Delete muslist1.bin, and make FOUR copies of muslist2.bin, named muslist1.bin to muslist4.bin . Each of them should be 6 bytes long: 81 82 83 84 85 86. Save them in this way for now, we're going to edit them later.
    Now the playlists have a different meaning: muslist1.bin contains the song played on the act 1 of each zone, muslist2.bin contains acts 2, etc. Muslist4.bin isn't really needed, but it will be handy. Keep on reading to find why.

    STEP 2: CHANGE THE PLAYLISTS IN THE ASM TO REFLECT THE NEW ORGANIZATION
    Go here:
    Code (ASM):
    1. MusicList:  incbin  misc\muslist1.bin
    2.         even
    And change it to:
    Code (ASM):
    1. MusicList1: incbin  misc\muslist1.bin
    2.         even
    3. MusicList2: incbin  misc\muslist2.bin
    4.         even
    5. MusicList3: incbin  misc\muslist3.bin
    6.         even
    7. MusicList4: incbin  misc\muslist4.bin
    8.         even
    Then go here:
    Code (ASM):
    1. MusicList2: incbin  misc\muslist2.bin
    2.         even
    And delete it. Of course I'm not talking about the one I just told you to add, there is one much below (look for "Music to play after invincibility wears off").

    STEP 3: CHANGE THE CODE THAT PICKS THE SONG AT THE BEGINNING OF THE ACT
    We're now going to use the act byte ($FFFFFE11) to load the correct playlist. Then we'll pick the entry from the playlist according to the zone byte ($FFFFFE10).
    Go to Level_GetBgm. It should look like:
    Code (ASM):
    1. Level_GetBgm:
    2.         tst.w   ($FFFFFFF0).w
    3.         bmi.s   loc_3946
    4.         moveq   #0,d0
    5.         move.b  ($FFFFFE10).w,d0
    6.         cmpi.w  #$103,($FFFFFE10).w ; is level SBZ3?
    7.         bne.s   Level_BgmNotLZ4 ; if not, branch
    8.         moveq   #5,d0       ; move 5 to d0
    9.  
    10. Level_BgmNotLZ4:
    11.         cmpi.w  #$502,($FFFFFE10).w ; is level FZ?
    12.         bne.s   Level_PlayBgm   ; if not, branch
    13.         moveq   #6,d0       ; move 6 to d0
    14.  
    15. Level_PlayBgm:
    16.         lea (MusicList).l,a1 ; load music playlist
    17.         move.b  (a1,d0.w),d0    ; add d0 to a1
    18.         bsr.w   PlaySound   ; play music
    19.         move.b  #$34,($FFFFD080).w ; load title card object
    Replace it with:
    Code (ASM):
    1. ; NineKode begins here - How to play different songs on different acts
    2.  
    3. Level_GetBgm:
    4.         tst.w   ($FFFFFFF0).w
    5.         bmi.w   loc_3946    ; change from bmi.s to bmi.w or you'll get an error
    6.         moveq   #0,d0
    7.         move.b  ($FFFFFE10).w,d0
    8.  
    9.         cmpi.b  #$0,($FFFFFE11).w   ; is this act 1?
    10.         bne.s   Level_GetBgm2   ; if not, branch
    11.         lea (MusicList1).l,a1   ; load Music Playlist for Acts 1
    12.         bra.s   Level_PlayBgm   ; go to PlayBgm
    13.  
    14. Level_GetBgm2:
    15.         cmpi.b  #$1,($FFFFFE11).w   ; is this act 2?
    16.         bne.s   Level_GetBgm3   ; if not, branch
    17.         lea (MusicList2).l,a1   ; load Music Playlist for Acts 2
    18.         bra.s   Level_PlayBgm   ; go to PlayBgm
    19.  
    20. Level_GetBgm3:
    21.         cmpi.b  #$2,($FFFFFE11).w   ; is this act 3?
    22.         bne.s   Level_GetBgm4   ; if not, branch
    23.         lea (MusicList3).l,a1   ; load Music Playlist for Acts 3
    24.         bra.s   Level_PlayBgm   ; go to PlayBgm
    25.  
    26. Level_GetBgm4:
    27.         cmpi.b  #$3,($FFFFFE11).w   ; is this act 4?
    28.         bne.s   Level_PlayBgm   ; if not, branch
    29.         lea (MusicList4).l,a1   ; load Music Playlist for Acts 4
    30.  
    31. Level_PlayBgm:
    32.         move.b  (a1,d0.w),d0    ; get d0-th entry from the playlist
    33.         bsr.w   PlaySound   ; play music
    34.         move.b  #$34,($FFFFD080).w ; load title card object
    35.  
    36. ; NineKode ends here
    STEP 4: CHANGE THE CODE THAT PICKS THE SONG WHEN INVINCIBILITY WEARS OFF
    Remember, the check after the invincibility wears off is done in another section of the code. If you don't fix it, you'll get a wrong song. We just need to copy and paste the code used above, of course with different labels. So, go here:
    Code (ASM):
    1. Obj01_ChkInvin:
    2.         tst.b   ($FFFFFE2D).w   ; does Sonic have invincibility?
    3.         beq.s   Obj01_ChkShoes  ; if not, branch
    4.         tst.w   $32(a0)     ; check time remaining for invinciblity
    5.         beq.s   Obj01_ChkShoes  ; if no time remains, branch
    6.         subq.w  #1,$32(a0)  ; subtract 1 from time
    7.         bne.s   Obj01_ChkShoes
    8.         tst.b   ($FFFFF7AA).w
    9.         bne.s   Obj01_RmvInvin
    10.         cmpi.w  #$C,($FFFFFE14).w
    11.         bcs.s   Obj01_RmvInvin
    12.         moveq   #0,d0
    13.         move.b  ($FFFFFE10).w,d0
    14.         cmpi.w  #$103,($FFFFFE10).w ; check if level is SBZ3
    15.         bne.s   Obj01_PlayMusic
    16.         moveq   #5,d0       ; play SBZ music
    17.  
    18. Obj01_PlayMusic:
    19.         lea (MusicList2).l,a1
    20.         move.b  (a1,d0.w),d0
    21.         jsr (PlaySound).l   ; play normal music
    And replace it with:
    Code (ASM):
    1. ; Second part of the NineKode. Play different music on different acts - after invincibility wears off
    2.  
    3. Obj01_ChkInvin:
    4.         tst.b   ($FFFFFE2D).w   ; does Sonic have invincibility?
    5.         beq.w   Obj01_ChkShoes  ; if not, branch    ; change to beq.w
    6.         tst.w   $32(a0)     ; check time remaining for invinciblity
    7.         beq.w   Obj01_ChkShoes  ; if no time remains, branch    ; change to beq.w
    8.         subq.w  #1,$32(a0)  ; subtract 1 from time
    9.         bne.w   Obj01_ChkShoes  ; change to bne.w
    10.         tst.b   ($FFFFF7AA).w
    11.         bne.w   Obj01_RmvInvin  ; change to bne.w
    12.         cmpi.w  #$C,($FFFFFE14).w
    13.         bcs.w   Obj01_RmvInvin  ; change to bcs.w
    14.         moveq   #0,d0
    15.         move.b  ($FFFFFE10).w,d0
    16.  
    17.         cmpi.b  #$0,($FFFFFE11).w   ; is this act 1?
    18.         bne.s   Obj01_GetBgm2   ; if not, branch
    19.         lea (MusicList1).l,a1   ; load Music Playlist for Acts 1
    20.         bra.s   Obj01_PlayMusic ; go to PlayMusic
    21.  
    22. Obj01_GetBgm2:
    23.         cmpi.b  #$1,($FFFFFE11).w   ; is this act 2?
    24.         bne.s   Obj01_GetBgm3   ; if not, branch
    25.         lea (MusicList2).l,a1   ; load Music Playlist for Acts 2
    26.         bra.s   Obj01_PlayMusic ; go to PlayMusic
    27.  
    28. Obj01_GetBgm3:
    29.         cmpi.b  #$2,($FFFFFE11).w   ; is this act 3?
    30.         bne.s   Obj01_GetBgm4   ; if not, branch
    31.         lea (MusicList3).l,a1   ; load Music Playlist for Acts 3
    32.         bra.s   Obj01_PlayMusic ; go to PlayMusic
    33.  
    34. Obj01_GetBgm4:
    35.         cmpi.b  #$3,($FFFFFE11).w   ; is this act 4?
    36.         bne.s   Obj01_PlayMusic ; if not, branch
    37.         lea (MusicList4).l,a1   ; load Music Playlist for Acts 4
    38.  
    39. Obj01_PlayMusic:
    40.         move.b  (a1,d0.w),d0
    41.         jsr (PlaySound).l   ; play normal music
    42.  
    43. ; NineKode ends here.
    And now you're going to get the correct music even after invincibility wears off. But there is one more istance we need to change or we're going to have problems in Labyrinth Zone after the countdown...

    STEP 5: CHANGE THE CODE THAT PICKS THE SONG AFTER THE COUNTDOWN
    Go here:
    Code (ASM):
    1. ResumeMusic:                ; XREF: Obj64_Wobble; Sonic_Water; Obj0A_ReduceAir
    2.         cmpi.w  #$C,($FFFFFE14).w
    3.         bhi.s   loc_140AC
    4.         move.w  #$82,d0     ; play LZ music
    5.         cmpi.w  #$103,($FFFFFE10).w ; check if level is 0103 (SBZ3)
    6.         bne.s   loc_140A6
    7.         move.w  #$86,d0     ; play SBZ music
    8.  
    9. loc_140A6:
    10.         jsr (PlaySound).l
    And replace it with:
    Code (ASM):
    1. ResumeMusic:                ; XREF: Obj64_Wobble; Sonic_Water; Obj0A_ReduceAir
    2.         cmpi.w  #$C,($FFFFFE14).w
    3.  
    4. ; Third section of the NineKode - Play correct music after the countdown (if you breathe)
    5.  
    6.         bhi.w   loc_140AC   ; change to bhi.w!
    7.  
    8.         cmpi.b  #$0,($FFFFFE11).w   ; is this act 1?
    9.         bne.s   Air_GetBgm2 ; if not, branch
    10.         lea (MusicList1).l,a1   ; load Music Playlist for Acts 1
    11.         bra.s   Air_PlayMusic   ; go to PlayMusic
    12.  
    13. Air_GetBgm2:
    14.         cmpi.b  #$1,($FFFFFE11).w   ; is this act 2?
    15.         bne.s   Air_GetBgm3 ; if not, branch
    16.         lea (MusicList2).l,a1   ; load Music Playlist for Acts 2
    17.         bra.s   Air_PlayMusic   ; go to PlayMusic
    18.  
    19. Air_GetBgm3:
    20.         cmpi.b  #$2,($FFFFFE11).w   ; is this act 3?
    21.         bne.s   Air_GetBgm4 ; if not, branch
    22.         lea (MusicList3).l,a1   ; load Music Playlist for Acts 3
    23.         bra.s   Air_PlayMusic   ; go to PlayMusic
    24.  
    25. Air_GetBgm4:
    26.         cmpi.b  #$3,($FFFFFE11).w   ; is this act 4?
    27.         bne.s   Air_PlayMusic   ; if not, branch
    28.         lea (MusicList4).l,a1   ; load Music Playlist for Acts 4
    29.  
    30. Air_PlayMusic:
    31.         move.b  1(a1),d0    ; load entry $1 from the playlist
    32.  
    33. loc_140A6:
    34.         jsr (PlaySound).l
    35.  
    36. ; NineKode ends here
    As you see the code is always the same, recycled each and every time.
    Now if you try to build your ROM you'll see that it works flawlessy! Well, you're still going to get the same songs, because of how we created the playlists, but if you change a byte in a playlist you'll see that it works.
    There is only one more small fix to do to make it perfect btw...

    STEP 6: FIX THE PLAYLIST ENTRIES FOR SCRAP BRAIN 3 AND FINAL ZONE
    You know that Scrap Brain 3 is actually Labyrinth 4, and Final Zone is actually Scrap Brain 3. Way to confuse people.
    So, hex edit playlist4.bin and change the 82 to 86. Hex edit playlist3.bin and change the 86 to 8D.
    Now your ROM should sound exactly as before, except that you're given the chance to pick different songs on different acts!
    Playlist4.bin is also useful if you plan to add acts 4 to other zones, so keep it, it's not a great waste of space.

    STEP 7: FIND 12 MORE SONGS :P
    Good luck on that. Now that I have the code working I can't find good songs D:
    You might also need to know how to extend the playlist entries, but I didn't get that far yet.

    For now, I'm really, really happy about this code as it's the very first time I challenge myself with 68K ASM. :D
    Now comments plz.
     
  2. Varion Icaria

    Varion Icaria

    He's waiting.... Tech Member
    1,019
    11
    18
    S4: Cybernetic Outbreak
    Great job! but you know there is a way to simplify the code a lot, like for the previously played song it could be deposited in Ram address $FF90 like Sonic 2, and you could narrow down the music play list by coding an array, Great job on your first attempt I am amazed you caught on so quickly :P.
     
  3. Tweaker

    Tweaker

    Banned
    12,387
    2
    0
    :thumbsup:

    Awesome stuff. It's not complicated, but it's great to see somebody figure these things out on their own, based on logical thought processes. And you're right, ASM isn't as complicated as people tend to say it is—instead of "learning ASM," the correct term is rather "learning the Sonic engine," because that's exactly what you're doing. Once you can do that, you'll really go places. :)
     
  4. It's actually quite amazing how sometimes the things that appear simple are actually very long. In my case, Super Tails was a copy-paste, homing attack was hardly twenty lines of code, yet making Tails lose rings for Sonic beta-style required edits to 3 different places, a bunch of new checks, and was actually harder to get working correctly than the former two.

    As Varion Icaria said though, the code could be a lot simpler. Sonic 2 was smart in that it copied the current level music to $FF90 and used that to resume the level music. Doing something similar would make Step 4 and 5 much simpler and avoid code duplication. In addition, the different music playlists could be unified into one big music playlist containing 4 bytes per level (one for each act) and a calculation made to determine the correct offset entry. Oh, and cmp.b #0,... is generally not used - tst.b ... is used instead.
     
  5. MoDule

    MoDule

    Tech Member
    327
    24
    18
    Procrastinating from writing bug-fix guides
    Ah, yes. Your first asm hack is always your greatest accomplishment...
    until you do something even better XD.

    In case you are interested in how the differnt branch types work, I found this little page that explains (all of?) the 68k opcodes and how they affect the condition codes (<- those are important to understand).

    And you of all people shouldn't complain about having to find new music, you know, making your own tool and all :P. There are huge xm and midi archives out there waiting to be used.
    Exactly how to extend the playlist, I don't know. I haven't looked into that yet. I'm interested in other things for now.
     
  6. Hitaxas

    Hitaxas

    Retro 80's themed Twitch streamer ( on hiatus) Member
    Ah, drat. you beat me to it. I was tring to figure out the same thing. Your way was quite like mine. Well, thanks. This is some good code.
     
  7. nineko

    nineko

    I am the Holy Cat Tech Member
    6,308
    486
    63
    italy
    There is something to say about this section (and the two equivalent ones), as I forgot to mention this the last time:
    Code (ASM):
    1. Level_GetBgm4:
    2.         cmpi.b  #$3,($FFFFFE11).w   ; is this act 4?
    3.         bne.s   Level_PlayBgm   ; if not, branch
    4.         lea (MusicList4).l,a1   ; load Music Playlist for Acts 4
    5.  
    6. Level_PlayBgm:
    7.         move.b  (a1,d0.w),d0    ; get d0-th entry from the playlist
    8.         bsr.w   PlaySound   ; play music
    9.         move.b  #$34,($FFFFD080).w ; load title card object
    The cmpi.b and the bne.s aren't really needed, as that's the last chance anyway. I left them in my code for "artistic" reasons, but you can (and you should) definitely remove them. Especially because the day you have act 5 and that condition is true, there will be no playlist loaded and the game won't be happy about it.
     
  8. Hitaxas

    Hitaxas

    Retro 80's themed Twitch streamer ( on hiatus) Member
    OR, If you were to have 5 acts, just make it branch to a Level_GetBgm5, the same way that the checks for acts 1, 2 and 3 work. :P
     
  9. Tweaker

    Tweaker

    Banned
    12,387
    2
    0
    Alternatively, you can keep the check for Act 4 and get rid of the check for Act 1—you can then place the act 1 playlist at the end of the chain of compares, from which if the act is anything OTHER than 1, it will never hit that section of code.
     
  10. Hitaxas

    Hitaxas

    Retro 80's themed Twitch streamer ( on hiatus) Member
    There are 3 ways to do that, I guess. I think that Tweaker's suggestion is the best one, because it takes less space in the code.
     
  11. Esrael

    Esrael

    Neto Tech Member
    304
    257
    63
    Brazil, São Paulo, Guarulhos
    Neto Assembler Editor / Sonic 2 Delta / Neto MD-DOS
    You can load music in sequence using the following code:

    Code (ASM):
    1. ;=============================================
    2. ;  One Song per Act by Esrael L. G. Neto
    3. ;  [ Begin ]
    4. ;=============================================
    5. Load_Play_List:
    6.                 moveq   #$00, D0
    7.                 move.w  ($FFFFFE10).w, D0      
    8.                 lea  Play_List(PC), A1
    9.                 lsr.w   #$08, D0               
    10.                 muls    #$04, D0            ; "#$04" determine acts per level
    11.                 add.b   ($FFFFFE11).w, D0    
    12.                 move.b  $00(A1, D0), D0
    13.                 jmp  Play_Music  
    14. Play_List:
    15.                 dc.b     $81, $82, $83, $84, $85, $86, $87, $88, $89
    16. ;=============================================
    17. ;  One Song per Act by Esrael L. G. Neto
    18. ;  [ End ]
    19. ;=============================================
    You can restore song calling this sub " jsr Load_Play_List " or Saving in Ram like Sonic 2
     
  12. Puto

    Puto

    Shin'ichi Kudō, detective. Tech Member
    2,013
    0
    16
    Portugal, Oeiras
    Part of Team Megamix, but haven't done any actual work in ages.
    ...muls on a power of 2? lsl.w #2 plz.
     
  13. Tweaker

    Tweaker

    Banned
    12,387
    2
    0
    Yeah, multiplication on the 68k is extremely slow—it might even be better to just use "add.b d0,d0" twice.
     
  14. Esrael

    Esrael

    Neto Tech Member
    304
    257
    63
    Brazil, São Paulo, Guarulhos
    Neto Assembler Editor / Sonic 2 Delta / Neto MD-DOS
    I am using muls because it can be used for any number of acts just changing one number, in other way you can use -> Add.w D0, D0
     
  15. Actually, for 4 acts, the most optimized way to get the index would be:

    Code (Text):
    1. move.b ($FFFFFE10).w,d0
    2. ror.b #2,d0
    3. lsr.w #6,d0
    (similar to how Sonic 2 does it for level layout indexes and stuff).
     
  16. nineko

    nineko

    I am the Holy Cat Tech Member
    6,308
    486
    63
    italy
    Bah, I'm still using my code. It looks easier to me.
     
  17. Esrael

    Esrael

    Neto Tech Member
    304
    257
    63
    Brazil, São Paulo, Guarulhos
    Neto Assembler Editor / Sonic 2 Delta / Neto MD-DOS
    Ok. But, I am Trying to give a flexible code.
    The fixed 4 acts will look like this:
    Code (Text):
    1. ;=============================================
    2. ;  One Song per Act by Esrael L. G. Neto
    3. ;  [ Begin ]
    4. ;=============================================
    5.                 moveq   #$00, D0
    6.                 move.w  ($FFFFFE10).w, D0    
    7.                 lea  Play_List(PC), A1
    8.                 ror.b   #$02, D0               
    9.                 lsr.w   #$06, D0               
    10.                 move.b  $00(A1, D0), D0
    11.                 jmp  Play_Music          
    12. Play_List:
    13.                 dc.b    $81, $82, $83, $84, $85, $86, $87, $88, $89
    14. ;=============================================
    15. ;  One Song per Act by Esrael L. G. Neto
    16. ;  [ End ]
    17. ;=============================================
     
  18. Actually, in my opinion at least, a unified playlist beats a long list of compares/branches. Using a unified playlist, the code would look something like:
    Code (ASM):
    1. Level_GetBgm:
    2.         tst.w   ($FFFFFFF0).w
    3.         bmi.s   loc_3946
    4.         moveq   #0,d0
    5.         move.w  ($FFFFFE10).w,d0
    6.         ror.b   #2,d0
    7.         lsr.w   #6,d0
    8.         lea (MusicList).l,a1 ; load music playlist
    9.         move.b  (a1,d0.w),d0    ; add d0 to a1
    10.         bsr.w   PlaySound   ; play music
    11.         move.b  #$34,($FFFFD080).w ; load title card object
    And the music playlist something like:
    Code (ASM):
    1.         dc.b $81 ; GHZ 1
    2.         dc.b $82 ; GHZ 2
    3.         dc.b $83 ; GHZ 3
    4.         dc.b $84 ; GHZ 4
    5.         dc.b $85 ; LZ 1
    6.         ...
    Alternatively, if you want to keep the four separate playlists, you could use an offset index to store their addresses, like:

    Code (ASM):
    1. Level_GetBgm:
    2.         tst.w   ($FFFFFFF0).w
    3.         bmi.s   loc_3946
    4.         moveq   #0,d0
    5.         move.b  ($FFFFFE10).w,d0
    6.         move.b  ($FFFFFE11).w,d1
    7.         add.w   d1,d1
    8.         add.w   d1,d1
    9.         movea.l MusicPlaylists(pc,d1.w),a1
    10.         move.b  (a1,d0.w),d0    ; add d0 to a1
    11.         bsr.w   PlaySound   ; play music
    12.         bra.s   Level_GetBgm_Cont
    13.  
    14. MusicPlaylists:
    15.         dc.l MusicList1
    16.         dc.l MusicList2
    17.         dc.l MusicList3
    18.         dc.l MusicList4
    19.  
    20. Level_GetBgm_Cont:
    21.         move.b  #$34,($FFFFD080).w ; load title card object
    I still prefer the first alternative however. The only think which could be considered hard about it would be the highly optimized method of calculating the array index, which I can explain in depth if you want.
     
  19. Puto

    Puto

    Shin'ichi Kudō, detective. Tech Member
    2,013
    0
    16
    Portugal, Oeiras
    Part of Team Megamix, but haven't done any actual work in ages.
    I still prefer my way kthx.

    Code (ASM):
    1.  
    2. PlayLevelBGM:  
    3.     moveq   #0,d0
    4.     move.b  ($FFFFFE11).w,d0
    5.     add.b   d0,d0
    6.     jmp PlayLevelBGM_Index(pc,d0.w)
    7.  
    8. PlayLevelBGM_Index:
    9.     bra.s   PlayLevelBGM_Act1
    10.     bra.s   PlayLevelBGM_Act2
    11.     bra.s   PlayLevelBGM_Act3
    12.     move.b  #$8D,d0         ; The only Act 4 we have is SBZ3, so just play song $8D on that one.
    13.     jmp PlaySound_Special
    14.  
    15. PlayLevelBGM_Act1:
    16.     move.b  (Current_Zone).w,d0 ; Move current zone To d0
    17.     add.b   #$81,d0         ; Add $81 To d0
    18.     jmp PlaySound_Special
    19.  
    20. PlayLevelBGM_Act2:
    21.     move.b  (Current_Zone).w,d0 ; Move current zone To d0
    22.     add.b   d0,d0           ; Double it.
    23.     add.b   #$94,d0         ; Add $94 To d0
    24.     jmp PlaySound_Special
    25.  
    26. PlayLevelBGM_Act3:
    27.     move.b  (Current_Zone).w,d0 ; Move current zone To d0
    28.     add.b   d0,d0           ; Double it.
    29.     add.b   #$95,d0         ; Add $95 To d0
    30.     jmp PlaySound_Special
    31.  
    Calculated values ftw.
     
  20. Well, if you were using a pre-arranged music order (which is a pretty good idea), my code would look like:

    Code (ASM):
    1. Level_PlayBgm:
    2.         moveq   #0,d0
    3.         move.w  ($FFFFFE10).w,d0
    4.         ror.b   #2,d0
    5.         lsr.w   #6,d0
    6.         add.w   #some_predecided_value,d0
    7.         bsr.w   PlaySound   ; play music
    which still beats everything else IMO.
     
Thread Status:
Not open for further replies.