Basic Questions and Answers Thread

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

  1. SuperSayian Zrise

    SuperSayian Zrise Well-Known Member Member

    Joined:
    May 10, 2021
    Messages:
    60
    I'm sorry, but I have a slight problem:
    [​IMG]
    My game crashes after going to Zone 07 01 (act 2) and I dc.w'd the level order myself and I have a green sonic ssrg screen. I'm not sure if those have anything to do with this but it just crashes even though the zone uses GHZ's level resize and stuff besides the palette. Here is the code:
    Code:
    sub_6BD6:                ; XREF: sub_6ADA; sub_6B06
            lea    ($FFFFB000).w,a1
            add.w    4(a3),d4
            add.w    (a3),d5
            move.w    d4,d3
            lsr.w    #1,d3
            andi.w    #$380,d3
            lsr.w    #3,d5
            move.w    d5,d0
            lsr.w    #5,d0
            andi.w    #$7F,d0
            add.w    d3,d0
            moveq    #-1,d3
            move.b    (a4,d0.w),d3
            beq.s    locret_6C1E
            subq.b    #1,d3
            andi.w    #$7F,d3
            ror.w    #7,d3
            add.w    d4,d4
            andi.w    #$1E0,d4
            andi.w    #$1E,d5
            add.w    d4,d3
            add.w    d5,d3
            movea.l    d3,a0
            move.w    (a0),d3
            andi.w    #$3FF,d3
            lsl.w    #3,d3
            adda.w    d3,a1
    
    locret_6C1E:
            rts  
    ; End of function sub_6BD6
    
    Very quick edit: I don't know how to read these crash handlers. Any help?
     
  2. Spicy Bread SSR

    Spicy Bread SSR You can call me Mal if you like Member

    Joined:
    Feb 27, 2021
    Messages:
    18
    Location:
    Green Hills, Australia
    Obj3A (act results) might be your issue. It has a level order array somewhere in the code, so the game can transition into a new stage. I'll provide an example (Github)
    Code:
    ; ---------------------------------------------------------------------------
    ; Level    order array
    ; ---------------------------------------------------------------------------
    LevelOrder:
            ; Green Hill Zone
            dc.b id_GHZ, 1    ; Act 1
            dc.b id_GHZ, 2    ; Act 2
            dc.b id_MZ, 0    ; Act 3
            dc.b 0, 0
    
            ; Labyrinth Zone
            dc.b id_LZ, 1    ; Act 1
            dc.b id_LZ, 2    ; Act 2
            dc.b id_SLZ, 0    ; Act 3
            dc.b id_SBZ, 2    ; Scrap Brain Zone Act 3
    
            ; Marble Zone
            dc.b id_MZ, 1    ; Act 1
            dc.b id_MZ, 2    ; Act 2
            dc.b id_SYZ, 0    ; Act 3
            dc.b 0, 0
    
            ; Star Light Zone
            dc.b id_SLZ, 1    ; Act 1
            dc.b id_SLZ, 2    ; Act 2
            dc.b id_SBZ, 0    ; Act 3
            dc.b 0, 0
    
            ; Spring Yard Zone
            dc.b id_SYZ, 1    ; Act 1
            dc.b id_SYZ, 2    ; Act 2
            dc.b id_LZ, 0    ; Act 3
            dc.b 0, 0
    
            ; Scrap Brain Zone
            dc.b id_SBZ, 1    ; Act 1
            dc.b id_LZ, 3    ; Act 2
            dc.b 0, 0    ; Final Zone
            dc.b 0, 0
            even
            zonewarning LevelOrder,8         ; also probably not here in hivebrain
    ; ============================================
    Since I'm assuming your using Hivebrain, id_GHZ might be 0. Your new level would most likely be 8 since the ending and special stage are 6 and 7 respectively (though as inferno said, your new level is probably 7), but the act results don't go beyond Scrap Brain (which is 5), so the game used data from the object itself, resulting in a crash. If you already added filler data for the special stage and ending to get level 8 to work, then your issue might be that you used dc.w, when the code is designed for dc.b
    Edit: Due to how I phrased it, it made it seem like the special stage was represented as 6.
     
    Last edited: Sep 29, 2021
    SuperSayian Zrise likes this.
  3. Inferno

    Inferno Rom Hacker Member

    Joined:
    Oct 27, 2015
    Messages:
    104
    Location:
    Sky Base Zone, South Island
    Actually... Special Stages aren't in Level Slot 6. That's the ending. Special Stages are their own separate thing. The only reason they have a zone constant for them in the GitHub disasm is so that the level select knows what ID links to jumping to the Special Stage gamemode from level select only. New zones would start at ID Slot 7.

    However, I think we should look at the caller here, aka where we branched to the module from. It only jumps into random stuff due to the Dynamic Screen Events routine. We'd actually need to see this. Either there's a mess up there or you are correct and we are jumping to an incorrect level.
     
    Last edited: Sep 28, 2021
  4. SuperSayian Zrise

    SuperSayian Zrise Well-Known Member Member

    Joined:
    May 10, 2021
    Messages:
    60
    Well, I tried to simply change the .w to a .b and It doesn't even build. (Probably because it uses 2 (00)'s which I am sure is a word.) And then I tried to put it right after Green Hill act 1 and it worked??? So the problem has nothing to do with these zones or whatever. Just with that sub_6BD6. Then I tried to change one of the ones listed to a byte and keep everything else word. Then the game crashed and it had something to do with Obj18_Nudge. And I'm very sure the module that came with it is wrong or something. Because, I could not find it in my assembly.
    (Yeah I'm giving up.)
    Note: I actually fixed the level order to what it has been before. After the crash of Obj18_Nudge. Also, this is hivebrain 2005 ASM68K disassembly.
    If you need my level structure here it is:
    Code:
    ; ---------------------------------------------------------------------------
    ; Level    order array
    ; ---------------------------------------------------------------------------
    LevelOrder:
                    dc.w GHZ2
                    dc.w GHZ3
                    dc.w RPZ1
                    dc.w RPZ2
                    dc.w RPZ3
                    dc.w MZ1
                    dc.w MZ2
                    dc.w MZ3
                    dc.w SYZ1
                    dc.w SYZ2
                    dc.w SYZ3
                    dc.w LZ1
                    dc.w LZ2
                    dc.w LZ3
                    dc.w SLZ1
                    dc.w SLZ2
                    dc.w SLZ3
                    dc.w SBZ1
                    dc.w SBZ2
                    dc.w SBZ3
                       even
     
  5. Inferno

    Inferno Rom Hacker Member

    Joined:
    Oct 27, 2015
    Messages:
    104
    Location:
    Sky Base Zone, South Island
    ... you do realize that this has to be in 4 act (due to S1 having 4 acts per zone) chunks in zone ID order, right? Assuming RPZ is in Slot 07, and that you have done no level ID rearranging, your level order should look like this:
    Code:
    ; ---------------------------------------------------------------------------
    ; Level    order array
    ; ---------------------------------------------------------------------------
    LevelOrder:
                    dc.w GHZ2
                    dc.w GHZ3
                    dc.w RPZ1
                    dc.w GHZ1
    
                    dc.w LZ2
                    dc.w LZ3
                    dc.w SLZ1
                    dc.w GHZ1
    
                    dc.w MZ2
                    dc.w MZ3
                    dc.w SYZ1
                    dc.w GHZ1
    
                    dc.w SLZ2
                    dc.w SLZ3
                    dc.w SBZ1
                    dc.w GHZ1
    
                    dc.w SYZ2
                    dc.w SYZ3
                    dc.w LZ1
                    dc.w GHZ1
    
                    dc.w SBZ2
                    dc.w SBZ3
                    dc.w GHZ1
                    dc.w GHZ1
    
                    dc.w GHZ1
                    dc.w GHZ1
                    dc.w GHZ1
                    dc.w GHZ1
    
                    dc.w RPZ2
                    dc.w RPZ3
                    dc.w MZ1
                    dc.w GHZ1
                       even
     
    Last edited: Sep 29, 2021
  6. SuperSayian Zrise

    SuperSayian Zrise Well-Known Member Member

    Joined:
    May 10, 2021
    Messages:
    60
    I wish it was easier to edit in the first place. And I can see why the game will jump to GHZ act 1 after "SBZ3". But for any level outside of that level like the game jumping to RPZ1 >>> RPZ2 is a bit confusing. Because it for whatever reason jumps to GHZ1 but never actually jumps to it. Like how does the game even know not to jump to it? Most of the text I can kinda see how. It "dc.w's" to RPZ1 and after goes RPZ2. And its like telling the game to jump to the next act of a zone somewhat like a label or whatever its called. And I don't understand how this helped the devs more then just making it simple. Also, tell me if you want credit for this. If you don't then ok.
    edit: When I said: "I wish it was easier to edit in the first place." Is simply talking about the bin file.
    edit2: The lorded thing was cool. But I used Inferno's method because I tried to add a zone 07 to lorded and the level ids are built in the program I think. Which means I got crashes.
     
    Last edited: Oct 1, 2021
  7. nineko

    nineko I am the Holy Cat Member

    Joined:
    Mar 24, 2008
    Messages:
    1,872
    Location:
    italy
    *cough*
     

    Attached Files:

  8. SuperSayian Zrise

    SuperSayian Zrise Well-Known Member Member

    Joined:
    May 10, 2021
    Messages:
    60
    The only reason I can't use it is because it requires a dll file and I can't find any from the microsoft website. And if I did it will be in a question someone asks then someone provides the most sketchy link even if it says its from microsoft.com I just can't trust it unless I find it on the actual thing on the website.
    edit: I used Inferno's method. And is explained in my upper post which your post is in between.
     
    Last edited: Oct 1, 2021
  9. nineko

    nineko I am the Holy Cat Member

    Joined:
    Mar 24, 2008
    Messages:
    1,872
    Location:
    italy
    I just tried to look for it, and indeed it appears that Microsoft took down the KB page with the relevant download.

    The file itself, however, is still on Microsoft's servers, and you can safely download it from this direct link: http://download.microsoft.com/download/vb50pro/utility/1/win98/EN-US/Msvbvm50.exe

    You trusted me when you downloaded the program I wrote, you can trust me when I tell you that the link above is legit.
     
  10. Inferno

    Inferno Rom Hacker Member

    Joined:
    Oct 27, 2015
    Messages:
    104
    Location:
    Sky Base Zone, South Island
    Aight, here we go again.

    Sonic 1 Definitive, I'm currently working slowly on level transitions. This doesn't cover the entire portion of that mess, though, specifically one part: Moduled Kosinski.

    It, for some reason, only wants to load 1 module.

    I'll send the code involved and the relevant portion of my variables file.

    Code:
    ;---------------------------------------------------------------------------
    ; Adds a Kosinski Moduled archive to the module queue
    ; Inputs:
    ; a1 = address of the archive
    ; d2 = destination in VRAM
    ; ---------------------------------------------------------------------------
    
    ; =============== S U B R O U T I N E =======================================
    
    
    Queue_Kos_Module:
            lea    (Kos_module_queue).w,a2
            tst.l    (a2)    ; is the first slot free?
            beq.s    Process_Kos_Module_Queue_Init    ; if it is, branch
            addq.w    #6,a2    ; otherwise, check next slot
    
    KosM_FindFreeSlot:
            tst.l    (a2)
            beq.s    KosM_FreeSlotFound
            addq.w    #6,a2
            bra.s    KosM_FindFreeSlot
    ; ---------------------------------------------------------------------------
    
    KosM_FreeSlotFound:
            move.l    a1,(a2)+    ; store source address
            move.w    d2,(a2)+    ; store destination VRAM address
            rts
    ; End of function Queue_Kos_Module
    
    ; ---------------------------------------------------------------------------
    ; Initializes processing of the first module on the queue
    ; ---------------------------------------------------------------------------
    
    ; =============== S U B R O U T I N E =======================================
    
    
    Process_Kos_Module_Queue_Init:
            move.w    (a1)+,d3    ; get uncompressed size
            cmpi.w    #$A000,d3
            bne.s    @size
            move.w    #$8000,d3    ; $A000 means $8000 for some reason
    @size:
            lsr.w    #1,d3
            move.w    d3,d0
            rol.w    #5,d0
            andi.w    #$1F,d0    ; get number of complete modules
            move.b    d0,(Kos_modules_left).w
            andi.l    #$7FF,d3    ; get size of last module in words
            bne.s    @nonzero    ; branch if it's non-zero
            subq.b    #1,(Kos_modules_left).w    ; otherwise decrement the number of modules
            move.l    #$800,d3    ; and take the size of the last module to be $800 words
    @nonzero:
            move.w    d3,(Kos_last_module_size).w
            move.w    d2,(Kos_module_destination).w
            move.l    a1,(Kos_module_queue).w
            addq.b    #1,(Kos_modules_left).w    ; store total number of modules
            rts
    ; End of function Process_Kos_Module_Queue_Init
    
    ; ---------------------------------------------------------------------------
    ; Processes the first module on the queue
    ; ---------------------------------------------------------------------------
    
    ; =============== S U B R O U T I N E =======================================
    
    
    Process_Kos_Module_Queue:
            tst.b    (Kos_modules_left).w
            bne.s    KosM_ModulesLeft
    
    KosM_Done:
            rts
    ; ---------------------------------------------------------------------------
    
    KosM_ModulesLeft:
            bmi.s    KosM_DecompressionStarted
            cmpi.w    #4,(Kos_decomp_queue_count).w
            bhs.s    KosM_Done    ; branch if the Kosinski decompression queue is full
            movea.l    (Kos_module_queue).w,a1
            lea    (Kos_decomp_buffer).w,a2
            bsr.w    Queue_Kos    ; add current module to decompression queue
            ori.b    #$80,(Kos_modules_left).w    ; and set bit to signify decompression in progress
            rts
    ; ---------------------------------------------------------------------------
    
    KosM_DecompressionStarted:
            tst.w    (Kos_decomp_queue_count).w
            bne.s    KosM_Done    ; branch if the decompression isn't complete
    
            ; otherwise, DMA the decompressed data to VRAM
            andi.b    #$7F,(Kos_modules_left).w
            move.l    #$800,d3
            subq.b    #1,(Kos_modules_left).w
            bne.s    @notlast    ; branch if it isn't the last module
            move.w    (Kos_last_module_size).w,d3
    @notlast:
            move.w    (Kos_module_destination).w,d2
            move.w    d2,d0
            add.w    d3,d0
            add.w    d3,d0
            move.w    d0,(Kos_module_destination).w    ; set new destination
            move.l    (Kos_module_queue).w,d0
            move.l    (Kos_decomp_queue).w,d1
            sub.l    d1,d0
            andi.l    #$F,d0
            add.l    d0,d1    ; round to the nearest $10 boundary
            move.l    d1,(Kos_module_queue).w    ; and set new source
            move.l    #Kos_decomp_buffer,d1
            andi.l    #$FFFFFF,d1
            jsr    (QueueDMATransfer).l
            tst.b    (Kos_modules_left).w
            bne.s    @return    ; return if this wasn't the last module
            lea    (Kos_module_queue).w,a0
            lea    (Kos_module_queue+6).w,a1
            move.l    (a1)+,(a0)+    ; otherwise, shift all entries up
            move.w    (a1)+,(a0)+
            move.l    (a1)+,(a0)+
            move.w    (a1)+,(a0)+
            move.l    (a1)+,(a0)+
            move.w    (a1)+,(a0)+
            move.l    #0,(a0)+    ; and mark the last slot as free
            move.w    #0,(a0)+
            move.l    (Kos_module_queue).w,d0
            beq.s    @return    ; return if the queue is now empty
            movea.l    d0,a1
            move.w    (Kos_module_destination).w,d2
            jmp    (Process_Kos_Module_Queue_Init).l
    @return:
            rts
    ; End of function Process_Kos_Module_Queue
    
    ; =============== S U B R O U T I N E =======================================
    
    
    Queue_Kos:
            move.w    (Kos_decomp_queue_count).w,d0
            lsl.w    #3,d0
            lea    (Kos_decomp_queue).w,a3
            move.l    a1,(a3,d0.w)    ; store source
            move.l    a2,4(a3,d0.w)    ; store destination
            addq.w    #1,(Kos_decomp_queue_count).w
            rts
    ; End of function Queue_Kos
    
    ; ---------------------------------------------------------------------------
    ; Checks if V-int occured in the middle of Kosinski queue processing
    ; and stores the location from which processing is to resume if it did
    ; ---------------------------------------------------------------------------
    
    ; =============== S U B R O U T I N E =======================================
    
    
    Set_Kos_Bookmark:
            tst.w    (Kos_decomp_queue_count).w
            bpl.s    @no    ; branch if a decompression wasn't in progress
            move.l    $42(sp),d0    ; check address V-int is supposed to rte to
            cmpi.l    #Process_Kos_Queue_Main,d0
            blo.s    @no
            cmpi.l    #Process_Kos_Queue_Done,d0
            bhs.s    @no
            move.l    $42(sp),(Kos_decomp_bookmark).w
            move.l    #Backup_Kos_Registers,$42(sp)    ; force V-int to rte here instead if needed
    @no:
            rts
    ; End of function Set_Kos_Bookmark
    
    ; ---------------------------------------------------------------------------
    ; Processes the first entry in the Kosinski decompression queue
    ; ---------------------------------------------------------------------------
    
    ; =============== S U B R O U T I N E =======================================
    
    
    Process_Kos_Queue:
            tst.w    (Kos_decomp_queue_count).w
            beq.w    Process_Kos_Queue_Done
            bmi.w    Restore_Kos_Bookmark    ; branch if a decompression was interrupted by V-int
    
    Process_Kos_Queue_Main:
            ori.w    #$8000,(Kos_decomp_queue_count).w    ; set sign bit to signify decompression in progress
            movea.l    (Kos_decomp_queue).w,a0
            movea.l    (Kos_decomp_destination).w,a1
    
            ; what follows is identical to the normal Kosinski decompressor except for using Kos_description_field instead of the stack
            lea    (Kos_description_field).w,a2
            move.b    (a0)+,1(a2)
            move.b    (a0)+,(a2)
            move.w    (a2),d5
            moveq    #$F,d4
    
    Process_Kos_Queue_Loop:
            lsr.w    #1,d5
            move    sr,d6
            dbf    d4,Process_Kos_Queue_ChkBit
            move.b    (a0)+,1(a2)
            move.b    (a0)+,(a2)
            move.w    (a2),d5
            moveq    #$F,d4
    
    Process_Kos_Queue_ChkBit:
            move    d6,ccr
            bcc.s    Process_Kos_Queue_RLE
            move.b    (a0)+,(a1)+
            bra.s    Process_Kos_Queue_Loop
    ; ---------------------------------------------------------------------------
    
    Process_Kos_Queue_RLE:
            moveq    #0,d3
            lsr.w    #1,d5
            move    sr,d6
            dbf    d4,Process_Kos_Queue_ChkBit2
            move.b    (a0)+,1(a2)
            move.b    (a0)+,(a2)
            move.w    (a2),d5
            moveq    #$F,d4
    
    Process_Kos_Queue_ChkBit2:
            move    d6,ccr
            bcs.s    Process_Kos_Queue_SeparateRLE
            lsr.w    #1,d5
            dbf    d4,@loop
            move.b    (a0)+,1(a2)
            move.b    (a0)+,(a2)
            move.w    (a2),d5
            moveq    #$F,d4
    @loop:
            roxl.w    #1,d3
            lsr.w    #1,d5
            dbf    d4,@loop2
            move.b    (a0)+,1(a2)
            move.b    (a0)+,(a2)
            move.w    (a2),d5
            moveq    #$F,d4
    @loop2:
            roxl.w    #1,d3
            addq.w    #1,d3
            moveq    #-1,d2
            move.b    (a0)+,d2
            bra.s    Process_Kos_Queue_RLELoop
    ; ---------------------------------------------------------------------------
    
    Process_Kos_Queue_SeparateRLE:
            move.b    (a0)+,d0
            move.b    (a0)+,d1
            moveq    #-1,d2
            move.b    d1,d2
            lsl.w    #5,d2
            move.b    d0,d2
            andi.w    #7,d1
            beq.s    Process_Kos_Queue_SeparateRLE2
            move.b    d1,d3
            addq.w    #1,d3
    
    Process_Kos_Queue_RLELoop:
            move.b    (a1,d2.w),d0
            move.b    d0,(a1)+
            dbf    d3,Process_Kos_Queue_RLELoop
            bra.s    Process_Kos_Queue_Loop
    ; ---------------------------------------------------------------------------
    
    Process_Kos_Queue_SeparateRLE2:
            move.b    (a0)+,d1
            beq.s    Process_Kos_Queue_EndReached
            cmpi.b    #1,d1
            beq.w    Process_Kos_Queue_Loop
            move.b    d1,d3
            bra.s    Process_Kos_Queue_RLELoop
    ; ---------------------------------------------------------------------------
    
    Process_Kos_Queue_EndReached:
            move.l    a0,(Kos_decomp_queue).w
            move.l    a1,(Kos_decomp_destination).w
            andi.w    #$7FFF,(Kos_decomp_queue_count).w    ; clear decompression in progress bit
            subq.w    #1,(Kos_decomp_queue_count).w
            beq.s    Process_Kos_Queue_Done    ; branch if there aren't any entries remaining in the queue
            lea    (Kos_decomp_queue).w,a0
            lea    (Kos_decomp_queue+8).w,a1    ; otherwise, shift all entries up
            move.l    (a1)+,(a0)+
            move.l    (a1)+,(a0)+
            move.l    (a1)+,(a0)+
            move.l    (a1)+,(a0)+
            move.l    (a1)+,(a0)+
            move.l    (a1)+,(a0)+
    
    Process_Kos_Queue_Done:
            rts
    ; ---------------------------------------------------------------------------
    
    Restore_Kos_Bookmark:
            movem.l    (Kos_decomp_stored_registers).w,d0-d6/a0-a2
            move.l    (Kos_decomp_bookmark).w,-(sp)
            move.w    (Kos_decomp_stored_SR).w,-(sp)
            rte
    ; ---------------------------------------------------------------------------
    
    Backup_Kos_Registers:
            move    sr,(Kos_decomp_stored_SR).w
            movem.l    d0-d6/a0-a2,(Kos_decomp_stored_registers).w
            rts
    ; End of function Process_Kos_Queue

    VBla_02:
    Code:
    VBla_02:
            bsr.w    sub_106E
    
    VBla_14:
            tst.w    (v_demolength).w
            beq.w    @end
            subq.w    #1,(v_demolength).w
    
        @end:
            jmp    (Set_Kos_Bookmark).l
    VBla_08:
    Code:
    VBla_08:
    ;        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.s Demo_Time
            jmp    (Set_Kos_Bookmark).l
    VBla_0A:
    Code:
    VBla_0A:
    ;        stopZ80
    ;        waitZ80
            bsr.w    ReadJoypads
            writeCRAM    v_pal_dry,$80,0
            writeVRAM    v_spritetablebuffer,$280,vram_sprites
            writeVRAM    v_hscrolltablebuffer,$380,vram_hscroll
            startZ80
            bsr.w    PalCycle_SS
            jsr    (ProcessDMAQueue).l
    
        @nochg:
            cmpi.b    #96,(v_hbla_line).w
            bcc.s   @update
            bra.w   @end
           
        @update:
            jsr    SS_LoadWalls
           
            tst.w    (v_demolength).w    ; is there time left on the demo?
            beq.w    @end    ; if not, return
            subq.w    #1,(v_demolength).w    ; subtract 1 from time left in demo
    
        @end:
            jmp    (Set_Kos_Bookmark).l
    VBla_0C:
    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
            jsr    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
            jmp    (Set_Kos_Bookmark).l
    VBla_16:
    Code:
    VBla_16:
    ;        stopZ80
    ;        waitZ80
            bsr.w    ReadJoypads
            writeCRAM    v_pal_dry,$80,0
            writeVRAM    v_spritetablebuffer,$280,vram_sprites
            writeVRAM    v_hscrolltablebuffer,$380,vram_hscroll
            startZ80
            jsr    (ProcessDMAQueue).l
    
        @nochg:
            cmpi.b    #96,(v_hbla_line).w
            bcc.s   @update
            bra.w   @end
           
        @update:
            jsr    SS_LoadWalls
            tst.w    (v_demolength).w
            beq.w    @end
            subq.w    #1,(v_demolength).w
    
        @end:
            jmp    (Set_Kos_Bookmark).l

    Code:
    Level_TtlCardLoop:
            move.b    #$C,(v_vbla_routine).w
            jsr    (Process_Kos_Queue).l
            bsr.w    WaitForVBla
            jsr    (ExecuteObjects).l
            jsr    (BuildSprites).l
            bsr.w    RunPLC
            jsr    (Process_Kos_Module_Queue).l
            move.w    (v_objspace+$108).w,d0
            cmp.w    (v_objspace+$130).w,d0 ; has title card sequence finished?
            bne.s    Level_TtlCardLoop ; if not, branch
            tst.l    (v_plc_buffer).w ; are there any items in the pattern load cue?
            bne.s    Level_TtlCardLoop ; if yes, branch
            jsr    (Hud_Base).l    ; load basic HUD gfx
    Code:
    Level_MainLoop:
            bsr.w    PauseGame
            move.b    #8,(v_vbla_routine).w
            jsr    (Process_Kos_Queue).l
            bsr.w    WaitForVBla
            addq.w    #1,(v_framecount).w ; add 1 to level timer
            bsr.w    MoveSonicInDemo
            bsr.w    LZWaterFeatures
            jsr    (ExecuteObjects).l
            if Revision=0
            else
                tst.w   (f_restart).w
                bne     GM_Level
            endc
            tst.w    (v_debuguse).w    ; is debug mode being used?
            bne.s    Level_DoScroll    ; if yes, branch
            cmpi.b    #6,(v_player+obRoutine).w ; has Sonic just died?
            bhs.s    Level_SkipScroll ; if yes, branch
    
        Level_DoScroll:
            bsr.w    DeformLayers
    
        Level_SkipScroll:
            jsr    (BuildSprites).l
            jsr    (ObjPosLoad).l
            jsr    RingsManager
            bsr.w    PaletteCycle
            bsr.w    RunPLC
            jsr    (Process_Kos_Module_Queue).l
            bsr.w    OscillateNumDo
            bsr.w    SynchroAnimate
            bsr.w    SignpostArtLoad
    
            cmpi.b    #id_Demo,(v_gamemode).w
            beq.s    Level_ChkDemo    ; if mode is 8 (demo), branch
            if Revision=0
            tst.w    (f_restart).w    ; is the level set to restart?
            bne.w    GM_Level    ; if yes, branch
            else
            endc
            cmpi.b    #id_Level,(v_gamemode).w
            beq.w    Level_MainLoop    ; if mode is $C (level), branch
            rts    

    Code:
    Camera_X_pos_last: equ $FFFFDC02
    Camera_Y_pos_last: equ $FFFFDC04
    
    ; $FFFFDC06 - $FFFFEFFF are unused.
    
    Kos_last_module_size:    equ $FFFFDC06            ; the uncompressed size of the last module in words. All other modules are $800 words.
    Kos_module_queue:    equ $FFFFDC08        ; 6 bytes per entry, first longword is source location and next word is VRAM destination. Twelve words.
    Kos_module_source:    equ $FFFFDC30    ; long ; the compressed data location for the first module in the queue
    Kos_decomp_source:    equ    Kos_decomp_queue    ; long ; the compressed data location for the first entry in the queue
    Kos_decomp_destination:    equ    Kos_decomp_queue+4    ; long ; the decompression location for the first entry in the queue
    Kos_module_destination: equ    Kos_module_queue+4    ; word ; the VRAM destination for the first module in the queue
    
    Kos_decomp_queue_count:    equ $FFFFDC38        ; the number of pieces of data on the queue. Sign bit set indicates a decompression is in progress. A word.
    Kos_decomp_stored_registers:    equ $FFFFDC3A        ; allows decompression to be spread over multiple frames. 40 bytes.
    Kos_decomp_stored_SR:    equ $FFFFDC80 ; word  
    Kos_decomp_bookmark:    equ $FFFFDC82            ; the address within the Kosinski queue processor at which processing is to be resumed. A longword.
    Kos_description_field:    equ $FFFFDC86            ; used by the Kosinski queue processor the same way the stack is used by the normal Kosinski decompression routine. A word.
    Kos_decomp_queue:    equ $FFFFDC90        ; 2 longwords per entry, first is source location and second is decompression location. 32 bytes.
    Kos_modules_left:    equ $FFFFDDFE        ; the number of modules left to decompresses. Sign bit set indicates a module is being decompressed/has been decompressed. Byte.
    
    Kos_decomp_buffer:    equ $FFFFDE00 ; $1000 byte buffer used by KosM.
    v_snddriver_ram:    equ $FFFFF000 ; start of RAM for the sound driver data ($5C0 bytes)

    I'm seriously baffled. If anyone can help, that'd be nice.
     
    Last edited: Oct 21, 2021
  11. SuperSayian Zrise

    SuperSayian Zrise Well-Known Member Member

    Joined:
    May 10, 2021
    Messages:
    60
    so I used the guide to add a options screen and I can't get rid of this error.
    Code:
    cmpi.w    #$700,d0        ; check    if level is 0700 (Special Stage)
    This is where the error points to is this line and I can't figure out what's wrong. I used .b and .l and tried to use chk and its still there.
    Code:
    add.w    d0,d0
            move.l    LSelectPointers(pc,d0.l),d0 ; load level number
            bmi.w    LevelSelect
            cmpi.w    #$700,d0        ; check    if level is 0700 (Special Stage)
            bne.s    LevSel_Level    ; if not, branch
            move.b    #$10,($FFFFF600).w ; set screen    mode to    $10 (Special Stage)
            clr.w    ($FFFFFE10).w    ; clear    level
            move.b    #3,($FFFFFE12).w ; set lives to    3
            moveq    #0,d0
            move.w    d0,($FFFFFE20).w ; clear rings
            move.l    d0,($FFFFFE22).w ; clear time
            move.l    d0,($FFFFFE26).w ; clear score
            rts
    quick edit: its an illegal value error.
     
  12. ProjectFM

    ProjectFM Optimistic and self-dependent Member

    Joined:
    Oct 4, 2014
    Messages:
    900
    Location:
    Orono, Maine
    There is no reason I can think of why that line in particular would cause an error. My assumption is that it's the line after it causing the issues. Try changing
    Code:
    bne.s    LevSel_Level    ; if not, branch
    to
    Code:
    bne.w    LevSel_Level    ; if not, branch
     
  13. TheInvisibleSun

    TheInvisibleSun Visible Member

    Joined:
    Jul 2, 2013
    Messages:
    392
    Location:
    Buffalo, NY, USA
    You sure it's not the line below it that's causing the error?

    [edit: ninja'd by FM]
     
    SuperSayian Zrise likes this.
  14. ProjectFM

    ProjectFM Optimistic and self-dependent Member

    Joined:
    Oct 4, 2014
    Messages:
    900
    Location:
    Orono, Maine
    It has been brought to my attention that the issue is more likely that LSelectPointers is out of range.
    Code:
            move.l    LSelectPointers(pc,d0.l),d0 ; load level number
    pc-relative instructions have a relatively limited range for how far the thing being pointed to can be from it. The fix would be either to move LSelectPointers to be closer, or to make the instruction not pc-relative like so:
    Code:
            lea    (LSelectPointers).l,a0 ; load level number
            move.l    (a0,d0.w),d0 ; load level number
    Also, "d0.l" is not used anywhere in Sonic 1 and I doubt you need it for anything "d0.w" can't do.
     
    JGamer2151 and SuperSayian Zrise like this.
  15. SuperSayian Zrise

    SuperSayian Zrise Well-Known Member Member

    Joined:
    May 10, 2021
    Messages:
    60
    Welp, I can finally finish my hack or hacks in peace without errors. Well, hopefully no errors.
    edit: yes it does work.
     
  16. Psi

    Psi Well-Known Member Member

    Joined:
    Dec 20, 2014
    Messages:
    98
    Is anyone here experienced with monitor editing or adding new icons?

    Basically I wanna add new monitors to Sonic 2, but I'm out of space, so my plan was to compress by having some icons like Eggman and the shield mirror one half. It displays alright on the monitor itself, but when you break it...

    [​IMG]

    It seems like the programming for the floating icon only takes the first block on the sprite. Anyone know how to fix this so the mirrored tiles take their extra block?

    EDIT: Now I have more technical info on the situation, what I wanna do is edit Obj2E (the hovering icon when you break a monitor natch).

    Code:
    loc_128C2:
    
      move.b    d0,anim(a0)
    
    loc_128C6:            ; Determine correct mappings offset.
       addq.b    #1,d0
       move.b    d0,mapping_frame(a0)
       movea.l    #Obj26_MapUnc_12D36,a1
       add.b    d0,d0
       adda.w    (a1,d0.w),a1
       addq.w    #2,a1
       move.l    a1,mappings(a0)
    
    loc_128DE:
       bsr.s    sub_128E4
       bra.w    DisplaySprite
    Basically from what I get the jist of, it just shows the very front chunk of the monitor frame (which is always the icon). This of course causes issue when I try to make the icon out of two mirrored chunks. Is there any way to get this routine to load the first TWO chunks of a frame instead of just one?
     
    Last edited: Oct 26, 2021
  17. SuperSayian Zrise

    SuperSayian Zrise Well-Known Member Member

    Joined:
    May 10, 2021
    Messages:
    60
    Hey again, and I have a new problem:
    [​IMG]
    I've just been working on my sonic 1 hack. Then maybe at least about 4 or 3 days ago. I realized it will crash when I turn around after going to the area with the first enemy/motobug. Then I changed the first chunk and deleted and added new objects in place. But for some reason the pylons from SLZ appears here. Yet I did not place any pylon objects anywhere in the level. And this is why I need help. Because I don't want this in my Green Hill Zone. And I didn't modify the object or the Zone features and stuff. I'm not sure what's wrong, any help?
     
  18. yami

    yami la la la! let's all sing a happy song! Member

    Joined:
    Sep 24, 2020
    Messages:
    25
    Did you use the foreground object code that Inferno posted in the Free Assets thread? That might be why...
     
    SuperSayian Zrise likes this.
  19. SuperSayian Zrise

    SuperSayian Zrise Well-Known Member Member

    Joined:
    May 10, 2021
    Messages:
    60
    No, why? Also, my disassembly is hivebrain 2005 (ASM68K) version. Even though I don't know what I could really do. Because, at least when it crashes, I can see a report. But here, anything could be going on.
    (Sorry for late response)
     
  20. Inferno

    Inferno Rom Hacker Member

    Joined:
    Oct 27, 2015
    Messages:
    104
    Location:
    Sky Base Zone, South Island
    My object wouldn't act like a SLZ pylon regardless, since it's basically a version that can be placed freely. So that's not it.

    I'm betting that they somehow overwrote their GHZ work with the SLZ layout.
     
    SuperSayian Zrise likes this.