Help with porting S3K's layout format?

Discussion in 'Engineering & Reverse Engineering' started by Clownacy, May 26, 2015.

  1. Clownacy

    Clownacy

    Tech Member
    782
    7
    18
    Where to begin... Well, I ported S3K's layout format to my S2 hack. I thought I had a pretty good idea of how it all worked, and have been able to track down and fix every issue encountered (outside of a recently-discovered bug in WFZ I'm sure I can fix). All but one, anyhow.

    MCZ's background now loads incorrect blocks as you progress through the level. I've been unable to find any code remotely related to layout reading outside of what I've already changed, so I'm lost as to what the problem could possibly be. It's not something I've encountered with any other level, and it appears even in otherwise-stock S2. That said, making MCZ use the 'standard' BG deformation instead of its own doesn't seem to incur the bug. I'll add some pics or a ROM when I get the chance.

    So, erm, yeah. Can anyone spare a little help, here?
     
  2. Varion Icaria

    Varion Icaria

    He's waiting.... Tech Member
    1,010
    0
    16
    S4: Cybernetic Outbreak
    Yes I'll help. Here's my documentation of the format.

    Edit: A Note. The Row Header must be the full size to avoid any issues. SonED2 doesn't do this but SonLVL does. If you're having trouble getting the S3K Draw System to display correctly show me what code you have and I'll fix it.

    Code (Text):
    1. ; ===========================================================================
    2. ; S3 Level Layout Format.
    3. ; ===========================================================================
    4. ; Header.
    5. ; ===========================================================================
    6. 00AA
    7. 00BB
    8. 00CC
    9. 00DD
    10.  
    11. AA: Number of FG Tiles Per Line.
    12. BB: Number of BG Tiles Per Line.
    13. CC: Number of FG lines.
    14. DD: Number of BG lines.
    15.  
    16.  
    17. ; ===========================================================================
    18. ; Row Header.
    19. ; ===========================================================================
    20. AAAA: Ram Address for FG.
    21. BBBB: Ram Address for BG.
    22.  
    23. ;** :Row Number.
    24. ;00 $AAAA,$BBBB
    25. ;01 $AAAA,$BBBB
    26. ;02 $AAAA,$BBBB
    27. ;03 $AAAA,$BBBB
    28. ;04 $AAAA,$BBBB
    29. ;05 $AAAA,$BBBB
    30. ;06 $AAAA,$BBBB
    31. ;07 $AAAA,$BBBB
    32. ;08 $AAAA,$BBBB
    33. ;09 $AAAA,$BBBB
    34. ;0A $AAAA,$BBBB
    35. ;0B $AAAA,$BBBB
    36. ;0C $AAAA,$BBBB
    37. ;0D $AAAA,$BBBB
    38. ;0E $AAAA,$BBBB
    39. ;0F $AAAA,$BBBB
    40. ;10 $AAAA,$BBBB
    41. ;11 $AAAA,$BBBB
    42. ;12 $AAAA,$BBBB
    43. ;13 $AAAA,$BBBB
    44. ;14 $AAAA,$BBBB
    45. ;15 $AAAA,$BBBB
    46. ;16 $AAAA,$BBBB
    47. ;17 $AAAA,$BBBB
    48. ;18 $AAAA,$BBBB
    49. ;19 $AAAA,$BBBB
    50. ;1A $AAAA,$BBBB
    51. ;1B $AAAA,$BBBB
    52. ;1C $AAAA,$BBBB
    53. ;1D $AAAA,$BBBB
    54. ;1E $AAAA,$BBBB
    55. ;1F $AAAA,$BBBB
    56. ; ===========================================================================
    57. ; Level Layout Data.
    58. ; ===========================================================================
    59. Which starts at $8088
    60.  
    61. Format is simple, Depending on the header and Ram addresses for rows chosen it is setup like that.
    62.  
    63. Format is, One byte per chunk, Chunk ID = Byte.
    64. ; ===========================================================================
     
  3. Clownacy

    Clownacy

    Tech Member
    782
    7
    18
    I'm sorry, I should have worded the title better. I'm aware of how the layout is composed, it's just that modifying S2's collision and display to work with it leads to a bug, and I don't know how my changes are responsible. I thought that there may have been another peice of code that tries to read from layout, but I've never been able to find any more than the two I've always modified.

    It just occurred to me, the bug might be similar to another one found in WFZ. The converter I used to convert layouts optimises its output by removing 'blankspaces' of chunk 0. I know WFZ needs the empty space for its bottomless pit, and for its end cutscene. Maybe MCZ's background needs the redundant chunks, too.
     
  4. Varion Icaria

    Varion Icaria

    He's waiting.... Tech Member
    1,010
    0
    16
    S4: Cybernetic Outbreak
    To test that theory, make a blank chunk in WFZ that's not 0 and place it around the layout where it's needed to space it out. From there try optimizing it again. S3K level draw is very picky in terms of drawing, It has the two major draw controls that call it's code, One to initialize the Draw and the other to continuously process the actual draw of the level. Without the routines properly called during draw with the proper data the levels won't fully display properly. Hopefully that's not the case here though. I'm on IRC I could probably help out more direct there.
     
  5. Clownacy

    Clownacy

    Tech Member
    782
    7
    18
    I don't have S3K's draw code. All I've modified is code relating to obtaining chunks, to work with the new layout format. I should be able to get some tests done soon, so I'll see what happens.
     
  6. Varion Icaria

    Varion Icaria

    He's waiting.... Tech Member
    1,010
    0
    16
    S4: Cybernetic Outbreak
    Ahh well I couldn't help you much there, I thought you ported the S3k Code.
     
  7. Clownacy

    Clownacy

    Tech Member
    782
    7
    18
    Don't worry about it.

    Restoring the BG redundancy had a slight effect on the bug, but nothing pleasing.
     
  8. Esrael

    Esrael

    Tech Member
    187
    0
    0
    Brazil, São Paulo, Guarulhos
    Neto Assembler Editor / Sonic 2 Delta / Neto Boot Loader
    Did you updated the LoadTilesAsYouMove/LoadTilesFromStart Routines? Because a lot of change are necessary to get S3 Y Indexed to work?

    For WFz you will need some code inside object B2 due to tile change on Transition for Death Egg.
    If you want I can provide Sonic 2 Delta source with these routines inside.

    Block code from Sonic 2 Delta Object B2 in WFz transition new RAM Address of Tiles
    Code (Text):
    1.  
    2. Offset_0x03A6EC:
    3.                 bsr     Offset_0x03A9CE
    4.                 btst    #$03, Obj_Status(A0)           ; btst    #$03, $0022(A0)
    5.                 beq.s   Offset_0x03A72A
    6.                 addq.b  #$02, Obj_Routine_2(A0)        ; addq.b  #$02, $0025(A0)
    7.                 move.w  #$0020, Obj_Custom_Var_02(A0)  ; move.w  #$0020, $002E(A0)
    8.                 lea     ($FFFF883A).w, A1              ; lea     ($FFFF80D2).w, A1  
    9.                 move.l  #$501F0025, (A1)+
    10.                 lea     ($FFFF88BA).w, A1              ; lea     ($FFFF81D2).w, A1
    11.                 move.l  #$25001F50, (A1)+
    12.                 lea     ($FFFF8DBE).w, A1              ; lea     ($FFFF8BD6).w, A1
    13.                 move.l  #$501F0025, (A1)+
    14.                 lea     ($FFFF8E3E).w, A1              ; lea     ($FFFF8CD6).w, A1
    15.                 move.l  #$25001F50, (A1)+                    
    16.  
     
  9. Clownacy

    Clownacy

    Tech Member
    782
    7
    18
    A lot of changes? For LoadTilesAsYouMove/LoadTilesFromStart, I only changed GetBlockAddr and GetBlockPtr (Git labels) to make them read the new format. I also had to move a4 to the stack to avoid having it modified in GetBlockAddr.
     
  10. Esrael

    Esrael

    Tech Member
    187
    0
    0
    Brazil, São Paulo, Guarulhos
    Neto Assembler Editor / Sonic 2 Delta / Neto Boot Loader
    Sorry , I am using different version, but I think with code you can figure compatible routines in your asm.
    If you want I can provide full source code.

    For A4 only Ram Address is changed in Sonic 2 Delta code.

    Code (Text):
    1.  
    2. Level_Map_Pointers      equ $FFFF8000 ; Novo <<<-
    3. Level_Map_Data          equ Level_Map_Pointers
    4. ; Fg_Mem_Start_Address    equ $FFFF8000 ; Remover <<<-
    5. Level_Foreground_Index  equ Level_Map_Pointers+$0008
    6. ; Bg_Mem_Start_Address    equ $FFFF8080 ; Remover <<<-
    7. Level_Background_Index  equ Level_Map_Pointers+$000A
    8.  
    Code (Text):
    1.  
    2. LoadTilesAsYouMove: ; Offset_0x00DA14                          
    3.                 lea     (VDP_Control_Port), A5                       ; $00C00004
    4.                 lea     (VDP_Data_Port), A6                          ; $00C00000
    5.                 lea     ($FFFFEEA2).w, A2
    6.                 lea     ($FFFFEE68).w, A3
    7.               ; lea     (Bg_Mem_Start_Address).w, A4                 ; $FFFF8080
    8.                 lea     (Level_Background_Index).w, A4
    9.                 move.w  #$6000, D2
    10.                 bsr     Offset_0x00DB7A        
    11.                 lea     ($FFFFEEA4).w, A2
    12.                 lea     ($FFFFEE70).w, A3
    13.                 bsr     Offset_0x00DC4A
    14.                 lea     ($FFFFEEA6).w, A2
    15.                 lea     ($FFFFEE78).w, A3
    16.                 bsr     Offset_0x00DD3E
    17.                 tst.w   (Two_Player_Flag).w                          ; $FFFFFFB8
    18.                 beq.s   Offset_0x00DA66
    19.                 lea     ($FFFFEEA8).w, A2
    20.                 lea     ($FFFFEE80).w, A3
    21.               ; lea     (Fg_Mem_Start_Address).w, A4                 ; $FFFF8000
    22.                 lea     (Level_Foreground_Index).w, A4  
    23.                 move.w  #$6000, D2
    24.                 bsr     Offset_0x00DB14
    25. Offset_0x00DA66:
    26.                 lea     ($FFFFEEA0).w, A2
    27.                 lea     ($FFFFEE60).w, A3
    28.               ; lea     (Fg_Mem_Start_Address).w, A4                 ; $FFFF8000
    29.                 lea     (Level_Foreground_Index).w, A4  
    30.                 move.w  #$4000, D2
    31.                 tst.b   (Refresh_Level_Layout).w                     ; $FFFFF72C
    32.                 beq.s   Draw_FG                                ; Offset_0x00DAAE
    33.                 move.b  #$00, (Refresh_Level_Layout).w               ; $FFFFF72C
    34.                 moveq   #$FFFFFFF0, D4
    35.                 moveq   #$0F, D6
    36. Draw_All:    
    37.  
    And
    Code (Text):
    1.  
    2. Calc_Chunk_RAM_Pos:                                            ; Offset_0x00E05E
    3.                 movem.l D4/D5, -(A7)
    4.                 move.w  D4, D3
    5.               ; add.w   D3, D3              ; Neto - Sonic 2 Delta
    6.               ; andi.w  #$0F00, D3          ; Neto - Sonic 2 Delta
    7. ;-------------------------------------------------------------------------------
    8. ; Neto - Sonic 2 Delta ->>>
    9.                 andi.w  #$0780, D3          ; Y Wrap    
    10.                 lsr.w   #$05, D3      
    11.                 lea     (A4, D3), A0  
    12.                 movea.w (A0), A0      
    13. ; Neto - Sonic 2 Delta <<<-
    14. ;-------------------------------------------------------------------------------                  
    15.                 lsr.w   #$03, D5
    16.                 move.w  D5, D0
    17.                 lsr.w   #$04, D0
    18.                 andi.w  #$007F, D0
    19.               ; add.w   D3, D0              ; Neto - Sonic 2 Delta
    20.                 moveq   #$FFFFFFFF, D3
    21.                 clr.w   D3  
    22.               ; move.b  $00(A4, D0), D3     ; Neto - Sonic 2 Delta
    23. ;-------------------------------------------------------------------------------
    24. ; Neto - Sonic 2 Delta ->>>  
    25.                 move.b  $00(A0, D0), D3
    26. ; Neto - Sonic 2 Delta <<<-
    27. ;-------------------------------------------------------------------------------            
    28.                 lsl.w   #$07, D3
    29.                 andi.w  #$0070, D4
    30.                 andi.w  #$000E, D5
    31.                 add.w   D4, D3
    32.                 add.w   D5, D3
    33.                 move.l  D3, A0
    34.                 movem.l (A7)+, D4/D5
    35.                 rts                
    36.  
    and

    Code (Text):
    1.  
    2. ;===============================================================================
    3. ; Sub Rotina Draw_Blocks - Rotina para desenhar os blocos  
    4. ; [ Início ]
    5. ;===============================================================================
    6. Draw_Blocks:                                                   ; Offset_0x00E204    
    7.                 add.w   (A3), D5  
    8.                 add.w   $0004(A3), D4
    9.                 lea     (Blocks_Mem_Address).w, A1                   ; $FFFF9000
    10.                 move.w  D4, D3                  ; Neto - Sonic 2 Delta
    11.               ; add.w   D3, D3                  ; Neto - Sonic 2 Delta
    12.               ; andi.w  #$0F00, D3
    13. ;-------------------------------------------------------------------------------
    14. ; Neto - Sonic 2 Delta ->>>
    15.                 andi.w  #$0780, D3              ; Y Wrap  
    16.                 lsr.w   #$05, D3      
    17.                 lea     (A4, D3), A0  
    18.                 movea.w (A0), A0    
    19. ; Neto - Sonic 2 Delta <<<-
    20. ;-------------------------------------------------------------------------------            
    21.                 lsr.w   #$03, D5
    22.                 move.w  D5, D0
    23.                 lsr.w   #$04, D0
    24.                 andi.w  #$007F, D0
    25.               ; add.w   D3, D0
    26.                 moveq   #$FFFFFFFF, D3
    27.                 clr.w   D3
    28.               ; move.b  $00(A4, D0), D3   ; Chunk 128x128 a ser desenhado
    29. ;-------------------------------------------------------------------------------
    30. ; Neto - Sonic 2 Delta ->>>  
    31.                 move.b  $00(A0, D0), D3
    32. ; Neto - Sonic 2 Delta <<<-
    33. ;-------------------------------------------------------------------------------              
    34.                 lsl.w   #$07, D3
    35.                 andi.w  #$0070, D4
    36.                 andi.w  #$000E, D5
    37.                 add.w   D4, D3
    38.                 add.w   D5, D3
    39.                 move.l  D3, A0
    40.                 move.w  (A0), D3
    41.                 andi.w  #$03FF, D3
    42.                 lsl.w   #$03, D3
    43.                 adda.w  D3, A1
    44.                 rts
    45. ;===============================================================================
    46. ; Sub Rotina Draw_Blocks - Rotina para desenhar os blocos  
    47. ; [ Término ]
    48. ;===============================================================================
    49.  
    Code (Text):
    1.  
    2. Load_Tiles_From_Start:                                         ; Offset_0x00E2C0
    3.                 lea     (VDP_Control_Port), A5                       ; $00C00004
    4.                 lea     (VDP_Data_Port), A6                          ; $00C00000                
    5. ;===============================================================================
    6. ; Carrega os Tiles durante o Início da Fase                    ; Neto - Sonic 2D      
    7. ; Usado na seqüência do final
    8. ; [ Início ]
    9. ;===============================================================================                
    10.                 tst.w   (End_Sequence_Flag).w  
    11.                 bpl.s   No_Credits_Running  
    12. Credits_Running:                                
    13.                 lea     ($FFFFEE00).w, A3
    14.               ; lea     (Fg_Mem_Start_Address).w, A4                  ; FFFF8000
    15. ;-------------------------------------------------------------------------------
    16. ; Neto - Sonic 2 Delta ->>>              
    17.                 lea     (Level_Foreground_Index).w, A4  
    18. ; Neto - Sonic 2 Delta <<<-                
    19. ;-------------------------------------------------------------------------------                
    20.                 move.w  #$4000, D2
    21.                 bsr.s   Draw_Bg    
    22. No_Credits_Running:
    23. ;===============================================================================
    24. ; Carrega os Tiles durante o Início da Fase                    ; Neto - Sonic 2D
    25. ; Usado na seqüência do final
    26. ; [ Término ]
    27. ;===============================================================================                  
    28.                 lea     ($FFFFEE08).w, A3
    29.               ; lea     (Bg_Mem_Start_Address).w, A4                 ; $FFFF8080
    30. ;-------------------------------------------------------------------------------
    31. ; Neto - Sonic 2 Delta ->>>
    32.                 lea     (Level_Background_Index).w, A4    
    33. ; Neto - Sonic 2 Delta <<<-
    34. ;-------------------------------------------------------------------------------  
    35.                 move.w  #$6000, D2
    36.                 moveq   #$00, D4
    37.                 cmpi.b  #$0C, (Level_Id).w                           ; $FFFFFE10
    38.                 beq     Draw_CNz_Bg                            ; Offset_0x00E2F8
    39.                 tst.w   (Two_Player_Flag).w                          ; $FFFFFFB8
    40.                 beq     Draw_Bg                                ; Offset_0x00E2F6
    41.                 cmpi.b  #$0B, (Level_Id).w                           ; $FFFFFE10
    42.                 beq     Draw_MCz_2P_Bg                         ; Offset_0x00E356
    43. Draw_Bg:                                                       ; Offset_0x00E2F6
    44.                 moveq   #$FFFFFFF0, D4
    45. Draw_CNz_Bg:    
    46.  
     
  11. Clownacy

    Clownacy

    Tech Member
    782
    7
    18
    Those are just about the same modifications I made... except my GetBlockAddr and GetBlockPtr (Calc_Chunk_RAM_Pos and Draw_Blocks) didn't have that 'andi.w #$7F'...

    As it turns out, that looks to have been the cause. S&K didn't have it, so I thought it was needless. Anyway, thanks. Seriously, thanks a lot.