mirror of
https://github.com/badvision/lawless-legends.git
synced 2024-09-08 11:54:28 +00:00
Now packing scripts for 2D map sections.
This commit is contained in:
parent
2d06dc337a
commit
430ee9ce65
@ -400,7 +400,7 @@ class PackPartitions
|
|||||||
buf.put((byte)0);
|
buf.put((byte)0);
|
||||||
}
|
}
|
||||||
|
|
||||||
def write2DMap(mapName, rows)
|
def write2DMap(mapName, mapEl, rows)
|
||||||
{
|
{
|
||||||
def width = rows[0].size()
|
def width = rows[0].size()
|
||||||
def height = rows.size()
|
def height = rows.size()
|
||||||
@ -434,6 +434,11 @@ class PackPartitions
|
|||||||
|
|
||||||
def (tileSetNum, tileMap) = packTileSet(rows, hOff, TILES_PER_ROW, vOff, ROWS_PER_SECTION)
|
def (tileSetNum, tileMap) = packTileSet(rows, hOff, TILES_PER_ROW, vOff, ROWS_PER_SECTION)
|
||||||
|
|
||||||
|
def xRange = hOff ..< hOff+TILES_PER_ROW
|
||||||
|
def yRange = vOff ..< vOff+ROWS_PER_SECTION
|
||||||
|
def sectName = "$mapName-$hsect-$vsect"
|
||||||
|
def (scriptModule, locationsWithTriggers) = packScripts(mapEl, sectName, xRange, yRange)
|
||||||
|
|
||||||
// Header: first come links to other map sections
|
// Header: first come links to other map sections
|
||||||
def buf = buffers[vsect][hsect]
|
def buf = buffers[vsect][hsect]
|
||||||
buf.put((byte) (vsect > 0) ? sectionNums[vsect-1][hsect] : 0xFF) // north
|
buf.put((byte) (vsect > 0) ? sectionNums[vsect-1][hsect] : 0xFF) // north
|
||||||
@ -443,7 +448,7 @@ class PackPartitions
|
|||||||
|
|
||||||
// Then links to the tile set and script library
|
// Then links to the tile set and script library
|
||||||
buf.put((byte) tileSetNum)
|
buf.put((byte) tileSetNum)
|
||||||
buf.put((byte) 0xFF) // script library placeholder
|
buf.put((byte) scriptModule)
|
||||||
|
|
||||||
// After the header comes the raw data
|
// After the header comes the raw data
|
||||||
(0..<ROWS_PER_SECTION).each { rowNum ->
|
(0..<ROWS_PER_SECTION).each { rowNum ->
|
||||||
@ -452,7 +457,8 @@ class PackPartitions
|
|||||||
(0..<TILES_PER_ROW).each { colNum ->
|
(0..<TILES_PER_ROW).each { colNum ->
|
||||||
def x = hOff + colNum
|
def x = hOff + colNum
|
||||||
def tile = (row && x < width) ? row[x] : null
|
def tile = (row && x < width) ? row[x] : null
|
||||||
buf.put((byte)(tile ? tileMap[tile.@id] : 0))
|
def flags = ([colNum, rowNum] in locationsWithTriggers) ? 0x20 : 0
|
||||||
|
buf.put((byte)((tile ? tileMap[tile.@id] : 0) | flags))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -543,10 +549,6 @@ class PackPartitions
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make a map of all the locations with triggers
|
|
||||||
def locMap = [:]
|
|
||||||
locationsWithTriggers.each { x,y -> locMap[[x,y]] = true }
|
|
||||||
|
|
||||||
// Header: width and height
|
// Header: width and height
|
||||||
buf.put((byte)width)
|
buf.put((byte)width)
|
||||||
buf.put((byte)height)
|
buf.put((byte)height)
|
||||||
@ -573,7 +575,7 @@ class PackPartitions
|
|||||||
buf.put((byte)0xFF) // sentinel at start of row
|
buf.put((byte)0xFF) // sentinel at start of row
|
||||||
row.eachWithIndex { tile,x ->
|
row.eachWithIndex { tile,x ->
|
||||||
// Mark scripted locations with a flag
|
// Mark scripted locations with a flag
|
||||||
def flags = locMap.containsKey([x,y]) ? 0x20 : 0
|
def flags = ([x,y] in locationsWithTriggers) ? 0x20 : 0
|
||||||
buf.put((byte)texMap[tile?.@id] | flags)
|
buf.put((byte)texMap[tile?.@id] | flags)
|
||||||
}
|
}
|
||||||
buf.put((byte)0xFF) // sentinel at end of row
|
buf.put((byte)0xFF) // sentinel at end of row
|
||||||
@ -762,7 +764,7 @@ class PackPartitions
|
|||||||
def num = mapNames[name][1]
|
def num = mapNames[name][1]
|
||||||
//println "Packing 2D map #$num named '$name'."
|
//println "Packing 2D map #$num named '$name'."
|
||||||
def rows = parseMap(mapEl, tileEls)
|
def rows = parseMap(mapEl, tileEls)
|
||||||
write2DMap(name, rows)
|
write2DMap(name, mapEl, rows)
|
||||||
}
|
}
|
||||||
|
|
||||||
def pack3DMap(mapEl, tileEls)
|
def pack3DMap(mapEl, tileEls)
|
||||||
@ -779,15 +781,17 @@ class PackPartitions
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def packScripts(mapEl, mapName)
|
def packScripts(mapEl, mapName, xRange = null, yRange = null)
|
||||||
{
|
{
|
||||||
if (!mapEl.scripts)
|
if (!mapEl.scripts)
|
||||||
return 0
|
return [0, [] as Set]
|
||||||
ScriptModule module = new ScriptModule()
|
ScriptModule module = new ScriptModule()
|
||||||
module.packScripts(mapEl.scripts[0])
|
if (!module.packScripts(mapEl.scripts[0], xRange, yRange))
|
||||||
|
return [0, [] as Set]
|
||||||
|
|
||||||
def num = modules.size() + 1
|
def num = modules.size() + 1
|
||||||
def name = "mapScript$num"
|
def name = "mapScript$num"
|
||||||
//println "Packing scripts for map $mapName, to module $num."
|
println "Packing scripts for map $mapName, to module $num."
|
||||||
modules[name] = [num:num, buf:wrapByteList(module.data)]
|
modules[name] = [num:num, buf:wrapByteList(module.data)]
|
||||||
bytecodes[name] = [num:num, buf:wrapByteList(module.bytecode)]
|
bytecodes[name] = [num:num, buf:wrapByteList(module.bytecode)]
|
||||||
fixups[name] = [num:num, buf:wrapByteList(module.fixups)]
|
fixups[name] = [num:num, buf:wrapByteList(module.fixups)]
|
||||||
@ -1325,7 +1329,7 @@ class PackPartitions
|
|||||||
|
|
||||||
def nScripts = 0
|
def nScripts = 0
|
||||||
|
|
||||||
def locationsWithTriggers = []
|
def locationsWithTriggers = [] as Set
|
||||||
|
|
||||||
def vec_locationTrigger = 0x300
|
def vec_locationTrigger = 0x300
|
||||||
def vec_displayStr = 0x303
|
def vec_displayStr = 0x303
|
||||||
@ -1344,18 +1348,42 @@ class PackPartitions
|
|||||||
return addr
|
return addr
|
||||||
}
|
}
|
||||||
|
|
||||||
def packScripts(scripts)
|
/**
|
||||||
|
* Pack scripts from a map. Either the whole map, or optionally just an X and Y
|
||||||
|
* bounded section of it.
|
||||||
|
*
|
||||||
|
* Returns true if any matching scripts were found.
|
||||||
|
*/
|
||||||
|
def packScripts(inScripts, xRange = null, yRange = null)
|
||||||
{
|
{
|
||||||
|
// If we're only processing a section of the map, make sure this script is
|
||||||
|
// referenced within that section.
|
||||||
|
//
|
||||||
|
def scripts = []
|
||||||
|
inScripts.script.eachWithIndex { script, idx ->
|
||||||
|
def name = script.name[0].text()
|
||||||
|
if (name.toLowerCase() == "init")
|
||||||
|
scripts << script
|
||||||
|
else if (script.locationTrigger.any { trig ->
|
||||||
|
(!xRange || trig.@x.toInteger() in xRange) &&
|
||||||
|
(!yRange || trig.@y.toInteger() in yRange) })
|
||||||
|
scripts << script
|
||||||
|
}
|
||||||
|
|
||||||
nScripts = scripts.script.size()
|
nScripts = scripts.script.size()
|
||||||
|
if (nScripts == 0)
|
||||||
|
return false
|
||||||
|
|
||||||
makeStubs()
|
makeStubs()
|
||||||
scripts.script.eachWithIndex { script, idx ->
|
scripts.eachWithIndex { script, idx ->
|
||||||
packScript(idx, script)
|
packScript(idx, script)
|
||||||
}
|
}
|
||||||
makeInit(scripts)
|
makeInit(scripts, xRange, yRange)
|
||||||
emitFixupByte(0xFF)
|
emitFixupByte(0xFF)
|
||||||
//println "data: $data"
|
//println "data: $data"
|
||||||
//println "bytecode: $bytecode"
|
//println "bytecode: $bytecode"
|
||||||
//println "fixups: $fixups"
|
//println "fixups: $fixups"
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
def makeStubs()
|
def makeStubs()
|
||||||
@ -1381,6 +1409,7 @@ class PackPartitions
|
|||||||
def name = script.name[0].text()
|
def name = script.name[0].text()
|
||||||
if (name.toLowerCase() == "init") // this special script gets processed later
|
if (name.toLowerCase() == "init") // this special script gets processed later
|
||||||
return
|
return
|
||||||
|
|
||||||
//println " Script '$name'"
|
//println " Script '$name'"
|
||||||
withContext("script '$name'")
|
withContext("script '$name'")
|
||||||
{
|
{
|
||||||
@ -1455,36 +1484,47 @@ class PackPartitions
|
|||||||
|
|
||||||
def emitDataByte(b)
|
def emitDataByte(b)
|
||||||
{
|
{
|
||||||
|
assert b <= 255
|
||||||
data.add((byte)(b & 0xFF))
|
data.add((byte)(b & 0xFF))
|
||||||
}
|
}
|
||||||
|
|
||||||
def emitDataWord(w)
|
def emitDataWord(w)
|
||||||
{
|
{
|
||||||
emitDataByte(w)
|
emitDataByte(w & 0xFF)
|
||||||
emitDataByte(w >> 8)
|
emitDataByte(w >> 8)
|
||||||
}
|
}
|
||||||
|
|
||||||
def emitCodeByte(b)
|
def emitCodeByte(b)
|
||||||
{
|
{
|
||||||
|
assert b <= 255
|
||||||
bytecode.add((byte)(b & 0xFF))
|
bytecode.add((byte)(b & 0xFF))
|
||||||
}
|
}
|
||||||
|
|
||||||
def emitCodeWord(w)
|
def emitCodeWord(w)
|
||||||
{
|
{
|
||||||
emitCodeByte(w)
|
emitCodeByte(w & 0xFF)
|
||||||
emitCodeByte(w >> 8)
|
emitCodeByte(w >> 8)
|
||||||
}
|
}
|
||||||
|
|
||||||
def emitFixupByte(b)
|
def emitFixupByte(b)
|
||||||
{
|
{
|
||||||
|
assert b <= 255
|
||||||
fixups.add((byte)(b & 0xFF))
|
fixups.add((byte)(b & 0xFF))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def emitDataFixup(toAddr)
|
||||||
|
{
|
||||||
|
// Src addr is reversed (i.e. it's hi then lo)
|
||||||
|
emitFixupByte(dataAddr() >> 8)
|
||||||
|
emitFixupByte(dataAddr() & 0xFF)
|
||||||
|
emitDataWord(toAddr)
|
||||||
|
}
|
||||||
|
|
||||||
def emitCodeFixup(toAddr)
|
def emitCodeFixup(toAddr)
|
||||||
{
|
{
|
||||||
// Src addr is reversed (i.e. it's hi then lo)
|
// Src addr is reversed (i.e. it's hi then lo), and marked by hi-bit flag.
|
||||||
emitFixupByte((bytecodeAddr() >> 8) | 0x80)
|
emitFixupByte((bytecodeAddr() >> 8) | 0x80)
|
||||||
emitFixupByte(bytecodeAddr())
|
emitFixupByte(bytecodeAddr() & 0xFF)
|
||||||
emitCodeWord(toAddr)
|
emitCodeWord(toAddr)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1624,11 +1664,16 @@ class PackPartitions
|
|||||||
emitCodeByte(0x30) // DROP
|
emitCodeByte(0x30) // DROP
|
||||||
}
|
}
|
||||||
|
|
||||||
def makeInit(scripts)
|
def makeInit(scripts, xRange, yRange)
|
||||||
{
|
{
|
||||||
//println " Script: special 'init'"
|
//println " Script: special 'init'"
|
||||||
startFunc(0)
|
startFunc(0)
|
||||||
scripts.script.eachWithIndex { script, idx ->
|
|
||||||
|
// Emit the code the user has stored for the init script. While we're scanning,
|
||||||
|
// might as well also collate all the location triggers into a sorted map.
|
||||||
|
//
|
||||||
|
TreeMap triggers = [:]
|
||||||
|
scripts.eachWithIndex { script, idx ->
|
||||||
def name = script.name[0].text()
|
def name = script.name[0].text()
|
||||||
if (name.toLowerCase() == "init")
|
if (name.toLowerCase() == "init")
|
||||||
{
|
{
|
||||||
@ -1645,21 +1690,49 @@ class PackPartitions
|
|||||||
script.locationTrigger.each { trig ->
|
script.locationTrigger.each { trig ->
|
||||||
def x = trig.@x.toInteger()
|
def x = trig.@x.toInteger()
|
||||||
def y = trig.@y.toInteger()
|
def y = trig.@y.toInteger()
|
||||||
locationsWithTriggers.add([x,y])
|
if ((!xRange || x in xRange) && (!yRange || y in yRange))
|
||||||
emitCodeByte(0x2A) // CB
|
{
|
||||||
assert x >= 0 && x < 255
|
if (xRange)
|
||||||
emitCodeByte(x)
|
x -= xRange[0]
|
||||||
emitCodeByte(0x2A) // CB
|
if (yRange)
|
||||||
assert y >= 0 && y < 255
|
y -= yRange[0]
|
||||||
emitCodeByte(y)
|
if (!triggers[y])
|
||||||
|
triggers[y] = [:] as TreeMap
|
||||||
|
triggers[y][x] = (idx+1) * 5 // address of function
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If any triggers, register and output a trigger table
|
||||||
|
if (triggers.size())
|
||||||
|
{
|
||||||
|
println("Putting trigger table at ${dataAddr()}")
|
||||||
|
|
||||||
|
// Code to register the table
|
||||||
emitCodeByte(0x26) // LA
|
emitCodeByte(0x26) // LA
|
||||||
emitCodeFixup((idx+1) * 5)
|
emitCodeFixup(dataAddr())
|
||||||
emitCodeByte(0x54) // CALL
|
emitCodeByte(0x54) // CALL
|
||||||
emitCodeWord(vec_locationTrigger)
|
emitCodeWord(vec_locationTrigger)
|
||||||
emitCodeByte(0x30) // DROP
|
emitCodeByte(0x30) // DROP
|
||||||
|
|
||||||
|
// The table itself goes in the data segment.
|
||||||
|
triggers.each { y, xs ->
|
||||||
|
println(" Trigger row: y=$y size=${xs.size()}")
|
||||||
|
emitDataByte(y)
|
||||||
|
emitDataByte(xs.size() * 3) // 3 bytes per trigger (x, adrlo, adrhi)
|
||||||
|
xs.each { x, funcAddr ->
|
||||||
|
println(" col: x=$x funcAddr=$funcAddr")
|
||||||
|
emitDataByte(x)
|
||||||
|
emitDataFixup(funcAddr)
|
||||||
|
// Record a list of trigger locations for the caller's reference
|
||||||
|
locationsWithTriggers << [x, y]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
emitDataByte(0xFF) // mark the end end of the trigger table
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// All done with the init function.
|
||||||
finishFunc()
|
finishFunc()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1749,13 +1749,13 @@ doAllFixups: !zone
|
|||||||
sta pDst+1
|
sta pDst+1
|
||||||
!if DEBUG >= 2 { jsr .debug2 }
|
!if DEBUG >= 2 { jsr .debug2 }
|
||||||
clc
|
clc
|
||||||
jsr .adMain
|
jsr .adMain ; recalc and store lo byte
|
||||||
iny
|
iny
|
||||||
jsr .adMain
|
jsr .adMain ; recalc and store hi byte
|
||||||
bne .proc ; always taken
|
bne .proc ; always taken
|
||||||
.adMain lda (pDst),y
|
.adMain lda (pDst),y ; get num to add to offset
|
||||||
adc .mainBase,y
|
adc .mainBase,y ; add the offset
|
||||||
sta (pDst),y
|
sta (pDst),y ; *STORE* back the result
|
||||||
rts
|
rts
|
||||||
.fxAux cmp #$FF ; end of fixups?
|
.fxAux cmp #$FF ; end of fixups?
|
||||||
beq .stubs ; if so, go do the stubs
|
beq .stubs ; if so, go do the stubs
|
||||||
@ -1769,14 +1769,14 @@ doAllFixups: !zone
|
|||||||
sta pDst+1
|
sta pDst+1
|
||||||
!if DEBUG >= 2 { jsr .debug3 }
|
!if DEBUG >= 2 { jsr .debug3 }
|
||||||
sta setAuxWr
|
sta setAuxWr
|
||||||
jsr .adAux
|
jsr .adAux ; recalc and store lo byte
|
||||||
iny
|
iny
|
||||||
jsr .adAux
|
jsr .adAux ; recalc and store hi byte
|
||||||
sta clrAuxWr
|
sta clrAuxWr
|
||||||
bne .proc ; always taken
|
bne .proc ; always taken
|
||||||
.adAux jsr .getBytecode
|
.adAux jsr .getBytecode ; get num to add to offset
|
||||||
adc .mainBase,y
|
adc .mainBase,y ; add the offset
|
||||||
sta (pDst),y
|
sta (pDst),y ; *STORE* back the result
|
||||||
rts
|
rts
|
||||||
.stubs ; fix up the stubs
|
.stubs ; fix up the stubs
|
||||||
lda .mainBase
|
lda .mainBase
|
||||||
|
@ -207,9 +207,9 @@ LOAD_TILESET
|
|||||||
; (Returns Tile # in Y, Flags in A)
|
; (Returns Tile # in Y, Flags in A)
|
||||||
; Each tile in memory can be 0-32, the flags are the upper 3 bits
|
; Each tile in memory can be 0-32, the flags are the upper 3 bits
|
||||||
; 0 0 0
|
; 0 0 0
|
||||||
; | | `- Script assigned, triggers script lookup
|
; | | `- Visible obstruction (Can not see behind it)
|
||||||
; | `--- Boundary (Can not walk on it)
|
; | `--- Boundary (Can not walk on it)
|
||||||
; `----- Visible obstruction (Can not see behind it)
|
; `----- Script assigned, triggers script lookup
|
||||||
;----------------------------------------------------------------------
|
;----------------------------------------------------------------------
|
||||||
; >> SET X,Y COORDINATES FOR VIEWPORT CENTER
|
; >> SET X,Y COORDINATES FOR VIEWPORT CENTER
|
||||||
SET_XY
|
SET_XY
|
||||||
|
Loading…
Reference in New Issue
Block a user