diff --git a/ORCACDefs/gte.h b/ORCACDefs/gte.h index e0103d2..9b294f7 100644 --- a/ORCACDefs/gte.h +++ b/ORCACDefs/gte.h @@ -135,6 +135,23 @@ extern pascal Word GTEClearOverlay() inline(0x23A0, tool_dispatcher); #define RENDER_BG1_HORZ_OFFSET 0x0002 #define RENDER_BG1_VERT_OFFSET 0x0004 #define RENDER_BG1_ROTATION 0x0008 +#define RENDER_PER_SCANLINE 0x0010 +#define RENDER_WITH_SHADOWING 0x0020 +#define RENDER_SPRITES_SORTED 0x0040 + +/* Overlay flags */ +#define OVERLAY_MASKED 0x0000 /* Overlay has a mask, so the background must be draw first */ +#define OVERLAY_SOLID 0x8000 /* Overlay covers the scan line and is fully opaque */ +#define OVERLAY_ABOVE 0x0000 /* Overlay is drawn above scanline sprites */ +#define OVERLAY_BELOW 0x4000 /* Overlay is drawn below scanline sprites */ + +/* GetAddress table IDs */ +#define scanlineHorzOffset 0x0001 +#define scanlineHorzOffset2 0x0002 + +/* CopyPicToBG1 flags */ +#define COPY_PIC_NORMAL 0x0000 /* Copy into BG1 buffer in "normal mode" */ +#define COPY_PIC_SCANLINE 0x0001 /* Copy in a way to support BG1 + RENDER_PER_SCANLINE. */ /* GTE Tile Constants */ #define TILE_PRIORITY_BIT 0x4000 /* Put tile on top of sprite */ @@ -147,6 +164,7 @@ extern pascal Word GTEClearOverlay() inline(0x23A0, tool_dispatcher); #define TILE_CTRL_MASK 0xFE00 /* GTE Sprite Constants */ +#define GTE_SPRITE_COMPILES 0x4000 #define GTE_SPRITE_HIDE 0x2000 #define GTE_SPRITE_16X16 0x1800 #define GTE_SPRITE_16X8 0x1000 @@ -155,7 +173,6 @@ extern pascal Word GTEClearOverlay() inline(0x23A0, tool_dispatcher); #define GTE_SPRITE_VFLIP 0x0400 #define GTE_SPRITE_HFLIP 0x0200 - /* GTE Sprint Stamp Storage Parameters */ #define GTE_VBUFF_STRIDE_BYTES (12 * 4) /* Each line has 4 slots of 16 pixels + 8 buffer pixels */ #define GTE_VBUFF_TILE_ROW_BYTES (8 * GTE_VBUFF_STRIDE_BYTES) /* Each row is comprised of 8 lines */ diff --git a/macros/GTE.Macs.s b/macros/GTE.Macs.s index a51873f..a022808 100644 --- a/macros/GTE.Macs.s +++ b/macros/GTE.Macs.s @@ -176,6 +176,10 @@ OVERLAY_BELOW equ $4000 ; Overlay is drawn below scanline sprite scanlineHorzOffset equ $0001 scanlineHorzOffset2 equ $0002 +; CopyPicToBG1 flags +COPY_PIC_NORMAL equ $0000 ; Copy into BG1 buffer in "normal mode" +COPY_PIC_SCANLINE equ $0001 ; Copy in a way to support BG1 + RENDER_PER_SCANLINE. + ; Tile constants ; TILE_RESERVED_BIT equ $8000 TILE_PRIORITY_BIT equ $4000 ; Put tile on top of sprite @@ -187,7 +191,6 @@ TILE_HFLIP_BIT equ $0200 TILE_ID_MASK equ $01FF TILE_CTRL_MASK equ $FE00 - ; Sprite constants SPRITE_COMPILED equ $4000 ; This is a compiled sprite SPRITE_HIDE equ $2000 diff --git a/src/Defs.s b/src/Defs.s index d3e737e..10e4529 100644 --- a/src/Defs.s +++ b/src/Defs.s @@ -198,6 +198,10 @@ DIRTY_BIT_SPRITE_ARRAY equ $0040 scanlineHorzOffset equ $0001 ; Table of 416 words, a double-array of scanline offset values. Values must be in range [0, 163] scanlineHorzOffset2 equ $0002 ; Table of 416 words, a double-array of scanline offset values. Values must be in range [0, 163] +; CopyPicToBG1 flags +COPY_PIC_NORMAL equ $0000 ; Copy into BG1 buffer in "normal mode" treating the buffer as a 164x208 pixmap with stride of 256 +COPY_PIC_SCANLINE equ $0001 ; Copy in a way to support BG1 + RENDER_PER_SCANLINE. Pixmap is double-width, 327x200 with stride of 327 + ; Script definition YIELD equ $8000 JUMP equ $4000 diff --git a/src/Render.s b/src/Render.s index b0ee933..da2b71b 100644 --- a/src/Render.s +++ b/src/Render.s @@ -156,12 +156,10 @@ _DoOverlay ; Use the per-scanline tables to set the screen. This is really meant to be used without the built-in tilemap ; support and is more of a low-level way to control the background rendering _RenderScanlines - lda BG1YTable ; Make sure we're in the right mode - cmp #$00A0 + lda BG1YTable ; Make sure we're in the right mode (0 = scanline mode, $1800 = normal mode) beq :ytbl_ok lda #1 jsr _ResetBG1YTable - lda BG1YTable :ytbl_ok jsr _ApplyBG0YPos ; Set stack addresses for the virtual lines to the physical screen @@ -173,12 +171,8 @@ _RenderScanlines jsr _ApplyBG0XPosPre jsr _ApplyBG1XPosPre -; jsr _RenderSprites ; Once the BG0 X and Y positions are committed, update sprite data - -; jsr _ApplyTiles ; This function actually draws the new tiles into the code field - - jsr _ApplyScanlineBG0XPos ; Patch the code field instructions with exit BRA opcode - jsr _ApplyScanlineBG1XPos + jsr _ApplyScanlineBG0XPos ; Patch the code field instructions with exit BRA opcode + jsr _ApplyScanlineBG1XPos jsr _BuildShadowList ; Create the rages based on the sorted sprite y-values @@ -187,57 +181,8 @@ _RenderScanlines jsr _DrawDirectSprites ; Draw the sprites directly to the Bank $01 graphics buffer (skipping the render-to-tile step) jsr _ShadowOn ; Turn shadowing back on -; jsr _DrawComplementList ; Alternate drawing scanlines and PEI slam to expose the full fram jsr _DrawFinalPass -; jsr _ApplyBG1XPos ; Update the direct page value based on the horizontal position - -; The code fields are locked in now and ready to be rendered. See if there is an overlay or any -; other reason to render with shadowing off. Otherwise, just do things quickly. - -; lda Overlays -; beq :no_ovrly - -; jsr _ShadowOff - -; Shadowing is turned off. Render all of the scan lines that need a second pass. One -; optimization that can be done here is that the lines can be rendered in any order -; since it is not shown on-screen yet. - -; ldx Overlays+2 ; Blit the full virtual buffer to the screen -; ldy Overlays+4 -; jsr _BltRange - -; Turn shadowing back on - -; jsr _ShadowOn - -; Now render all of the remaining lines in top-to-bottom (or bottom-to-top) order - -; ldx #0 -; ldy Overlays+2 -; beq :skip -; jsr _BltRange -:skip -; jsr _DoOverlay - -; ldx Overlays+4 -; cpx ScreenHeight -; beq :done -; ldy ScreenHeight -; jsr _BltRange -; bra :done - -;:no_ovrly -; ldx #0 ; Blit the full virtual buffer to the screen -; ldy ScreenHeight -; jsr _BltRange -;:done - -; ldx #0 -; ldy ScreenHeight -; jsr _BltSCB - lda StartYMod208 ; Restore the fields back to their original state ldx ScreenHeight jsr _RestoreScanlineBG0Opcodes @@ -693,7 +638,6 @@ _DrawFinalPass bmi :empty lda _Sprites+SPRITE_CLIP_TOP,x ; Load the first object's top edge -; sta :curr_top beq :loop ; If it's at the top edge of the screen, proceed. Othrewise _BltRange the top range ldx #0 @@ -761,6 +705,7 @@ _DrawFinalPass tax ldy _Sprites+SPRITE_CLIP_TOP,x ; Draw the background in between ldx :curr_bottom +; brk $34 jsr _BltRange plx bra :loop @@ -804,6 +749,8 @@ _DrawFinalPass adc ScreenX0 ldx :curr_top ldy :curr_bottom +; brk $33 + :disp jsl $000000 rts @@ -826,8 +773,6 @@ _DrawComplementList lda _DirectListTop,x ldy _DirectListBottom,x tax -; lda #0 -; jsr DebugSCBs jsr _BltRange plx @@ -841,8 +786,6 @@ _DrawComplementList phx ldy _DirectListTop,x tax -; lda #1 -; jsr DebugSCBs jsr _PEISlam plx bra :blt_range @@ -852,13 +795,11 @@ _DrawComplementList bcs :out ; screen, then expose that range tax ldy ScreenHeight -; lda #1 -; jsr DebugSCBs jsr _PEISlam :out rts -; Helper to set a palette index on a range of SCBs to help show whicih actions are applied to which lines +; Helper to set a palette index on a range of SCBs to help show which actions are applied to which lines DebugSCBs phx phy diff --git a/src/blitter/BG1.s b/src/blitter/BG1.s index 0fb7ecd..4891fb6 100644 --- a/src/blitter/BG1.s +++ b/src/blitter/BG1.s @@ -22,7 +22,8 @@ _CopyBinToBG1 sta :src_width lda #208 sta :src_height - stz :src_flags + lda #COPY_PIC_NORMAL + sta :src_flags pla jmp _CopyToBG1 @@ -31,7 +32,7 @@ _CopyBinToBG1 ; ; A = mode ; 0 = default (base = $1800, stride = 256) -; 1 = scanline (base = $A0, stride = 324) +; 1 = scanline (base = $0, stride = 327) _ResetBG1YTable :base equ tmp0 :stride equ tmp1 @@ -80,8 +81,9 @@ _CopyPicToBG1 sta :src_stride lda #200 sta :src_height + lda #COPY_PIC_NORMAL + sta :src_flags pla - stz :src_flags jmp _CopyToBG1 ; Generic routine to copy image data into BG1 @@ -104,15 +106,27 @@ _CopyToBG1 sty :dstptr+2 ; Everything goes into this bank sty :dstptr2+2 +; "Normal" BG1 mode as a stride of 164 bytes and mirrors the BG0 size (328 x 208) +; In "Scanline" mode, the BG1 is treated as a 328x200 bitfield with each horizontal line doubled + + lda :src_flags + cmp #COPY_PIC_NORMAL + bne *+5 + jmp :_CopyToBG1Normal + + cmp #COPY_PIC_SCANLINE + bne *+5 + jmp :_CopyToBG1SCanline + + rts ; Flag do not match a known copy mode + +:_CopyToBG1SCanline lda #0 ; Start a byte 1 because odd offsets might go back 1 byte and don't want to wrap around sta :dstptr clc adc #164 ; The first part is 1-byte short, the second part is a full 164 bytes sta :dstptr2 -; "Normal" BG1 mode as a stride of 164 bytes and mirrors the BG0 size (328 x 208) -; In "Scanline" mode, the BG1 is treated as a 320x200 bitfield with each horizontal line doubled - lda :src_width min #164 sta :src_width @@ -164,6 +178,49 @@ _CopyToBG1 bcc :rloop rts +:_CopyToBG1Normal + stz :line_cnt +:rloop2 + lda :line_cnt ; get the pointer to the code field line + asl + tax + + lda BG1YTable,x + sta :dstptr + clc + adc #164 + sta :dstptr2 + + ldy #0 ; move forward in the image data and image data +:cloop2 + lda [:srcptr],y + sta [:dstptr],y + + iny + iny + + cpy :src_width + bcc :cloop2 + + ldy #0 + lda [:dstptr],y ; Duplicate the last couple of words in the extra space at the end of the line + sta [:dstptr2],y + + ldy #2 + lda [:dstptr],y + sta [:dstptr2],y + + lda :srcptr + clc + adc :src_stride + sta :srcptr + + inc :line_cnt + lda :line_cnt + cmp :src_height + bcc :rloop2 + rts + _SetBG1XPos cmp BG1StartX beq :out ; Easy, if nothing changed, then nothing changes