Basic Questions and Answers Thread

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

  1. Dragonightmare

    Dragonightmare The Dark Dragon Member

    Joined:
    Jan 31, 2021
    Messages:
    23
    Location:
    Italy
    Maybe it is a issue in terms of palette matches, but there are tons of issues regarding your game crash
     
  2. Ashuro

    Ashuro Anti-Cosmic Metal Of Death Member

    Joined:
    Sep 27, 2014
    Messages:
    542
    Location:
    France
    Hi guys, I noticed a bug? I noticed that in Star Light Zone, the Pylons disappear when you reappear from a lamppost. That's like the art or the object itself won't load if we start from a checkpoint. Why???
     
  3. Mr. Joker 27 Music prod.

    Mr. Joker 27 Music prod. Musician, composer, remixer. Member

    Joined:
    Aug 26, 2016
    Messages:
    200
    I always wanted to know about that bug, especially in SLZ 2 and 3 happened to me.
     
    Ashuro likes this.
  4. Inferno

    Inferno Rom Hacker Member

    Joined:
    Oct 27, 2015
    Messages:
    82
    Location:
    Hidden Palace Zone, Westside Island
    The pylon object is in the level layout and therefore isn't loaded if you're too far from it. Fix it by loading it at 0,0 upon level init manually.
     
  5. Inferno

    Inferno Rom Hacker Member

    Joined:
    Oct 27, 2015
    Messages:
    82
    Location:
    Hidden Palace Zone, Westside Island
    Uggghhhh, I've hit another dead end.

    So, I've been working on a Bonus Stage, and it's mostly functional... excluding one small thing.
    Compare what happens in these two videos:



    I have no clue what the garbage sprite is, but I have traced down the code at hand for causing the issue, first, the routine itself:

    Code:
    ; ---------------------------------------------------------------------------
    ; Subroutine to    update the HUD
    ; ---------------------------------------------------------------------------
    
    ; ||||||||||||||| S U B    R O U T    I N E |||||||||||||||||||||||||||||||||||||||
    
    HUD_UpdateBS:
            tst.b    (f_ringcount).w    ; does the ring    counter    need updating?
            beq.s    @chktime    ; if not, branch
            bpl.s    @notzero
            bsr.w    Hud_LoadZero    ; reset rings to 0 if Sonic is hit
    
        @notzero:
            clr.b    (f_ringcount).w
            hudVRAM    $DF40        ; set VRAM address
            moveq    #0,d1
            move.w    (v_rings).w,d1    ; load number of rings
            bsr.w    Hud_Rings
    
        @chktime:
            tst.b    (f_timecount).w    ; does the time    need updating?
            beq.w    @chklives    ; if not, branch
            tst.w    (f_pause).w    ; is the game paused?
            bne.w    @chklives    ; if yes, branch
            lea    (v_time).w,a1
            tst.l    (a1)+ ; is the time 9:59:59?
            beq.w    TimeOverBS    ; if yes, branch
    
            addq.b    #1,-(a1)    ; increment 1/60s counter
            cmpi.b    #60,(a1)    ; check if passed 60
            bcs.s    @chklives
            move.b    #0,(a1)
            subq.b    #1,-(a1)    ; increment second counter
            cmpi.b    #60,(a1)    ; check if passed 60
            bcs.s    @updatetime
            move.b    #0,(a1)
            subq.b    #1,-(a1)    ; increment minute counter
            cmpi.b    #9,(a1)        ; check if passed 9
            bcs.s    @BS_UpdateTime
            move.b    #9,(a1)        ; keep as 9
            
        @BS_UpdateTime:
            cmpi.w    #0,(v_timesec).w
            move.w #$3C3C,(v_timesec).w
    
        @updatetime:
            hudVRAM    $DE40
            moveq    #0,d1
            move.b    (v_timemin).w,d1 ; load    minutes
            bsr.w    Hud_Mins
            hudVRAM    $DEC0
            moveq    #0,d1
            move.b    (v_timesec).w,d1 ; load    seconds
            bsr.w    Hud_Secs
    
        @chklives:
            tst.b    (f_lifecount).w ; does the lives counter need updating?
            beq.s    @chkbonus    ; if not, branch
            clr.b    (f_lifecount).w
            bsr.w    Hud_Lives
    
        @chkbonus:
            tst.b    (f_endactbonus).w ; do time/ring bonus counters need updating?
            beq.s    @finish        ; if not, branch
            clr.b    (f_endactbonus).w
            locVRAM    $AE00
            moveq    #0,d1
            move.w    (v_timebonus).w,d1 ; load time bonus
            bsr.w    Hud_TimeRingBonus
            moveq    #0,d1
            move.w    (v_ringbonus).w,d1 ; load ring bonus
            bsr.w    Hud_TimeRingBonus
    
        @finish:
            rts   
    ; ===========================================================================
    
    TimeOverBS:
            clr.b    (f_timecount).w
            lea    (v_player).w,a0
            movea.l    a0,a2
            bsr.w    KillSonic
            move.b    #1,(f_timeover).w
            rts   
    ; ===========================================================================

    But, here's the exact subroutine I've traced it down to:

    Code:
        @chktime:
            tst.b    (f_timecount).w    ; does the time    need updating?
            beq.w    @chklives    ; if not, branch
            tst.w    (f_pause).w    ; is the game paused?
            bne.w    @chklives    ; if yes, branch
            lea    (v_time).w,a1
            tst.l    (a1)+ ; is the time 9:59:59?
            beq.w    TimeOverBS    ; if yes, branch
    
            addq.b    #1,-(a1)    ; increment 1/60s counter
            cmpi.b    #60,(a1)    ; check if passed 60
            bcs.s    @chklives
            move.b    #0,(a1)
            subq.b    #1,-(a1)    ; increment second counter
            cmpi.b    #60,(a1)    ; check if passed 60
            bcs.s    @updatetime
            move.b    #0,(a1)
            subq.b    #1,-(a1)    ; increment minute counter
            cmpi.b    #9,(a1)        ; check if passed 9
            bcs.s    @BS_UpdateTime
            move.b    #9,(a1)        ; keep as 9
            
        @BS_UpdateTime:
            cmpi.w    #0,(v_timesec).w
            move.w #$3C3C,(v_timesec).w 
    Specficially, just making it tick backwards time wise is all that is needed to trigger the bug.
    I've tried pretty much everything, and have established some things:
    - The time is indeed being properly set.
    - @BS_UpdateTime is not responsible. Neither is the time over check.
    - An address error occurs, but the code causing it is not responsible and is just a check for the bonus stage swapping out HUD mappings.
    This is the code in question:

    Code:
    @norings:
            cmpi.b    #id_BS,(v_zone).w
            beq.s   @alternatetimer
            cmpi.b    #9,(v_timemin).w ; have    9 minutes elapsed?
            bne.s    @display    ; if not, branch
            addq.w    #2,d0        ; make time counter flash red
    
        @display:
            move.b    d0,obFrame(a0)
            jmp    DisplaySprite
            
    @alternatetimer:
            cmpi.w    #0010,(v_timemin).w ; have    9 minutes elapsed?
            bgt.s    @display    ; if not, branch
            addq.w    #2,d0        ; make time counter flash red
            bra.s    @display
    And the address error which occurred with a slightly earlier version of the code above:
    [​IMG]
    - You don't even need to enter via checkpoint. Seeing a level at all is enough.
    - Debug HUD is not involved.
    Here's some other pieces of code related to the attempts to make the timer in the Bonus Stage start at 1:30 and tick towards 0.
    VBla_0C (bypassing vanilla HUD update):

    Code:
    VBla_0C:
    ;        stopZ80
    ;        waitZ80
            bsr.w    ReadJoypads
            tst.b    (f_wtr_state).w
            bne.s    @waterabove
    
            writeCRAM    v_pal_dry,$80,0
            bra.s    @waterbelow
    
    @waterabove:
            writeCRAM    v_pal_water,$80,0
    
        @waterbelow:
            move.w    (v_hbla_hreg).w,(a5)
            move.b   (v_hbla_line).w,(v_cramwaterpos).w
            writeVRAM    v_hscrolltablebuffer,$380,vram_hscroll
            writeVRAM    v_spritetablebuffer,$280,vram_sprites
            jsr    (ProcessDMAQueue).l
    
        @nochg:
            startZ80
            movem.l    (v_screenposx).w,d0-d7
            movem.l    d0-d7,(v_screenposx_dup).w
            movem.l    (v_fg_scroll_flags).w,d0-d1
            movem.l    d0-d1,(v_fg_scroll_flags_dup).w
            bsr.w    LoadTilesAsYouMove
            jsr    (AnimateLevelGfx).l
            cmpi.b #id_BS,(v_zone).w
            bne.s  @normal
            jsr    (HUD_UpdateBS).l
            bra.s @cont
            
    @normal:
            jsr    (HUD_Update).l
    @cont:
            bsr.w    sub_1642
            rts    
    Setting the base timer time:

    Code:
    Level_LoadObj:
            cmpi.b  #id_BS,(v_zone).w
            bne.s   @cont1
            move.l #(1*$10000)+(31*$100)+59,(v_time).w ; set the timer to maximum possible time
            
        @cont1:
            move.b    #0,(Rings_manager_routine).w
            jsr    RingsManager
            jsr    (ObjPosLoad).l
            jsr    (ExecuteObjects).l
            jsr    (BuildSprites).l
            moveq    #0,d0
            tst.b    (v_lastlamp).w    ; are you starting from    a lamppost?
            bne.s    Level_SkipClr    ; if yes, branch
            move.w    d0,(v_rings).w    ; clear rings
            cmpi.b  #id_BS,(v_zone).w
            beq.s   @cont
           
            move.l    d0,(v_time).w    ; clear time
        @cont:
            moveq    #0,d0
    
    I'm completely baffled. Is there something I should be clearing?
     
  6. ProjectFM

    ProjectFM Optimistic and self-dependent Member

    Joined:
    Oct 4, 2014
    Messages:
    893
    Location:
    Orono, Maine
    Resolved!
     
    Inferno likes this.
  7. Speems

    Speems Active Member Member

    Joined:
    Mar 14, 2017
    Messages:
    46
    Location:
    Rochester Hills, MI
    How can you adjust the Debug Mode in Sonic 1 to function a bit more like Sonic 2's? Mainly like how you aren't immortal and you can enter object placement before the death animation leaves the screen boundaries, allowing you to resume the game as if nothing happened. I know of the ring/monitor fixes and the S3K esque display thing, but not the mortality and entering object placement to avoid death.