diff --git a/demos/kfest-2022/demo-10/App.Main.s b/demos/kfest-2022/demo-10/App.Main.s index 4aa5f8c..f963458 100644 --- a/demos/kfest-2022/demo-10/App.Main.s +++ b/demos/kfest-2022/demo-10/App.Main.s @@ -50,6 +50,7 @@ LastHFlip equ 48 SpriteFrame equ 50 SpriteToggle equ 52 SpriteCount equ 54 +Scale equ 56 phk plb @@ -72,6 +73,7 @@ SpriteCount equ 54 stz LastHFlip stz SpriteCount stz SpriteToggle + stz Scale ; Initialize the graphics screen playfield @@ -205,6 +207,17 @@ EvtLoop jsr handle_a pla :no_a + bit #PAD_KEY_DOWN + beq :reg_key + and #$007F + cmp #'s' + bne :reg_key + inc Scale + pei Scale + _GTESetBG1Scale + jmp do_render + +:reg_key and #$007F cmp #LEFT_ARROW bne *+5 diff --git a/macros/GTE.Macs.s b/macros/GTE.Macs.s index 2ca278b..e1cfcaa 100644 --- a/macros/GTE.Macs.s +++ b/macros/GTE.Macs.s @@ -120,6 +120,12 @@ _GTESetBG1Displacement MAC _GTESetBG1Rotation MAC UserTool $2900+GTEToolNum <<< +_GTEClearBG1Buffer MAC + UserTool $2A00+GTEToolNum + <<< +_GTESetBG1Scale MAC + UserTool $2B00+GTEToolNum + <<< ; EngineMode definitions ; Script definition @@ -145,6 +151,7 @@ ENGINE_MODE_BNK0_BUFF equ $0004 RENDER_ALT_BG1 equ $0001 RENDER_BG1_HORZ_OFFSET equ $0002 RENDER_BG1_VERT_OFFSET equ $0004 +RENDER_BG1_ROTATION equ $0008 ; Tile constants ; TILE_RESERVED_BIT equ $8000 diff --git a/src/Defs.s b/src/Defs.s index dc1ef27..5188195 100644 --- a/src/Defs.s +++ b/src/Defs.s @@ -98,7 +98,7 @@ LastTick equ 118 ForceSpriteFlag equ 120 SpriteRemovedFlag equ 122 ; Indicate if any sprites were removed this frame RenderFlags equ 124 ; Flags passed to the Render() function - +BG1Scaling equ 126 activeSpriteList equ 128 ; 32 bytes for the active sprite list (can persist across frames) ; tiletmp equ 178 ; 16 bytes of temp storage for the tile renderers @@ -170,6 +170,7 @@ ENGINE_MODE_BNK0_BUFF equ $0004 RENDER_ALT_BG1 equ $0001 RENDER_BG1_HORZ_OFFSET equ $0002 RENDER_BG1_VERT_OFFSET equ $0004 +RENDER_BG1_ROTATION equ $0008 ; DirtyBits definitions DIRTY_BIT_BG0_X equ $0001 @@ -263,6 +264,7 @@ VBuffVertTableSelect EXT VBuffHorzTableSelect EXT Overlays EXT BG1YCache EXT +ScalingTables EXT ; Tool error codes NO_TIMERS_AVAILABLE equ 10 diff --git a/src/Render.s b/src/Render.s index 240e04a..1836d9a 100644 --- a/src/Render.s +++ b/src/Render.s @@ -33,10 +33,16 @@ _Render stz SpriteRemovedFlag ; If we remove a sprite, then we need to flag a rebuild for the next frame jsr _ApplyBG0YPos ; Set stack addresses for the virtual lines to the physical screen -; jsr _ApplyBG1YPos + + lda #RENDER_BG1_ROTATION + bit RenderFlags + bne :skip_bg1_y + jsr _ApplyBG1YPos ; Set the y-register values of the blitter +:skip_bg1_y ; _ApplyBG0Xpos need to be split because we have to set the offsets, then draw in any updated tiles, and ; finally patch out the code field. Right now, the BRA operand is getting overwritten by tile data. + jsr _ApplyBG0XPosPre jsr _ApplyBG1XPosPre @@ -47,8 +53,12 @@ _Render jsr _ApplyTiles ; This function actually draws the new tiles into the code field - jsr _ApplyBG0XPos ; Patch the code field instructions with exit BRA opcode -; jsr _ApplyBG1XPos ; Update the direct page value based on the horizontal position + jsr _ApplyBG0XPos ; Patch the code field instructions with exit BRA opcode + lda #RENDER_BG1_ROTATION + bit RenderFlags + bne :skip_bg1_x + jsr _ApplyBG1XPos ; Update the direct page value based on the horizontal position +:skip_bg1_x ; 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. diff --git a/src/Tool.s b/src/Tool.s index 1e40d96..e49b645 100644 --- a/src/Tool.s +++ b/src/Tool.s @@ -93,6 +93,9 @@ _CallTable adrl _TSRenderDirty-1 adrl _TSSetBG1Displacement-1 adrl _TSSetBG1Rotation-1 + + adrl _TSClearBG1Buffer-1 + adrl _TSSetBG1Scale-1 _CTEnd _GTEAddSprite MAC UserTool $1000+GTEToolNum @@ -775,6 +778,20 @@ y_angles EXT _TSExit #0;#2 +_TSClearBG1Buffer +:value equ FirstParam+0 + _TSEntry + lda :value,s + jsr _ClearBG1Buffer + _TSExit #0;#2 + +_TSSetBG1Scale +:sIndex equ FirstParam+0 + _TSEntry + lda :value,s + sta BG1Scaling + _TSExit #0;#2 + ; Insert the GTE code put Math.s diff --git a/src/blitter/Rotation.s b/src/blitter/Rotation.s index 54ffb43..f797426 100644 --- a/src/blitter/Rotation.s +++ b/src/blitter/Rotation.s @@ -11,20 +11,29 @@ ANGLEBNK EXT _ApplyBG1XPosAngle +:ptr equ $FC +:stbl equ $FA phd ; save the direct page because we are going to switch to the - lda BlitterDP ; blitter direct page space and fill in the addresses - tcd + pei BlitterDP ; blitter direct page space and fill in the addresses + lda BG1Scaling + pld + + and #$000F + asl + tax + lda ScalingTables,x + sta :stbl lda #^ANGLEBNK - sta $fe - sty $fc ; Store in the new direct page - ldy #162 - tyx + sta :ptr+2 + sty :ptr ; Store in the new direct page + ldx #162 :loop - lda [$fc],y - sta 00,x ; store the value - dey - dey + txy + lda (:stbl),y ; Map the through the scaling factor + tay + lda [:ptr],y ; Load the underlying value + sta 00,x ; store the value dex dex bpl :loop @@ -37,9 +46,17 @@ _ApplyBG1YPosAngle :draw_count equ tmp2 :ytbl_idx equ tmp3 :angle_tbl equ tmp4 +:scale_ptr equ tmp5 sty :angle_tbl + lda BG1Scaling ; Set the scaling table + and #$0007 + asl + tax + lda ScalingTables,x + sta :scale_ptr + lda BG1StartYMod208 sta :ytbl_idx ; Start copying from the first entry in the table @@ -49,6 +66,10 @@ _ApplyBG1YPosAngle lda ScreenHeight sta :lines_left +; Copy out the y-values from the rotation table into a temporary buffer + +; Copy the rotation values into the code fields + phb :loop lda :virt_line @@ -111,13 +132,23 @@ _ApplyBG1YPosAngle ; Y = starting line * $1000 ; X = number of lines (x2) CopyAngleYTableToBG1Addr - +:ptr equ $FC +:stbl equ $FA ; tax ; ldal ANGLEBNK+XX,x ; sta BG1_ADDR+$F000,y + phy ; save y; used when writing phx + +; Scale the mapping + tay + + + + jsr SaveBG1AngleValues plx ; x is used directly in this routine + ply jmp ApplyBG1OffsetValues SaveBG1AngleValues diff --git a/src/static/TileStore.s b/src/static/TileStore.s index 789d8e5..772cb04 100644 --- a/src/static/TileStore.s +++ b/src/static/TileStore.s @@ -375,9 +375,6 @@ BG1YTable ENT ]step = ]step+256 --^ -BG1YCache ENT - ds 32 - ; Repeat BG1YOffsetTable ENT lup 2 @@ -512,5 +509,30 @@ _stamp_step ENT BG1YCache ENT ds 32 + +; Scaling tables for the BG1 rotation tables. +ScalingTables ENT + dw Scale0,Scale1,Scale2,Scale3 + dw Scale4,Scale5,Scale6,Scale7 + dw Scale8,Scale9,Scale10,Scale11 + dw Scale12,Scale13,Scale14,Scale15 + +Scale0 dw $0050,$0054,$0058,$005C,$0060,$0064,$0068,$006C,$0070,$0074,$0078,$007C,$0080,$0084,$0088,$008C,$0090,$0094,$0098,$009C,$00A0,$0002,$0006,$000A,$000E,$0012,$0016,$001A,$001E,$0022,$0026,$002A,$002E,$0032,$0036,$003A,$003E,$0042,$0046,$004A,$004E,$0052,$0056,$005A,$005E,$0062,$0066,$006A,$006E,$0072,$0076,$007A,$007E,$0082,$0086,$008A,$008E,$0092,$0096,$009A,$009E,$00A2,$0004,$0008,$000C,$0010,$0014,$0018,$001C,$0020,$0024,$0028,$002C,$0030,$0034,$0038,$003C,$0040,$0044,$0048,$004C,$0050 +Scale1 dw $0072,$0074,$0078,$007A,$007E,$0082,$0084,$0088,$008A,$008E,$0092,$0094,$0098,$009A,$009E,$0000,$0002,$0006,$0008,$000C,$000E,$0012,$0016,$0018,$001C,$001E,$0022,$0026,$0028,$002C,$002E,$0032,$0036,$0038,$003C,$003E,$0042,$0044,$0048,$004C,$004E,$0052,$0054,$0058,$005C,$005E,$0062,$0064,$0068,$006A,$006E,$0072,$0074,$0078,$007A,$007E,$0082,$0084,$0088,$008A,$008E,$0092,$0094,$0098,$009A,$009E,$00A0,$0002,$0006,$0008,$000C,$000E,$0012,$0016,$0018,$001C,$001E,$0022,$0026,$0028,$002C,$002E +Scale2 dw $0086,$0088,$008C,$008E,$0090,$0094,$0096,$0098,$009C,$009E,$00A0,$0002,$0004,$0006,$000A,$000C,$000E,$0012,$0014,$0016,$001A,$001C,$001E,$0022,$0024,$0026,$002A,$002C,$002E,$0032,$0034,$0036,$003A,$003C,$003E,$0042,$0044,$0046,$004A,$004C,$004E,$0052,$0054,$0056,$005A,$005C,$005E,$0062,$0064,$0066,$006A,$006C,$006E,$0072,$0074,$0076,$007A,$007C,$007E,$0082,$0084,$0086,$008A,$008C,$008E,$0092,$0094,$0096,$009A,$009C,$009E,$00A2,$0002,$0004,$0008,$000A,$000C,$0010,$0012,$0014,$0018,$001A +Scale3 dw $0094,$0098,$009A,$009C,$009E,$00A0,$0000,$0002,$0006,$0008,$000A,$000C,$000E,$0010,$0014,$0016,$0018,$001A,$001C,$001E,$0020,$0024,$0026,$0028,$002A,$002C,$002E,$0030,$0034,$0036,$0038,$003A,$003C,$003E,$0042,$0044,$0046,$0048,$004A,$004C,$004E,$0052,$0054,$0056,$0058,$005A,$005C,$005E,$0062,$0064,$0066,$0068,$006A,$006C,$0070,$0072,$0074,$0076,$0078,$007A,$007C,$0080,$0082,$0084,$0086,$0088,$008A,$008C,$0090,$0092,$0094,$0096,$0098,$009A,$009E,$00A0,$00A2,$0002,$0004,$0006,$0008,$000C +Scale4 dw $0000,$0002,$0004,$0006,$0008,$000A,$000C,$000E,$0010,$0012,$0014,$0016,$0018,$001A,$001C,$001E,$0020,$0022,$0024,$0026,$0028,$002A,$002C,$002E,$0030,$0032,$0034,$0036,$0038,$003A,$003C,$003E,$0040,$0042,$0044,$0046,$0048,$004A,$004C,$004E,$0050,$0052,$0054,$0056,$0058,$005A,$005C,$005E,$0060,$0062,$0064,$0066,$0068,$006A,$006C,$006E,$0070,$0072,$0074,$0076,$0078,$007A,$007C,$007E,$0080,$0082,$0084,$0086,$0088,$008A,$008C,$008E,$0090,$0092,$0094,$0096,$0098,$009A,$009C,$009E,$00A0,$00A2 +Scale5 dw $0008,$000A,$000C,$000E,$0010,$0010,$0012,$0014,$0016,$0018,$001A,$001C,$001E,$0020,$0020,$0022,$0024,$0026,$0028,$002A,$002C,$002E,$0030,$0030,$0032,$0034,$0036,$0038,$003A,$003C,$003E,$0040,$0040,$0042,$0044,$0046,$0048,$004A,$004C,$004E,$0050,$0050,$0052,$0054,$0056,$0058,$005A,$005C,$005E,$0060,$0060,$0062,$0064,$0066,$0068,$006A,$006C,$006E,$0070,$0070,$0072,$0074,$0076,$0078,$007A,$007C,$007E,$0080,$0080,$0082,$0084,$0086,$0088,$008A,$008C,$008E,$0090,$0090,$0092,$0094,$0096,$0098 +Scale6 dw $0010,$0010,$0012,$0014,$0016,$0018,$0018,$001A,$001C,$001E,$0020,$0020,$0022,$0024,$0026,$0028,$0028,$002A,$002C,$002E,$0030,$0030,$0032,$0034,$0036,$0038,$0038,$003A,$003C,$003E,$0040,$0040,$0042,$0044,$0046,$0048,$0048,$004A,$004C,$004E,$0050,$0050,$0052,$0054,$0056,$0058,$0058,$005A,$005C,$005E,$0060,$0060,$0062,$0064,$0066,$0068,$0068,$006A,$006C,$006E,$0070,$0070,$0072,$0074,$0076,$0078,$0078,$007A,$007C,$007E,$0080,$0080,$0082,$0084,$0086,$0088,$0088,$008A,$008C,$008E,$0090,$0090 +Scale7 dw $0016,$0016,$0018,$001A,$001A,$001C,$001E,$0020,$0020,$0022,$0024,$0026,$0026,$0028,$002A,$002A,$002C,$002E,$0030,$0030,$0032,$0034,$0036,$0036,$0038,$003A,$003A,$003C,$003E,$0040,$0040,$0042,$0044,$0046,$0046,$0048,$004A,$004A,$004C,$004E,$0050,$0050,$0052,$0054,$0056,$0056,$0058,$005A,$005A,$005C,$005E,$0060,$0060,$0062,$0064,$0066,$0066,$0068,$006A,$006A,$006C,$006E,$0070,$0070,$0072,$0074,$0076,$0076,$0078,$007A,$007A,$007C,$007E,$0080,$0080,$0082,$0084,$0086,$0086,$0088,$008A,$008A +Scale8 dw $001A,$001C,$001C,$001E,$0020,$0020,$0022,$0024,$0024,$0026,$0028,$0028,$002A,$002C,$002C,$002E,$0030,$0030,$0032,$0034,$0034,$0036,$0038,$0038,$003A,$003C,$003C,$003E,$0040,$0040,$0042,$0044,$0044,$0046,$0048,$0048,$004A,$004C,$004C,$004E,$0050,$0050,$0052,$0054,$0054,$0056,$0058,$0058,$005A,$005C,$005C,$005E,$0060,$0060,$0062,$0064,$0064,$0066,$0068,$0068,$006A,$006C,$006C,$006E,$0070,$0070,$0072,$0074,$0074,$0076,$0078,$0078,$007A,$007C,$007C,$007E,$0080,$0080,$0082,$0084,$0084,$0086 +Scale9 dw $0020,$0020,$0022,$0022,$0024,$0026,$0026,$0028,$0028,$002A,$002C,$002C,$002E,$002E,$0030,$0032,$0032,$0034,$0034,$0036,$0038,$0038,$003A,$003A,$003C,$003E,$003E,$0040,$0040,$0042,$0044,$0044,$0046,$0046,$0048,$004A,$004A,$004C,$004C,$004E,$0050,$0050,$0052,$0054,$0054,$0056,$0056,$0058,$005A,$005A,$005C,$005C,$005E,$0060,$0060,$0062,$0062,$0064,$0066,$0066,$0068,$0068,$006A,$006C,$006C,$006E,$006E,$0070,$0072,$0072,$0074,$0074,$0076,$0078,$0078,$007A,$007A,$007C,$007E,$007E,$0080,$0080 +Scale10 dw $0024,$0024,$0026,$0028,$0028,$002A,$002A,$002C,$002C,$002E,$002E,$0030,$0030,$0032,$0034,$0034,$0036,$0036,$0038,$0038,$003A,$003A,$003C,$003C,$003E,$0040,$0040,$0042,$0042,$0044,$0044,$0046,$0046,$0048,$0048,$004A,$004C,$004C,$004E,$004E,$0050,$0050,$0052,$0052,$0054,$0054,$0056,$0058,$0058,$005A,$005A,$005C,$005C,$005E,$005E,$0060,$0060,$0062,$0064,$0064,$0066,$0066,$0068,$0068,$006A,$006A,$006C,$006C,$006E,$0070,$0070,$0072,$0072,$0074,$0074,$0076,$0076,$0078,$0078,$007A,$007C,$007C +Scale11 dw $0028,$0028,$002A,$002A,$002C,$002C,$002E,$002E,$0030,$0030,$0032,$0032,$0034,$0034,$0036,$0036,$0038,$0038,$003A,$003A,$003C,$003C,$003E,$003E,$0040,$0040,$0042,$0042,$0044,$0044,$0046,$0046,$0048,$0048,$004A,$004A,$004C,$004C,$004E,$004E,$0050,$0050,$0052,$0052,$0054,$0054,$0056,$0056,$0058,$0058,$005A,$005A,$005C,$005C,$005E,$005E,$0060,$0060,$0062,$0062,$0064,$0064,$0066,$0066,$0068,$0068,$006A,$006A,$006C,$006C,$006E,$006E,$0070,$0070,$0072,$0072,$0074,$0074,$0076,$0076,$0078,$0078 +Scale12 dw $0030,$0030,$0032,$0032,$0032,$0034,$0034,$0036,$0036,$0036,$0038,$0038,$003A,$003A,$003A,$003C,$003C,$003E,$003E,$003E,$0040,$0040,$0042,$0042,$0042,$0044,$0044,$0046,$0046,$0046,$0048,$0048,$004A,$004A,$004A,$004C,$004C,$004E,$004E,$004E,$0050,$0050,$0052,$0052,$0052,$0054,$0054,$0056,$0056,$0056,$0058,$0058,$005A,$005A,$005A,$005C,$005C,$005E,$005E,$005E,$0060,$0060,$0062,$0062,$0062,$0064,$0064,$0066,$0066,$0066,$0068,$0068,$006A,$006A,$006A,$006C,$006C,$006E,$006E,$006E,$0070,$0070 +Scale13 dw $0036,$0036,$0036,$0038,$0038,$0038,$003A,$003A,$003A,$003C,$003C,$003C,$003E,$003E,$003E,$0040,$0040,$0040,$0042,$0042,$0042,$0044,$0044,$0044,$0046,$0046,$0046,$0048,$0048,$0048,$004A,$004A,$004A,$004C,$004C,$004C,$004E,$004E,$004E,$0050,$0050,$0050,$0052,$0052,$0052,$0054,$0054,$0054,$0056,$0056,$0056,$0058,$0058,$0058,$005A,$005A,$005A,$005C,$005C,$005C,$005E,$005E,$005E,$0060,$0060,$0060,$0062,$0062,$0062,$0064,$0064,$0064,$0066,$0066,$0066,$0068,$0068,$0068,$006A,$006A,$006A,$006C +Scale14 dw $0038,$003A,$003A,$003A,$003C,$003C,$003C,$003C,$003E,$003E,$003E,$0040,$0040,$0040,$0040,$0042,$0042,$0042,$0044,$0044,$0044,$0044,$0046,$0046,$0046,$0048,$0048,$0048,$0048,$004A,$004A,$004A,$004C,$004C,$004C,$004C,$004E,$004E,$004E,$0050,$0050,$0050,$0050,$0052,$0052,$0052,$0054,$0054,$0054,$0054,$0056,$0056,$0056,$0058,$0058,$0058,$0058,$005A,$005A,$005A,$005C,$005C,$005C,$005C,$005E,$005E,$005E,$0060,$0060,$0060,$0060,$0062,$0062,$0062,$0064,$0064,$0064,$0064,$0066,$0066,$0066,$0068 +Scale15 dw $003C,$003C,$003C,$003E,$003E,$003E,$003E,$0040,$0040,$0040,$0040,$0042,$0042,$0042,$0042,$0044,$0044,$0044,$0044,$0046,$0046,$0046,$0046,$0048,$0048,$0048,$0048,$004A,$004A,$004A,$004A,$004C,$004C,$004C,$004C,$004E,$004E,$004E,$004E,$0050,$0050,$0050,$0050,$0052,$0052,$0052,$0052,$0054,$0054,$0054,$0054,$0056,$0056,$0056,$0056,$0058,$0058,$0058,$0058,$005A,$005A,$005A,$005A,$005C,$005C,$005C,$005C,$005E,$005E,$005E,$005E,$0060,$0060,$0060,$0060,$0062,$0062,$0062,$0062,$0064,$0064,$0064 + blt_return stk_save \ No newline at end of file diff --git a/tools/mkscales.js b/tools/mkscales.js new file mode 100644 index 0000000..434d229 --- /dev/null +++ b/tools/mkscales.js @@ -0,0 +1,50 @@ +/** + * Generated data tables for BG1 scaling + */ +const RATIOS = [0.5, 0.63, 0.75, 0.87, 1.0, 1.125, 1.25, 1.375, 1.5, 1.66, 1.83, 2.0, 2.5, 3.0, 3.5, 4.0]; +const NUM_SCALES = RATIOS.length; + +main(process.argv.slice(2)).then( + () => process.exit(0), + (e) => { + console.error(e); + process.exit(1); + } +); + +function toHex(n) { + return '$' + n.toString(16).toUpperCase().padStart(4, '0'); +} + +async function main(argv) { + + const _ = console.log; + + for (let i = 0; i < NUM_SCALES; i += 1) { + const arr = gen_scale_table(RATIOS[i]).map(n => toHex(n)).join(','); + _(`Scale${i} dw ${arr}`); + } +} + +function gen_scale_table(ratio) { + // Take a bunch of values from 0 to 162 (82 total). Use the middle as a reference + // and scale out based on the (inverse) ratio, e.g. a ratio of 2 will double the pixels + const ref = Array.from({ length: 82 }, (_, i) => i * 2); + const center = 40.5; + const factor = 1. / ratio; + + const table = []; + for (let i = 0; i < 82; i++) { + + let index = 2 * Math.floor(center + (factor * (i - center))); + while (index < 0) { + index += 162; + } + while (index > 162) { + index -= 162; + } + table.push(index); + } + + return table; +}