Mini-tutorials Thread

Discussion in 'Tutorials' started by DeltaWooloo, Feb 16, 2021.

Tags:
  1. Apple Boy

    Apple Boy Newcomer Trialist

    Joined:
    Jan 12, 2021
    Messages:
    2
    What address would I go to for the GitHub Disassembly?
     
  2. DeltaWooloo

    DeltaWooloo dead account Member

    Joined:
    Aug 7, 2019
    Messages:
    358
    Dunno what you mean by address. If you want to find the label, might I suggest this handy label comparison that compares Hivebrain's disassembly with SVN/GitHub's disassembly.

    In this case, you need to look for Got_Config
     
    Giovanni and TheInvisibleSun like this.
  3. SuperSayian Zrise

    SuperSayian Zrise Well-Known Member Exiled

    Joined:
    May 10, 2021
    Messages:
    78
    Using selbi's text code generator for Sonic 1. Anyways, with the text code generator you only have to worry about modding the blue oval, the act number and the bonuses. But most likely you are editing the SONIC HAS PASSED message. If so, use the Sonic 1 text code generator by selbi.
     
  4. DeltaWooloo

    DeltaWooloo dead account Member

    Joined:
    Aug 7, 2019
    Messages:
    358
    Well yeah... but the mini tutorial I wrote tells you about the structure of the results card, not the text.
     
    SuperSayian Zrise likes this.
  5. Scrap Sorra

    Scrap Sorra Well-Known Member Member

    Joined:
    Sep 18, 2020
    Messages:
    101
    Location:
    Sonic the Hedgehog for the Sega Genesis
    Play Animated Level GFX when the game is paused.

    Sonic CD does this kinda strange thing where if the game is paused animated level GFX doesn't stop playing, so let's add it to Sonic 1!

    In sonic1.asm, go to "AniArt_Load" and comment out or delete these two lines:

    Code:
    tst.w    ($FFFFF63A).w    ; is the game paused?
            bne.s    AniArt_Pause    ; if yes, branch
    That's it.


    In inc\AnimateLevelGfx.asm, comment out or delete these two lines at the start of AnimateLevelGfx:

    Code:
    tst.w    (f_pause).w    ; is the game paused?
            bne.s    @ispaused    ; if yes, branch
    That's it.

    Now animated level graphics will continue to play even when the game is paused.
     
  6. Painto

    Painto Arthurus Paintus Erinaceus Member

    Joined:
    Mar 24, 2014
    Messages:
    321
    Location:
    Lublin, Poland
    Fixing the swinging wrecking ball object in GHZ
    As you probably know, there's an unused subtype of the swinging platform which uses wrecking ball at its end instead of a platform. However if you intend to use it in your level design, you may notice a little error in it - while invincible (either after hurt or from powerup) you can stand on it like it's a normal platform.
    [​IMG]
    The fix to this is easy. This object ($15) is also used in Scrap Brain Zone for spikeballs on a chain and in that setup it works as intended (that is, you can't stand on it). Comparing both setups reveals that there is one difference: spikeball variant changes the object's routine to a simpler one, while wrecking ball one still uses the regular platform routines. This means the fix is as simple as setting the correct routine. Here's how to do that:

    Open sonic1.asm and search for loc_7AD4:. Just above it, you should see the following code:
    Code:
    		btst	#4,d1		; is object type $8X ?
    		beq.s	loc_7AD4	; if not, branch
    		move.l	#Map_obj48,4(a0) ; use GHZ ball	mappings
    		move.w	#$43AA,2(a0)
    		move.b	#1,$1A(a0)
    		move.b	#2,$18(a0)
    		move.b	#$81,$20(a0)	; make object hurt when	touched
    
    Under it add the following lines:
    Code:
    		move.b	#$C,$24(a0)	; set routine to Obj15_Action
    		bra.s	Obj15_Action	; skip solidity routines
    
    Save and build.
    Open _incObj/15 Swinging Platforms (part 1).asm and search for @not1X:. Just above it, you should see the following code:
    Code:
    		btst	#4,d1		; is object type $1X ?
    		beq.s	@not1X	; if not, branch
    		move.l	#Map_GBall,obMap(a0) ; use GHZ ball mappings
    		move.w	#$43AA,obGfx(a0)
    		move.b	#1,obFrame(a0)
    		move.b	#2,obPriority(a0)
    		move.b	#$81,obColType(a0) ; make object hurt when touched
    
    Under it add the following lines:
    Code:
    		move.b	#$C,obRoutine(a0)	; set routine to Swing_Action
    		bra.s	Swing_Action	; skip solidity routines
    
    Save and build.
     
    Last edited: Nov 14, 2021
  7. TheFieldWarrior

    TheFieldWarrior Green Villager is a treasure Member

    Joined:
    Oct 9, 2015
    Messages:
    93
    Location:
    United Kingdom
    How to add instant recovery from getting hit:

    Getting tired of taking major knockback and having your controls locked upon getting hit? Here is a way to remove both of these issues by utilising a couple of lines from an unused subroutine in Sonic 2 for instant recovery. I'll be using Sonic 1 (Hivebrain) for this guide but ideally you should be able to add this feature into any of the trilogy regardless of disassembly.


    Search for Obj01_Hurt and before the line "jsr SpeedToPos" add these two lines:

    Code:
            subq.b    #2,$24(a0)
            move.b  #0,$25(a0)

    Build the ROM and now Sonic will have instant recovery after taking a hit allowing you to control yourself during the hurt animation. Your i-frames start up sooner than normal however but you can always increase the i-frame timer, I personally keep the timer as it is as a trade off for the instant recovery.


    Spin Dash bug fix:

    If you have the Spin Dash implemented there is now a bug where if Sonic get's hit during the rev animation he will boost off after he's hit the ground, fixing this is simple: after the line "move.b #0,$25(a0)" add this:

    Code:
    move.b    #0,$39(a0)
    All done. There might be a better and more optimal way to add instant recovery so you're more than welcome to reply to this post with it
     
    Painto, Scrap Sorra and DeltaWooloo like this.
  8. Speems

    Speems Well-Known Member Member

    Joined:
    Mar 14, 2017
    Messages:
    66
    Location:
    Rochester Hills, MI
    How to Remove the Points Object in Sonic 1 (Hivebrain 2005)

    If you hate the occasional instance of the points art fucking up some aspects of your Sonic art, or need to save some VRAM, removing the points art/object may be the way to go. Here's how you can do it! This is based off a finding by Cinossu.

    1. Head to sonic1.asm and you'll need to find this line of code:

    Code:
            move.b    #$29,0(a1)    ; load points object
    There are three traces of this line of code throughout the asm. They are in loc_90C0, Obj47_Score, and Obj51_Smash. You've gotta delete those.


    2. Find Nem_Points in the same file, which is the incbin for the art.

    Code:
    Nem_Points:    incbin    artnem\points.bin    ; points from destroyed enemy or object
    
            even
    Delete it. Now the game will refuse to build due to it missing from the game but requiring the pattern load cues present. We need to take care of the pointer in another file.


    3. Head to the Pattern load cues.asm in the _inc folder, which has Nem_Points as the last part of Standard block 1.

    Code:
            dc.l Nem_Points        ; points from enemy
    
            dc.w $F2E0
    You think that simply deleting it will work, right? Wrong! Do that and it crashes right at the title screen when built. So what you need to do is change the dc.w digit from 4 to 3, lowering the amount of objects that need to be loaded, also making sure correct amounts of data are read.


    4. One last thing! Head to the Object pointers.asm and you'll see Obj29 like this:

    Code:
        dc.l Obj29, Obj2A, Obj2B, Obj2C
    Replace the singular instance with DeleteObject.


    Build the game and you should be able to dish out broken badniks and various level-specific objects, and still earn the points even with the art for it gone. You also have some extra free tiles in VRAM when you do it, that's always nice. There should be equivalent labeling in the Github disassembly, although the code for the points object may be in a separate ASM file.


    Credit should go to Cinossu for his input on simply disabling it, I prefer it considering this is merely a goodwill tutorial meant to help newcomers who think the points object/art is rather pesky. Thanks!


    EDIT: 12/13/2021 - All steps (except for 2) have been adjusted following criticism regarding RAM issues from vladikcomper.
     
    Last edited: Dec 13, 2021
  9. vladikcomper

    vladikcomper Well-Known Member Member

    Joined:
    Dec 2, 2009
    Messages:
    410
    @Speems, not to discourage you or anything, but the guide you've just posted is dangerous and gives some bad advice.

    First of all, you remove the points object (Obj29), but don't disable code that spawns it. This is dangerous and leads to memory leaks.

    If you check animals object (Obj28), it actually spawns points object here:

    Code:
    loc_90C0:
                    ; <...>
                    bsr.w    SingleObjLoad
                    bne.s    Obj28_Display
                    move.b    #$29,(a1)        ; load points object
                    ; <...>
    You make it so object slot ID $29 now points to ObjectFall, which is fine, except one thing: this object will never delete itself and free memory.

    And there are several other places, where object $29 is being created.

    Spawning broken objects like this is dangerous, because they'll occupy objects RAM forever and eventually prevent any other objects from loading. Try spamming and destroying as many badniks as you can in debug mode, you'll soon notice any level objects won't spawn at all.

    So, to fix this serious bug, your guide should be appended with the following:

    Find every occurrence of "move.b #$29,(a1)" in disassembly, and remove the related code, starting from "bsr.w SingleObjLoad" until the very last line where "X(a1)" is being written to...​

    There are quite a few places, actually.

    Or, better yet, use "DeleteObject" instead "ObjectFall" for object slot ID $29, to make this fail-proof and reliable.

    This is just plain bad advice, and it's teaching people wrong and dengerous things to do.

    If you get a crash, but instead of trying to figure it out, you chose to randomly hack in one thing instead of another, and you aren't even sure what that thing should be, you're clearly doing something wrong...

    You get a crash, because in the beginning of every Pattern Load Cues list there's a word that determines how many entries should be in that list. You removed an entry from the list, but you didn't decrease that number. If you decrease it, the game won't read incorrect data at the end of now-shorter list, and any crashes will be gone.
     
  10. Speems

    Speems Well-Known Member Member

    Joined:
    Mar 14, 2017
    Messages:
    66
    Location:
    Rochester Hills, MI
    @vladikcomper
    Post has been updated with the tidbits, thanks for informing me of the risks.
     
    Crimson Neo and vladikcomper like this.
  11. TheInvisibleSun

    TheInvisibleSun Visible Member

    Joined:
    Jul 2, 2013
    Messages:
    408
    Location:
    Buffalo, NY, USA
    Manual Special Stage Rotation Control in Sonic 1


    Would you like to have Sonic 1 Special Stages where you control the rotation with the d-pad, a la Sonic 4: Episode 1? It's actually quite simple, and should only involve about 7 lines of code.


    In the Special gamemode's init code, comment out this line:

    Code:
    move.w    #$40,(v_ssrotate).w ; set stage rotation speed
    Optionally, comment out this line under the 'SS_ShowLayout' subroutine, for smooth rotation (courtesy of Cinossu):

    Code:
    andi.b    #$FC,d0    
    Next, in Object 09's code, add these lines to disable Sonic's movement, and make your input rotate the stage instead:

    Code:
    ...
    
    Obj09_MoveLeft:
    
            sub.w #$XX,(v_ssangle).w    ; TIS - include whatever value you'd like, tweak to desired rotation speed
            rts    ;TIS     - Disable Sonic's left movement
            bset    #0,obStatus(a0)
            move.w    obInertia(a0),d0
    
            ...
    
    

    Code:
    Obj09_MoveRight:
    
            add.w #$XX,(v_ssangle).w    ;TIS - include whatever value you'd like, tweak to desired rotation speed
            rts      ;TIS - Disable Sonic's right movement
            bclr    #0,obStatus(a0)
            move.w    obInertia(a0),d0
            ...

    Finally, disable Object 09's jump here:



    Code:
    Obj09_Jump:
            rts    ;TIS - Disable Jump Routine
            move.b    (v_jpadpress2).w,d0
            andi.b    #btnABC,d0    ; is A,    B or C pressed?
            ...
    
    

    Enjoy!
     
  12. EddyTF

    EddyTF #romhacker Member

    Joined:
    Jan 9, 2022
    Messages:
    34
    Location:
    Russia
    How to increase or decrease Boss Hits in Sonic 1 (Hivebrain Disasm)

    To increase or decrease the blows of the Boss of the Green Hill, you need to find loc_17772:

    Code:
    loc_17772:
            move.w    8(a0),$30(a0)
            move.w    $C(a0),$38(a0)
            move.b    #$F,$20(a0)
            move.b    #8,$21(a0)    ; set number of hits to 8
    We will need a line:

    Code:
    move.b    #8,$21(a0)    ; set number of hits to 8
    And at $8 we increase or decrease the hits

    For the boss of the Labyrinth - Obj77_Main:
    For the boss of the Marble - Obj73_Main:
    For the boss of the Star Light - Obj7A_Main:
    For the boss of the Spring Yard - Obj75_Main:
    For the boss of the Final - loc_19E5A:

    We are looking for the same line specified above.


    Enjoy hacking!;)
     
    Last edited: Mar 7, 2022
  13. Nik Pi

    Nik Pi Newcomer Member

    Joined:
    Feb 14, 2022
    Messages:
    19
    Wall recoil in final Sonic 2 (based on https://sonicresearch.org/community/index.php?threads/sonic-1-porting-s2na-wall-recoil.6052/):
    The first- you need to find in Obj01_CheckWallsOnGround this:
    Code:
    bset    #5,status(a0)
    move.w    #0,inertia(a0)
    And after this- place:
    Code:
    cmpi.w    #$300,$10(a0)    ; Check if player is at running speed
    bge.s    Sonic_WallRecoil    ; If so, bonk
    Second: In loc_1A6A8 after move.w #0,inertia(a0) insert:
    Code:
    cmpi.w    #-$300,$10(a0)    ; If player is at running speed to the left
    ble.s    Sonic_WallRecoil    ; Bonk!
    And now- before Sonic_MoveLeft write:
    Code:
    Sonic_WallRecoil:   ; Routine to bounce Sonic off a wall when going too fast
    move.b    #4,$24(a0)
    bsr.w    Sonic_ResetOnFloor
    bset    #1,$22(a0)  ; Set Sonic as in air
    move.w    #$FE00,d0   ; Move recoil speed into d0 for later
    tst.w    $10(a0) ; Check if player is moving right
    bpl.s    cont  ; If so, branch
    neg.w    d0  ; Negate recoil speed if facing left
    
    cont
    move.w    d0,$10(a0)  ; Move recoil speed into X speed
    move.w    #$FC00,$12(a0)  ; Vertical recoil speed
    move.w    #0,$14(a0)  ; Clear inertia
    move.b    #AniIDSonAni_Hurt2,anim(a0) ; Play recoil animation
    move.b    #1,$25(a0)
    move.w    #SndID_Hurt,d0
    jsr    (PlaySound).l
    rts ; Return
    I hope it will be useful for someone

    EDIT: Used code line
     
    Last edited: Mar 8, 2022
  14. EddyTF

    EddyTF #romhacker Member

    Joined:
    Jan 9, 2022
    Messages:
    34
    Location:
    Russia
    How to display the inscription "Press Start Button" (Alternative) (Sonic 1 Hivebrain Disasm)

    Find Title_ClrObjRam2:

    We see this:

    Code:
    Title_ClrObjRam2:
            move.l    d0,(a1)+
            dbf    d1,Title_ClrObjRam2
    
            move.b    #$E,($FFFFD040).w ; load big Sonic object
            move.b    #$F,($FFFFD080).w ; load "PRESS    START BUTTON" object
            move.b    #$F,($FFFFD0C0).w ; load "TM" object
            move.b    #3,($FFFFD0DA).w
            move.b    #$F,($FFFFD100).w
            move.b    #2,($FFFFD11A).w
            jsr    ObjectsLoad
            bsr.w    DeformBgLayer
            jsr    BuildSprites
            moveq    #0,d0
            bsr.w    LoadPLC2
            move.w    #0,($FFFFFFE4).w
            move.w    #0,($FFFFFFE6).w
            move.w    ($FFFFF60C).w,d0
            ori.b    #$40,d0
            move.w    d0,($C00004).l
            bsr.w    Pal_FadeTo
    After dbf d1,Title_ClrObjRam2, insert:

    Code:
    jsr     DeleteObject2     ; clear object RAM to make room for the "Press Start Button" object
    Compile, check. Works :D

    Enjoy hacking!;)
     
  15. ralakimus

    ralakimus IMPOLITE AND EVIL! Member

    Joined:
    Aug 26, 2013
    Messages:
    1,113
    I haven't seen anyone else bring this up, but I thought this was a tad interesting.

    So, you might know of the change to make special stages rotate smoother, which is done by removing the "andi.b #$FC,d0" line in SS_ShowLayout that limits the rotation value. Did you know that angle value limitation is also found in Sonic's special stage object and subtley affects his physics for jumping and gravity?

    In Obj09_Jump, you can find:
    Code:
            move.b    (v_ssangle).w,d0
            andi.b    #$FC,d0
            neg.b    d0
            subi.b    #$40,d0
            jsr    (CalcSine).l

    Which calculates the angle to jump at. Note the "andi" instruction, that same line that limits the sprite rotation.

    You can also find a similar line here in Obj09_Fall:
    Code:
            move.b    (v_ssangle).w,d0
            andi.b    #$FC,d0
            jsr    (CalcSine).l

    Which affects how gravity is calculated. Again, that "andi" instruction is there.

    So, if you wanna enable slightly smoother jumping and gravity, comment out those "andi" lines.

    Also, if you followed this guide, then there's 2 additional instances in Obj09_JumpHeight.
     
    Last edited: Jun 24, 2022