mirror of
https://github.com/badvision/lawless-legends.git
synced 2024-07-03 17:29:46 +00:00
Fixed bug where script module wasn't beeing freed when wandering (or teleporting) for a long time on the wilderness map.
This commit is contained in:
parent
4964220863
commit
1e9813ba2a
|
@ -1176,7 +1176,7 @@ class A2PackPartitions
|
||||||
if (!new File(scriptDir).exists())
|
if (!new File(scriptDir).exists())
|
||||||
new File(scriptDir).mkdirs()
|
new File(scriptDir).mkdirs()
|
||||||
ScriptModule module = new ScriptModule()
|
ScriptModule module = new ScriptModule()
|
||||||
module.packMapScripts(mapName, new File(new File(scriptDir), name+".pla.new"),
|
module.packMapScripts(mapName, num, new File(new File(scriptDir), name+".pla.new"),
|
||||||
mapEl.scripts ? mapEl.scripts[0] : [],
|
mapEl.scripts ? mapEl.scripts[0] : [],
|
||||||
totalWidth, totalHeight, xRange, yRange)
|
totalWidth, totalHeight, xRange, yRange)
|
||||||
replaceIfDiff(scriptDir + name + ".pla")
|
replaceIfDiff(scriptDir + name + ".pla")
|
||||||
|
@ -3960,7 +3960,7 @@ end
|
||||||
* Pack scripts from a map. Either the whole map, or optionally just an X and Y
|
* Pack scripts from a map. Either the whole map, or optionally just an X and Y
|
||||||
* bounded section of it.
|
* bounded section of it.
|
||||||
*/
|
*/
|
||||||
def packMapScripts(mapName, outFile, inScripts, maxX, maxY, xRange = null, yRange = null)
|
def packMapScripts(mapName, moduleNum, outFile, inScripts, maxX, maxY, xRange = null, yRange = null)
|
||||||
{
|
{
|
||||||
startScriptFile(outFile)
|
startScriptFile(outFile)
|
||||||
|
|
||||||
|
@ -3997,7 +3997,7 @@ end
|
||||||
|
|
||||||
// Always generate outer initialization code, because even if there were no scripts,
|
// Always generate outer initialization code, because even if there were no scripts,
|
||||||
// we still need an init to display the map name.
|
// we still need an init to display the map name.
|
||||||
makeInit(mapName, initScript, timeScript, maxX, maxY)
|
makeInit(mapName, moduleNum, initScript, timeScript, maxX, maxY)
|
||||||
|
|
||||||
out.close()
|
out.close()
|
||||||
}
|
}
|
||||||
|
@ -4845,12 +4845,12 @@ end
|
||||||
out << "byte = \$FF\n\n"
|
out << "byte = \$FF\n\n"
|
||||||
}
|
}
|
||||||
|
|
||||||
def makeInit(mapName, initScript, timeScript, maxX, maxY)
|
def makeInit(mapName, moduleNum, initScript, timeScript, maxX, maxY)
|
||||||
{
|
{
|
||||||
// Code to register the map name, trigger table, and map extent.
|
// Code to register the map name, trigger table, and map extent.
|
||||||
def shortName = mapName.replaceAll(/[\s-]*[23][dD][-0-9]*$/, '').take(16)
|
def shortName = mapName.replaceAll(/[\s-]*[23][dD][-0-9]*$/, '').take(16)
|
||||||
def timeFunc = timeScript ? "@${scriptNames[timeScript]}" : "NULL"
|
def timeFunc = timeScript ? "@${scriptNames[timeScript]}" : "NULL"
|
||||||
out << "setScriptInfo(\"$shortName\", $timeFunc, @triggerTbl, $maxX, $maxY)\n"
|
out << "setScriptInfo(\"$shortName\", $moduleNum, $timeFunc, @triggerTbl, $maxX, $maxY)\n"
|
||||||
|
|
||||||
// Call init script if one was defined
|
// Call init script if one was defined
|
||||||
if (initScript)
|
if (initScript)
|
||||||
|
|
|
@ -1164,12 +1164,23 @@ grabSegment: !zone
|
||||||
; Input: None
|
; Input: None
|
||||||
; Output: Y-reg = segment grabbed
|
; Output: Y-reg = segment grabbed
|
||||||
; Note: Does not disturb X reg
|
; Note: Does not disturb X reg
|
||||||
ldy unusedSeg ; first unused segment
|
lda #1 ; if we run out, we will try one reclaim
|
||||||
beq .fail ; ran out?
|
sta .reclaimFlg
|
||||||
|
.try ldy unusedSeg ; first unused segment
|
||||||
|
beq .many ; ran out?
|
||||||
lda tSegLink,y ; no, grab next segment in list
|
lda tSegLink,y ; no, grab next segment in list
|
||||||
sta unusedSeg ; that is now first unused
|
sta unusedSeg ; that is now first unused
|
||||||
rts ; return with Y = the segment grabbed
|
rts ; return with Y = the segment grabbed
|
||||||
|
.many dec .reclaimFlg
|
||||||
|
bmi .fail
|
||||||
|
txa
|
||||||
|
pha
|
||||||
|
jsr reclaim
|
||||||
|
pla
|
||||||
|
tax
|
||||||
|
jmp .try
|
||||||
.fail: jsr inlineFatal : !text "MaxSegs", 0
|
.fail: jsr inlineFatal : !text "MaxSegs", 0
|
||||||
|
.reclaimFlg !byte 0
|
||||||
|
|
||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
releaseSegment: !zone
|
releaseSegment: !zone
|
||||||
|
@ -1302,6 +1313,9 @@ dispatch:
|
||||||
+ cmp #QUEUE_LOAD
|
+ cmp #QUEUE_LOAD
|
||||||
bne +
|
bne +
|
||||||
jmp mem_queueLoad
|
jmp mem_queueLoad
|
||||||
|
+ cmp #FIND_IN_MEM
|
||||||
|
bne +
|
||||||
|
jmp mem_find
|
||||||
+ cmp #LOCK_MEMORY
|
+ cmp #LOCK_MEMORY
|
||||||
bne +
|
bne +
|
||||||
jmp mem_lock
|
jmp mem_lock
|
||||||
|
@ -1791,6 +1805,11 @@ mem_calcFree: !zone
|
||||||
|
|
||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
mem_queueLoad: !zone
|
mem_queueLoad: !zone
|
||||||
|
clc
|
||||||
|
!byte $A5 ; to skip next instructon
|
||||||
|
mem_find:
|
||||||
|
sec
|
||||||
|
ror .findonly
|
||||||
stx resType ; save resource type
|
stx resType ; save resource type
|
||||||
sty resNum ; save resource number
|
sty resNum ; save resource number
|
||||||
cpx #RES_TYPE_MODULE ; loading a module?
|
cpx #RES_TYPE_MODULE ; loading a module?
|
||||||
|
@ -1822,6 +1841,8 @@ mem_queueLoad: !zone
|
||||||
sta tSegRes,x
|
sta tSegRes,x
|
||||||
; fall through to re-load the resource
|
; fall through to re-load the resource
|
||||||
.notFound:
|
.notFound:
|
||||||
|
bit .findonly
|
||||||
|
bmi .nullret
|
||||||
ldx resType ; restore res type
|
ldx resType ; restore res type
|
||||||
ldy resNum ; and number
|
ldy resNum ; and number
|
||||||
lda #QUEUE_LOAD ; set to re-try same operation
|
lda #QUEUE_LOAD ; set to re-try same operation
|
||||||
|
@ -1837,12 +1858,18 @@ mem_queueLoad: !zone
|
||||||
ora #$80 ; reactivate bytecode if necessary
|
ora #$80 ; reactivate bytecode if necessary
|
||||||
sta tSegType,y
|
sta tSegType,y
|
||||||
bne .found ; (always taken) we have both parts -- no need for fixups
|
bne .found ; (always taken) we have both parts -- no need for fixups
|
||||||
|
.nullret
|
||||||
|
ldy #0 ; find-only mode, not found: return null
|
||||||
|
ldx #0
|
||||||
|
rts
|
||||||
; The following is for the unusual situation where somehow we have the main memory
|
; The following is for the unusual situation where somehow we have the main memory
|
||||||
; part (the module) without the aux part (the bytecode). If we allowed that to go
|
; part (the module) without the aux part (the bytecode). If we allowed that to go
|
||||||
; forward, we'd end up running fixups on both parts, and double-fixing-up the module
|
; forward, we'd end up running fixups on both parts, and double-fixing-up the module
|
||||||
; is a very bad thing (fixups should not be cumulative). So we force both parts out
|
; is a very bad thing (fixups should not be cumulative). So we force both parts out
|
||||||
; of memory before proceeding.
|
; of memory before proceeding.
|
||||||
.reload jsr .scanForBytecode
|
.reload bit .findonly
|
||||||
|
bmi .nullret
|
||||||
|
jsr .scanForBytecode
|
||||||
jsr .forceFree ; if bytecode without module, forcibly free it
|
jsr .forceFree ; if bytecode without module, forcibly free it
|
||||||
jsr .scanForModule
|
jsr .scanForModule
|
||||||
jsr .forceFree ; if module without bytecode, forcibly free it
|
jsr .forceFree ; if module without bytecode, forcibly free it
|
||||||
|
@ -1883,6 +1910,7 @@ mem_queueLoad: !zone
|
||||||
+ lda #0
|
+ lda #0
|
||||||
sta tSegType,x ; force reload so fixup works right
|
sta tSegType,x ; force reload so fixup works right
|
||||||
++ rts
|
++ rts
|
||||||
|
.findonly !byte 0
|
||||||
|
|
||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
diskLoader: !zone
|
diskLoader: !zone
|
||||||
|
|
|
@ -339,20 +339,15 @@ ADVANCE_ANIMS = $1C
|
||||||
; or main) are processed.
|
; or main) are processed.
|
||||||
|
|
||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
CHAIN_LOADER = $1E
|
FIND_IN_MEM = $1D
|
||||||
; Input: X-reg / Y-reg - pointer to loader (X=lo, Y=hi) to add to chain
|
; Input: X-reg - resource type
|
||||||
|
; Y-reg - resource number
|
||||||
;
|
;
|
||||||
; Output: None
|
; Output: X-reg(lo) / Y-reg (hi) - address of resource, or NULL
|
||||||
;
|
;
|
||||||
; Add a loader to the chain just after this loader. The current next
|
; If the given resource is present in memory, mark it as active and return
|
||||||
; loader (if there is one) will be passed to the new loader with another
|
; its address. Otherwise returns 0000.
|
||||||
; CHAIN_LOADER command.
|
|
||||||
;
|
|
||||||
; The purpose of a loader chain is to insert faster devices between the
|
|
||||||
; main/aux loader (fastest) and the disk loader (slowest). Note that the
|
|
||||||
; main mem and aux mem loaders are conceptually one; a chained loader will
|
|
||||||
; always be inserted after them, not between them.
|
|
||||||
|
|
||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
FATAL_ERROR = $1F
|
FATAL_ERROR = $1F
|
||||||
; Input: X-reg(lo) / Y-reg(hi): message pointer. Message can be:
|
; Input: X-reg(lo) / Y-reg(hi): message pointer. Message can be:
|
||||||
|
|
|
@ -120,7 +120,7 @@ import gamelib
|
||||||
predef useMapWindow()#0
|
predef useMapWindow()#0
|
||||||
predef setBigWindow()#0
|
predef setBigWindow()#0
|
||||||
predef setPortrait(portraitNum)#0
|
predef setPortrait(portraitNum)#0
|
||||||
predef setScriptInfo(mapName, timeFunc, trigTbl, wdt, hgt)#0
|
predef setScriptInfo(mapName, moduleNum, timeFunc, trigTbl, wdt, hgt)#0
|
||||||
predef setSky(num)#0
|
predef setSky(num)#0
|
||||||
predef setStat(player, statName, val)#0
|
predef setStat(player, statName, val)#0
|
||||||
predef setWindow(top, bottom, left, right)#0
|
predef setWindow(top, bottom, left, right)#0
|
||||||
|
|
|
@ -95,6 +95,9 @@ byte textClearCountdown = 0
|
||||||
export byte isPlural = 0 // valid values: 0 or $40
|
export byte isPlural = 0 // valid values: 0 or $40
|
||||||
byte inScript = FALSE
|
byte inScript = FALSE
|
||||||
|
|
||||||
|
byte scriptModule = 0
|
||||||
|
byte prevScriptModule = 0
|
||||||
|
|
||||||
export word skyNum = 9
|
export word skyNum = 9
|
||||||
export word groundNum = 10
|
export word groundNum = 10
|
||||||
export byte portraitNum = 0
|
export byte portraitNum = 0
|
||||||
|
@ -2627,17 +2630,14 @@ end
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Get a key and dispatch it to a command. Then do it again, forever.
|
// Get a key and dispatch it to a command. Then do it again, forever.
|
||||||
def kbdLoop()#0
|
def kbdLoop()#0
|
||||||
word key, func
|
word key, func, tmp
|
||||||
byte xreg, tmp
|
byte xreg
|
||||||
xreg = getXReg()
|
xreg = getXReg()
|
||||||
while TRUE
|
while TRUE
|
||||||
// If the asm routines all work correctly, by the time we get to the top of this loop
|
// If the asm routines all work correctly, by the time we get to the top of this loop
|
||||||
// the X register should always have the same value.
|
// the X register should always have the same value.
|
||||||
tmp = getXReg()
|
tmp = getXReg()
|
||||||
if tmp <> xreg
|
if tmp <> xreg; printHex(xreg<<8 | tmp); fatal("xRegChg"); fin
|
||||||
printHex(xreg<<8 | tmp)
|
|
||||||
fatal("xRegChg")
|
|
||||||
fin
|
|
||||||
key = getUpperKey()
|
key = getUpperKey()
|
||||||
if key >= 0 and key < $60
|
if key >= 0 and key < $60
|
||||||
func = cmdTbl[key]
|
func = cmdTbl[key]
|
||||||
|
@ -2649,12 +2649,14 @@ def kbdLoop()#0
|
||||||
func()
|
func()
|
||||||
fin
|
fin
|
||||||
fin
|
fin
|
||||||
if q_mapNum
|
if q_mapNum; setMap(q_mapIs3D, q_mapNum, q_x, q_y, q_dir); q_mapNum = 0; fin
|
||||||
setMap(q_mapIs3D, q_mapNum, q_x, q_y, q_dir)
|
if needRender; doRender(); fin
|
||||||
q_mapNum = 0
|
if prevScriptModule
|
||||||
fin
|
if prevScriptModule <> scriptModule
|
||||||
if needRender
|
tmp = mmgr(FIND_IN_MEM, prevScriptModule<<8 | RES_TYPE_MODULE)
|
||||||
doRender()
|
if tmp; mmgr(FREE_MEMORY, tmp); fin
|
||||||
|
fin
|
||||||
|
prevScriptModule = 0
|
||||||
fin
|
fin
|
||||||
loop
|
loop
|
||||||
end
|
end
|
||||||
|
@ -2681,11 +2683,20 @@ end
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Set initial info for the scripts on this map: the name of the map, its trigger table, and the
|
// Set initial info for the scripts on this map: the name of the map, its trigger table, and the
|
||||||
// maximum extent (width, height). This is called by the init function for the scripts.
|
// maximum extent (width, height). This is called by the init function for the scripts.
|
||||||
export def setScriptInfo(mapName, timeFn, trigTbl, wdt, hgt)#0
|
export def setScriptInfo(mapName, moduleNum, timeFn, trigTbl, wdt, hgt)#0
|
||||||
|
word tmp
|
||||||
|
|
||||||
// Record the time event function, if any
|
// Record the time event function, if any
|
||||||
timeEventFunc = timeFn
|
timeEventFunc = timeFn
|
||||||
|
|
||||||
|
// Record new script, and prepare to free old one. While theoretically there could be a
|
||||||
|
// circumstance where the old prev is still un-freed, it's rare enough that it'd be hard to
|
||||||
|
// get freeing it here correct. So we leave freeing to the main keyboard loop.
|
||||||
|
if scriptModule <> moduleNum
|
||||||
|
prevScriptModule = scriptModule
|
||||||
|
scriptModule = moduleNum
|
||||||
|
fin
|
||||||
|
|
||||||
// Grab the trigger table origins (used so the table can be more compact)
|
// Grab the trigger table origins (used so the table can be more compact)
|
||||||
triggerOriginX = trigTbl=>0
|
triggerOriginX = trigTbl=>0
|
||||||
triggerOriginY = trigTbl=>2
|
triggerOriginY = trigTbl=>2
|
||||||
|
|
|
@ -61,7 +61,7 @@ const CALC_FREE = $19
|
||||||
const DEBUG_MEM = $1A
|
const DEBUG_MEM = $1A
|
||||||
const CHECK_MEM = $1B
|
const CHECK_MEM = $1B
|
||||||
const ADVANCE_ANIMS = $1C
|
const ADVANCE_ANIMS = $1C
|
||||||
const CHAIN_LOADER = $1E
|
const FIND_IN_MEM = $1D
|
||||||
const FATAL_ERROR = $1F
|
const FATAL_ERROR = $1F
|
||||||
const HEAP_SET = $20
|
const HEAP_SET = $20
|
||||||
const HEAP_ADD_TYPE = $21
|
const HEAP_ADD_TYPE = $21
|
||||||
|
|
|
@ -88,6 +88,8 @@ def kbdTeleport()#1
|
||||||
dir = getDir()
|
dir = getDir()
|
||||||
printf3("Current: X=%d Y=%d Facing=%d\n", x, y, dir)
|
printf3("Current: X=%d Y=%d Facing=%d\n", x, y, dir)
|
||||||
|
|
||||||
|
d3 = mapIs3D
|
||||||
|
num = mapNum
|
||||||
printf1("3D [%d]: ", mapIs3D)
|
printf1("3D [%d]: ", mapIs3D)
|
||||||
d3 = parseDecWithDefault(readStr(), mapIs3D)
|
d3 = parseDecWithDefault(readStr(), mapIs3D)
|
||||||
if d3 > 1; d3 = 1; fin
|
if d3 > 1; d3 = 1; fin
|
||||||
|
|
Loading…
Reference in New Issue
Block a user