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?
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): ; =========================================================================== ; S3 Level Layout Format. ; =========================================================================== ; Header. ; =========================================================================== 00AA 00BB 00CC 00DD AA: Number of FG Tiles Per Line. BB: Number of BG Tiles Per Line. CC: Number of FG lines. DD: Number of BG lines. ; =========================================================================== ; Row Header. ; =========================================================================== AAAA: Ram Address for FG. BBBB: Ram Address for BG. ;** :Row Number. ;00 $AAAA,$BBBB ;01 $AAAA,$BBBB ;02 $AAAA,$BBBB ;03 $AAAA,$BBBB ;04 $AAAA,$BBBB ;05 $AAAA,$BBBB ;06 $AAAA,$BBBB ;07 $AAAA,$BBBB ;08 $AAAA,$BBBB ;09 $AAAA,$BBBB ;0A $AAAA,$BBBB ;0B $AAAA,$BBBB ;0C $AAAA,$BBBB ;0D $AAAA,$BBBB ;0E $AAAA,$BBBB ;0F $AAAA,$BBBB ;10 $AAAA,$BBBB ;11 $AAAA,$BBBB ;12 $AAAA,$BBBB ;13 $AAAA,$BBBB ;14 $AAAA,$BBBB ;15 $AAAA,$BBBB ;16 $AAAA,$BBBB ;17 $AAAA,$BBBB ;18 $AAAA,$BBBB ;19 $AAAA,$BBBB ;1A $AAAA,$BBBB ;1B $AAAA,$BBBB ;1C $AAAA,$BBBB ;1D $AAAA,$BBBB ;1E $AAAA,$BBBB ;1F $AAAA,$BBBB ; =========================================================================== ; Level Layout Data. ; =========================================================================== Which starts at $8088 Format is simple, Depending on the header and Ram addresses for rows chosen it is setup like that. Format is, One byte per chunk, Chunk ID = Byte. ; ===========================================================================
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.
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.
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.
Don't worry about it. Restoring the BG redundancy had a slight effect on the bug, but nothing pleasing.
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): Offset_0x03A6EC: bsr Offset_0x03A9CE btst #$03, Obj_Status(A0) ; btst #$03, $0022(A0) beq.s Offset_0x03A72A addq.b #$02, Obj_Routine_2(A0) ; addq.b #$02, $0025(A0) move.w #$0020, Obj_Custom_Var_02(A0) ; move.w #$0020, $002E(A0) lea ($FFFF883A).w, A1 ; lea ($FFFF80D2).w, A1 move.l #$501F0025, (A1)+ lea ($FFFF88BA).w, A1 ; lea ($FFFF81D2).w, A1 move.l #$25001F50, (A1)+ lea ($FFFF8DBE).w, A1 ; lea ($FFFF8BD6).w, A1 move.l #$501F0025, (A1)+ lea ($FFFF8E3E).w, A1 ; lea ($FFFF8CD6).w, A1 move.l #$25001F50, (A1)+
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.
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): Level_Map_Pointers equ $FFFF8000 ; Novo <<<- Level_Map_Data equ Level_Map_Pointers ; Fg_Mem_Start_Address equ $FFFF8000 ; Remover <<<- Level_Foreground_Index equ Level_Map_Pointers+$0008 ; Bg_Mem_Start_Address equ $FFFF8080 ; Remover <<<- Level_Background_Index equ Level_Map_Pointers+$000A Code (Text): LoadTilesAsYouMove: ; Offset_0x00DA14 lea (VDP_Control_Port), A5 ; $00C00004 lea (VDP_Data_Port), A6 ; $00C00000 lea ($FFFFEEA2).w, A2 lea ($FFFFEE68).w, A3 ; lea (Bg_Mem_Start_Address).w, A4 ; $FFFF8080 lea (Level_Background_Index).w, A4 move.w #$6000, D2 bsr Offset_0x00DB7A lea ($FFFFEEA4).w, A2 lea ($FFFFEE70).w, A3 bsr Offset_0x00DC4A lea ($FFFFEEA6).w, A2 lea ($FFFFEE78).w, A3 bsr Offset_0x00DD3E tst.w (Two_Player_Flag).w ; $FFFFFFB8 beq.s Offset_0x00DA66 lea ($FFFFEEA8).w, A2 lea ($FFFFEE80).w, A3 ; lea (Fg_Mem_Start_Address).w, A4 ; $FFFF8000 lea (Level_Foreground_Index).w, A4 move.w #$6000, D2 bsr Offset_0x00DB14 Offset_0x00DA66: lea ($FFFFEEA0).w, A2 lea ($FFFFEE60).w, A3 ; lea (Fg_Mem_Start_Address).w, A4 ; $FFFF8000 lea (Level_Foreground_Index).w, A4 move.w #$4000, D2 tst.b (Refresh_Level_Layout).w ; $FFFFF72C beq.s Draw_FG ; Offset_0x00DAAE move.b #$00, (Refresh_Level_Layout).w ; $FFFFF72C moveq #$FFFFFFF0, D4 moveq #$0F, D6 Draw_All: And Code (Text): Calc_Chunk_RAM_Pos: ; Offset_0x00E05E movem.l D4/D5, -(A7) move.w D4, D3 ; add.w D3, D3 ; Neto - Sonic 2 Delta ; andi.w #$0F00, D3 ; Neto - Sonic 2 Delta ;------------------------------------------------------------------------------- ; Neto - Sonic 2 Delta ->>> andi.w #$0780, D3 ; Y Wrap lsr.w #$05, D3 lea (A4, D3), A0 movea.w (A0), A0 ; Neto - Sonic 2 Delta <<<- ;------------------------------------------------------------------------------- lsr.w #$03, D5 move.w D5, D0 lsr.w #$04, D0 andi.w #$007F, D0 ; add.w D3, D0 ; Neto - Sonic 2 Delta moveq #$FFFFFFFF, D3 clr.w D3 ; move.b $00(A4, D0), D3 ; Neto - Sonic 2 Delta ;------------------------------------------------------------------------------- ; Neto - Sonic 2 Delta ->>> move.b $00(A0, D0), D3 ; Neto - Sonic 2 Delta <<<- ;------------------------------------------------------------------------------- lsl.w #$07, D3 andi.w #$0070, D4 andi.w #$000E, D5 add.w D4, D3 add.w D5, D3 move.l D3, A0 movem.l (A7)+, D4/D5 rts and Code (Text): ;=============================================================================== ; Sub Rotina Draw_Blocks - Rotina para desenhar os blocos ; [ Início ] ;=============================================================================== Draw_Blocks: ; Offset_0x00E204 add.w (A3), D5 add.w $0004(A3), D4 lea (Blocks_Mem_Address).w, A1 ; $FFFF9000 move.w D4, D3 ; Neto - Sonic 2 Delta ; add.w D3, D3 ; Neto - Sonic 2 Delta ; andi.w #$0F00, D3 ;------------------------------------------------------------------------------- ; Neto - Sonic 2 Delta ->>> andi.w #$0780, D3 ; Y Wrap lsr.w #$05, D3 lea (A4, D3), A0 movea.w (A0), A0 ; Neto - Sonic 2 Delta <<<- ;------------------------------------------------------------------------------- lsr.w #$03, D5 move.w D5, D0 lsr.w #$04, D0 andi.w #$007F, D0 ; add.w D3, D0 moveq #$FFFFFFFF, D3 clr.w D3 ; move.b $00(A4, D0), D3 ; Chunk 128x128 a ser desenhado ;------------------------------------------------------------------------------- ; Neto - Sonic 2 Delta ->>> move.b $00(A0, D0), D3 ; Neto - Sonic 2 Delta <<<- ;------------------------------------------------------------------------------- lsl.w #$07, D3 andi.w #$0070, D4 andi.w #$000E, D5 add.w D4, D3 add.w D5, D3 move.l D3, A0 move.w (A0), D3 andi.w #$03FF, D3 lsl.w #$03, D3 adda.w D3, A1 rts ;=============================================================================== ; Sub Rotina Draw_Blocks - Rotina para desenhar os blocos ; [ Término ] ;=============================================================================== Code (Text): Load_Tiles_From_Start: ; Offset_0x00E2C0 lea (VDP_Control_Port), A5 ; $00C00004 lea (VDP_Data_Port), A6 ; $00C00000 ;=============================================================================== ; Carrega os Tiles durante o Início da Fase ; Neto - Sonic 2D ; Usado na seqüência do final ; [ Início ] ;=============================================================================== tst.w (End_Sequence_Flag).w bpl.s No_Credits_Running Credits_Running: lea ($FFFFEE00).w, A3 ; lea (Fg_Mem_Start_Address).w, A4 ; FFFF8000 ;------------------------------------------------------------------------------- ; Neto - Sonic 2 Delta ->>> lea (Level_Foreground_Index).w, A4 ; Neto - Sonic 2 Delta <<<- ;------------------------------------------------------------------------------- move.w #$4000, D2 bsr.s Draw_Bg No_Credits_Running: ;=============================================================================== ; Carrega os Tiles durante o Início da Fase ; Neto - Sonic 2D ; Usado na seqüência do final ; [ Término ] ;=============================================================================== lea ($FFFFEE08).w, A3 ; lea (Bg_Mem_Start_Address).w, A4 ; $FFFF8080 ;------------------------------------------------------------------------------- ; Neto - Sonic 2 Delta ->>> lea (Level_Background_Index).w, A4 ; Neto - Sonic 2 Delta <<<- ;------------------------------------------------------------------------------- move.w #$6000, D2 moveq #$00, D4 cmpi.b #$0C, (Level_Id).w ; $FFFFFE10 beq Draw_CNz_Bg ; Offset_0x00E2F8 tst.w (Two_Player_Flag).w ; $FFFFFFB8 beq Draw_Bg ; Offset_0x00E2F6 cmpi.b #$0B, (Level_Id).w ; $FFFFFE10 beq Draw_MCz_2P_Bg ; Offset_0x00E356 Draw_Bg: ; Offset_0x00E2F6 moveq #$FFFFFFF0, D4 Draw_CNz_Bg:
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.