Basic Questions and Answers Thread

Discussion in 'Discussion & Q&A' started by Malevolence, Jul 7, 2009.

  1. Giovanni

    Giovanni It's Joevanni, not Geovanni. Member

    Joined:
    Apr 16, 2015
    Messages:
    264
    Location:
    Italy
    I think I would need some code, as well as a better idea of what you're trying to achieve (especially level design wise) for me to try and help you.
     
    Last edited: Mar 30, 2022
  2. EpsilionDubwool

    EpsilionDubwool I am the danger. Member

    Joined:
    Aug 7, 2019
    Messages:
    363
    I'll show you the resize code to GHZ Act 1 (since I provided a screenshot of that as an example):
    Code:
    Resize_GHZ1:
             move.w    #$300,(v_limitbtm1).w ; set lower y-boundary
             move.w    #$300,(v_limitbtm2).w ; set lower y-boundary         
             cmpi.w #$1500,($FFFFF700).w ; has the camera reached $1780 on x-axis?
             bcs.s locret_6E08 ; if not, branch
             move.w    #$400,(v_limitbtm1).w ; set lower y-boundary
             move.w    #$400,(v_limitbtm2).w ; set lower y-boundary   
             cmpi.w #$1880,($FFFFF700).w
             bcs.s locret_6E08
             rts
    
    locret_6E08:
            rts
    If you need any more code, gimme a shout.
     
  3. Giovanni

    Giovanni It's Joevanni, not Geovanni. Member

    Joined:
    Apr 16, 2015
    Messages:
    264
    Location:
    Italy
    Hmm. In Green Hill Act 1, when replacing v_limitbtm1 with $FFFFF726 and v_limitbtm2 with $FFFFF72E, everything seems to work fine. If the behavior you're experiencing is the same as in Sonic 1, my only suggestion is checking your equates.
    However, you should be extra careful if you're planning to use $FFFFF72E with resizing routines, especially if you're making custom levels! In fact, if you're using $FFFFF72E on every single instance of $FFFFF726, the game may behave very weirdly when the screen moves upwards. Sure, you can design your level in such a way that visual issues never occur, in fact, Green Hill 1 is already designed in such a way, ironically, but you can use subroutines in your resizing routines to make sure that you don't need to.

    But you should be careful when using subroutines, too! In fact, Sonic 1 has a glaring bug: it executes resizing routines while a new level is loading, which can lead to invalid subroutines being loaded, which create a chance for the game to crash! The fact Sonic 1 does not crash while also using subroutines in some dynamically resized levels is pretty much due to chance, actually, but you may not have the same luck the original developers had if you're coding custom resizing routines.

    I highly recommend you apply this fix to pretty much every Sonic 1 hack you make. I give my thanks to djohe for teaching me this fix in the first place.
    In loc_3B14, you'll find these two lines:

    Code:
            tst.w    ($FFFFFE02).w    ; is the level set to restart?
            bne.w    Level        ; if yes, branch
    You want to move them to Level_MainLoop, right above the "tst.w ($FFFFFE08).w". This is what your code will look like:

    Code:
    Level_MainLoop:
            bsr.w    PauseGame
            move.b    #8,($FFFFF62A).w
            bsr.w    DelayProgram
            addq.w    #1,($FFFFFE04).w ; add 1 to level timer
            bsr.w    MoveSonicInDemo
            bsr.w    LZWaterEffects
            jsr    ObjectsLoad
            tst.w    ($FFFFFE02).w    ; is the level set to restart?
            bne.w    Level        ; if yes, branch
            tst.w    ($FFFFFE08).w
            bne.s    loc_3B10
            cmpi.b    #6,($FFFFD024).w
            bcc.s    loc_3B14
    
    loc_3B10:
            bsr.w    DeformBgLayer
    
    loc_3B14:
            jsr    BuildSprites
            jsr    ObjPosLoad
            bsr.w    PalCycle_Load
            bsr.w    RunPLC_RAM
            bsr.w    OscillateNumDo
            bsr.w    ChangeRingFrame
            bsr.w    SignpostArtLoad
            cmpi.b    #8,($FFFFF600).w
            beq.s    Level_ChkDemo    ; if screen mode is 08 (demo), branch
            cmpi.b    #$C,($FFFFF600).w
            beq.w    Level_MainLoop    ; if screen mode is $0C    (level), branch
            rts    
    With that done, you will never experience crashes when you use subroutines in dynamically resized levels.

    Now, I will create a pretty simple sample level.

    testlevel.png

    And, for whatever bizarre reason, I want to start the level like this.

    s1built001.png

    Of course, you'll need to dynamically resize the level to make it through the loop.

    If you just do this:

    Code:
    Resize_SLZ1:
            move.w  #$120,($FFFFF726).w        ; load original level size in target size
            cmpi.w  #$180,($FFFFF700).w        ; has the camera reached this point in the level?
            bcs.s   Resize_SLZ12            ; if that's not the case, return
            move.w  #$320,($FFFFF726).w     ; change target level size
    
    
    Resize_SLZ12:
            rts    
    There's no need for me to even show you that Sonic will die in a very similar fashion to how he dies in the first S pipe from Green Hill 1 (Unless you've followed Part 1 of the Spin Dash guide.)

    So let's set the actual level size, along with the target level size!

    Code:
    Resize_SLZ1:
            move.w  #$120,($FFFFF726).w        ; load original level size in target size
            move.w  #$120,($FFFFF72E).w        ; load original level size in actual size (for when you return to the starting section)
            cmpi.w  #$180,($FFFFF700).w        ; has the camera reached this point in the level?
            bcs.s   Resize_SLZ12            ; if that's not the case, return
            move.w  #$320,($FFFFF726).w     ; change target level size
            move.w  #$320,($FFFFF72E).w     ; change actuallevel size
    
    
    Resize_SLZ12:
            rts    
    Now, we test!



    See the problem?
    While Sonic makes the loop just fine, when coming back, the screen does not update properly. This occurs every single time $FFFFF72E is reduced at the wrong time.

    Pretty easy fix! Just don't set $FFFFF72E at the start!

    Code:
    Resize_SLZ1:
            move.w  #$120,($FFFFF726).w        ; load original level size in target size
            cmpi.w  #$180,($FFFFF700).w        ; has the camera reached this point in the level?
            bcs.s   Resize_SLZ12            ; if that's not the case, return
            move.w  #$320,($FFFFF726).w     ; change target level size
            move.w  #$320,($FFFFF72E).w     ; change actuallevel size
    
    
    Resize_SLZ12:
            rts    


    Works fine, does it not?

    Now, let's try extending the level a small bit, and while we're at it, let's also change the lower boundary.

    again.png

    As proven earlier, reducing $FFFFF72E here would cause issues, so let's not.

    Code:
    Resize_SLZ1:
            move.w  #$120,($FFFFF726).w        ; load original level size in target size
            cmpi.w  #$180,($FFFFF700).w        ; has the camera reached this point in the level?
            bcs.s   Resize_SLZ12            ; if that's not the case, return
            move.w  #$320,($FFFFF726).w     ; change target level size
            move.w  #$320,($FFFFF72E).w     ; change actual level size
            cmpi.w  #$530,($FFFFF700).w        ; has the camera reached this point in the level?
            bcs.s   Resize_SLZ12            ; if that's not the case, return  
            move.w  #$2A0,($FFFFF726).w     ; change target level size
    
    Resize_SLZ12:
            rts    
    WARNING: Shaking image


    If the warning does not give away what's going on, then the video will definitely help.
    What's happening is that the level is trying to instantly set its lower boundary to $320. But the target boundary is not $320! The level will constantly and very quickly go from switching itself from the target boundary to $320. Every single frame. This results in the ground shaking when you're at the dead bottom of the screen.
    The only way to fix this by keeping the level design AND your current level events untouched is by using subroutines. Many levels (especially those that use bosses) use them, so you can copy paste the index from another level and edit it according to your needs. Since I only need two routines, here's the index for my level:

    Code:
    Resize_SLZ1:
            moveq    #0,d0
            move.b    ($FFFFF742).w,d0
            move.w    Resize_SLZ1Index(pc,d0.w),d0
            jmp    Resize_SLZ1Index(pc,d0.w)
    ; ===========================================================================
    Resize_SLZ1Index:    dc.w Resize_SLZ1part1-Resize_SLZ1Index    ;0
            dc.w Resize_SLZ1part2-Resize_SLZ1Index                ;2
    ; ===========================================================================
    Now, we need to change the routine to support resizing routines.

    Under the final branch to Resize_SLZ12, we add an "addq.b #2,($FFFFF742).w". Our code looks like this now:

    Code:
    Resize_SLZ1:
            moveq    #0,d0
            move.b    ($FFFFF742).w,d0
            move.w    Resize_SLZ1Index(pc,d0.w),d0
            jmp    Resize_SLZ1Index(pc,d0.w)
    ; ===========================================================================
    Resize_SLZ1Index:    dc.w Resize_SLZ1part1-Resize_SLZ1Index    ;0
            dc.w Resize_SLZ1part2-Resize_SLZ1Index                ;2
    ; ===========================================================================
    Resize_SLZ1part1:
            move.w  #$120,($FFFFF726).w        ; load original level size in target size
            cmpi.w  #$180,($FFFFF700).w        ; has the camera reached this point in the level?
            bcs.s   Resize_SLZ12            ; if that's not the case, return
            move.w  #$320,($FFFFF726).w     ; change target level size
            move.w  #$320,($FFFFF72E).w     ; change actual level size
            cmpi.w  #$530,($FFFFF700).w        ; has the camera reached this point in the level?
            bcs.s   Resize_SLZ12            ; if that's not the case, return
            addq.b  #2,($FFFFF742).w        ; change routine
        Resize_SLZ1part2:
            move.w  #$2A0,($FFFFF726).w     ; change target level size
    
    Resize_SLZ12:
            rts    


    Hurray! The shaking has stopped! However, the level size is stuck. That's because all code prior to the "Resize_SLZ1part2" label is being ignored. We're on routine 2, after all!

    We need to add a check that, whenever we return, sets the routine back to zero.

    Right under the "Resize_SLZ1part2" label, add these lines:

    Code:
            cmpi.w  #$530,($FFFFF700).w     ; has the camera reached this point in the level?
            bcc.s   @continue               ; if that IS the case, branch
            subq.b  #2,($FFFFF742).w
            bra.s   Resize_SLZ12
        @continue:
    If your disassembly does not support labels like "@continue", you are free to replace them with whatever you'd like.

    Your code will turn out like this:

    Code:
    Resize_SLZ1:
            moveq    #0,d0
            move.b    ($FFFFF742).w,d0
            move.w    Resize_SLZ1Index(pc,d0.w),d0
            jmp    Resize_SLZ1Index(pc,d0.w)
    ; ===========================================================================
    Resize_SLZ1Index:    dc.w Resize_SLZ1part1-Resize_SLZ1Index    ;0
            dc.w Resize_SLZ1part2-Resize_SLZ1Index                ;2
    ; ===========================================================================
    Resize_SLZ1part1:
            move.w  #$120,($FFFFF726).w        ; load original level size in target size
            cmpi.w  #$180,($FFFFF700).w        ; has the camera reached this point in the level?
            bcs.s   Resize_SLZ12            ; if that's not the case, return
            move.w  #$320,($FFFFF726).w     ; change target level size
            move.w  #$320,($FFFFF72E).w     ; change actual level size
            cmpi.w  #$530,($FFFFF700).w        ; has the camera reached this point in the level?
            bcs.s   Resize_SLZ12            ; if that's not the case, return
            addq.b  #2,($FFFFF742).w        ; change routine
        Resize_SLZ1part2:
            cmpi.w  #$530,($FFFFF700).w     ; has the camera reached this point in the level?
            bcc.s   @continue               ; if that IS the case, branch
            subq.b  #2,($FFFFF742).w        ; change routine
            bra.s   Resize_SLZ12            ; return
        @continue:
            move.w  #$2A0,($FFFFF726).w     ; change target level size
    
    Resize_SLZ12:
            rts    


    It's a success! The resizing works just fine with no issues whatsoever!

    TL;DR: This giant wall of text and code exists just to warn you of the dangers of using $FFFFF72E in your resizing routines. Of course, this level is a huge edge case scenario, but in zones based on Green Hill, you might find yourself actually wanting/having to use these routines in your code.

    So yeah, be careful with $FFFFF72E.
     
    Last edited: May 23, 2022
  4. SuperSayian Zrise

    SuperSayian Zrise Well-Known Member Exiled

    Joined:
    May 10, 2021
    Messages:
    78
    Very quick edit: Fixed some small grammer mistakes up and yes my main language is english.

    I never saw anyone mention this glitch in Sonic The Hedgehog 3 & Knuckles but it's time to finally mention it.

    Also, can anyone tell me how and why this happens from a technical stand point.

    I call it the Broken bridge glitch.

    Firstly, in Angel Island Zone Act 2 or forest? What is the name of the Angel Island forest? Well, questions aside and lets Super Spindash into act 2 of zone 1 and just get to the boss section and beat the boss.... Yes that's all it takes before the second part.

    Next, just messing around a bit. And trigger the bridge and untrigger it and just chill. You might hear the bridge breaking sound effect.

    Then, just hit the capsule or don't your choice.


    Sonic and Knuckles & Sonic 3.519.png

    Then as you walk over you see "Glitch Forest Zone act 2."

    Sonic and Knuckles & Sonic 3.520.png


    Sonic and Knuckles & Sonic 3.521.png



    Sonic and Knuckles & Sonic 3.522.png



    Sonic and Knuckles & Sonic 3.523.png

    Now, look closely at the life counter in the photo above.



    Sonic and Knuckles & Sonic 3.524.png

    WHAT! I got robbed out of six lives!


    Sonic and Knuckles & Sonic 3.525.png



    Maybe......


    Sonic was NEVER good.





    At navigating this island...........
     
  5. B.T.H Yeehaw!

    B.T.H Yeehaw! Newcomer Trialist

    Joined:
    Jun 20, 2020
    Messages:
    8
    Location:
    City Streets Zone
    Alright, I have a question of my own to ask. How does one achieve per-character HUD graphics switching like Sonic Megamix did it in Sonic 2?

    I've already tried to toss my hat into the ring by doing a simple "add new Nemesis graphics and put it in the Miles Life Icon and Tails Life icon patch PLC slots" thing, but when I go into a Tails game, Sonic 2 ends up just hanging on the Emerald Hill Zone title card forever which is obviously a bad. So no luck.

    Heck, I even tried to do it how the special stage did things by doing a small branch to decide which characters get what graphics, and that didn't even work for me!

    It would mean a lot if somebody could help me with this kerfuffle, really, it would.
     
  6. saan1ty

    saan1ty Well-Known Member Member

    Joined:
    Mar 1, 2021
    Messages:
    69
    Location:
    North Carolina
    I don't think I've ever seen that glitch before...
     
  7. Nik Pi

    Nik Pi Well-Known Member Member

    Joined:
    Feb 14, 2022
    Messages:
    55
    Location:
    Kazakhstan
    Ok, after some month, I know- the call to 'JmpTo_SoundDriverLoad' was removed from above 'MainGameLoop'. That needs to be put back (Thanks to Clownacy)
     
    Last edited: Jun 3, 2022
  8. hebereke

    hebereke opa opa! Member

    Joined:
    May 3, 2012
    Messages:
    32
    I've been trying to convert a track I made from SMPS 68k to Z80 Type 1 using smpsconv, but the output isn't turning out right. The percussion channel is converting just fine, but FM1-5 seem to be playing way too slow. Could anyone take a look at this? I suspect bad/wrong flags, but I usually get lost looking into this type of thing. BIN file is the 68k version, SMY file is the Z80 conversion (with CF08 as the offset). I'm mainly trying to figure out what needs to be changed to get the sound channels playing right for future reference since the offset probably isn't final.

    Edit: It seems to specifically affect tracks converted with vgm2mid. For reference, I composed the track in Deflemask, exported a VGM, and then used vgm2mid to convert it to a MIDI with a matching tempo (100bpm in this case). A solution I found is running the output from vgm2mid through OpenMPT and then re-exporting as a MIDI once more.
     

    Attached Files:

    Last edited: Jun 23, 2022
  9. aydenrw

    aydenrw Newcomer Trialist

    Joined:
    Jun 26, 2021
    Messages:
    1
    Location:
    Iowa, USA
    How do I port the 128x128 chunk system to Sonic 1?
     
  10. ⸸ devon ⸸

    ⸸ devon ⸸ There's nothing left but faith Member

    Joined:
    Aug 26, 2013
    Messages:
    1,175
    Check out Project Sonic 1: Two-Eight.
    s1disasm GitHub branch
    Original

    You can find all the changes made by searching "MJ:". Basically a matter of updating the level rendering, collision code, and anything else that references chunk data to take into account the different chunk size. This project also includes pathswapper objects, which allow more dynamic loop and path setups compared to Sonic 1's method of hardcoding loop chunk IDs.
     
  11. Nik Pi

    Nik Pi Well-Known Member Member

    Joined:
    Feb 14, 2022
    Messages:
    55
    Location:
    Kazakhstan
    Ok, I don't know how delete a message, so i should have question..
    Ok.
    How in Sonic 2's options menu work option "ALL KINDS ITEMS/TELEPORT ONLY"? I can't find the code, that set flag for it...
     
    Last edited: Jul 24, 2022
  12. Bluestreak

    Bluestreak Lady in red, living in dread. Member

    Joined:
    Apr 1, 2016
    Messages:
    226
    Location:
    Eastwatch Island
    Decided to go back and work on Sonic 2 DX for Master System again, and after modifying Scrambled Egg Act 1 & 3's tiles to match the new tileset I made for Act 2, it seems that the layout fot Scrambled Egg Act 1 is now completely messed up. All I changed for the mappings was some mappings that had only to do with the background and not the ground or tubes or any of that. What exactly happened? I kept going through the different level heights, and now it's messed up. What do I do? How did it get messed up like this?

    I've come so far with this hack, so now I'm worried. Height 80 seems to be the most correct, but still messed up.
     
  13. Veracity

    Veracity Newcomer Trialist

    Joined:
    Jun 21, 2022
    Messages:
    4
    Location:
    Somewhere, out there.
    How do you edit the zone order in the GitHub Sonic 2 disassembly?
     
  14. MCTravisYT

    MCTravisYT Newcomer Trialist

    Joined:
    Dec 22, 2019
    Messages:
    5
    How could I force a sound ID to play within a game that uses SMPS Z80? I'm aware there's a RAM address in games that use SMPS 68K that you can change to force-play music/sound effects, although I'm unable to find out how to do that within games that use SMPS Z80. I've noticed it works a bit differently (the game I'm looking at is Sorcerian), with the first half of Z80 RAM not changing (sound driver code?), and the second half swapping out depending on what's playing (is it copying from ROM then reading off of that?). Thanks in advance.
     
  15. Nik Pi

    Nik Pi Well-Known Member Member

    Joined:
    Feb 14, 2022
    Messages:
    55
    Location:
    Kazakhstan
    Hi everybody!
    I have a question: how big arm is marked in S3 github disasm? I think about restoring them in S3K...
    Or exist another way? Maybe.. I can use big arm from Knuckles story in ST playground?
     
    Last edited: Sep 7, 2022
  16. ⸸ devon ⸸

    ⸸ devon ⸸ There's nothing left but faith Member

    Joined:
    Aug 26, 2013
    Messages:
    1,175
    Obj_LBZFinalBoss2, I believe, in both s3.asm and sonic3k.asm. Obviously they have their differences, so be aware of that.
     
    Nik Pi likes this.
  17. Nik Pi

    Nik Pi Well-Known Member Member

    Joined:
    Feb 14, 2022
    Messages:
    55
    Location:
    Kazakhstan
    Oh, thank you very much!!!
     
  18. warr1or2

    warr1or2 I AM CLG Member

    Joined:
    Apr 7, 2008
    Messages:
    411
    Location:
    Town Creek, AL
    Question
    In Sinic 1 Hivebrain disassembly, in levsel_sndtest
    Code:
    andi.b #$C,d1
    
    It reads only Left and Right. What is it to also have A & B to be read?
     
  19. ⸸ devon ⸸

    ⸸ devon ⸸ There's nothing left but faith Member

    Joined:
    Aug 26, 2013
    Messages:
    1,175
    Bit 7 = Start
    Bit 6 = A
    Bit 5 = C
    Bit 4 = B
    Bit 3 = Right
    Bit 2 = Left
    Bit 1 = Down
    Bit 0 = Up

    AND masks outs the read controller bits with the source value. $C is %00001100 in binary. Bits 2 and 3 (left and right) are set (bit 0 is the rightmost bit), so it masks out those bits. To add A and B, you just set bits 4 and 6 in the mask, which gets you %01011100, which is $5C in hex.
     
  20. Nik Pi

    Nik Pi Well-Known Member Member

    Joined:
    Feb 14, 2022
    Messages:
    55
    Location:
    Kazakhstan
    OK, I managed to port the big arm (for the most part, only minor polishing is needed), and now I'm thinking about porting sprites from origins.
    It would be stupid to ask someone to do all the work for me (although it would be nice), so I'll ask:
    How to expand sprite indexes? (When you force the game to load a new sprite, the game shows a piece of messy tiles instead. How to fix this?)
    And second: to give more sprites to Sonic- do I need to split the dlc mappings and the sprites themselves into different files?
     
    Last edited: Sep 12, 2022