iigs-game-engine/src/Actions.s

311 lines
8.6 KiB
ArmAsm

MoveLeft
clc
adc StartX ; Increment the virtual X-position
jsr SetBG0XPos
lda StartX
lsr
jsr SetBG1XPos
jsr DoFrame
rts
MoveRight
pha
lda StartX
sec
sbc 1,s
bpl *+5
lda #0
jsr SetBG0XPos
lda StartX
lsr
jsr SetBG1XPos
jsr DoFrame
pla
rts
MoveUp
clc
adc StartY ; Increment the virtual Y-position
jsr SetBG0YPos
lda StartY
lsr
jsr SetBG1YPos
jsr DoFrame
rts
MoveDown
pha
lda StartY
sec
sbc 1,s
bpl *+5
lda #0
jsr SetBG0YPos
lda StartY
lsr
jsr SetBG1YPos
jsr DoFrame
pla
rts
; Very simple, scroll as fast as possible
oldOneSecondCounter ds 2
frameCount ds 2
lastTick ds 2
Demo
lda OneSecondCounter
sta oldOneSecondCounter
stz frameCount
; Set a timer to fire every 16 ticks
; lda #6
; sta Timers
; sta Timers+2
; lda #UpdateBG1Rotation
; sta Timers+4
; Every 3 ticks (20 fps) cycle some colors
lda #3
sta Timers+8
sta Timers+10
lda #DoColorCycle
sta Timers+12
:loop
PushLong #0
_GetTick
pla
plx
cmp lastTick ; Throttle to 60 fps
beq :loop
tax ; Calculate the increment
sec
sbc lastTick
stx lastTick
; jsr _DoTimers
; lda #1
; jsr MoveLeft
jsr UpdateBG1Rotation
; jsr DoColorCycle
jsr DoFrame
inc frameCount
ldal KBD_STROBE_REG
bit #$0080
beq :nokey
and #$007F
cmp #'s'
bne :nokey
rts
:nokey
lda OneSecondCounter
cmp oldOneSecondCounter
beq :loop
sta oldOneSecondCounter
lda ScreenWidth
cmp #150
bcs :loop
lda #FPSStr
ldx #0 ; top-left corner
ldy #$7777
jsr DrawString
lda frameCount
ldx #4*4
jsr DrawWord
stz frameCount
bra :loop
FPSStr str 'FPS'
; Move some colors around color (6 - 11) address 12 - 22
DoColorCycle
ldal $E19E0C
pha
ldal $E19E0E
pha
ldal $E19E10
pha
ldal $E19E12
pha
ldal $E19E14
pha
ldal $E19E16
stal $E19E0C
pla
stal $E19E16
pla
stal $E19E14
pla
stal $E19E12
pla
stal $E19E10
pla
stal $E19E0E
rts
; Triggered timer to sway the background
UpdateBG1Offset
lda BG1OffsetIndex
inc
inc
cmp #32 ; 16 entries x 2 for indexing
bcc *+5
sbc #32
sta BG1OffsetIndex
rts
AngleUp
lda angle
inc
cmp #64
bcc *+5
sbc #64
sta angle
jsr _ApplyAngle
jsr DoFrame
rts
AngleDown
lda angle
dec
bpl *+6
clc
adc #64
sta angle
jsr _ApplyAngle
jsr DoFrame
rts
angle dw 0
UpdateBG1Rotation
jsr _ApplyAngle
; Increment the angle
lda angle
inc
cmp #64
bcc *+5
lda #0
sta angle
rts
x_angles EXT
y_angles EXT
_ApplyAngle
lda angle ; debug with angle = 0
asl
tax
ldal x_angles,x ; load the address of addressed for this angle
tay
phx
jsr _ApplyBG1XPosAngle
plx
ldal y_angles,x ; load the address of addresses for this angle
tay
jsr _ApplyBG1YPosAngle
rts
; A collection of 8 timers that are triggered when their countdown
; goes below zero. Each timer takes up 8 bytes
;
; A timer can fire multiple times during a singular evaluation. For example, if the
; timer delay is set to 1 and 3 VBL ticks happen, then the timer delta is -2, will fire,
; have the delay added and get -1, fire again, increment to zero, first again and then
; finally reset to 1.
;
; +0 counter decremented by the number of ticks since last run
; +2 reset copied into counter when triggered. 0 turns off the timer.
; +4 addr address of time routine
; +6 reserved
MAX_TIMERS equ 4
Timers ds 8*MAX_TIMERS
; Countdown the timers
;
; A = number of elapsed ticks
_DoTimers
pha
ldx #0
:loop
lda Timers,x ; A zero means do not fire
beq :skip
sec
sbc 1,s ; subtract the number of ticks
sta Timers,x
:retry beq :fire ; getting <= zero triggers
bpl :skip
:fire pha ; Save the counter
phx ; Save our index
jsr (Timers+4,x)
plx
pla
clc
adc Timers+2,x ; Add the increment
sta Timers,x ; Store in the count
bra :retry ; See if we have >0 ticks to wait until the next trigger
:skip txa
clc
adc #8
tax
cpx #8*MAX_TIMERS
bcc :loop
pla
rts