mirror of
https://github.com/jmechner/Prince-of-Persia-Apple-II.git
synced 2024-06-10 02:29:31 +00:00
1 line
28 KiB
ArmAsm
Executable File
1 line
28 KiB
ArmAsm
Executable File
* mover
|
|
org = $ee00
|
|
PalaceEditor = 0
|
|
tr on
|
|
lst off
|
|
*-------------------------------
|
|
org org
|
|
|
|
jmp ANIMTRANS
|
|
jmp TRIGSPIKES
|
|
jmp PUSHPP
|
|
jmp BREAKLOOSE1
|
|
jmp BREAKLOOSE
|
|
|
|
jmp ANIMMOBS
|
|
jmp ADDMOBS
|
|
jmp CLOSEEXIT
|
|
jmp GETSPIKES
|
|
jmp SHAKEM
|
|
|
|
jmp TRIGSLICER
|
|
jmp TRIGTORCH
|
|
jmp GETFLAMEFRAME
|
|
jmp SMASHMIRROR
|
|
jmp JAMSPIKES
|
|
|
|
jmp TRIGFLASK
|
|
jmp GETFLASKFRAME
|
|
jmp TRIGSWORD
|
|
jmp JAMPP
|
|
|
|
*-------------------------------
|
|
lst
|
|
put eq
|
|
lst
|
|
put gameeq
|
|
lst
|
|
put seqdata
|
|
lst
|
|
put movedata
|
|
lst
|
|
put soundnames
|
|
|
|
dum locals
|
|
state ds 1
|
|
temp1 ds 2
|
|
linkindex ds 1
|
|
pptype ds 1
|
|
mobframe ds 1
|
|
underFF ds 1
|
|
dend
|
|
|
|
*-------------------------------
|
|
gatevel db 0,0,0,20,40,60,80,100,120
|
|
|
|
maxgatevel = *-gatevel-1
|
|
|
|
*-------------------------------
|
|
pptimer = 5 ;pressplate timer setting (min=3, max=30)
|
|
;(# cycles till plate pops up)
|
|
|
|
spiketimer = 15+128 ;spike timer setting (2-127) +128
|
|
;(# cycles till spikes retract)
|
|
|
|
slicetimer = 15 ;# cycles between slices
|
|
|
|
gatetimer = gmaxval+50 ;# cycles gate stays open
|
|
|
|
loosetimer = Ffalling ;# cycles till floor detaches
|
|
|
|
* falling floor params
|
|
|
|
wiggletime = 4 ;# wiggling frames
|
|
FFaccel = 3
|
|
FFtermvel = 29
|
|
crumbletime = 2 ;# crumbling frames
|
|
crumbletime2 = 10
|
|
disappeartime = 2
|
|
FFheight = 17
|
|
CrushDist = 30
|
|
|
|
* wipe heights
|
|
|
|
loosewipe = 31 ;[might erase spikes]
|
|
spikewipe = 31
|
|
slicerwipe = 63
|
|
platewipe = 16
|
|
|
|
gateinc db -1,4,4 ;for trdirec = 0,1,2 (down,up,upjam)
|
|
|
|
exitinc = 4
|
|
emaxval = 43*4
|
|
|
|
maxtr = trobspace-1
|
|
maxmob = mobspace-1
|
|
|
|
*-------------------------------
|
|
*
|
|
* Search trans list for object (trloc,trscrn)
|
|
*
|
|
* In: numtrans, trloc, trscrn
|
|
* Out: X = index, 0 if not listed
|
|
*
|
|
*-------------------------------
|
|
searchtrob
|
|
ldx numtrans
|
|
beq :rts
|
|
|
|
:loop lda trloc,x
|
|
cmp trloc
|
|
bne :next
|
|
lda trscrn,x
|
|
cmp trscrn
|
|
beq :rts ;found it
|
|
|
|
:next dex
|
|
bne :loop
|
|
|
|
:rts rts
|
|
|
|
*-------------------------------
|
|
*
|
|
* Add a new object to transition list
|
|
* If it's already listed, just change trdirec to new value
|
|
*
|
|
* In: trdirec, trloc, trscrn
|
|
*
|
|
*-------------------------------
|
|
addtrob
|
|
jsr searchtrob ;Is object already listed?
|
|
|
|
cpx #0
|
|
bne :chdir ;Yes--just change direc
|
|
|
|
* It's not on the list - add it
|
|
|
|
ldx numtrans
|
|
cpx #maxtr
|
|
beq :rts ;too many objects--trigger fails
|
|
|
|
inx
|
|
stx numtrans
|
|
|
|
lda trdirec
|
|
sta trdirec,x
|
|
lda trloc
|
|
sta trloc,x
|
|
lda trscrn
|
|
sta trscrn,x
|
|
rts
|
|
|
|
* Object already listed - change direction
|
|
|
|
:chdir lda trdirec
|
|
sta trdirec,x
|
|
:rts rts
|
|
|
|
*-------------------------------
|
|
*
|
|
* Add a MOB to MOB list
|
|
*
|
|
*-------------------------------
|
|
addamob
|
|
ldx nummob
|
|
cpx #maxmob
|
|
beq :rts
|
|
|
|
inx
|
|
stx nummob
|
|
|
|
jmp savemob
|
|
|
|
:rts rts
|
|
|
|
*-------------------------------
|
|
*
|
|
* S A V E / L O A D M O B
|
|
*
|
|
*-------------------------------
|
|
savemob
|
|
lda mobx
|
|
sta mobx,x
|
|
lda moby
|
|
sta moby,x
|
|
lda mobscrn
|
|
sta mobscrn,x
|
|
lda mobvel
|
|
sta mobvel,x
|
|
lda mobtype
|
|
sta mobtype,x
|
|
lda moblevel
|
|
sta moblevel,x
|
|
rts
|
|
|
|
loadmob
|
|
lda mobx,x
|
|
sta mobx
|
|
lda moby,x
|
|
sta moby
|
|
lda mobscrn,x
|
|
sta mobscrn
|
|
lda mobvel,x
|
|
sta mobvel
|
|
lda mobtype,x
|
|
sta mobtype
|
|
lda moblevel,x
|
|
sta moblevel
|
|
]rts rts
|
|
|
|
*-------------------------------
|
|
*
|
|
* Trigger slicer
|
|
*
|
|
* In: A = initial state
|
|
*
|
|
*-------------------------------
|
|
TRIGSLICER
|
|
sta state ;temp
|
|
|
|
lda (BlueSpec),y
|
|
beq :ok
|
|
cmp #slicerRet
|
|
bcc ]rts ;in mid-slice--don't interfere
|
|
|
|
* Between slices--OK to trigger
|
|
|
|
:ok sty trloc
|
|
|
|
lda state
|
|
sta (BlueSpec),y
|
|
|
|
lda VisScrn
|
|
sta trscrn
|
|
|
|
lda #1
|
|
sta trdirec
|
|
|
|
jmp addtrob ;add slicer to trans list
|
|
|
|
*-------------------------------
|
|
*
|
|
* Close exit
|
|
* (Open it all the way & let it slam shut)
|
|
*
|
|
*-------------------------------
|
|
CLOSEEXIT
|
|
sty trloc
|
|
sta trscrn
|
|
|
|
lda #emaxval ;all the way open
|
|
sta (BlueSpec),y
|
|
|
|
lda #3 ;coming down fast
|
|
sta trdirec
|
|
|
|
jmp addtrob ;add to trans list
|
|
|
|
*-------------------------------
|
|
SMASHMIRROR
|
|
lda #86
|
|
sta (BlueSpec),y
|
|
]rts rts
|
|
|
|
*-------------------------------
|
|
*
|
|
* Trigger flask
|
|
*
|
|
*-------------------------------
|
|
TRIGFLASK
|
|
sty trloc
|
|
sta trscrn
|
|
|
|
lda #1
|
|
sta trdirec
|
|
|
|
* Get rnd starting frame
|
|
|
|
jsr rnd
|
|
and #7
|
|
ora (BlueSpec),y
|
|
sta (BlueSpec),y
|
|
jmp addtrob
|
|
|
|
*-------------------------------
|
|
*
|
|
* Trigger sword
|
|
*
|
|
*-------------------------------
|
|
TRIGSWORD
|
|
sty trloc
|
|
sta trscrn
|
|
lda #1
|
|
sta trdirec
|
|
jsr rnd
|
|
and #$1f
|
|
sta (BlueSpec),y
|
|
jmp addtrob
|
|
|
|
*-------------------------------
|
|
*
|
|
* Trigger torch
|
|
*
|
|
*-------------------------------
|
|
TRIGTORCH
|
|
sty trloc
|
|
sta trscrn
|
|
|
|
lda #1
|
|
sta trdirec
|
|
|
|
* Get rnd starting frame
|
|
|
|
jsr rnd
|
|
and #$f
|
|
sta (BlueSpec),y
|
|
jmp addtrob
|
|
|
|
*-------------------------------
|
|
*
|
|
* Trigger spikes
|
|
*
|
|
*-------------------------------
|
|
TRIGSPIKES
|
|
lda (BlueSpec),y
|
|
beq :ready ;State = 0: spikes are fully retracted--
|
|
;spring 'em
|
|
bpl ]rts ;Nonzero, hibit clear: spikes are in motion
|
|
cmp #$ff
|
|
beq ]rts ;jammed
|
|
lda #spiketimer ;Nonzero, hibit set: spikes are fully
|
|
sta (BlueSpec),y ;extended--reset timer to max value
|
|
]rts rts
|
|
;Spring spikes
|
|
:ready ldx #1
|
|
]cont stx trdirec
|
|
sty trloc
|
|
|
|
lda tempscrn ;from rdblock
|
|
sta trscrn
|
|
|
|
jsr addtrob ;add spikes to trans list
|
|
jsr redspikes
|
|
|
|
lda #GateDown ;TEMP
|
|
jmp addsound
|
|
|
|
*-------------------------------
|
|
*
|
|
* Jam spikes (& remove from trans list)
|
|
*
|
|
* In: Same as TRIGSPIKES
|
|
*
|
|
*-------------------------------
|
|
JAMSPIKES
|
|
lda #$ff
|
|
sta (BlueSpec),y
|
|
ldx #-1 ;stop object
|
|
bmi ]cont
|
|
|
|
*-------------------------------
|
|
*
|
|
* Get spike status: 0 = safe, 1 = sprung, 2 = springing
|
|
*
|
|
*-------------------------------
|
|
GETSPIKES
|
|
lda (BlueSpec),y
|
|
bmi :sprung
|
|
beq :safe ;fully retracted
|
|
|
|
cmp #spikeExt
|
|
bcc :springing
|
|
|
|
:safe lda #0 ;safe: retracted or retracting
|
|
rts
|
|
|
|
:sprung cmp #$ff ;jammed (body impaled on them)?
|
|
beq :safe
|
|
lda #1
|
|
rts
|
|
|
|
:springing lda #2
|
|
]rts rts
|
|
|
|
*-------------------------------
|
|
*
|
|
* Break off section of loose floor
|
|
*
|
|
*-------------------------------
|
|
BREAKLOOSE
|
|
lda #1
|
|
|
|
BREAKLOOSE1 ;in: A = initial state
|
|
sta state
|
|
|
|
lda (BlueType),y
|
|
and #reqmask ;required floorpiece?
|
|
bne ]rts ;yes--blocked below
|
|
|
|
lda (BlueSpec),y
|
|
bmi :ok ;wiggling
|
|
bne ]rts ;already triggered
|
|
|
|
:ok lda state
|
|
sta (BlueSpec),y
|
|
|
|
sty trloc
|
|
|
|
lda tempscrn ;from rdblock
|
|
sta trscrn
|
|
|
|
lda #0 ;down
|
|
sta trdirec
|
|
|
|
jsr addtrob ;add floor to trans list
|
|
jmp redloose
|
|
|
|
*-------------------------------
|
|
*
|
|
* Depress pressplate
|
|
*
|
|
* In: results of RDBLOCK
|
|
* (tempblockx-y, tempscrn refer to pressplate)
|
|
*
|
|
*-------------------------------
|
|
PUSHPP
|
|
lda (BlueType),y
|
|
and #idmask
|
|
sta pptype ;pressplate/upressplate/rubble
|
|
pushpp1
|
|
lda (BlueSpec),y ;LINKLOC index
|
|
sta linkindex
|
|
tax
|
|
jsr gettimer
|
|
|
|
cmp #31
|
|
beq ]rts ;plate is permanently down
|
|
|
|
cmp #2
|
|
bcs :starttimer ;plate is temporarily down--
|
|
;just restart timer
|
|
|
|
* Fresh plate has been stepped on--reset timer
|
|
|
|
lda #pptimer ;put plate down for the count
|
|
jsr chgtimer
|
|
|
|
sty trloc
|
|
|
|
lda tempscrn ;from rdblock1
|
|
sta trscrn
|
|
|
|
lda #1
|
|
sta trdirec
|
|
|
|
jsr addtrob ;add to trans list
|
|
|
|
jsr redplate ;add plate to redraw list
|
|
|
|
lda #1
|
|
sta alertguard
|
|
lda #PlateDown
|
|
jsr addsound
|
|
|
|
:trig jmp trigger ;trigger something?
|
|
|
|
* plate is already down--just restart timer
|
|
* (& retrigger gates)
|
|
|
|
:starttimer lda #pptimer
|
|
jsr chgtimer
|
|
jmp :trig
|
|
|
|
*-------------------------------
|
|
*
|
|
* Jam pressplate (dead weight)
|
|
*
|
|
* In: Same as PUSHPP
|
|
*
|
|
*-------------------------------
|
|
JAMPP
|
|
lda (BlueType),y
|
|
and #idmask
|
|
sta pptype
|
|
cmp #pressplate
|
|
beq :1
|
|
|
|
lda #floor
|
|
sta (BlueType),y
|
|
lda #0
|
|
sta (BlueSpec),y
|
|
lda #rubble
|
|
sta pptype
|
|
bne pushpp1
|
|
|
|
:1 lda #dpressplate
|
|
sta (BlueType),y
|
|
bne pushpp1
|
|
|
|
*-------------------------------
|
|
*
|
|
* We just pushed a pressplate -- did we trigger something?
|
|
*
|
|
* In: linkindex, pptype
|
|
*
|
|
*-------------------------------
|
|
trigger
|
|
:loop ldx linkindex
|
|
|
|
lda LINKLOC,x
|
|
cmp #$ff
|
|
beq :rts ;linked to nothing
|
|
|
|
jsr getloc
|
|
sta trloc
|
|
|
|
jsr getscrn ;get block # and screen # of
|
|
sta trscrn ;gadget to trigger
|
|
|
|
jsr calcblue
|
|
ldy trloc
|
|
lda (BlueType),y
|
|
and #idmask ;get objid into A
|
|
|
|
jsr trigobj ;call appropriate trigger routine
|
|
|
|
lda trdirec
|
|
bmi :skip ;trigger fails
|
|
|
|
jsr addtrob ;add gadget to transition list
|
|
|
|
:skip ldx linkindex
|
|
inc linkindex
|
|
|
|
jsr getlastflag
|
|
beq :loop
|
|
|
|
:rts rts
|
|
|
|
*-------------------------------
|
|
*
|
|
* Trigger object
|
|
*
|
|
* Out: trdirec (-1 if trigger fails)
|
|
*
|
|
*-------------------------------
|
|
trigobj
|
|
cmp #gate
|
|
bne :1
|
|
jmp triggate
|
|
:1
|
|
cmp #exit
|
|
bne :2
|
|
jmp openexit
|
|
:2
|
|
]rts rts
|
|
|
|
*-------------------------------
|
|
*
|
|
* Open exit
|
|
*
|
|
*-------------------------------
|
|
openexit
|
|
lda (BlueSpec),y
|
|
bne :fail ;Exit can only open, not close
|
|
|
|
lda #1
|
|
bpl :1
|
|
|
|
:fail lda #-1
|
|
:1 sta trdirec
|
|
rts
|
|
|
|
*-------------------------------
|
|
*
|
|
* Trigger gate
|
|
*
|
|
* In: BlueSpec, Y, pptype
|
|
* Out: trdirec
|
|
*
|
|
*-------------------------------
|
|
triggate
|
|
lda (BlueSpec),y ;current gate position
|
|
|
|
ldx pptype
|
|
cpx #upressplate
|
|
beq :raise
|
|
cpx #rubble
|
|
beq :jam
|
|
|
|
* Lower gate
|
|
|
|
:lower cmp #gminval ;at bottom?
|
|
bne :yeslower ;no--lower it
|
|
;yes--trigger fails
|
|
:fail jmp stopobj
|
|
|
|
:yeslower
|
|
lda #3 ;down fast
|
|
sta trdirec
|
|
rts
|
|
|
|
:jam ldx #2 ;open & jam
|
|
stx trdirec
|
|
cmp #gmaxval
|
|
bcc :1
|
|
lda #$ff ;"jammed open" state
|
|
bmi :3
|
|
|
|
:raise ldx #1 ;open
|
|
stx trdirec
|
|
cmp #$ff
|
|
beq :fail ;jammed
|
|
cmp #gmaxval
|
|
bcc :1
|
|
lda #gatetimer
|
|
:3 sta (BlueSpec),y ;reset timer
|
|
bne :fail
|
|
:1
|
|
]rts rts
|
|
|
|
*-------------------------------
|
|
*
|
|
* Animate transitional objects
|
|
* (Advance each object to next frame in animation table)
|
|
*
|
|
*-------------------------------
|
|
]cleanflag ds 1
|
|
|
|
ANIMTRANS
|
|
lda #0
|
|
sta trobcount
|
|
|
|
ldx numtrans ;# objs in trans (0-maxtr)
|
|
beq ]rts
|
|
|
|
lda #0
|
|
sta ]cleanflag
|
|
|
|
:loop stx tempnt
|
|
|
|
jsr animobj ;animate obj #x
|
|
|
|
ldx tempnt
|
|
|
|
lda trdirec ;has object stopped?
|
|
bpl :1 ;no
|
|
|
|
lda #-1 ;yes--mark it for deletion
|
|
sta ]cleanflag ;& set cleanup flag
|
|
|
|
:1 sta trdirec,x ;save direction change if any
|
|
|
|
dex
|
|
bne :loop
|
|
|
|
lda ]cleanflag
|
|
beq ]rts
|
|
|
|
* Delete all stopped objects (trdirec = ff)
|
|
* (i.e., copy entire list back onto
|
|
* itself, omitting stopped objects)
|
|
|
|
ldx #1 ;source index (assume numtrans > 0)
|
|
ldy #0 ;dest index
|
|
|
|
:dloop lda trdirec,x
|
|
cmp #$ff
|
|
beq :next
|
|
|
|
iny
|
|
sta trdirec,y
|
|
lda trloc,x
|
|
sta trloc,y
|
|
lda trscrn,x ;source
|
|
sta trscrn,y ;dest
|
|
|
|
:next inx
|
|
|
|
cpx numtrans
|
|
bcc :dloop
|
|
beq :dloop
|
|
|
|
sty numtrans
|
|
rts
|
|
|
|
*-------------------------------
|
|
*
|
|
* Animate TROB #x
|
|
*
|
|
*-------------------------------
|
|
animobj lda trloc,x
|
|
sta trloc
|
|
lda trscrn,x
|
|
sta trscrn
|
|
lda trdirec,x
|
|
sta trdirec
|
|
|
|
* Find out what kind of object it is
|
|
|
|
lda trscrn
|
|
jsr calcblue
|
|
|
|
ldy trloc
|
|
lda (BlueSpec),y
|
|
sta state ;original state
|
|
|
|
lda (BlueType),y
|
|
and #idmask ;objid
|
|
|
|
* and branch to appropriate subroutine
|
|
|
|
cmp #torch
|
|
bne :1
|
|
jsr animtorch
|
|
jmp :done
|
|
|
|
:1 cmp #upressplate
|
|
beq :plate
|
|
cmp #pressplate
|
|
bne :2
|
|
:plate jsr animplate
|
|
jmp :done
|
|
|
|
:2 cmp #spikes
|
|
bne :3
|
|
jsr animspikes
|
|
jmp :done
|
|
|
|
:3 cmp #loose
|
|
bne :31
|
|
jsr animfloor
|
|
jmp :done
|
|
|
|
:31 cmp #space ;(loose floor turns into space)
|
|
bne :4
|
|
jsr animspace
|
|
jmp :done
|
|
|
|
:4 cmp #slicer
|
|
bne :5
|
|
jsr animslicer
|
|
jmp :done
|
|
|
|
:5 cmp #gate
|
|
bne :6
|
|
jsr animgate
|
|
jmp :done
|
|
|
|
:6 cmp #exit
|
|
bne :7
|
|
jsr animexit
|
|
jmp :done
|
|
|
|
:7 cmp #flask
|
|
bne :8
|
|
jsr animflask
|
|
jmp :done
|
|
|
|
:8 cmp #sword
|
|
bne :9
|
|
jsr animsword
|
|
jmp :done
|
|
|
|
:9 jsr stopobj ;obj is none of these--purge it from trans list!
|
|
|
|
:done lda state
|
|
ldy trloc
|
|
sta (BlueSpec),y
|
|
|
|
:rts rts
|
|
|
|
*-------------------------------
|
|
*
|
|
* Animate exit
|
|
*
|
|
*-------------------------------
|
|
animexit
|
|
ldx trdirec
|
|
bmi :cont
|
|
cpx #3
|
|
bcs :downfast ;>= 3: coming down fast
|
|
|
|
lda #RaisingExit
|
|
jsr addsound
|
|
|
|
lda state
|
|
clc
|
|
adc #exitinc
|
|
sta state
|
|
|
|
cmp #emaxval
|
|
bcs :stop
|
|
|
|
:cont jmp redexit
|
|
|
|
:stop jsr stopobj
|
|
|
|
lda #GateDown
|
|
jsr addsound
|
|
lda #s_Stairs
|
|
ldx #15
|
|
jsr cuesong
|
|
lda #1
|
|
sta exitopen
|
|
jsr mirappear
|
|
jmp :cont
|
|
|
|
* Exit coming down fast
|
|
|
|
:downfast
|
|
cpx #maxgatevel
|
|
bcs :2
|
|
inx
|
|
stx trdirec
|
|
:2 lda state
|
|
sec
|
|
sbc gatevel,x
|
|
sta state
|
|
beq :cont
|
|
bcs :cont
|
|
|
|
jsr stopobj
|
|
|
|
lda #0
|
|
sta state
|
|
|
|
lda #GateSlam
|
|
jsr addsound
|
|
|
|
jmp :cont
|
|
|
|
*-------------------------------
|
|
*
|
|
* Animate gate
|
|
*
|
|
*-------------------------------
|
|
animgate
|
|
ldx trdirec
|
|
bmi :cont ;gate has stopped
|
|
|
|
cpx #3 ;trdirec >= 3: coming down fast
|
|
bcs :downfast
|
|
|
|
lda state
|
|
cmp #$ff
|
|
beq :stop ;jammed open
|
|
clc
|
|
adc gateinc,x
|
|
sta state
|
|
|
|
cpx #0
|
|
beq :goingdown
|
|
|
|
cmp #gmaxval
|
|
bcs :attop ;stop at top
|
|
|
|
lda #RaisingGate
|
|
jsr addsound
|
|
|
|
jmp :cont
|
|
|
|
:goingdown
|
|
cmp #gminval
|
|
beq :stop
|
|
bcc :stop
|
|
|
|
cmp #gmaxval
|
|
bcs :cont ;at top
|
|
jsr addlowersound
|
|
|
|
:cont jmp redgate ;mark gate for redrawing
|
|
|
|
:stop jsr stopobj
|
|
|
|
lda #GateDown
|
|
jsr addsound
|
|
|
|
jmp :cont
|
|
|
|
* Gate has reached top
|
|
* trdirec = 1: pause, then start to close again
|
|
* trdirec = 2: jam at top
|
|
|
|
:attop
|
|
cpx #2
|
|
bcc :tr1
|
|
lda #$ff ;jammed-open value
|
|
sta state
|
|
jmp :stop
|
|
|
|
:tr1 lda #gatetimer
|
|
sta state
|
|
|
|
lda #0 ;down
|
|
sta trdirec
|
|
]rts rts
|
|
|
|
* Down fast
|
|
|
|
:downfast
|
|
cpx #maxgatevel
|
|
bcs :2
|
|
|
|
inx
|
|
stx trdirec ;trdirec is velocity index
|
|
:2
|
|
lda state
|
|
sec
|
|
sbc gatevel,x
|
|
sta state
|
|
beq :cont
|
|
bcs :cont
|
|
|
|
lda #0
|
|
sta state
|
|
jsr stopobj
|
|
|
|
lda #GateSlam
|
|
jsr addsound
|
|
jmp :cont
|
|
|
|
*-------------------------------
|
|
*
|
|
* Animate pressplate
|
|
*
|
|
*-------------------------------
|
|
animplate
|
|
ldx trdirec
|
|
bmi ]rts
|
|
|
|
lda state
|
|
tax
|
|
jsr gettimer
|
|
sec
|
|
sbc #1
|
|
pha
|
|
jsr chgtimer
|
|
pla
|
|
cmp #2
|
|
bcs ]rts ;timer stops at t=1
|
|
|
|
lda #PlateUp
|
|
jsr addsound
|
|
|
|
jsr stopobj
|
|
|
|
jmp redplate ;add obj to redraw buffer
|
|
]rts rts
|
|
|
|
*-------------------------------
|
|
*
|
|
* Animate slicer
|
|
*
|
|
*-------------------------------
|
|
animslicer
|
|
ldx trdirec
|
|
bmi :done
|
|
|
|
lda state
|
|
tax
|
|
and #$80
|
|
sta state ;preserve hibit
|
|
txa
|
|
and #$7f
|
|
clc
|
|
adc #1
|
|
cmp #slicetimer+1
|
|
bcc :1
|
|
lda #1 ;wrap around
|
|
:1 ora state
|
|
sta state
|
|
and #$7f ;next frame #
|
|
cmp #slicerExt
|
|
bne :2
|
|
|
|
lda #JawsClash
|
|
jsr addsound
|
|
|
|
:2 lda trscrn
|
|
cmp VisScrn ;is slicer on visible screen?
|
|
bne :os ;no
|
|
|
|
lda trloc
|
|
jsr unindex
|
|
cpx KidBlockY ;on same level as kid?
|
|
bne :os ;no
|
|
|
|
lda KidLife
|
|
bmi :done
|
|
;If kid is dead, stop all unbloodied slicers
|
|
lda state
|
|
and #$80
|
|
bne :done
|
|
|
|
* As soon as slicer is retracted, purge it from trans list
|
|
|
|
:os lda state
|
|
and #$7f
|
|
cmp #slicerRet
|
|
bcc :done
|
|
|
|
:purge jsr stopobj
|
|
|
|
:done lda state
|
|
and #$7f
|
|
cmp #slicerRet ;retracted?
|
|
bcs ]rts ;yes--don't bother to redraw
|
|
|
|
jmp redslicer
|
|
|
|
*-------------------------------
|
|
*
|
|
* Animate flask
|
|
*
|
|
*-------------------------------
|
|
animflask
|
|
ldx trdirec
|
|
bmi ]rts
|
|
|
|
lda trscrn
|
|
cmp VisScrn
|
|
bne :purge
|
|
|
|
lda state
|
|
and #%11100000 ;potion #
|
|
sta temp1
|
|
lda state
|
|
and #%00011111 ;frame #
|
|
jsr GETFLASKFRAME
|
|
ora temp1
|
|
sta state
|
|
|
|
jmp redflask
|
|
]purge
|
|
:purge jmp stopobj
|
|
|
|
*-------------------------------
|
|
*
|
|
* Animate gleaming sword
|
|
*
|
|
*-------------------------------
|
|
animsword
|
|
lda trscrn
|
|
cmp VisScrn
|
|
bne ]purge
|
|
|
|
dec state
|
|
bne :1
|
|
jsr rnd
|
|
and #$3f
|
|
clc
|
|
adc #40
|
|
sta state
|
|
|
|
:1 jmp redsword
|
|
]rts rts
|
|
|
|
*-------------------------------
|
|
*
|
|
* Animate torch
|
|
*
|
|
*-------------------------------
|
|
animtorch
|
|
ldx trdirec
|
|
bmi ]rts
|
|
|
|
lda trscrn
|
|
cmp VisScrn
|
|
bne ]purge
|
|
|
|
lda state
|
|
jsr GETFLAMEFRAME
|
|
sta state
|
|
|
|
jmp redtorch
|
|
|
|
*-------------------------------
|
|
*
|
|
* Get flame frame
|
|
*
|
|
* In/out: A = state
|
|
*
|
|
*-------------------------------
|
|
GETFLAMEFRAME
|
|
sta state
|
|
|
|
jsr rnd
|
|
|
|
cmp state
|
|
beq :2
|
|
cmp #torchLast+1
|
|
bcc :1
|
|
|
|
lda state
|
|
:2 clc
|
|
adc #1
|
|
cmp #torchLast+1
|
|
bcc :1
|
|
|
|
lda #0 ;wrap around
|
|
:1
|
|
]rts rts
|
|
|
|
*-------------------------------
|
|
*
|
|
* Get flask frame
|
|
*
|
|
* In/out: A = state (low 5 bits)
|
|
*
|
|
*-------------------------------
|
|
GETFLASKFRAME
|
|
clc
|
|
adc #1
|
|
cmp #bubbLast+1
|
|
bcc ]rts
|
|
lda #1
|
|
]rts rts
|
|
|
|
*-------------------------------
|
|
*
|
|
* Animate spikes
|
|
*
|
|
*-------------------------------
|
|
animspikes
|
|
ldx trdirec
|
|
bmi :done
|
|
|
|
lda state
|
|
bmi :timerloop ;Hibit set: remaining 7 bits
|
|
;represent timer value
|
|
|
|
* Hibit clear: remaining 7 bits represent BGDATA frame #
|
|
|
|
inc state
|
|
|
|
cmp #spikeExt ;is extension complete?
|
|
beq :starttimer ;yes--start timer
|
|
|
|
cmp #spikeRet ;is retraction complete?
|
|
bne :done ;not yet
|
|
|
|
lda #0
|
|
sta state ;yes--reset to "ready" state
|
|
|
|
jsr stopobj
|
|
|
|
:done jmp redspikes
|
|
|
|
* Spike timer loop
|
|
|
|
:starttimer
|
|
lda #spiketimer
|
|
sta state
|
|
|
|
bne :done
|
|
|
|
:timerloop
|
|
dec state
|
|
|
|
lda state
|
|
and #$7f
|
|
bne :rts
|
|
;Time's up
|
|
lda #spikeExt+1 ;First "retracting" frame
|
|
sta state
|
|
|
|
bne :done
|
|
:rts
|
|
]rts rts
|
|
|
|
*-------------------------------
|
|
*
|
|
* Animate loose floor
|
|
*
|
|
*-------------------------------
|
|
animfloor
|
|
ldx trdirec
|
|
bmi :red
|
|
|
|
* When timer reaches max value & loose floor detaches:
|
|
* (1) Change objid from "loose floor" to "empty space"
|
|
* (2) Create a MOB to take over where TROB stopped
|
|
|
|
inc state
|
|
|
|
lda state
|
|
bmi :wiggle ;floor is only wiggling
|
|
|
|
cmp #loosetimer
|
|
bcc :red
|
|
|
|
* Timer has reached max value--detach floor
|
|
|
|
jsr makespace
|
|
sta state
|
|
|
|
jsr stopobj
|
|
|
|
* and create new MOB
|
|
|
|
lda trloc
|
|
jsr unindex
|
|
|
|
asl
|
|
asl ;x4
|
|
sta mobx
|
|
stx moblevel
|
|
|
|
lda BlockBot+1,x
|
|
sta moby
|
|
|
|
lda trscrn
|
|
sta mobscrn
|
|
|
|
lda #0
|
|
sta mobvel
|
|
sta mobtype
|
|
|
|
jsr addamob
|
|
|
|
:red jmp redloose
|
|
|
|
* Floor is only wiggling
|
|
|
|
:wiggle ldx level
|
|
cpx #13
|
|
beq ]rts
|
|
|
|
cmp #wiggletime+$80
|
|
bcc :red
|
|
|
|
lda #0
|
|
sta state
|
|
jsr stopobj ;stop wiggling
|
|
|
|
jmp :red
|
|
|
|
animspace jsr stopobj
|
|
jmp redloose
|
|
|
|
*-------------------------------
|
|
*
|
|
* Stop object (set trdirec = -1)
|
|
*
|
|
*-------------------------------
|
|
stopobj lda #-1
|
|
sta trdirec
|
|
rts
|
|
|
|
*-------------------------------
|
|
* General redraw-object routine
|
|
*-------------------------------
|
|
redtrobj
|
|
jsr check
|
|
lda #2
|
|
jsr markred
|
|
jsr markwipe
|
|
jsr checkright
|
|
lda #2
|
|
jsr markred
|
|
jmp markwipe
|
|
|
|
*-------------------------------
|
|
* redraw torch/exit
|
|
*-------------------------------
|
|
redexit
|
|
redtorch
|
|
jsr checkright
|
|
lda #2
|
|
jmp markmove
|
|
|
|
*-------------------------------
|
|
* redraw flask/sword
|
|
*-------------------------------
|
|
redsword
|
|
redflask
|
|
jsr check
|
|
lda #2
|
|
jmp markmove
|
|
|
|
*-------------------------------
|
|
* redraw loose floor
|
|
*-------------------------------
|
|
redloose
|
|
inc trobcount
|
|
lda #loosewipe
|
|
sta height
|
|
jmp redtrobj
|
|
|
|
*-------------------------------
|
|
* redraw gate
|
|
*-------------------------------
|
|
redgate
|
|
jsr checkright ;mark piece to right of gate
|
|
lda #2
|
|
jsr markmove
|
|
jsr markfred
|
|
jsr checkabover ;& piece to right of gate panel
|
|
lda #2
|
|
jmp markmove
|
|
|
|
*-------------------------------
|
|
* redraw spikes
|
|
*-------------------------------
|
|
redspikes
|
|
inc trobcount
|
|
lda #spikewipe
|
|
sta height
|
|
jmp redtrobj
|
|
|
|
*-------------------------------
|
|
* redraw slicer
|
|
*-------------------------------
|
|
redslicer
|
|
inc trobcount
|
|
lda #slicerwipe
|
|
sta height
|
|
jsr check
|
|
lda #2
|
|
jsr markred
|
|
jmp markwipe
|
|
|
|
*-------------------------------
|
|
* redraw pressplate
|
|
*-------------------------------
|
|
redplate
|
|
lda #platewipe
|
|
sta height
|
|
jmp redtrobj
|
|
|
|
*-------------------------------
|
|
*
|
|
* Before marking a piece in redraw buffer,
|
|
* check whether it's visible.
|
|
*
|
|
* If piece is visible onscreen:
|
|
* return with carry clear, y = redbuf index
|
|
* If piece is not visible:
|
|
* return with carry set
|
|
*
|
|
*-------------------------------
|
|
]no ldy #30
|
|
sec
|
|
]rts rts
|
|
|
|
]above cmp scrnAbove
|
|
bne ]rts
|
|
|
|
lda trloc
|
|
sec
|
|
sbc #20 ;if on top row, return 0-9 and cs
|
|
tay
|
|
|
|
sec
|
|
rts
|
|
|
|
*-------------------------------
|
|
* Check (trscrn, trloc)
|
|
*-------------------------------
|
|
check
|
|
lda trscrn
|
|
cmp VisScrn
|
|
bne ]above
|
|
|
|
ldy trloc
|
|
cpy #30 ;i.e., "clc"
|
|
rts
|
|
|
|
*-------------------------------
|
|
* Check piece to left of (trscrn,trloc)
|
|
*-------------------------------
|
|
checkleft
|
|
lda trscrn
|
|
cmp VisScrn
|
|
bne :notonscrn
|
|
;piece is on this screen
|
|
cpy #0
|
|
beq ]no
|
|
cpy #10
|
|
beq ]no
|
|
cpy #20
|
|
beq ]no
|
|
;yes--piece is visible
|
|
dey
|
|
clc
|
|
rts
|
|
|
|
:notonscrn
|
|
cmp scrnRight
|
|
bne ]above
|
|
;piece is on screen to right
|
|
ldy trloc
|
|
cpy #0
|
|
beq :yesr
|
|
cpy #10
|
|
beq :yesr
|
|
cpy #20
|
|
bne :yesr
|
|
|
|
:yesr tya
|
|
clc
|
|
adc #9 ;mark corresponding right-edge piece
|
|
tay ;on this screen
|
|
|
|
clc
|
|
rts
|
|
|
|
*-------------------------------
|
|
* Check piece to right of (trscrn,trloc)
|
|
*-------------------------------
|
|
checkright
|
|
lda trscrn
|
|
cmp VisScrn
|
|
bne :notonscrn
|
|
;piece is on this screen
|
|
ldy trloc
|
|
cpy #9
|
|
beq ]no
|
|
|
|
cpy #19
|
|
beq ]no
|
|
|
|
cpy #29
|
|
beq ]no
|
|
;yes
|
|
iny
|
|
clc
|
|
rts
|
|
|
|
:notonscrn
|
|
cmp scrnLeft
|
|
bne ]above
|
|
;piece is on screen to left
|
|
ldy trloc
|
|
cpy #9
|
|
beq :yesl
|
|
|
|
cpy #19
|
|
beq :yesl
|
|
|
|
cpy #29
|
|
bne ]no
|
|
|
|
:yesl tya
|
|
sec
|
|
sbc #9 ;mark corresponding left-edge piece
|
|
tay ;on this screen
|
|
|
|
clc
|
|
rts
|
|
|
|
]no ldy #30
|
|
sec
|
|
]rts rts
|
|
|
|
*-------------------------------
|
|
* Check piece above & to right of (trscrn,trloc)
|
|
*-------------------------------
|
|
checkabover
|
|
lda trscrn
|
|
cmp VisScrn
|
|
bne :notonscrn
|
|
;piece is on this screen
|
|
ldy trloc
|
|
cpy #10
|
|
bcc :above ;piece is on top row
|
|
|
|
cpy #19
|
|
beq ]no
|
|
|
|
cpy #29
|
|
beq ]no
|
|
;yes
|
|
tya
|
|
sec
|
|
sbc #9
|
|
tay
|
|
|
|
clc
|
|
rts
|
|
|
|
:above
|
|
iny
|
|
sec
|
|
rts
|
|
|
|
:notonscrn
|
|
cmp scrnLeft
|
|
bne :notonleft
|
|
;piece is on screen to left
|
|
ldy trloc
|
|
cpy #9
|
|
beq :yes0
|
|
|
|
cpy #19
|
|
beq :yesl
|
|
|
|
cpy #29
|
|
bne ]no
|
|
|
|
:yesl tya
|
|
sec
|
|
sbc #19 ;mark corresponding left-edge piece
|
|
tay ;on this screen
|
|
|
|
clc
|
|
rts
|
|
|
|
:yes0 ldy #0
|
|
sec
|
|
rts
|
|
|
|
:notonleft
|
|
cmp scrnBelow
|
|
bne :notbelow
|
|
;piece is on screen below
|
|
ldy trloc
|
|
cpy #9
|
|
bcs ]no
|
|
;yes--piece is on top row
|
|
tya
|
|
clc
|
|
adc #21
|
|
tay
|
|
|
|
clc
|
|
rts
|
|
|
|
:notbelow
|
|
cmp scrnBelowL
|
|
bne ]rts
|
|
;piece is on scrn below & to left
|
|
ldy trloc
|
|
cpy #9
|
|
bne ]no
|
|
;yes--piece is in u.r.
|
|
ldy #20
|
|
clc
|
|
rts
|
|
|
|
*-------------------------------
|
|
*
|
|
* Extract information from LINKLOC/LINKMAP
|
|
*
|
|
* In: X = linkindex
|
|
* Out: A = info
|
|
*
|
|
*-------------------------------
|
|
gettimer
|
|
lda LINKMAP,x
|
|
and #%00011111 ;pressplate timer (0-31)
|
|
rts
|
|
chgtimer ;In: A = new timer setting
|
|
and #%00011111
|
|
sta temp1
|
|
lda LINKMAP,x
|
|
and #%11100000
|
|
ora temp1
|
|
sta LINKMAP,x
|
|
rts
|
|
getloc
|
|
lda LINKLOC,x
|
|
and #%00011111 ;screen posn (0-29)
|
|
rts
|
|
getlastflag
|
|
lda LINKLOC,x
|
|
and #%10000000 ;last-entry flag (0-1)
|
|
rts
|
|
getscrn
|
|
lda LINKLOC,x
|
|
and #%01100000 ;low 2 bits
|
|
lsr
|
|
lsr
|
|
sta temp1
|
|
lda LINKMAP,x
|
|
and #%11100000 ;high 3 bits
|
|
adc temp1
|
|
lsr
|
|
lsr
|
|
lsr ;Result: screen # (0-31)
|
|
]rts rts
|
|
|
|
*-------------------------------
|
|
*
|
|
* Update all MOBs (falling floors)
|
|
*
|
|
*-------------------------------
|
|
ANIMMOBS
|
|
ldx nummob ;# MOBs in motion (0-maxmob)
|
|
beq ]rts
|
|
|
|
:loop stx tempnt
|
|
jsr loadmob
|
|
|
|
jsr animmob ;animate MOB #x
|
|
|
|
jsr checkcrush ;did we just crush a character?
|
|
|
|
ldx tempnt
|
|
jsr savemob
|
|
|
|
dex
|
|
bne :loop
|
|
|
|
* Delete MOBs that have ceased to exist
|
|
|
|
ldx #1 ;source index (assume nummob > 0)
|
|
ldy #0 ;dest index
|
|
|
|
:dloop lda mobvel,x
|
|
cmp #$ff
|
|
beq :next
|
|
|
|
iny
|
|
sta mobvel,y
|
|
lda mobx,x ;source
|
|
sta mobx,y ;dest
|
|
lda moby,x
|
|
sta moby,y
|
|
lda mobscrn,x
|
|
sta mobscrn,y
|
|
lda mobtype,x
|
|
sta mobtype,y
|
|
lda moblevel,x
|
|
sta moblevel,y
|
|
|
|
:next inx
|
|
|
|
cpx nummob
|
|
bcc :dloop
|
|
beq :dloop
|
|
|
|
sty nummob
|
|
|
|
]rts rts
|
|
|
|
*-------------------------------
|
|
*
|
|
* Animate MOB #x
|
|
*
|
|
*-------------------------------
|
|
animmob
|
|
lda mobtype
|
|
bne :done
|
|
jsr mobfloor
|
|
:done
|
|
lda mobvel
|
|
bpl ]rts ;is object stopping?
|
|
inc mobvel ;yes
|
|
]rts rts
|
|
|
|
*-------------------------------
|
|
*
|
|
* Animate falling floor
|
|
*
|
|
*-------------------------------
|
|
mobfloor
|
|
lda mobvel
|
|
bmi ]rts
|
|
:ok1
|
|
cmp #FFtermvel
|
|
bcs :tv
|
|
clc
|
|
adc #FFaccel
|
|
sta mobvel
|
|
|
|
:tv clc
|
|
adc moby
|
|
sta moby
|
|
|
|
* check for collision w/floor
|
|
|
|
ldx mobscrn ;on null screen?
|
|
beq :null ;yes--fall on
|
|
|
|
cmp #-30 ;negative?
|
|
bcs :fallon ;yes--fall on
|
|
|
|
ldx moblevel
|
|
cmp BlockAy+1,x
|
|
bcc :fallon
|
|
|
|
* Passing thru floor plane--what to do?
|
|
* First see what's there
|
|
|
|
ldx moblevel
|
|
stx tempblocky
|
|
|
|
lda mobx
|
|
lsr
|
|
lsr
|
|
sta tempblockx
|
|
|
|
lda mobscrn
|
|
sta tempscrn
|
|
|
|
jsr rdblock1 ;A = objid
|
|
sta underFF ;under falling floor
|
|
|
|
cmp #space
|
|
beq :passthru
|
|
|
|
cmp #loose
|
|
bne :crash
|
|
|
|
* Lands on loose floor
|
|
* Knock out loose floor & continue
|
|
|
|
jsr knockloose
|
|
|
|
jmp :passthru
|
|
|
|
* Lands on solid floor
|
|
|
|
:crash
|
|
lda #LooseCrash
|
|
jsr addsound
|
|
|
|
lda mobscrn
|
|
sta tempscrn
|
|
lda moblevel
|
|
sta tempblocky
|
|
jsr SHAKEM1 ;shake loose floors
|
|
|
|
ldx moblevel
|
|
lda BlockAy+1,x
|
|
sta moby
|
|
|
|
lda #-crumbletime
|
|
sta mobvel
|
|
|
|
jmp makerubble
|
|
|
|
* Passes thru floor plane
|
|
|
|
:passthru
|
|
jsr passthru
|
|
:fallon
|
|
]rts rts
|
|
|
|
* Falling on null screen
|
|
|
|
:null
|
|
lda moby
|
|
cmp #192+17
|
|
bcc ]rts
|
|
;MOB has fallen off null screen--delete it
|
|
lda #-disappeartime
|
|
sta mobvel
|
|
|
|
]rts rts
|
|
|
|
*-------------------------------
|
|
* Knock out loose floor
|
|
*-------------------------------
|
|
knockloose
|
|
jsr makespace
|
|
sta (BlueSpec),y
|
|
|
|
lda mobvel
|
|
lsr
|
|
sta mobvel
|
|
|
|
ldx tempnt
|
|
jsr savemob ;save this MOB
|
|
|
|
* Create new MOB (add'l falling floor)
|
|
|
|
lda moby
|
|
clc
|
|
adc #6
|
|
sta moby
|
|
|
|
jsr passthru
|
|
|
|
jsr addamob
|
|
|
|
* Retrieve old MOB
|
|
|
|
ldx tempnt
|
|
jsr loadmob
|
|
|
|
jmp markmob
|
|
|
|
*-------------------------------
|
|
* Make space
|
|
* Return A = BlueSpec
|
|
*-------------------------------
|
|
makespace lda #space ;change objid to empty space
|
|
sta (BlueType),y
|
|
|
|
do PalaceEditor
|
|
lda #1
|
|
rts
|
|
fin
|
|
|
|
lda #0
|
|
ldx BGset1
|
|
cpx #1 ;pal?
|
|
bne ]rts
|
|
lda #1 ;stripe
|
|
]rts rts
|
|
|
|
*-------------------------------
|
|
* Pass thru floor plane
|
|
*-------------------------------
|
|
passthru
|
|
inc moblevel
|
|
|
|
lda moblevel
|
|
cmp #3
|
|
bcc ]rts
|
|
|
|
* ... and onto next screen
|
|
* (NOTE: moby may be negative)
|
|
|
|
lda moby
|
|
sec
|
|
sbc #192
|
|
sta moby
|
|
|
|
lda #0
|
|
sta moblevel
|
|
|
|
lda mobscrn
|
|
jsr getdown
|
|
sta mobscrn
|
|
]rts rts
|
|
|
|
*-------------------------------
|
|
* Delete MOB & change objid of floorpiece it landed on
|
|
* If pressplate, trigger before reducing it to rubble
|
|
*-------------------------------
|
|
makerubble
|
|
lda moblevel
|
|
sta tempblocky
|
|
|
|
lda mobx
|
|
lsr
|
|
lsr
|
|
sta tempblockx
|
|
|
|
lda mobscrn
|
|
sta tempscrn
|
|
|
|
jsr rdblock1
|
|
|
|
cmp #pressplate
|
|
beq :pp
|
|
cmp #upressplate
|
|
beq :jampp
|
|
cmp #floor
|
|
beq :notpp
|
|
cmp #spikes
|
|
beq :notpp
|
|
cmp #flask
|
|
beq :notpp
|
|
cmp #torch
|
|
beq :notpp
|
|
bne ]rts ;can't transform this piece into rubble
|
|
|
|
:jampp lda #rubble
|
|
sta (BlueType),y
|
|
|
|
:pp jsr PUSHPP ;block lands on pressplate--
|
|
jsr rdblock1 ;crush pp & jam open all gates
|
|
|
|
:notpp lda #rubble
|
|
sta (BlueType),y
|
|
jmp markmob
|
|
|
|
*-------------------------------
|
|
* Mark MOB
|
|
*-------------------------------
|
|
markmob
|
|
lda mobscrn
|
|
cmp VisScrn
|
|
bne ]rts
|
|
|
|
lda #loosewipe
|
|
sta height
|
|
|
|
jsr indexblock
|
|
lda #2
|
|
jsr markred
|
|
jsr markwipe
|
|
|
|
inc tempblockx
|
|
|
|
jsr indexblock
|
|
lda #2
|
|
jsr markred
|
|
jsr markfred
|
|
jmp markwipe
|
|
|
|
]rts rts
|
|
|
|
*-------------------------------
|
|
*
|
|
* Did falling floor crush anybody?
|
|
*
|
|
*-------------------------------
|
|
checkcrush
|
|
jsr LoadKid
|
|
jsr chcrush1 ;return cs if crush
|
|
bcc ]rts
|
|
jsr crushchar
|
|
jmp SaveKid
|
|
|
|
chcrush1
|
|
lda mobscrn
|
|
cmp CharScrn ;on same screen as char?
|
|
bne :no
|
|
|
|
lda mobx
|
|
lsr
|
|
lsr
|
|
cmp CharBlockX ;same blockx?
|
|
bne :no
|
|
|
|
lda moby
|
|
cmp CharY
|
|
bcs :no ;mob is below char altogether
|
|
|
|
lda CharY
|
|
sec
|
|
sbc #CrushDist
|
|
cmp moby
|
|
bcs :no
|
|
sec ;crush!
|
|
rts
|
|
|
|
:no clc
|
|
]rts rts
|
|
|
|
*-------------------------------
|
|
*
|
|
* Crush char with falling block
|
|
* (Ordered by ANIMMOB)
|
|
*
|
|
*-------------------------------
|
|
crushchar
|
|
lda level
|
|
cmp #13
|
|
beq :1
|
|
lda CharPosn
|
|
cmp #5
|
|
bcc :1
|
|
cmp #15
|
|
bcc ]rts ;running-->escape
|
|
|
|
:1 lda CharAction
|
|
cmp #2
|
|
bcc :ground
|
|
cmp #7
|
|
bne ]rts
|
|
|
|
* Action code 0,1,7 -- on ground
|
|
|
|
:ground
|
|
ldx CharBlockY
|
|
inx
|
|
lda FloorY,x
|
|
sta CharY ;align w/floor
|
|
|
|
lda #1
|
|
jsr decstr
|
|
beq :kill
|
|
|
|
lda CharPosn
|
|
cmp #109
|
|
beq ]rts
|
|
lda #crush
|
|
jmp jumpseq
|
|
|
|
:kill lda #hardland ;temp
|
|
jmp jumpseq
|
|
|
|
*-------------------------------
|
|
*
|
|
* Add all visible MOBs to object table (to be drawn later)
|
|
*
|
|
*-------------------------------
|
|
ADDMOBS
|
|
ldx nummob ;# objs in motion (0-maxmob)
|
|
beq :rts
|
|
|
|
:loop stx tempnt
|
|
jsr loadmob
|
|
|
|
lda mobtype
|
|
bne :1
|
|
jsr ATM ;Add this MOB
|
|
:1
|
|
ldx tempnt
|
|
dex
|
|
bne :loop
|
|
:rts
|
|
]rts rts
|
|
|
|
*-------------------------------
|
|
*
|
|
* Add this MOB to obj table (if visible)
|
|
*
|
|
*-------------------------------
|
|
ATM
|
|
|
|
* Is floorpiece visible onscreen?
|
|
|
|
lda mobscrn
|
|
cmp VisScrn
|
|
bne :ok2
|
|
|
|
lda moby
|
|
cmp #192+17 ;17 is generous estimate of image height
|
|
bcc :ok
|
|
rts
|
|
:ok2
|
|
cmp scrnBelow
|
|
bne ]rts ;not on screen below
|
|
|
|
lda moby
|
|
cmp #-17
|
|
bcs :ok1
|
|
cmp #17
|
|
bcs ]rts
|
|
:ok1
|
|
clc
|
|
adc #192
|
|
sta moby ;(this change won't be saved)
|
|
:ok
|
|
|
|
* Get block #; index char
|
|
|
|
lda moby
|
|
jsr getblocky ;return blocky (0-3)
|
|
sta tempblocky
|
|
|
|
lda mobx
|
|
lsr
|
|
lsr
|
|
sta tempblockx
|
|
|
|
jsr indexblock
|
|
sty FCharIndex
|
|
|
|
* Mark floorbuf & fredbuf of affected blocks to R
|
|
|
|
:cont1
|
|
inc tempblockx
|
|
jsr indexblock ;block to R
|
|
|
|
lda #2
|
|
jsr markfloor
|
|
jsr markfred
|
|
|
|
lda moby
|
|
sec
|
|
sbc #FFheight
|
|
jsr getblocky ;highest affected blocky
|
|
cmp tempblocky
|
|
beq :same
|
|
|
|
sta tempblocky
|
|
jsr indexblock ;block to U.R.
|
|
|
|
lda #2
|
|
jsr markfloor
|
|
jsr markfred
|
|
:same
|
|
|
|
* Get frame #
|
|
|
|
lda #Ffalling
|
|
sta mobframe
|
|
|
|
jmp addmobobj ;add MOB to object table
|
|
|
|
*-------------------------------
|
|
*
|
|
* Add MOB to object table
|
|
*
|
|
* In: mob data
|
|
*
|
|
*-------------------------------
|
|
addmobobj
|
|
inc objX
|
|
ldx objX
|
|
|
|
lda mobtype ;0 = falling floor
|
|
ora #$80
|
|
sta objTYP,x
|
|
|
|
lda mobx
|
|
sta objX,x
|
|
lda #0
|
|
sta objOFF,x
|
|
|
|
lda moby
|
|
sta objY,x
|
|
|
|
lda mobframe
|
|
sta objIMG,x
|
|
|
|
lda #0
|
|
sta objCU,x
|
|
sta objCL,x
|
|
lda #40
|
|
sta objCR,x
|
|
|
|
jmp setobjindx
|
|
]rts rts
|
|
*-------------------------------
|
|
*
|
|
* Shake floors
|
|
*
|
|
* In: A = CharBlockY
|
|
*
|
|
*-------------------------------
|
|
SHAKEM
|
|
ldx level
|
|
cpx #13
|
|
beq ]rts
|
|
|
|
sta tempblocky
|
|
|
|
lda VisScrn
|
|
sta tempscrn
|
|
|
|
SHAKEM1
|
|
ldx #9
|
|
:loop txa
|
|
pha
|
|
sta tempblockx
|
|
|
|
jsr rdblock1
|
|
cmp #loose
|
|
bne :cont
|
|
|
|
jsr shakeit
|
|
|
|
:cont pla
|
|
tax
|
|
dex
|
|
bpl :loop
|
|
|
|
]rts rts
|
|
|
|
*-------------------------------
|
|
* Shake loose floor
|
|
*-------------------------------
|
|
shakeit
|
|
lda (BlueSpec),y
|
|
bmi ]rts ;already wiggling
|
|
bne ]rts ;active
|
|
|
|
lda #$80
|
|
sta (BlueSpec),y
|
|
|
|
sty trloc
|
|
|
|
lda tempscrn ;from rdblock
|
|
sta trscrn
|
|
|
|
lda #1
|
|
sta trdirec
|
|
|
|
jmp addtrob ;add floor to trans list
|
|
|
|
*-------------------------------
|
|
lst
|
|
ds 1
|
|
usr $a9,21,$00,*-org
|
|
lst off
|