More work on script triggers.

This commit is contained in:
Martin Haye 2015-02-27 05:33:11 -08:00
parent 5109fcf41a
commit 2b686a8629
3 changed files with 170 additions and 71 deletions

View File

@ -1724,7 +1724,7 @@ class PackPartitions
triggers.each { y, xs -> triggers.each { y, xs ->
println(" Trigger row: y=$y size=${xs.size()}") println(" Trigger row: y=$y size=${xs.size()}")
emitDataByte(y) emitDataByte(y)
emitDataByte(xs.size() * 3) // 3 bytes per trigger (x, adrlo, adrhi) emitDataByte(2 + (xs.size() * 3)) // 2 bytes for y+off, plus 3 bytes per trigger (x, adrlo, adrhi)
xs.each { x, funcAddr -> xs.each { x, funcAddr ->
println(" col: x=$x funcAddr=$funcAddr") println(" col: x=$x funcAddr=$funcAddr")
emitDataByte(x) emitDataByte(x)

View File

@ -85,6 +85,9 @@ const frontBuf = $6B
// Tile engine variables // Tile engine variables
const relX = $50 const relX = $50
const relY = $51 const relY = $51
const avatarTile= $9D // the avatar variables are set by tile engine during its draw phase
const avatarX = $9E
const avatarY = $9F
/////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////
// Font engine variables // Font engine variables
@ -98,7 +101,6 @@ const cursv = $75 // Cursor V-pos 0-23
/////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////
// Strings. // Strings.
byte helloStr[] = "Loading Lawless Legends.\n" byte helloStr[] = "Loading Lawless Legends.\n"
byte tooManyTriggers[] = "Too many triggers"
/////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////
// Global variables // Global variables
@ -108,13 +110,9 @@ word pFont
word pMap word pMap
word pScripts word pScripts
word cmdTbl[64] word cmdTbl[64]
byte nLocTrig word triggerTbl
byte locTrig_x[MAX_LOC_TRIG]
byte locTrig_y[MAX_LOC_TRIG]
word locTrig_func[MAX_LOC_TRIG]
byte prevX byte prevX
byte prevY byte prevY
word prevScript
byte prevMapNum byte prevMapNum
byte prevMapIs3D byte prevMapIs3D
byte redraw byte redraw
@ -123,6 +121,7 @@ byte cacheSky, cacheGround
word cacheX, cacheY word cacheX, cacheY
byte cacheDir byte cacheDir
byte resetLocFromCache = FALSE byte resetLocFromCache = FALSE
byte anyText = FALSE
// Movement amounts when walking at each angle // Movement amounts when walking at each angle
// Each entry consists of an X bump and a Y bump, in 8.8 fixed point // Each entry consists of an X bump and a Y bump, in 8.8 fixed point
@ -182,12 +181,26 @@ word groundNum = 10
/////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////
// Definitions used by assembly code // Definitions used by assembly code
asm __defs asm __defs
; Headers
!source "../../include/global.i" !source "../../include/global.i"
!source "../../include/plasma.i" !source "../../include/plasma.i"
!source "../../include/mem.i" !source "../../include/mem.i"
!source "../../include/fontEngine.i" !source "../../include/fontEngine.i"
; Optional debug printing support
DEBUG = 1
!if DEBUG { !source "../../include/debug.i" }
; General use
tmp = $2 tmp = $2
pTmp = $4 pTmp = $4
; Variables that get set by the tile engine when it draws
avatarTile = $9D
avatarX = $9E ; from the tile engine
avatarY = $9F ; ...ditto
end end
/////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////
@ -322,7 +335,6 @@ asm initDisplayEngine
rts rts
end end
/////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////
// Render one frame using the ray caster or tile engine (they share the same address) // Render one frame using the ray caster or tile engine (they share the same address)
// Params: none // Params: none
@ -354,43 +366,62 @@ asm checkCrossing
end end
/////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////
// Is the player's current position a physical obstruction? // Scan the trigger table for avatar's current X/Y, return the function
// Params: none asm callScriptsAsm
asm isBlocked lda evalStkL,x ; get trigger table address
txa sta pTmp ; save to zero page so we can index it
lda evalStkH,x
sta pTmp+1
; Scan the Y coordinates.
- ldy #0
lda (pTmp),y ; get Y coordinate from table
!if DEBUG { +prStr : !text "Y=",0 : +prA : +crout }
cmp #$FF ; hmm, is it end of table?
bne + ; if not, advance to next
rts ; table exhausted, give up and return.
+ iny
cmp avatarY ; is this the Y coord we're looking for?
beq + ; if yes, go scan X coords
lda (pTmp),y ; get length of this Y-X-X-X set
clc
adc pTmp ; advance past X-coord entries for this Y
sta pTmp
bcc - ; and loop to next Y coord
inc pTmp+1 ; handle page crossings
bne - ; always taken
; We've now matched the Y coord. Scan X coords.
+ lda (pTmp),y ; get limit of X-adrLo-adrHi array
sta tmp ; and save it
iny ; advance to first X-coord entry
lda #0 ; put a sentinel on the stack...
pha ; ...so we can later know the end of addresses pushed.
- lda (pTmp),y ; get X coordinate from table
!if DEBUG { +prStr : !text "X=",0 : +prA : +crout }
iny
cmp avatarX ; is this the X coord we're looking for?
bne + ; if not, advance to next
lda (pTmp),y ; found a match! save the script's address on the stack
pha pha
bit setROM iny
jsr $6006 lda (pTmp),y
tay
pla
tax
dex
tya
sta evalStkL,x
lda #0
sta evalStkH,x
bit setLcRW+lcBank2
rts
end
///////////////////////////////////////////////////////////////////////////////////////////////////
// Is there a script attached to the player's current position?
// Params: none
asm isScripted
txa
pha pha
bit setROM dey
jsr $6009 + iny ; advance over address to next X coord entry
tay iny
pla cpy tmp ; are we at end of X-coord table?
tax bmi - ; if not at end, loop to next X coord
dex ; Addresses of matching scripts are now on the stack. Call each one until we hit the sentinel.
tya - pla ; hi byte of script address
sta evalStkL,x bne + ; sentinel? if not, go call it
lda #0 rts ; hit the sentinel; we're all done.
sta evalStkH,x + sta tmp+2 ; save hi byte
bit setLcRW+lcBank2 pla ; lo byte of script address
rts sta tmp+1 ; save that too
lda #$4C ; JMP opcode
sta tmp
jsr tmp ; call the script (it's a PLASMA function, so no need to save/restore X reg)
clc
bcc - ; loop back for next script (always taken)
end end
/////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////
@ -439,6 +470,9 @@ asm displayStr
bit setROM bit setROM
txa txa
pha pha
; record that text was drawn - for clear window on next script phase
lda #1
sta textDrawn
lda evalStkL,x lda evalStkL,x
sta pTmp sta pTmp
lda evalStkH,x lda evalStkH,x
@ -526,6 +560,18 @@ def getUpperKey()
return key return key
end end
///////////////////////////////////////////////////////////////////////////////////////////////////
// Is the player's current position a physical obstruction?
def isBlocked()
return ^avatarTile & $40
end
///////////////////////////////////////////////////////////////////////////////////////////////////
// Is there a script attached to the player's current position?
def isScripted()
return ^avatarTile & $20
end
/////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////
// Set the sky color (relevant to 3D display only) // Set the sky color (relevant to 3D display only)
def setSky(num) def setSky(num)
@ -654,11 +700,11 @@ def initMap3D()
// Initialize the map scripts // Initialize the map scripts
setWindow2() setWindow2()
clearWindow() clearWindow()
anyText = FALSE
prevX = -1 prevX = -1
prevY = -1 prevY = -1
prevScript = -1 triggerTbl = NULL
nLocTrig = 0
prevMapNum = mapNum prevMapNum = mapNum
prevMapIs3D = mapIs3D prevMapIs3D = mapIs3D
if pScripts if pScripts
@ -720,8 +766,7 @@ def initMap2D()
// For now // For now
prevX = -1 prevX = -1
prevY = -1 prevY = -1
prevScript = -1 triggerTbl = NULL
nLocTrig = 0
prevMapNum = mapNum prevMapNum = mapNum
prevMapIs3D = mapIs3D prevMapIs3D = mapIs3D
pScripts = NULL pScripts = NULL
@ -782,29 +827,75 @@ def flipToFirstPage
fin fin
end end
///////////////////////////////////////////////////////////////////////////////////////////////////
def callScripts(x, y)
word p
word pNext
word script
printHex($1001)
printHex(x)
crout()
p = triggerTbl
while TRUE
printHex($1002)
printHex(p)
printHex(^p)
crout()
getUpperKey
if ^p == $FF
return
fin
pNext = p + p.1
if ^p == y
while p < pNext
printHex($1003)
printHex(p)
printHex(^p)
crout()
if ^p == x
script = p:1
printHex($1004)
printHex(script)
crout()
*script
fin
p = p + 3
loop
fin
p = pNext
loop
end
/////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////
// Check for script(s) attached to the current location, and call them if there are any. // Check for script(s) attached to the current location, and call them if there are any.
def checkScript() def checkScripts()
word x word x
word y word y
word i if !triggerTbl
word func return
fin
if mapIs3D
x = playerX.1 - 1 x = playerX.1 - 1
y = playerY.1 - 1 y = playerY.1 - 1
else
x = ^avatarX
y = ^avatarY
fin
if x <> prevX or y <> prevY if x <> prevX or y <> prevY
prevX = x prevX = x
prevY = y prevY = y
if prevScript if anyText
clearWindow() clearWindow()
anyText = FALSE
fin fin
prevScript = NULL
if isScripted() if isScripted()
for i = 0 to nLocTrig-1 textDrawn = FALSE
if x == locTrig_x[i] and y == locTrig_y[i] callScripts(x, y)
prevScript = locTrig_func[i] anyText = ^textDrawn
*prevScript()
fin
next
fin fin
fin fin
if (mapNum <> prevMapNum) or (mapIs3D <> prevMapIs3D) if (mapNum <> prevMapNum) or (mapIs3D <> prevMapIs3D)
@ -926,8 +1017,8 @@ def teleport(x, y, dir)
*playerY = ((y+1)<<8) | $80 *playerY = ((y+1)<<8) | $80
prevX = x prevX = x
prevY = y prevY = y
prevScript = -1
clearWindow() clearWindow()
anyText = FALSE
^playerDir = dir ^playerDir = dir
redraw = TRUE redraw = TRUE
end end
@ -945,7 +1036,7 @@ def kbdLoop()
func() func()
renderFrame() renderFrame()
redraw = FALSE redraw = FALSE
checkScript() checkScripts()
if redraw if redraw
renderFrame() renderFrame()
redraw = FALSE redraw = FALSE
@ -958,9 +1049,15 @@ end
/////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////
// Associate a location with a trigger function (i.e. a script) // Associate a location with a trigger function (i.e. a script)
def setLocationTrigger(tbl) def setLocationTrigger(tbl)
printHex($1001) triggerTbl = tbl
printHex(tbl) end
^$c053
///////////////////////////////////////////////////////////////////////////////////////////////////
// Called by scripts to display a string. We set the flag noting that something has been
// displayed, then use an assembly routine to do the work.
def scriptDisplayStr(str)
anyText = TRUE
displayStr(str)
end end
/////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////
@ -973,6 +1070,7 @@ def getYN()
return 1 return 1
elsif key == 'N' elsif key == 'N'
clearWindow() clearWindow()
anyText = FALSE
return 0 return 0
fin fin
beep() beep()
@ -1049,7 +1147,7 @@ def setCallbacks()
// $303 // $303
callbacks.3 = $4c callbacks.3 = $4c
callbacks:4 = @displayStr callbacks:4 = @scriptDisplayStr
// $306 // $306
callbacks.6 = $4c callbacks.6 = $4c

View File

@ -56,9 +56,10 @@ mapWidth = $62 ; len 1
mapHeight = $63 ; len 1 mapHeight = $63 ; len 1
spriteX = $64 ; len 2 spriteX = $64 ; len 2
spriteY = $66 ; len 2 spriteY = $66 ; len 2
plasmaFrames = $68 ; len 2 _unused68 = $68 ; len 2
backBuf = $6A ; len 1 backBuf = $6A ; len 1
frontBuf = $6B ; len 1 frontBuf = $6B ; len 1
_unused6C = $6C ; len 4
; Sprite calculations zero page ; Sprite calculations zero page
bSgnSinT = $90 bSgnSinT = $90