Add horizontal scaling to the background rotation

This commit is contained in:
Lucas Scharenbroich 2022-07-22 02:01:34 -05:00
parent f7eb80f2fe
commit 18da2546bd
8 changed files with 170 additions and 18 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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

50
tools/mkscales.js Normal file
View File

@ -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;
}