[Sonic 1 Github] How to fade music after a level ends

Discussion in 'Tutorials Archive' started by Giovanni, Oct 26, 2016.

  1. Giovanni

    Giovanni It's Joe-vanni, not Geo-vanni. Member

    Joined:
    Apr 16, 2015
    Messages:
    311
    Location:
    Italy
    Welcome to my first tutorial. In this very basic tutorial, I will show you how to fade out a level's music after it ends.

    GAME: Sonic 1
    DISASSEMBLY: Github
    DIFFICULTY: Very Easy

    STEP 1: Signposts

    Let's start with signposts. Open _incObj and search the object 0D. Go to Sign_Touch. You will see this.

    Code:
    Sign_Touch:    ; Routine 2
            move.w    (v_player+obX).w,d0
            sub.w    obX(a0),d0
            bcs.s    @notouch
            cmpi.w    #$20,d0        ; is Sonic within $20 pixels of    the signpost?
            bcc.s    @notouch    ; if not, branch
            music    sfx_Signpost,0,0,0    ; play signpost sound
            clr.b    (f_timecount).w    ; stop time counter
            move.w    (v_limitright2).w,(v_limitleft2).w ; lock screen position
            addq.b    #2,obRoutine(a0)
    Replace "sfx_Signpost,0,0,0" with "bgm_Fade,1,0,0".
    This will allow the sign to let the music fade right when you touch it.
    This behavior is used in some other hacks, like Mobius Evolution. I feel like I should credit the author(s) for inspiration, so go check it out if you want to!

    STEP 2: Prison Capsules

    This is actually made and tested by me, and it's possible to do it in two ways.
    This time, go look for object 3E, and find Pri_Switched.
    You will find this code:

    Code:
            addq.w    #8,obY(a0)
            move.b    #$A,obRoutine(a0)
            move.w    #60,obTimeFrame(a0) ; set time between animal spawns
            clr.b    (f_timecount).w    ; stop time counter
            clr.b    (f_lockscreen).w ; lock screen position
            move.b    #1,(f_lockctrl).w ; lock controls
            move.w    #(btnR<<8),(v_jpadhold2).w ; make Sonic run to the right
            clr.b    ob2ndRout(a0)
            bclr    #3,(v_player+obStatus).w
            bset    #1,(v_player+obStatus).w
    Add "music bgm_Fade,1,0,0" between the second "clr.b" and the first "move.b".
    You will get something like this:

    Code:
            addq.w    #8,obY(a0)
            move.b    #$A,obRoutine(a0)
            move.w    #60,obTimeFrame(a0) ; set time between animal spawns
            clr.b    (f_timecount).w    ; stop time counter
            clr.b    (f_lockscreen).w ; lock screen position
            music   bgm_Fade,1,0,0
            move.b    #1,(f_lockctrl).w ; lock controls
            move.w    #(btnR<<8),(v_jpadhold2).w ; make Sonic run to the right
            clr.b    ob2ndRout(a0)
            bclr    #3,(v_player+obStatus).w
            bset    #1,(v_player+obStatus).w
    Now, music will fade out right when the button is pressed, but explosions won't be heard.
    If you don't like this, then follow the next step instead.

    STEP 2 ALT: Prison Capsules

    NOTE: If you followed step 2, but you want to follow this method, then delete the "music bgm_Fade,1,0,0" previously added. If not done, this will be useless.
    This time, you will need to look for @makeanimal and add "music bgm_Fade,1,0,0" at the end of it.
    It should look like this:
    Code:
    @makeanimal:
            move.b    #2,(v_bossstatus).w
            move.b    #$C,obRoutine(a0)    ; replace explosions with animals
            move.b    #6,obFrame(a0)
            move.w    #150,obTimeFrame(a0)
            addi.w    #$20,obY(a0)
            moveq    #7,d6
            move.w    #$9A,d5
            moveq    #-$1C,d4
            music   bgm_Fade,1,0,0
    
    And this is it. Now music will fade out after the explosions.

    Thank you for following this tutorial! I hope you will like the results.

    This time, you will need to look for Pri_Animals.
    You will find this:

    Code:
    Pri_Animals:    ; Routine $C
            moveq    #7,d0
            and.b    (v_vbla_byte).w,d0
            bne.s    @noanimal
            jsr    (FindFreeObj).l
            bne.s    @noanimal
            move.b    #id_Animals,0(a1) ; load animal object
            move.w    obX(a0),obX(a1)
            move.w    obY(a0),obY(a1)
            jsr    (RandomNumber).l
            andi.w    #$1F,d0
            subq.w    #6,d0
            tst.w    d1
            bpl.s    @ispositive
            neg.w    d0
    Add "music bgm_Fade,1,0,0" right at the end. The result will be this:

    Code:
    Pri_Animals:    ; Routine $C
            moveq    #7,d0
            and.b    (v_vbla_byte).w,d0
            bne.s    @noanimal
            jsr    (FindFreeObj).l
            bne.s    @noanimal
            move.b    #id_Animals,0(a1) ; load animal object
            move.w    obX(a0),obX(a1)
            move.w    obY(a0),obY(a1)
            jsr    (RandomNumber).l
            andi.w    #$1F,d0
            subq.w    #6,d0
            tst.w    d1
            bpl.s    @ispositive
            neg.w    d0
            music   bgm_Fade,1,0,0
     
    Last edited: Oct 26, 2016
    breakthetargets and HackGame like this.
  2. AURORA☆FIELDS

    AURORA☆FIELDS so uh yes Exiled

    Joined:
    Oct 7, 2011
    Messages:
    759
    This looks good enough as a tutorial, except the second method for prison capsule; Since d0 is used to offset the X position here, you will end up spawning animals outside of the screen and playing fadeout multiple times! There is no negative effect to the game in form of crashes or glitches, but you end up losing animals.
     
  3. Giovanni

    Giovanni It's Joe-vanni, not Geo-vanni. Member

    Joined:
    Apr 16, 2015
    Messages:
    311
    Location:
    Italy
    I've made a great mistake when writing the guide. The alternative second method is wrong, and has been edited.
    The "music bgm_Fade,1,0,0" should have been added at the end of @makeanimal, leading to this result:

    Code:
    @makeanimal:
            move.b    #2,(v_bossstatus).w
            move.b    #$C,obRoutine(a0)    ; replace explosions with animals
            move.b    #6,obFrame(a0)
            move.w    #150,obTimeFrame(a0)
            addi.w    #$20,obY(a0)
            moveq    #7,d6
            move.w    #$9A,d5
            moveq    #-$1C,d4
            music   bgm_Fade,1,0,0
    I was looking to the code of a plain, unedited object, so I didn't look to my code.
    This should work out better, as testing doesn't seem to generate noticeable differences.

    EDIT: Further testing revealed that even this code causes less animals to spawn
     
  4. redhotsonic

    redhotsonic Also known as RHS Member

    Joined:
    Aug 10, 2007
    Messages:
    2,969
    Location:
    England
    You could just move the ID of the music to the RAM address instead of moving the ID to a data register then to a RAM address. It may help if you're struggling to find data registers.

    Also, with the location you're sticking the instruction to fade the music, it will still play several times (because "makeanimal" will be read several times).