mirror of
https://github.com/lscharen/iigs-game-engine.git
synced 2024-06-04 21:29:27 +00:00
221 lines
8.5 KiB
ArmAsm
221 lines
8.5 KiB
ArmAsm
; Support rotating the BG1 graphics by leveraging the fact that a rotation function can be decomposed
|
|
; into an addition of two function parametertized by the angle of rotation: pixel = *(f(x, a) + f(y, a))
|
|
;
|
|
; The pre-build a number of rotation tables and then populate the direct page values and Y-register values
|
|
; for each line of the blitter, such that a single lda (00),y instruction fetched the appropriate data
|
|
;
|
|
; This is about as fast of a rotation as we can do.
|
|
;
|
|
; When possible, off-screen locations are calculate to produce an address of $FFFE, so that the last two bytes
|
|
; of the BG1 data buffer provides the "fill value".
|
|
|
|
ANGLEBNK ext
|
|
_ApplyBG1XPosAngle
|
|
; phy
|
|
|
|
; lda BG1StartX
|
|
; jsr Mod164
|
|
; sta BG1StartXMod164
|
|
|
|
; lda #162
|
|
; sec
|
|
; sbc StartXMod164
|
|
; bpl *+6
|
|
; clc
|
|
; adc #164
|
|
; clc
|
|
; adc BG1StartXMod164
|
|
; cmp #164
|
|
; bcc *+5
|
|
; sbc #164
|
|
|
|
; clc
|
|
; adc 1,s
|
|
; tay ; cache the value
|
|
|
|
; pla ; pop the value
|
|
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
|
|
|
|
lda #^ANGLEBNK
|
|
sta $fe
|
|
sty $fc ; Store in the new direct page
|
|
ldy #162
|
|
tyx
|
|
:loop
|
|
lda [$fc],y
|
|
sta 00,x ; store the value
|
|
dey
|
|
dey
|
|
dex
|
|
dex
|
|
bpl :loop
|
|
pld
|
|
rts
|
|
|
|
_ApplyBG1YPosAngle
|
|
:virt_line equ tmp0
|
|
:lines_left equ tmp1
|
|
:draw_count equ tmp2
|
|
:ytbl_idx equ tmp3
|
|
:angle_tbl equ tmp4
|
|
|
|
sty :angle_tbl
|
|
|
|
lda BG1StartY
|
|
jsr Mod208
|
|
sta BG1StartYMod208
|
|
sta :ytbl_idx ; Start copying from the first entry in the table
|
|
|
|
lda StartYMod208 ; This is the base line of the virtual screen
|
|
sta :virt_line ; Keep track of it
|
|
|
|
lda ScreenHeight
|
|
sta :lines_left
|
|
|
|
phb
|
|
:loop
|
|
lda :virt_line
|
|
asl
|
|
tax
|
|
ldal BTableLow,x ; Get the address of the first code field line
|
|
tay
|
|
|
|
sep #$20
|
|
ldal BTableHigh,x
|
|
pha ; push the bank on the stack
|
|
plb
|
|
rep #$20
|
|
|
|
lda :virt_line
|
|
and #$000F
|
|
eor #$FFFF
|
|
inc
|
|
clc
|
|
adc #16
|
|
min :lines_left
|
|
|
|
sta :draw_count ; Do this many lines
|
|
asl
|
|
tax
|
|
|
|
lda :ytbl_idx ; Read from this location (duplicate every 4 lines)
|
|
lsr
|
|
lsr
|
|
asl
|
|
clc
|
|
adc :angle_tbl
|
|
sec
|
|
sbc #ANGLEBNK
|
|
jsr CopyAngleYTableToBG1Addr ; or CopyBG1YTableToBG1Addr2
|
|
|
|
lda :virt_line ; advance to the virtual line after the segment we just
|
|
clc ; filled in
|
|
adc :draw_count
|
|
sta :virt_line
|
|
|
|
lda :ytbl_idx ; advance the index into the YTable
|
|
adc :draw_count
|
|
sta :ytbl_idx
|
|
|
|
lda :lines_left ; subtract the number of lines we just completed
|
|
sec
|
|
sbc :draw_count
|
|
sta :lines_left
|
|
|
|
jne :loop
|
|
|
|
plb
|
|
rts
|
|
|
|
; Unrolled copy routine to move y_angle entries into BG1_ADDR position with an additional
|
|
; shift. This has to be split into two
|
|
;
|
|
; A = index into the array (x2)
|
|
; Y = starting line * $1000
|
|
; X = number of lines (x2)
|
|
CopyAngleYTableToBG1Addr
|
|
phx
|
|
phb
|
|
|
|
|
|
jsr _SetDataBank ; restore access to this bank
|
|
jsr SaveBG1AngleValues
|
|
|
|
plb
|
|
plx ; x is used directly in this routine
|
|
jmp ApplyBG1OffsetValues
|
|
|
|
SaveBG1AngleValues
|
|
jmp (:tbl,x)
|
|
:tbl da :none
|
|
da :do01,:do02,:do03,:do04
|
|
da :do05,:do06,:do07,:do08
|
|
da :do09,:do10,:do11,:do12
|
|
da :do13,:do14,:do15,:do16
|
|
:do15 tax
|
|
bra :x15
|
|
:do14 tax
|
|
bra :x14
|
|
:do13 tax
|
|
bra :x13
|
|
:do12 tax
|
|
bra :x12
|
|
:do11 tax
|
|
bra :x11
|
|
:do10 tax
|
|
bra :x10
|
|
:do09 tax
|
|
bra :x09
|
|
:do08 tax
|
|
bra :x08
|
|
:do16 tax
|
|
ldal ANGLEBNK+06,x
|
|
sta BG1YCache+30
|
|
:x15 ldal ANGLEBNK+06,x
|
|
sta BG1YCache+28
|
|
:x14 ldal ANGLEBNK+06,x
|
|
sta BG1YCache+26
|
|
:x13 ldal ANGLEBNK+06,x
|
|
sta BG1YCache+24
|
|
:x12 ldal ANGLEBNK+04,x
|
|
sta BG1YCache+22
|
|
:x11 ldal ANGLEBNK+04,x
|
|
sta BG1YCache+20
|
|
:x10 ldal ANGLEBNK+04,x
|
|
sta BG1YCache+18
|
|
:x09 ldal ANGLEBNK+04,x
|
|
sta BG1YCache+16
|
|
:x08 ldal ANGLEBNK+02,x
|
|
sta BG1YCache+14
|
|
:x07 ldal ANGLEBNK+02,x
|
|
sta BG1YCache+12
|
|
:x06 ldal ANGLEBNK+02,x
|
|
sta BG1YCache+10
|
|
:x05 ldal ANGLEBNK+02,x
|
|
sta BG1YCache+08
|
|
:x04 ldal ANGLEBNK+00,x
|
|
sta BG1YCache+06
|
|
:x03 ldal ANGLEBNK+00,x
|
|
sta BG1YCache+04
|
|
:x02 ldal ANGLEBNK+00,x
|
|
sta BG1YCache+02
|
|
:x01 ldal ANGLEBNK+00,x
|
|
sta BG1YCache+00
|
|
:none rts
|
|
:do07 tax
|
|
bra :x07
|
|
:do06 tax
|
|
bra :x06
|
|
:do05 tax
|
|
bra :x05
|
|
:do04 tax
|
|
bra :x04
|
|
:do03 tax
|
|
bra :x03
|
|
:do02 tax
|
|
bra :x02
|
|
:do01 tax
|
|
bra :x01
|