From a7dad98d50c07194fae3d7b8292953b7db82c776 Mon Sep 17 00:00:00 2001 From: Lucas Scharenbroich Date: Mon, 27 Jun 2022 11:24:04 -0500 Subject: [PATCH] Additional tweaks to get old sprite demo working --- demos/shell/Overlay.s | 245 +++++++++++++++++++++++++++++++-------- demos/sprites/App.Main.s | 17 +-- src/CoreImpl.s | 3 - src/Defs.s | 1 + src/Render.s | 57 ++++++--- src/Tool.s | 49 +++++++- src/static/TileStore.s | 3 + 7 files changed, 301 insertions(+), 74 deletions(-) diff --git a/demos/shell/Overlay.s b/demos/shell/Overlay.s index e0a7b7d..ee3fb46 100644 --- a/demos/shell/Overlay.s +++ b/demos/shell/Overlay.s @@ -10,7 +10,27 @@ ; There are two subroutines that need to be implemented -- one to update the overlay content and a ; second to actually render to the screen -; Initialize the overlay be drawin gin static content that will not change over time +STATE_REG equ $E0C068 + +_R0W0 mac ; Read Bank 0 / Write Bank 0 + ldal STATE_REG + and #$FFCF + stal STATE_REG + <<< + +_R0W1 mac ; Read Bank 0 / Write Bank 1 + ldal STATE_REG + ora #$0010 + stal STATE_REG + <<< + +_R1W1 mac ; Read Bank 0 / Write Bank 1 + ldal STATE_REG + ora #$0030 + stal STATE_REG + <<< + +; Initialize the overlay be drawing in static content that will not change over time CHAR_TILE_BASE equ 193 ; set this to the real tile id that starts an ASCII run starting at '0' through 'Z' @@ -32,35 +52,57 @@ l_mask equ ovrly_mask MASK_OFFSET equ {ovrly_mask-ovrly_buff} +TileDataPtr equ $FC +TileMaskPtr equ $F8 + InitOverlay + + pha + pha + _GTEGetTileDataAddr + pla + sta TileDataPtr + clc + adc #32 + sta TileMaskPtr + pla + sta TileDataPtr+2 + sta TileMaskPtr+2 + lda #'F' - ldy #l_line+{CHAR_WIDTH*0} + ldx #l_line+{CHAR_WIDTH*0} jsr _DrawChar lda #'P' - ldy #l_line+{CHAR_WIDTH*1} + ldx #l_line+{CHAR_WIDTH*1} jsr _DrawChar lda #'S' - ldy #l_line+{CHAR_WIDTH*2} + ldx #l_line+{CHAR_WIDTH*2} jsr _DrawChar lda #':' - ldy #l_line+{CHAR_WIDTH*3} + ldx #l_line+{CHAR_WIDTH*3} jsr _DrawChar lda #'T' - ldy #r_line+{CHAR_WIDTH*0} + ldx #r_line+{CHAR_WIDTH*0} jsr _DrawChar lda #'I' - ldy #r_line+{CHAR_WIDTH*1} + ldx #r_line+{CHAR_WIDTH*1} jsr _DrawChar lda #'C' - ldy #r_line+{CHAR_WIDTH*2} + ldx #r_line+{CHAR_WIDTH*2} jsr _DrawChar lda #'K' - ldy #r_line+{CHAR_WIDTH*3} + ldx #r_line+{CHAR_WIDTH*3} jsr _DrawChar lda #':' - ldy #r_line+{CHAR_WIDTH*4} + ldx #r_line+{CHAR_WIDTH*4} jsr _DrawChar + + pea $0000 + pea $0008 + pea #^StatusBar + pea #StatusBar + _GTESetOverlay rts ; Update the dynamic content of the overlay @@ -79,8 +121,8 @@ UdtOverlay lda frameCount ; render the FPS value xba jsr _num2ascii - ldy #l_line+{CHAR_WIDTH*4} - jsr _DrawChar + ldx #l_line+{CHAR_WIDTH*4} + jsr _DrawChar lda frameCount lsr @@ -88,44 +130,52 @@ UdtOverlay lsr lsr jsr _num2ascii - ldy #l_line+{CHAR_WIDTH*5} + ldx #l_line+{CHAR_WIDTH*5} jsr _DrawChar lda frameCount jsr _num2ascii - ldy #l_line+{CHAR_WIDTH*6} + ldx #l_line+{CHAR_WIDTH*6} jsr _DrawChar - ldal OneSecondCounter ; reder the number of remaining seconds + pha + _GTEGetSeconds + pla + sta oneSecondCounter ; render the number of remaining seconds xba jsr _num2ascii - ldy #r_line+{CHAR_WIDTH*5} + ldx #r_line+{CHAR_WIDTH*5} jsr _DrawChar - ldal OneSecondCounter + lda oneSecondCounter lsr lsr lsr lsr jsr _num2ascii - ldy #r_line+{CHAR_WIDTH*6} + ldx #r_line+{CHAR_WIDTH*6} jsr _DrawChar - ldal OneSecondCounter + lda oneSecondCounter jsr _num2ascii - ldy #r_line+{CHAR_WIDTH*7} - jsr _DrawChar + ldx #r_line+{CHAR_WIDTH*7} + jsr _DrawChar rts +oneSecondCounter ds 2 + ; Draw the overlay ; A = address of the left edge of the screen -Overlay ENT - phb ; Called via JSL +StatusBar phb ; Called via JSL + phd ; save the direct page register + phk plb - phd ; save the direct page register + ldx MyDirectPage ; Preserve the accumulator + phx + pld sta l_addr ; save this value (will go into D-reg later) clc @@ -144,12 +194,12 @@ Overlay ENT sec sbc m_addr ; calculate the number of words between the two ends and #$FFFE - pha - lda #m_end - sec - sbc 1,s + + eor #$FFFF + inc + clc + adc #m_end sta m_patch+1 - pla sei _R1W1 @@ -192,7 +242,7 @@ l_ovrly_rtn _R0W0 cli -:exit +o_exit pld ; restore the direct page and bank and return plb rtl @@ -201,7 +251,6 @@ l_addr ds 2 m_addr ds 2 r_addr ds 2 - r_ovrly ]idx equ 0 lup R_CHAR_COUNT @@ -247,10 +296,7 @@ m_end ; ; A = Tile ID ; Y = overlay address location -tiledata EXT - _DCOut rts - _DrawChar cmp #'0' bcc _DCOut @@ -261,19 +307,122 @@ _DrawChar sbc #'0' clc adc #CHAR_TILE_BASE - jsl GetTileAddr - tax + jsr _GetTileAddr + tay -]idx equ 0 - lup 8 - ldal tiledata+32+{]idx*4},x - sta: {]idx*OVRLY_SPAN}+MASK_OFFSET,y - ldal tiledata+{]idx*4},x - sta: {]idx*OVRLY_SPAN},y - ldal tiledata+32+{]idx*4}+2,x - sta: {]idx*OVRLY_SPAN}+MASK_OFFSET+2,y - ldal tiledata+{]idx*4}+2,x - sta: {]idx*OVRLY_SPAN}+2,y -]idx equ ]idx+1 - --^ + lda [TileMaskPtr],y + sta: {0*OVRLY_SPAN}+MASK_OFFSET,x + lda [TileDataPtr],y + sta: {0*OVRLY_SPAN},x + iny + iny + lda [TileMaskPtr],y + sta: {0*OVRLY_SPAN}+MASK_OFFSET+2,x + lda [TileDataPtr],y + sta: {0*OVRLY_SPAN}+2,x + iny + iny + + lda [TileMaskPtr],y + sta: {1*OVRLY_SPAN}+MASK_OFFSET,x + lda [TileDataPtr],y + sta: {1*OVRLY_SPAN},x + iny + iny + lda [TileMaskPtr],y + sta: {1*OVRLY_SPAN}+MASK_OFFSET+2,x + lda [TileDataPtr],y + sta: {1*OVRLY_SPAN}+2,x + iny + iny + + lda [TileMaskPtr],y + sta: {2*OVRLY_SPAN}+MASK_OFFSET,x + lda [TileDataPtr],y + sta: {2*OVRLY_SPAN},x + iny + iny + lda [TileMaskPtr],y + sta: {2*OVRLY_SPAN}+MASK_OFFSET+2,x + lda [TileDataPtr],y + sta: {2*OVRLY_SPAN}+2,x + iny + iny + + lda [TileMaskPtr],y + sta: {3*OVRLY_SPAN}+MASK_OFFSET,x + lda [TileDataPtr],y + sta: {3*OVRLY_SPAN},x + iny + iny + lda [TileMaskPtr],y + sta: {3*OVRLY_SPAN}+MASK_OFFSET+2,x + lda [TileDataPtr],y + sta: {3*OVRLY_SPAN}+2,x + iny + iny + + lda [TileMaskPtr],y + sta: {4*OVRLY_SPAN}+MASK_OFFSET,x + lda [TileDataPtr],y + sta: {4*OVRLY_SPAN},x + iny + iny + lda [TileMaskPtr],y + sta: {4*OVRLY_SPAN}+MASK_OFFSET+2,x + lda [TileDataPtr],y + sta: {4*OVRLY_SPAN}+2,x + iny + iny + + lda [TileMaskPtr],y + sta: {5*OVRLY_SPAN}+MASK_OFFSET,x + lda [TileDataPtr],y + sta: {5*OVRLY_SPAN},x + iny + iny + lda [TileMaskPtr],y + sta: {5*OVRLY_SPAN}+MASK_OFFSET+2,x + lda [TileDataPtr],y + sta: {5*OVRLY_SPAN}+2,x + iny + iny + + lda [TileMaskPtr],y + sta: {6*OVRLY_SPAN}+MASK_OFFSET,x + lda [TileDataPtr],y + sta: {6*OVRLY_SPAN},x + iny + iny + lda [TileMaskPtr],y + sta: {6*OVRLY_SPAN}+MASK_OFFSET+2,x + lda [TileDataPtr],y + sta: {6*OVRLY_SPAN}+2,x + iny + iny + + lda [TileMaskPtr],y + sta: {7*OVRLY_SPAN}+MASK_OFFSET,x + lda [TileDataPtr],y + sta: {7*OVRLY_SPAN},x + iny + iny + lda [TileMaskPtr],y + sta: {7*OVRLY_SPAN}+MASK_OFFSET+2,x + lda [TileDataPtr],y + sta: {7*OVRLY_SPAN}+2,x + + rts + +_GetTileAddr + asl ; Multiply by 2 + bit #2*TILE_HFLIP_BIT ; Check if the horizontal flip bit is set + beq :no_flip + inc ; Set the LSB +:no_flip asl ; x4 + asl ; x8 + asl ; x16 + asl ; x32 + asl ; x64 + asl ; x128 rts \ No newline at end of file diff --git a/demos/sprites/App.Main.s b/demos/sprites/App.Main.s index e2f9747..f5d042f 100644 --- a/demos/sprites/App.Main.s +++ b/demos/sprites/App.Main.s @@ -38,6 +38,9 @@ ScreenHeight equ 14 plb sta MyUserId ; GS/OS passes the memory manager user ID for the application into the program + tdc + sta MyDirectPage ; Keep a copy for the overlay callback + _MTStartUp ; GTE requires the miscellaneous toolset to be running jsr GTEStartUp ; Load and install the GTE User Tool @@ -68,17 +71,16 @@ ScreenHeight equ 14 ; Set up our level data jsr BG0SetUp - jsr TileAnimInit jsr SetLimits -; jsr InitOverlay ; Initialize the status bar + jsr InitOverlay ; Initialize the status bar stz frameCount pha _GTEGetSeconds pla sta oldOneSecondCounter -; jsr UdtOverlay + jsr UdtOverlay ; Allocate a buffer for loading files jsl AllocBank ; Alloc 64KB for Load/Unpack @@ -349,7 +351,7 @@ EvtLoop cmp oldOneSecondCounter beq :noudt sta oldOneSecondCounter -; jsr UdtOverlay + jsr UdtOverlay stz frameCount :noudt brl EvtLoop @@ -400,6 +402,7 @@ MaxBG0Y ds 2 oldOneSecondCounter ds 2 frameCount ds 2 MyUserId ds 2 +MyDirectPage ds 2 PLAYER_X_MIN equ 0 PLAYER_X_MAX equ 160-4 @@ -783,6 +786,6 @@ _GetVBLTicks plx rts -; PUT ../shell/Overlay.s - PUT gen/App.TileMapBG0.s - PUT gen/App.TileSetAnim.s + PUT ../shell/Overlay.s + PUT gen/App.TileMapBG0.s + PUT gen/App.TileSetAnim.s diff --git a/src/CoreImpl.s b/src/CoreImpl.s index a514c03..fc1dd8c 100644 --- a/src/CoreImpl.s +++ b/src/CoreImpl.s @@ -71,9 +71,6 @@ TileStore EXT spritedata EXT spritemask EXT -; If there are overlays, they are provided as an external -Overlay EXT - ; Core engine functionality. The idea is that that source file can be PUT into ; a main source file and all of the functionality will be available. ; diff --git a/src/Defs.s b/src/Defs.s index 5d08b47..0ef0580 100644 --- a/src/Defs.s +++ b/src/Defs.s @@ -254,6 +254,7 @@ VBuffArray EXT _stamp_step EXT VBuffVertTableSelect EXT VBuffHorzTableSelect EXT +Overlays EXT ; Tool error codes NO_TIMERS_AVAILABLE equ 10 diff --git a/src/Render.s b/src/Render.s index 618211b..2a322f0 100644 --- a/src/Render.s +++ b/src/Render.s @@ -42,37 +42,47 @@ _Render jsr _ApplyBG0XPos ; Patch the code field instructions with exit BRA opcode jsr _ApplyBG1XPos ; Update the direct page value based on the horizontal position -; The code fields are locked in now and ready to be rendered +; 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. -; jsr _ShadowOff + 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 #0 ; Blit the full virtual buffer to the screen -; ldy #8 -; jsr _BltRange + ldx Overlays+2 ; Blit the full virtual buffer to the screen + ldy Overlays+4 + jsr _BltRange ; Turn shadowing back on -; jsr _ShadowOn + jsr _ShadowOn ; Now render all of the remaining lines in top-to-bottom (or bottom-to-top) order -; lda ScreenY0 ; pass the address of the first line of the overlay -; clc -; adc #0 -; asl -; tax -; lda ScreenAddr,x -; clc -; adc ScreenX0 -; jsl Overlay + 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 @@ -102,6 +112,23 @@ _Render :no_removal rts +_DoOverlay + lda Overlays+6 + stal :disp+1 + lda Overlays+7 + stal :disp+2 + + lda ScreenY0 ; pass the address of the first line of the overlay + clc + adc Overlays+2 + asl + tax + lda ScreenAddr,x + clc + adc ScreenX0 +:disp jsl $000000 + rts + ; The _ApplyTilesFast is the same as _ApplyTiles, but we use the _RenderTileFast subroutine _ApplyTilesFast ldx DirtyTileCount diff --git a/src/Tool.s b/src/Tool.s index 118c018..9e00188 100644 --- a/src/Tool.s +++ b/src/Tool.s @@ -83,6 +83,11 @@ _CallTable adrl _TSAddTimer-1 adrl _TSRemoveTimer-1 adrl _TSStartScript-1 + + adrl _TSSetOverlay-1 + adrl _TSClearOverlay-1 + + adrl _TSGetTileDataAddr-1 _CTEnd _GTEAddSprite MAC UserTool $1000+GTEToolNum @@ -472,7 +477,6 @@ _TSGetScreenInfo sta :x,s lda ScreenY0 sta :y,s - sta :width,s lda ScreenWidth sta :width,s lda ScreenHeight @@ -615,6 +619,49 @@ _TSStartScript jsr _StartScript _TSExit #0;#6 +; SetOverlay(top, bottom, proc) +_TSSetOverlay +:proc equ FirstParam+0 +:bottom equ FirstParam+4 +:top equ FirstParam+6 + + _TSEntry + + lda #1 + sta Overlays + lda :top,s + sta Overlays+2 + lda :bottom,s + sta Overlays+4 + lda :proc,s + sta Overlays+6 + lda :proc+2,s + sta Overlays+8 + + _TSExit #0;#8 + +; ClearOverlay() +_TSClearOverlay + + _TSEntry + + lda #0 + sta Overlays + + _TSExit #0;#0 + +; GetTileDataAddr() +_TSGetTileDataAddr +:output equ FirstParam+0 + + _TSEntry + + lda #tiledata + sta :output,s + lda #^tiledata + sta :output+2,s + + _TSExit #0;#0 ; Insert the GTE code diff --git a/src/static/TileStore.s b/src/static/TileStore.s index 7b13242..06c218c 100644 --- a/src/static/TileStore.s +++ b/src/static/TileStore.s @@ -388,6 +388,9 @@ OldOneSecVec ENT ds 4 Timers ENT ds TIMER_REC_SIZE*MAX_TIMERS +Overlays ENT + dw 0 ; count + ds 8 ; only support one or now (start_line, end_line, function call) ; From the IIgs ref DefaultPalette ENT