2121 lines
27 KiB
ArmAsm
Executable File
2121 lines
27 KiB
ArmAsm
Executable File
* ctrlsubs
|
|
org = $d000
|
|
tr on
|
|
lst off
|
|
*-------------------------------
|
|
*
|
|
* PRINCE OF PERSIA
|
|
* Copyright 1989 Jordan Mechner
|
|
*
|
|
*-------------------------------
|
|
*
|
|
* Misc. subroutines relating to character control & movement
|
|
*
|
|
*-------------------------------
|
|
org org
|
|
|
|
jmp GETFRAME
|
|
jmp GETSEQ
|
|
jmp GETBASEX
|
|
jmp GETBLOCKX
|
|
jmp GETBLOCKXP
|
|
|
|
jmp GETBLOCKY
|
|
jmp GETBLOCKEJ
|
|
jmp ADDCHARX
|
|
jmp GETDIST
|
|
jmp GETDIST1
|
|
|
|
jmp GETABOVEBEH
|
|
jmp RDBLOCK
|
|
jmp RDBLOCK1
|
|
jmp SETUPSWORD
|
|
jmp GETSCRNS
|
|
|
|
jmp ADDGUARDOBJ
|
|
jmp OPJUMPSEQ
|
|
jmp GETEDGES
|
|
jmp INDEXCHAR
|
|
jmp QUICKFG
|
|
|
|
jmp CROPCHAR
|
|
jmp GETLEFT
|
|
jmp GETRIGHT
|
|
jmp GETUP
|
|
jmp GETDOWN
|
|
|
|
jmp CMPSPACE
|
|
jmp CMPBARR
|
|
jmp ADDKIDOBJ
|
|
jmp ADDSHADOBJ
|
|
jmp ADDREFLOBJ
|
|
|
|
jmp LOADKID
|
|
jmp LOADSHAD
|
|
jmp SAVEKID
|
|
jmp SAVESHAD
|
|
jmp SETUPCHAR
|
|
|
|
jmp GETFRAMEINFO
|
|
jmp INDEXBLOCK
|
|
jmp MARKRED
|
|
jmp MARKFRED
|
|
jmp MARKWIPE
|
|
|
|
jmp MARKMOVE
|
|
jmp MARKFLOOR
|
|
jmp UNINDEX
|
|
jmp QUICKFLOOR
|
|
jmp UNEVENFLOOR
|
|
|
|
jmp MARKHALF
|
|
jmp ADDSWORDOBJ
|
|
jmp GETBLOCKYP
|
|
jmp CHECKLEDGE
|
|
jmp GET2INFRONT
|
|
|
|
jmp CHECKSPIKES
|
|
jmp RECHARGEMETER
|
|
jmp ADDFCHARX
|
|
jmp FACEDX
|
|
jmp JUMPSEQ
|
|
|
|
jmp GETBASEBLOCK
|
|
jmp LOADKIDWOP
|
|
jmp SAVEKIDWOP
|
|
jmp GETOPDIST
|
|
jmp LOADSHADWOP
|
|
|
|
jmp SAVESHADWOP
|
|
jmp BOOSTMETER
|
|
jmp GETUNDERFT
|
|
jmp GETINFRONT
|
|
jmp GETBEHIND
|
|
|
|
jmp GETABOVE
|
|
jmp GETABOVEINF
|
|
jmp CMPWALL
|
|
|
|
*-------------------------------
|
|
lst
|
|
put eq
|
|
lst
|
|
put gameeq
|
|
lst
|
|
put movedata
|
|
lst
|
|
put seqdata
|
|
lst
|
|
put soundnames
|
|
lst off
|
|
|
|
*-------------------------------
|
|
dum locals
|
|
|
|
tempright ds 1
|
|
ztemp ds 2
|
|
tempstate ds 1
|
|
]cutdir ds 1
|
|
|
|
dend
|
|
|
|
*-------------------------------
|
|
* Misc. data
|
|
|
|
plus1 db -1,1
|
|
minus1 db 1,-1
|
|
|
|
maxmaxstr = 10 ;strength meter maximum
|
|
|
|
thinner = 3
|
|
|
|
*-------------------------------
|
|
*
|
|
* R E A D B L O C K
|
|
*
|
|
* In: A = screen #
|
|
* X = block x (0-9 onscreen)
|
|
* Y = block y (0-2 onscreen)
|
|
*
|
|
* Out: A,X = objid
|
|
* Y = block # (0-29)
|
|
* BlueType, BlueSpec set
|
|
* tempscrn,tempblockx,tempblocky = onscreen block coords
|
|
*
|
|
* - Offscreen block values are traced to their home screen
|
|
* - Screen 0 is treated as a solid mass
|
|
*
|
|
*-------------------------------
|
|
RDBLOCK
|
|
sta tempscrn
|
|
stx tempblockx
|
|
sty tempblocky
|
|
|
|
RDBLOCK1
|
|
jsr handler ;handle offscreen references
|
|
|
|
lda tempscrn
|
|
beq :nullscrn ;screen 0
|
|
jsr calcblue ;returns BlueType/Spec
|
|
|
|
ldy tempblocky
|
|
lda Mult10,y
|
|
clc
|
|
adc tempblockx
|
|
tay
|
|
lda (BlueType),y
|
|
and #idmask
|
|
tax ;return result in X & A
|
|
rts
|
|
|
|
:nullscrn lda #block
|
|
tax
|
|
rts
|
|
|
|
*-------------------------------
|
|
* Handle offscreen block references (recursive)
|
|
|
|
handler lda tempblockx
|
|
bpl :1
|
|
jsr offleft
|
|
jmp handler
|
|
|
|
:1 cmp #10
|
|
bcc :2
|
|
jsr offrt
|
|
jmp handler
|
|
|
|
:2 lda tempblocky
|
|
bpl :3
|
|
jsr offtop
|
|
jmp handler
|
|
|
|
:3 cmp #3
|
|
bcc :rts
|
|
jsr offbot
|
|
jmp handler
|
|
|
|
:rts rts
|
|
|
|
offtop clc
|
|
adc #3
|
|
sta tempblocky
|
|
|
|
lda tempscrn
|
|
jsr GETUP
|
|
sta tempscrn
|
|
rts
|
|
|
|
offbot sec
|
|
sbc #3
|
|
sta tempblocky
|
|
|
|
lda tempscrn
|
|
jsr GETDOWN
|
|
sta tempscrn
|
|
rts
|
|
|
|
offleft clc
|
|
adc #10
|
|
sta tempblockx
|
|
|
|
lda tempscrn
|
|
jsr GETLEFT
|
|
sta tempscrn
|
|
rts
|
|
|
|
offrt sec
|
|
sbc #10
|
|
sta tempblockx
|
|
|
|
lda tempscrn
|
|
jsr GETRIGHT
|
|
sta tempscrn
|
|
]rts rts
|
|
|
|
*-------------------------------
|
|
*
|
|
* Get adjacent screen numbers
|
|
*
|
|
* In: A = original screen #
|
|
* Out: A = adjacent screen #
|
|
*
|
|
*-------------------------------
|
|
GETLEFT
|
|
beq ]rts
|
|
asl
|
|
asl
|
|
tax
|
|
lda MAP-4,x
|
|
]rts rts
|
|
|
|
GETRIGHT
|
|
beq ]rts
|
|
asl
|
|
asl
|
|
tax
|
|
lda MAP-3,x
|
|
rts
|
|
|
|
GETUP
|
|
beq ]rts
|
|
asl
|
|
asl
|
|
tax
|
|
lda MAP-2,x
|
|
rts
|
|
|
|
GETDOWN
|
|
beq ]rts
|
|
asl
|
|
asl
|
|
tax
|
|
lda MAP-1,x
|
|
rts
|
|
|
|
*-------------------------------
|
|
*
|
|
* G E T S C R E E N S
|
|
*
|
|
* Get VisScrn's 8 surrounding screens from map
|
|
* (Store in scrnAbove, scrnBelow, etc.)
|
|
*
|
|
*-------------------------------
|
|
GETSCRNS
|
|
lda VisScrn
|
|
jsr GETLEFT
|
|
sta scrnLeft
|
|
|
|
lda VisScrn
|
|
jsr GETRIGHT
|
|
sta scrnRight
|
|
|
|
lda VisScrn
|
|
jsr GETUP
|
|
sta scrnAbove
|
|
|
|
lda VisScrn
|
|
jsr GETDOWN
|
|
sta scrnBelow
|
|
|
|
* and diagonals
|
|
|
|
lda scrnBelow
|
|
jsr GETLEFT
|
|
sta scrnBelowL
|
|
|
|
lda scrnBelow
|
|
jsr GETRIGHT
|
|
sta scrnBelowR
|
|
|
|
lda scrnAbove
|
|
jsr GETLEFT
|
|
sta scrnAboveL
|
|
|
|
lda scrnAbove
|
|
jsr GETRIGHT
|
|
sta scrnAboveR
|
|
]rts rts
|
|
|
|
*-------------------------------
|
|
*
|
|
* G E T B A S E X
|
|
*
|
|
* In: Char data; frame data
|
|
*
|
|
* Out: A = character's base X-coord
|
|
*
|
|
*-------------------------------
|
|
GETBASEX
|
|
lda Fcheck
|
|
and #Ffootmark
|
|
;# pixels to count in from left edge of image
|
|
eor #$ff
|
|
clc
|
|
adc #1 ;- Fcheck
|
|
|
|
clc
|
|
adc Fdx ;Fdx (+ = fwd, - = bkwd)
|
|
|
|
jmp ADDCHARX ;Add to CharX in direction char is facing
|
|
|
|
*-------------------------------
|
|
*
|
|
* Add A to CharX in direction char is facing
|
|
*
|
|
* In: A = # pixels to add (+ = fwd, - = bkwd)
|
|
* CharX = original char X-coord
|
|
* CharFace = direction char is facing
|
|
*
|
|
* Out: A = new char X-coord
|
|
*
|
|
*-------------------------------
|
|
ADDCHARX
|
|
bit CharFace ;-1 = left (normal)
|
|
bpl :right ;0 = right (mirrored)
|
|
|
|
eor #$ff
|
|
clc
|
|
adc #1 ;A := -A
|
|
|
|
:right clc
|
|
adc CharX
|
|
rts
|
|
|
|
*-------------------------------
|
|
*
|
|
* Add A to FCharX
|
|
* (A range: -127 to 127)
|
|
*
|
|
* In: A; FChar data
|
|
* Out: FCharX
|
|
*
|
|
*-------------------------------
|
|
ADDFCHARX
|
|
sta ztemp
|
|
bpl :1 ;hibit clr
|
|
|
|
lda #0
|
|
sec
|
|
sbc ztemp
|
|
sta ztemp ;make it posititve
|
|
|
|
lda #$ff ;hibit set
|
|
:1 eor FCharFace
|
|
bmi :left
|
|
|
|
lda ztemp
|
|
clc
|
|
adc FCharX
|
|
sta FCharX
|
|
|
|
lda FCharX+1
|
|
adc #0
|
|
sta FCharX+1
|
|
rts
|
|
|
|
:left lda FCharX
|
|
sec
|
|
sbc ztemp
|
|
sta FCharX
|
|
|
|
lda FCharX+1
|
|
sbc #0
|
|
sta FCharX+1
|
|
rts
|
|
|
|
*-------------------------------
|
|
*
|
|
* In: CharFace,CharBlockX,CharBlockY,CharScrn
|
|
*
|
|
* Out: Results of RDBLOCK for block underfoot/in front/etc.
|
|
*
|
|
*-------------------------------
|
|
GETUNDERFT
|
|
ldx CharBlockX
|
|
ldy CharBlockY
|
|
lda CharScrn
|
|
jmp RDBLOCK
|
|
|
|
GETINFRONT
|
|
ldx CharFace
|
|
inx
|
|
lda CharBlockX
|
|
clc
|
|
adc plus1,x
|
|
sta infrontx
|
|
tax
|
|
|
|
ldy CharBlockY
|
|
lda CharScrn
|
|
jmp RDBLOCK
|
|
|
|
GET2INFRONT
|
|
ldx CharFace
|
|
inx
|
|
lda CharBlockX
|
|
clc
|
|
adc plus1,x
|
|
clc
|
|
adc plus1,x
|
|
tax
|
|
|
|
ldy CharBlockY
|
|
lda CharScrn
|
|
jmp RDBLOCK
|
|
|
|
GETBEHIND
|
|
ldx CharFace
|
|
inx
|
|
lda CharBlockX
|
|
clc
|
|
adc minus1,x
|
|
sta behindx
|
|
tax
|
|
|
|
ldy CharBlockY
|
|
lda CharScrn
|
|
jmp RDBLOCK
|
|
|
|
GETABOVE
|
|
ldy CharBlockY
|
|
dey
|
|
sty abovey
|
|
|
|
ldx CharBlockX
|
|
lda CharScrn
|
|
jmp RDBLOCK
|
|
|
|
GETABOVEINF
|
|
ldx CharFace
|
|
inx
|
|
lda CharBlockX
|
|
clc
|
|
adc plus1,x
|
|
sta infrontx
|
|
tax
|
|
|
|
ldy CharBlockY
|
|
dey
|
|
sty abovey
|
|
|
|
lda CharScrn
|
|
jmp RDBLOCK
|
|
|
|
GETABOVEBEH
|
|
ldx CharFace
|
|
inx
|
|
lda CharBlockX
|
|
clc
|
|
adc minus1,x
|
|
sta behindx
|
|
tax
|
|
|
|
ldy CharBlockY
|
|
dey
|
|
sty abovey
|
|
|
|
lda CharScrn
|
|
jmp RDBLOCK
|
|
|
|
*-------------------------------
|
|
*
|
|
* G E T D I S T A N C E
|
|
*
|
|
* In: Char data
|
|
*
|
|
* Out: A = # of pixels (0-13) to add to CharX to move
|
|
* char base X-coord to end of current block
|
|
*
|
|
*-------------------------------
|
|
GETDIST
|
|
jsr GETBASEX ;returns A = base X-coord
|
|
|
|
GETDIST1
|
|
jsr GETBLOCKXP ;returns A = block #, OFFSET = pixel #
|
|
|
|
lda CharFace ;0=right, -1=left
|
|
beq :facingright
|
|
|
|
:facingleft
|
|
lda OFFSET
|
|
rts
|
|
|
|
:facingright
|
|
lda #13
|
|
sec
|
|
sbc OFFSET
|
|
rts
|
|
|
|
*-------------------------------
|
|
*
|
|
* G E T B L O C K E D G E
|
|
*
|
|
* In: A = block # (-5 to 14)
|
|
* Out: A = screen X-coord of left edge
|
|
*
|
|
*-------------------------------
|
|
GETBLOCKEJ
|
|
clc
|
|
adc #5
|
|
tax
|
|
lda BlockEdge,x
|
|
rts
|
|
|
|
*-------------------------------
|
|
*
|
|
* G E T B L O C K X
|
|
*
|
|
* In: A = X-coord
|
|
*
|
|
* Out: A = # of the 14-pixel-wide block within which
|
|
* this pixel falls (0-9 onscreen)
|
|
*
|
|
* OFFSET = pixel within this block
|
|
*
|
|
* - Use GETBLOCKXP for objects on center plane
|
|
* - Use GETBLOCKX for absolute X-coords & foreground plane
|
|
*
|
|
*-------------------------------
|
|
GETBLOCKXP
|
|
sec
|
|
sbc #angle
|
|
|
|
GETBLOCKX
|
|
tay
|
|
|
|
lda PixelTable,y
|
|
sta OFFSET
|
|
|
|
lda BlockTable,y
|
|
rts
|
|
|
|
*-------------------------------
|
|
*
|
|
* G E T B L O C K Y
|
|
*
|
|
* In: A = screen Y-coord (0-255)
|
|
*
|
|
* Out: A = block y (3 = o.s.)
|
|
*
|
|
* - Use GETBLOCKYP for objects on center plane
|
|
* - Use GETBLOCKY for absolute Y-coords & foreground plane
|
|
*
|
|
*-------------------------------
|
|
GETBLOCKY
|
|
ldx #3
|
|
:loop cmp BlockTop+1,x
|
|
bcs :gotY
|
|
dex
|
|
bpl :loop
|
|
:gotY txa
|
|
rts
|
|
|
|
|
|
GETBLOCKYP
|
|
ldx #3
|
|
:loop cmp FloorY+1,x
|
|
bcs :gotY
|
|
dex
|
|
bpl :loop
|
|
:gotY txa
|
|
]rts rts
|
|
|
|
*-------------------------------
|
|
*
|
|
* I N D E X B L O C K
|
|
*
|
|
* Index (tempblockx,tempblocky)
|
|
*
|
|
* Return y = block # (0-29) and cc if block is onscreen
|
|
* y = 0 to 9 and cs if block is on screen above
|
|
* y = 30 and cs if block is o.s.
|
|
*
|
|
*-------------------------------
|
|
INDEXBLOCK
|
|
ldy tempblocky
|
|
bmi :above
|
|
cpy #3
|
|
bcs :os
|
|
|
|
lda tempblockx
|
|
cmp #10
|
|
bcs :os ;0 <= tempblockx <= 9
|
|
|
|
clc
|
|
adc Mult10,y
|
|
|
|
tay ;return y = block #
|
|
clc ;and carry clr
|
|
rts
|
|
|
|
:os ldy #30
|
|
sec ;and carry set
|
|
rts
|
|
|
|
:above ldy tempblockx
|
|
sec
|
|
]rts rts
|
|
|
|
*-------------------------------
|
|
*
|
|
* U N I N D E X
|
|
*
|
|
* In: A = block index (0-29)
|
|
* Out: A = blockx, X = blocky
|
|
*
|
|
*-------------------------------
|
|
UNINDEX
|
|
ldx #0
|
|
:loop cmp #10
|
|
bcc ]rts
|
|
sec
|
|
sbc #10
|
|
inx
|
|
bne :loop
|
|
]rts rts
|
|
|
|
*-------------------------------
|
|
*
|
|
* G E T B A S E B L O C K
|
|
*
|
|
* In: Char data
|
|
* Out: CharBlockX
|
|
*
|
|
*-------------------------------
|
|
GETBASEBLOCK
|
|
jsr getbasex
|
|
jsr getblockxp
|
|
sta CharBlockX
|
|
]rts rts
|
|
|
|
*-------------------------------
|
|
*
|
|
* F A C E D X
|
|
*
|
|
* In: CharFace; A = DX
|
|
*
|
|
* Out: DX if char is facing right, -DX if facing left
|
|
*
|
|
*-------------------------------
|
|
FACEDX
|
|
bit CharFace
|
|
bmi ]rts
|
|
|
|
eor #$ff
|
|
clc
|
|
adc #1 ;negate
|
|
|
|
]rts rts
|
|
|
|
*-------------------------------
|
|
*
|
|
* J U M P S E Q
|
|
*
|
|
* Jump to some other point in sequence table
|
|
*
|
|
* In: A = sequence # (1-127)
|
|
*
|
|
*-------------------------------
|
|
JUMPSEQ
|
|
sec
|
|
sbc #1
|
|
asl
|
|
tax ;x = 2(a-1)
|
|
|
|
lda seqtab,x
|
|
sta CharSeq
|
|
|
|
lda seqtab+1,x
|
|
sta CharSeq+1
|
|
]rts rts
|
|
|
|
*-------------------------------
|
|
*
|
|
* Similar routine for Opponent
|
|
*
|
|
*-------------------------------
|
|
OPJUMPSEQ
|
|
sec
|
|
sbc #1
|
|
asl
|
|
tax ;x = 2(a-1)
|
|
|
|
lda seqtab,x
|
|
sta OpSeq
|
|
|
|
lda seqtab+1,x
|
|
sta OpSeq+1
|
|
]rts rts
|
|
|
|
*-------------------------------
|
|
*
|
|
* I N D E X C H A R
|
|
*
|
|
* In: Char data; GETEDGES results
|
|
*
|
|
* Out: FCharIndex = character block index
|
|
*
|
|
*-------------------------------
|
|
INDEXCHAR
|
|
lda CharAction
|
|
cmp #1
|
|
bne :4
|
|
;If CharAction = 1 (on solid ground)
|
|
;use leftblock/bottomblock
|
|
lda bottomblock
|
|
sta tempblocky
|
|
|
|
lda leftblock
|
|
:1 sta tempblockx
|
|
|
|
lda CharPosn
|
|
cmp #135
|
|
bcc :2
|
|
cmp #149
|
|
bcc :climbup
|
|
|
|
:2 cmp #2
|
|
beq :fall
|
|
cmp #3
|
|
beq :fall
|
|
cmp #4
|
|
beq :fall
|
|
cmp #6
|
|
bne :3
|
|
:fall
|
|
:climbup dec tempblockx ;if falling or climbing up
|
|
|
|
:3 jsr indexblock
|
|
sty FCharIndex
|
|
rts
|
|
|
|
* else use CharBlockX/Y
|
|
|
|
:4 lda CharBlockY
|
|
sta tempblocky
|
|
|
|
lda CharBlockX
|
|
jmp :1
|
|
|
|
*-------------------------------
|
|
*
|
|
* S E T U P C H A R
|
|
*
|
|
* Set up character for FRAMEADV
|
|
*
|
|
* In: Char data
|
|
* Out: FChar data
|
|
*
|
|
* Translate char data into the form "addchar" expects
|
|
* (Decode image #; get actual 280 x 192 screen coords)
|
|
*
|
|
*-------------------------------
|
|
SETUPCHAR
|
|
jsr zerocrop ;(can call cropchar later)
|
|
|
|
jsr GETFRAMEINFO
|
|
|
|
lda CharFace
|
|
sta FCharFace
|
|
|
|
jsr decodeim ;get FCharImage & Table from
|
|
;encoded Fimage & Fsword data
|
|
lda #0
|
|
sta FCharX+1
|
|
|
|
lda Fdx
|
|
jsr addcharx ;A := CharX + Fdx
|
|
sec
|
|
sbc #ScrnLeft ;different coord system
|
|
sta FCharX
|
|
|
|
asl FCharX
|
|
rol FCharX+1
|
|
beq :pos
|
|
|
|
lda FCharX
|
|
cmp #$f0
|
|
bcc :pos
|
|
lda #$ff
|
|
sta FCharX+1
|
|
:pos ;X := 2X
|
|
lda Fdy
|
|
clc
|
|
adc CharY
|
|
sec
|
|
sbc #ScrnTop
|
|
sta FCharY
|
|
|
|
lda Fcheck
|
|
eor FCharFace ;Look only at the hibits
|
|
bmi :ok ;They don't match-->even X-coord
|
|
;They match-->odd X-coord
|
|
lda FCharX
|
|
clc
|
|
adc #1
|
|
sta FCharX
|
|
bcc :ok
|
|
inc FCharX+1
|
|
:ok
|
|
]rts rts
|
|
|
|
*-------------------------------
|
|
*
|
|
* S E T U P S W O R D
|
|
*
|
|
* In: Char & FChar data
|
|
*
|
|
* If character's sword is visible, add it to obj table
|
|
*
|
|
*-------------------------------
|
|
SETUPSWORD
|
|
lda CharID
|
|
cmp #2
|
|
bne :3
|
|
lda CharLife
|
|
bmi :2 ;live guard's sword is always visible
|
|
|
|
:3 lda CharPosn
|
|
cmp #229
|
|
bcc :1
|
|
cmp #238
|
|
bcc :2 ;sheathing
|
|
:1 lda CharSword
|
|
beq ]rts
|
|
:2
|
|
lda Fsword
|
|
and #$3f ;frame #
|
|
beq ]rts ;no sword for this frame
|
|
|
|
jsr getswordframe
|
|
|
|
ldy #0
|
|
lda (framepoint),y
|
|
beq ]rts
|
|
|
|
jsr decodeswim ;get FCharImage & Table
|
|
|
|
iny
|
|
lda (framepoint),y
|
|
sta Fdx
|
|
|
|
iny
|
|
lda (framepoint),y
|
|
sta Fdy
|
|
|
|
lda Fdx
|
|
jsr ADDFCHARX ;A := FCharX + Fdx
|
|
|
|
lda Fdy
|
|
clc
|
|
adc FCharY
|
|
sta FCharY
|
|
|
|
jmp ADDSWORDOBJ
|
|
|
|
*-------------------------------
|
|
*
|
|
* G E T F R A M E
|
|
*
|
|
* In: A = frame # (1-192)
|
|
* Out: framepoint = 2-byte pointer to frame def table
|
|
*
|
|
*-------------------------------
|
|
GETFRAME ;Kid uses main char set
|
|
jsr getfindex
|
|
lda framepoint
|
|
clc
|
|
adc #Fdef
|
|
sta framepoint
|
|
lda framepoint+1
|
|
adc #>Fdef
|
|
sta framepoint+1
|
|
rts
|
|
|
|
*-------------------------------
|
|
getaltframe1 ;Enemy uses alt set 1
|
|
jsr getfindex
|
|
lda framepoint
|
|
clc
|
|
adc #altset1
|
|
sta framepoint
|
|
lda framepoint+1
|
|
adc #>altset1
|
|
sta framepoint+1
|
|
rts
|
|
|
|
*-------------------------------
|
|
getaltframe2 ;Princess & Vizier use alt set 2
|
|
jsr getfindex
|
|
lda framepoint
|
|
clc
|
|
adc #altset2
|
|
sta framepoint
|
|
lda framepoint+1
|
|
adc #>altset2
|
|
sta framepoint+1
|
|
rts
|
|
|
|
*-------------------------------
|
|
getfindex
|
|
sec
|
|
sbc #1
|
|
sta ztemp
|
|
sta framepoint
|
|
|
|
lda #0
|
|
sta ztemp+1
|
|
sta framepoint+1
|
|
|
|
asl framepoint
|
|
rol framepoint+1
|
|
asl framepoint
|
|
rol framepoint+1 ;2-byte multiply by 4
|
|
|
|
lda framepoint
|
|
clc
|
|
adc ztemp
|
|
sta framepoint
|
|
|
|
lda framepoint+1
|
|
adc ztemp+1
|
|
sta framepoint+1 ;make it x5
|
|
rts
|
|
|
|
*-------------------------------
|
|
*
|
|
* getswordframe
|
|
*
|
|
* In: A = frame #
|
|
* Out: framepoint
|
|
*
|
|
*-------------------------------
|
|
getswordframe
|
|
sec
|
|
sbc #1
|
|
sta ztemp
|
|
sta framepoint
|
|
|
|
lda #0
|
|
sta ztemp+1
|
|
sta framepoint+1
|
|
|
|
asl framepoint
|
|
rol framepoint+1 ;x2
|
|
|
|
lda framepoint
|
|
clc
|
|
adc ztemp
|
|
sta framepoint
|
|
|
|
lda framepoint+1
|
|
adc ztemp+1
|
|
sta framepoint+1 ;+1 is 3
|
|
|
|
lda framepoint
|
|
clc
|
|
adc #swordtab
|
|
sta framepoint
|
|
|
|
lda framepoint+1
|
|
adc #>swordtab
|
|
sta framepoint+1
|
|
|
|
rts
|
|
|
|
*-------------------------------
|
|
*
|
|
* Decode char image
|
|
*
|
|
* In: Fimage, Fsword (encoded)
|
|
*
|
|
* Out: FCharImage (image #, 0-127)
|
|
* FCharTable (table #, 0-7)
|
|
*
|
|
*-------------------------------
|
|
decodeim
|
|
lda Fimage
|
|
and #%10000000 ;bit 2 of table #
|
|
sta ztemp
|
|
|
|
lda Fsword
|
|
and #%11000000 ;bits 0-1 of table #
|
|
|
|
lsr
|
|
adc ztemp
|
|
lsr
|
|
lsr
|
|
lsr
|
|
lsr
|
|
lsr
|
|
sta FCharTable
|
|
|
|
lda Fimage
|
|
and #$7f
|
|
ora timebomb ;must be 0!
|
|
sta FCharImage
|
|
|
|
rts
|
|
|
|
*-------------------------------
|
|
*
|
|
* Decode sword image
|
|
*
|
|
* In: A = image #
|
|
*
|
|
* Out: FCharImage, FCharTable
|
|
*
|
|
*-------------------------------
|
|
decodeswim
|
|
sta FCharImage ;image #
|
|
|
|
lda #2 ;chtable3
|
|
sta FCharTable
|
|
rts
|
|
|
|
*-------------------------------
|
|
*
|
|
* G E T E D G E S
|
|
*
|
|
* Get edges of character image
|
|
*
|
|
* In: FChar data as set by "setframe"
|
|
*
|
|
* Out: leftej/rightej/topej = boundaries of image (140-res)
|
|
* leftblock, rightblock, topblock, bottomblock
|
|
* CDLeftEj, CDRightEj (for coll detection)
|
|
* imheight, imwidth
|
|
*
|
|
*-------------------------------
|
|
GETEDGES
|
|
lda FCharImage
|
|
ldx FCharTable
|
|
jsr dimchar ;return A = image width, x = height
|
|
stx imheight
|
|
|
|
tax ;image width in bytes
|
|
lda Mult7,x ;in 1/2 pixels
|
|
clc
|
|
adc #1 ;add 1/2 pixel
|
|
lsr ;and divide by 2
|
|
sta imwidth ;to get width in pixels
|
|
|
|
lda FCharX+1
|
|
lsr
|
|
lda FCharX
|
|
ror
|
|
clc
|
|
adc #ScrnLeft ;convert back to 140-res
|
|
|
|
* (If facing LEFT, X-coord is leftmost pixel of LEFTMOST byte
|
|
* of image; if facing RIGHT, leftmost pixel of RIGHTMOST byte.)
|
|
|
|
ldx CharFace
|
|
bmi :ok ;facing L
|
|
;facing R
|
|
sec
|
|
sbc imwidth
|
|
|
|
:ok sta leftej
|
|
clc
|
|
adc imwidth
|
|
sta rightej
|
|
|
|
lda FCharY
|
|
sec
|
|
sbc imheight
|
|
clc
|
|
adc #1
|
|
|
|
cmp #192
|
|
bcc :ok2
|
|
lda #0
|
|
|
|
:ok2 sta topej
|
|
|
|
jsr getblocky
|
|
|
|
cmp #3
|
|
bne :1
|
|
lda #-1 ;if o.s., call it -1
|
|
|
|
:1 sta topblock
|
|
|
|
lda FCharY
|
|
jsr getblocky ;if o.s., call it 3
|
|
sta bottomblock
|
|
|
|
lda leftej
|
|
jsr getblockx ;leftmost affected block
|
|
sta leftblock
|
|
|
|
lda rightej
|
|
jsr getblockx ;rightmost affected block
|
|
sta rightblock
|
|
|
|
* get leading edge (for collision detection)
|
|
|
|
lda #0
|
|
sta ztemp
|
|
|
|
lda Fcheck
|
|
and #Fthinmark
|
|
beq :nothin
|
|
|
|
lda #thinner ;make character 3 bits thinner
|
|
sta ztemp ;on both sides
|
|
|
|
:nothin lda leftej
|
|
clc
|
|
adc ztemp
|
|
sta CDLeftEj
|
|
|
|
lda rightej
|
|
sec
|
|
sbc ztemp
|
|
sta CDRightEj
|
|
|
|
]rts rts
|
|
|
|
*===============================
|
|
*
|
|
* Q U I C K F L O O R
|
|
*
|
|
* Mark for redraw whatever floorpieces character might be
|
|
* impinging on
|
|
*
|
|
* In: CharData; GETEDGES results
|
|
*
|
|
*-------------------------------
|
|
QUICKFLOOR
|
|
lda CharPosn
|
|
cmp #135
|
|
bcc :2
|
|
cmp #149
|
|
bcc :climbup
|
|
|
|
:2 lda CharAction
|
|
cmp #1
|
|
bne :1
|
|
|
|
lda CharPosn
|
|
cmp #78
|
|
bcc ]rts
|
|
cmp #80
|
|
bcc :fall
|
|
]rts rts
|
|
|
|
:1 cmp #2
|
|
beq :fall
|
|
cmp #3
|
|
beq :fall
|
|
cmp #4
|
|
beq :fall
|
|
cmp #6
|
|
bne ]rts
|
|
|
|
:fall lda #markfloor
|
|
ldx #>markfloor
|
|
bne :cont1
|
|
|
|
:climbup
|
|
lda #markhalf
|
|
ldx #>markhalf
|
|
|
|
* Mark floorbuf/halfbuf for up to 6 affected blocks
|
|
* Start with rightblock, work left to leftblock
|
|
|
|
:cont1
|
|
sta marksm1+1
|
|
sta marksm2+1
|
|
stx marksm1+2
|
|
stx marksm2+2
|
|
|
|
lda rightblock
|
|
:loop sta tempblockx
|
|
|
|
jsr markul
|
|
|
|
lda tempblockx
|
|
cmp leftblock
|
|
beq ]rts
|
|
sec
|
|
sbc #1
|
|
bpl :loop
|
|
|
|
]rts rts
|
|
|
|
* mark upper & lower blocks for this blockx
|
|
|
|
markul
|
|
lda bottomblock
|
|
sta tempblocky
|
|
|
|
jsr indexblock ;lower block
|
|
lda #2
|
|
marksm1 jsr markhalf
|
|
|
|
lda topblock
|
|
cmp bottomblock
|
|
beq ]rts
|
|
sta tempblocky
|
|
|
|
jsr indexblock ;upper block
|
|
lda #2
|
|
marksm2 jmp markhalf
|
|
|
|
*-------------------------------
|
|
*
|
|
* Q U I C K F G
|
|
*
|
|
* Mark for redraw any f.g. elements char (or his sword)
|
|
* might be impinging on
|
|
*
|
|
* In: Char data; left/right/top/bottomblock
|
|
*
|
|
*-------------------------------
|
|
QUICKFG
|
|
|
|
* Quick fix to cover sword
|
|
|
|
lda CharSword
|
|
cmp #2
|
|
bcc :cont
|
|
|
|
lda CharFace
|
|
bpl :faceR
|
|
dec leftblock
|
|
jmp :cont
|
|
|
|
:faceR inc rightblock
|
|
|
|
* Continue
|
|
|
|
:cont lda bottomblock
|
|
:outloop
|
|
sta tempblocky
|
|
|
|
lda rightblock
|
|
:loop sta tempblockx
|
|
|
|
jsr indexblock
|
|
lda #3
|
|
jsr MARKFRED
|
|
|
|
lda tempblockx
|
|
cmp leftblock
|
|
beq :end
|
|
sec
|
|
sbc #1
|
|
bpl :loop
|
|
:end
|
|
lda tempblocky
|
|
cmp topblock
|
|
beq ]rts
|
|
sec
|
|
sbc #1
|
|
bpl :outloop
|
|
rts
|
|
|
|
]bug jmp showpage
|
|
|
|
*-------------------------------
|
|
*
|
|
* C R O P C H A R A C T E R
|
|
*
|
|
* In: FChar data as set by "setframe"
|
|
* leftej,rightej, etc. as set by "getedges"
|
|
*
|
|
* Out: FCharCL/CR/CU/CD
|
|
*
|
|
*-------------------------------
|
|
CROPCHAR
|
|
|
|
* If char is climbing stairs, mask door
|
|
|
|
lda CharPosn
|
|
cmp #224
|
|
bcc :nost
|
|
cmp #229
|
|
bcs :nost
|
|
lda doortop ;set by drawexitb
|
|
clc
|
|
adc #2
|
|
cmp FCharY
|
|
bcs :bug ;temp!
|
|
sta FCharCU
|
|
]rts rts
|
|
:bug ldy #$F0
|
|
jsr showpage
|
|
:nost
|
|
|
|
* If char is under solid (a&b) floor, crop top
|
|
|
|
ldx leftblock
|
|
ldy topblock
|
|
lda CharScrn
|
|
jsr rdblock
|
|
cmp #block
|
|
beq :1
|
|
jsr cmpspace
|
|
beq :not
|
|
|
|
* Special case (more lenient): if char is jumping
|
|
* up to touch ceiling
|
|
|
|
:1 lda CharAction
|
|
bne :10
|
|
lda CharPosn
|
|
cmp #79
|
|
beq :2
|
|
cmp #81
|
|
bne :10
|
|
beq :2
|
|
|
|
* Otherwise, both left & right topblocks must be solid
|
|
|
|
:10 ldx rightblock
|
|
ldy topblock
|
|
lda CharScrn
|
|
jsr rdblock
|
|
cmp #block
|
|
beq :2
|
|
jsr cmpspace
|
|
beq :not
|
|
|
|
:2 ldx CharBlockY
|
|
inx
|
|
cpx #1
|
|
beq :ok
|
|
|
|
lda BlockTop,x
|
|
cmp FCharY
|
|
bcs :not
|
|
|
|
sec
|
|
sbc #floorheight
|
|
cmp topej
|
|
bcs :not
|
|
|
|
:ok lda BlockTop,x
|
|
sta FCharCU
|
|
sta topej
|
|
:not
|
|
|
|
* If char is standing left of a panel, crop R
|
|
* Char is considered "left" if CDLeftEj falls within
|
|
* panel block
|
|
|
|
lda CDLeftEj
|
|
jsr getblockx
|
|
sta blockx
|
|
|
|
tax
|
|
ldy CharBlockY
|
|
lda CharScrn
|
|
jsr rdblock
|
|
|
|
cmp #panelwof
|
|
beq :r
|
|
cmp #panelwif
|
|
bne :nor
|
|
|
|
* Char's foot is within panel block
|
|
* Special case: If character is hanging R, we don't
|
|
* need to check his head
|
|
|
|
:r lda CharFace
|
|
bmi :cont
|
|
|
|
lda CharAction
|
|
cmp #2
|
|
beq :r2 ;yes--hanging R
|
|
|
|
* Check block to right of char's head
|
|
|
|
:cont
|
|
ldx blockx
|
|
ldy topblock
|
|
lda CharScrn
|
|
jsr rdblock
|
|
|
|
cmp #block
|
|
beq :r2
|
|
cmp #panelwof
|
|
beq :r2
|
|
cmp #panelwif
|
|
bne :nor
|
|
|
|
* Also a panel -- make a wall
|
|
|
|
:r2 lda tempblockx
|
|
asl
|
|
asl
|
|
clc
|
|
adc #4
|
|
sta FCharCR
|
|
rts
|
|
|
|
* Is char standing to L of solid block?
|
|
* (i.e. does CDRightEj fall within block?)
|
|
|
|
:nor
|
|
lda CDRightEj
|
|
jsr getblockx
|
|
sta blockx
|
|
|
|
tax
|
|
ldy CharBlockY
|
|
lda CharScrn
|
|
jsr rdblock
|
|
|
|
cmp #block
|
|
bne :nob
|
|
|
|
* Foot is under block--what about head?
|
|
|
|
ldx blockx
|
|
ldy topblock
|
|
lda CharScrn
|
|
jsr rdblock
|
|
|
|
cmp #block
|
|
bne :nob
|
|
|
|
* Also a panel -- make a wall
|
|
|
|
:yescrop
|
|
lda tempscrn
|
|
cmp CharScrn
|
|
bne :nob
|
|
|
|
lda tempblockx
|
|
asl
|
|
asl
|
|
sta FCharCR
|
|
:nob
|
|
rts
|
|
|
|
*-------------------------------
|
|
*
|
|
* Z E R O C R O P
|
|
*
|
|
*-------------------------------
|
|
zerocrop
|
|
lda #0
|
|
sta FCharCU
|
|
sta FCharCL
|
|
lda #40
|
|
sta FCharCR
|
|
lda #192
|
|
sta FCharCD
|
|
rts
|
|
|
|
*===============================
|
|
*
|
|
* C O M P A R E S P A C E
|
|
*
|
|
* Is it a space (can you pass thru)?
|
|
* NOTE: Solid block is considered a space (it has no floor)
|
|
*
|
|
* In: A = objid
|
|
* Out: 0 = space, 1 = floor
|
|
*
|
|
*-------------------------------
|
|
CMPSPACE
|
|
cmp #space
|
|
beq :space
|
|
cmp #pillartop
|
|
beq :space
|
|
cmp #panelwof
|
|
beq :space
|
|
cmp #block
|
|
beq :space
|
|
cmp #archtop1
|
|
bcs :space
|
|
|
|
lda #1
|
|
rts
|
|
|
|
:space lda #0
|
|
rts
|
|
|
|
*-------------------------------
|
|
*
|
|
* C O M P A R E B A R R I E R
|
|
*
|
|
* Is it a barrier?
|
|
*
|
|
* Return A = 0 if clear, else A = barrier code #
|
|
*
|
|
*-------------------------------
|
|
CMPBARR
|
|
cmp #panelwif
|
|
beq :b1
|
|
cmp #panelwof
|
|
beq :b1
|
|
cmp #gate
|
|
bne :2
|
|
|
|
:b1 lda #1 ;panel/gate
|
|
rts
|
|
|
|
:2 cmp #mirror
|
|
beq :yes3
|
|
|
|
cmp #slicer
|
|
bne :3
|
|
|
|
:yes3 lda #3 ;mirror/slicer
|
|
rts
|
|
|
|
:3 cmp #block
|
|
bne :4
|
|
|
|
lda #4 ;block
|
|
rts
|
|
:4
|
|
:clear lda #0
|
|
:rts rts
|
|
|
|
:barr lda #1
|
|
]rts rts
|
|
|
|
*-------------------------------
|
|
*
|
|
* Is it a wall? Return 0 if yes, 1 if no
|
|
* (Solid block, or panel if you're facing L)
|
|
*
|
|
*-------------------------------
|
|
CMPWALL
|
|
cmp #block
|
|
beq :yes
|
|
ldx CharFace
|
|
bpl :no
|
|
cmp #panelwif
|
|
beq :yes
|
|
cmp #panelwof
|
|
beq :yes
|
|
:no lda #1
|
|
rts
|
|
:yes lda #0
|
|
rts
|
|
|
|
*-------------------------------
|
|
*
|
|
* Add kid/reflection/shadowman/guard to object table
|
|
*
|
|
* In: FChar data
|
|
*
|
|
*-------------------------------
|
|
ADDKIDOBJ
|
|
lda #TypeKid
|
|
jmp addcharobj
|
|
|
|
*-------------------------------
|
|
ADDREFLOBJ
|
|
lda #TypeReflect
|
|
jmp addcharobj
|
|
|
|
*-------------------------------
|
|
ADDSHADOBJ
|
|
lda #TypeShad
|
|
jmp addcharobj
|
|
|
|
*-------------------------------
|
|
ADDGUARDOBJ
|
|
lda #TypeGd
|
|
jmp addcharobj
|
|
|
|
*-------------------------------
|
|
*
|
|
* Add sword to object table
|
|
* In: FChar data for character holding sword
|
|
*
|
|
*-------------------------------
|
|
ADDSWORDOBJ
|
|
lda #TypeSword
|
|
jmp addcharobj
|
|
|
|
*-------------------------------
|
|
*
|
|
* G E T S E Q
|
|
*
|
|
* Get next byte from seqtable & advance CharSeq
|
|
* (2-byte pointer to sequence table)
|
|
*
|
|
*-------------------------------
|
|
GETSEQ
|
|
ldy #0
|
|
lda (CharSeq),y
|
|
pha
|
|
|
|
inc CharSeq
|
|
bne :done
|
|
inc CharSeq+1
|
|
|
|
:done pla
|
|
rts
|
|
|
|
*-------------------------------
|
|
*
|
|
* G E T F R A M E I N F O
|
|
*
|
|
* Get frame info for char (based on CharPosn)
|
|
*
|
|
*-------------------------------
|
|
GETFRAMEINFO
|
|
lda CharPosn
|
|
jsr GETFRAME ;set framepoint
|
|
|
|
jsr usealtsets ;if appropriate
|
|
|
|
ldy #0
|
|
lda (framepoint),y
|
|
sta Fimage
|
|
|
|
iny
|
|
lda (framepoint),y
|
|
sta Fsword
|
|
|
|
iny
|
|
lda (framepoint),y
|
|
sta Fdx
|
|
|
|
iny
|
|
lda (framepoint),y
|
|
sta Fdy
|
|
|
|
iny
|
|
lda (framepoint),y
|
|
sta Fcheck
|
|
|
|
]rts rts
|
|
|
|
*-------------------------------
|
|
*
|
|
* Use alternate character image sets
|
|
* (if appropriate)
|
|
*
|
|
* In: Char data; framepoint
|
|
* Out: framepoint
|
|
*
|
|
*-------------------------------
|
|
usealtsets
|
|
ldx CharID
|
|
beq ]rts ;kid uses main set, enemy uses alt set 1
|
|
cpx #24
|
|
beq ]rts ;mouse uses main set
|
|
cpx #5
|
|
bcs :usealt2 ;princess & vizier use alt set 2
|
|
|
|
lda CharPosn
|
|
cpx #2
|
|
bcc :1
|
|
cmp #102
|
|
bcc ]rts
|
|
cmp #107
|
|
bcs :1
|
|
;frames 102-106 (falling): substitute 172-176 altset
|
|
clc
|
|
adc #70
|
|
|
|
:1 cmp #150
|
|
bcc ]rts
|
|
cmp #190
|
|
bcs ]rts
|
|
;frames 150-189: use altset
|
|
sec
|
|
sbc #149
|
|
jmp getaltframe1
|
|
|
|
:usealt2
|
|
lda CharPosn
|
|
jmp getaltframe2
|
|
|
|
*===============================
|
|
*
|
|
* M A R K
|
|
*
|
|
* In: A = mark value (usually 2)
|
|
* Results of INDEXBLOCK:
|
|
* Y = block #; carry set or clear
|
|
*
|
|
* Out: Preserve A, Y, carry
|
|
*
|
|
*-------------------------------
|
|
]os cpy #10 ;top line from scrn above?
|
|
bcs ]rts ;no
|
|
sta topbuf,y
|
|
sec ;preserve cs
|
|
]rts rts
|
|
|
|
MARKRED
|
|
bcs ]os
|
|
sta redbuf,y
|
|
rts
|
|
|
|
MARKFRED
|
|
bcs ]rts
|
|
sta fredbuf,y
|
|
rts
|
|
|
|
MARKWIPE
|
|
bcs ]rts
|
|
pha
|
|
lda wipebuf,y
|
|
beq :2
|
|
lda height
|
|
cmp whitebuf,y ;if wipebuf is already marked,
|
|
bcc :1 ;use larger of 2 whitebuf values
|
|
:2 lda height
|
|
sta whitebuf,y
|
|
:1 pla
|
|
sta wipebuf,y
|
|
clc ;return with cc
|
|
rts
|
|
|
|
MARKMOVE
|
|
bcs ]os
|
|
sta movebuf,y
|
|
rts
|
|
|
|
MARKFLOOR
|
|
bcs ]os
|
|
sta floorbuf,y
|
|
rts
|
|
|
|
MARKHALF
|
|
bcs ]os
|
|
sta halfbuf,y
|
|
rts
|
|
|
|
*-------------------------------
|
|
*
|
|
* Z E R O R E D
|
|
*
|
|
* zero redraw buffers
|
|
*
|
|
*-------------------------------
|
|
ZERORED
|
|
lda #0
|
|
|
|
ldy #29
|
|
|
|
:loop sta redbuf,y
|
|
sta fredbuf,y
|
|
sta floorbuf,y
|
|
sta wipebuf,y
|
|
sta movebuf,y
|
|
sta objbuf,y
|
|
sta halfbuf,y
|
|
|
|
dey
|
|
bpl :loop
|
|
|
|
ldy #9
|
|
:dloop sta topbuf,y
|
|
dey
|
|
bpl :dloop
|
|
|
|
rts
|
|
|
|
*-------------------------------
|
|
*
|
|
* C H E C K L E D G E
|
|
*
|
|
* In: blockid = block that must be clear;
|
|
* A = RDBLOCK results for block that must be ledge
|
|
*
|
|
* Out: A = 1 if grabbable, 0 if not
|
|
*
|
|
*-------------------------------
|
|
CHECKLEDGE
|
|
sta ztemp
|
|
|
|
lda (BlueSpec),y
|
|
sta tempstate
|
|
|
|
lda blockid ;must be clear
|
|
|
|
cmp #block
|
|
beq :no
|
|
|
|
cmp #panelwof ;CMPSPACE considers panel w/o floor
|
|
bne :cont ;to be clear--
|
|
|
|
bit CharFace ;but it isn't if char wants to grab
|
|
bpl :no ;floorpiece to right
|
|
:cont
|
|
jsr cmpspace
|
|
bne :no
|
|
|
|
* Clear above -- is there a ledge in front?
|
|
|
|
lda ztemp ;must be a solid floorpiece
|
|
;with exposed ledge
|
|
cmp #loose
|
|
bne :notloose
|
|
|
|
bit tempstate
|
|
bne :no ;floor is already loose
|
|
|
|
:notloose
|
|
cmp #panelwif
|
|
bne :cont2 ;panel w/floor can be grabbed
|
|
;only if facing right
|
|
bit CharFace
|
|
bmi :no
|
|
|
|
:cont2 jsr cmpspace
|
|
beq :no
|
|
|
|
:yes lda #1
|
|
rts
|
|
|
|
:no lda #0
|
|
]rts rts
|
|
|
|
*-------------------------------
|
|
*
|
|
* C H E C K S P I K E S
|
|
*
|
|
* Spikes spring out when char passes over them (at any
|
|
* height).
|
|
*
|
|
*-------------------------------
|
|
CHECKSPIKES
|
|
lda rightej
|
|
jsr getblockxp
|
|
bmi ]rts
|
|
sta tempright
|
|
|
|
* for blockx = leftblock to rightblock
|
|
|
|
lda leftej
|
|
jsr getblockxp
|
|
:loop sta blockx
|
|
|
|
jsr sub
|
|
|
|
lda blockx
|
|
cmp tempright
|
|
beq ]rts
|
|
clc
|
|
adc #1
|
|
jmp :loop
|
|
|
|
sub sta tempblockx
|
|
lda CharBlockY
|
|
sta tempblocky
|
|
lda CharScrn
|
|
sta tempscrn
|
|
:loop jsr rdblock1
|
|
|
|
cmp #spikes
|
|
bne :again
|
|
jmp trigspikes
|
|
|
|
:again jsr cmpspace
|
|
bne ]rts
|
|
|
|
lda tempscrn
|
|
beq ]rts ;null scrn
|
|
cmp CharScrn
|
|
bne ]rts ;wait till he's on same screen
|
|
|
|
inc tempblocky
|
|
jmp :loop ;check 1 level below
|
|
|
|
*===============================
|
|
*
|
|
* Load/save kid/shad vars
|
|
*
|
|
*-------------------------------
|
|
numvars = 16
|
|
|
|
LOADKID
|
|
ldx #numvars-1
|
|
|
|
:loop lda Kid,x
|
|
sta Char,x
|
|
|
|
dex
|
|
bpl :loop
|
|
]rts rts
|
|
|
|
SAVEKID
|
|
ldx #numvars-1
|
|
|
|
:loop lda Char,x
|
|
sta Kid,x
|
|
|
|
dex
|
|
bpl :loop
|
|
]rts rts
|
|
|
|
LOADSHAD
|
|
ldx #numvars-1
|
|
|
|
:loop lda Shad,x
|
|
sta Char,x
|
|
|
|
dex
|
|
bpl :loop
|
|
]rts rts
|
|
|
|
|
|
SAVESHAD
|
|
ldx #numvars-1
|
|
|
|
:loop lda Char,x
|
|
sta Shad,x
|
|
|
|
dex
|
|
bpl :loop
|
|
rts
|
|
|
|
* Load kid w/ opponent
|
|
|
|
LOADKIDWOP
|
|
ldx #numvars-1
|
|
|
|
:loop lda Kid,x
|
|
sta Char,x
|
|
|
|
lda Shad,x
|
|
sta Op,x
|
|
|
|
dex
|
|
bpl :loop
|
|
rts
|
|
|
|
SAVEKIDWOP
|
|
ldx #numvars-1
|
|
|
|
:loop lda Char,x
|
|
sta Kid,x
|
|
|
|
lda Op,x
|
|
sta Shad,x
|
|
|
|
dex
|
|
bpl :loop
|
|
rts
|
|
|
|
* Load shadowman w/ opponent
|
|
|
|
LOADSHADWOP
|
|
ldx #numvars-1
|
|
|
|
:loop lda Shad,x
|
|
sta Char,x
|
|
|
|
lda Kid,x
|
|
sta Op,x
|
|
|
|
dex
|
|
bpl :loop
|
|
rts
|
|
|
|
SAVESHADWOP
|
|
ldx #numvars-1
|
|
|
|
:loop lda Char,x
|
|
sta Shad,x
|
|
|
|
lda Op,x
|
|
sta Kid,x
|
|
|
|
dex
|
|
bpl :loop
|
|
rts
|
|
|
|
*-------------------------------
|
|
*
|
|
* Recharge strength meter to max
|
|
*
|
|
*-------------------------------
|
|
RECHARGEMETER
|
|
lda MaxKidStr
|
|
sec
|
|
sbc KidStrength
|
|
sta ChgKidStr
|
|
]rts rts
|
|
|
|
*-------------------------------
|
|
*
|
|
* Boost strength meter max by 1 and recharge
|
|
*
|
|
*-------------------------------
|
|
BOOSTMETER
|
|
lda MaxKidStr
|
|
cmp #maxmaxstr
|
|
bcs :1
|
|
|
|
clc
|
|
adc #1
|
|
sta MaxKidStr
|
|
|
|
:1 jmp RECHARGEMETER
|
|
|
|
*-------------------------------
|
|
*
|
|
* Get distance between char & opponent
|
|
* (# pixels char must move fwd to reach opponent)
|
|
* If dist is greater than 127, return 127 (+ or -)
|
|
*
|
|
*-------------------------------
|
|
estwidth = 13 ;rough est of char width
|
|
|
|
GETOPDIST
|
|
lda CharScrn
|
|
cmp OpScrn
|
|
bne :safe
|
|
|
|
* First, get A = OpX-CharX (abs. value <= 127)
|
|
|
|
lda OpX
|
|
cmp CharX
|
|
bcc :neg
|
|
sec
|
|
sbc CharX
|
|
bpl :got
|
|
lda #127
|
|
bpl :got
|
|
|
|
:neg lda CharX
|
|
sec
|
|
sbc OpX
|
|
bpl :1
|
|
lda #127
|
|
:1 eor #$ff
|
|
clc
|
|
adc #1 ;negate
|
|
|
|
* If CharFace = left, negate
|
|
|
|
:got ldx CharFace
|
|
bpl :cont
|
|
eor #$ff
|
|
clc
|
|
adc #1
|
|
|
|
* If chars are facing in opposite directions,
|
|
* adjust by estimate of width of figure
|
|
|
|
:cont tax
|
|
lda CharFace
|
|
eor OpFace
|
|
bpl :done
|
|
txa
|
|
cmp #127-estwidth
|
|
bcs :done2
|
|
clc
|
|
adc #estwidth
|
|
:done2 tax
|
|
rts
|
|
|
|
:safe ldx #127 ;arbitrary large dist.
|
|
:done txa ;return value in A
|
|
]rts rts
|
|
|
|
*-------------------------------
|
|
*
|
|
* Adjust CharY for uneven floor
|
|
*
|
|
*-------------------------------
|
|
UNEVENFLOOR
|
|
jsr getunderft
|
|
cmp #dpressplate
|
|
bne ]rts
|
|
inc CharY
|
|
]rts rts
|
|
|
|
*-------------------------------
|
|
lst
|
|
ds 1
|
|
usr $a9,19,$200,*-org
|
|
lst off
|