mirror of
https://github.com/badvision/lawless-legends.git
synced 2024-10-02 00:54:48 +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())
|
||||
new File(scriptDir).mkdirs()
|
||||
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] : [],
|
||||
totalWidth, totalHeight, xRange, yRange)
|
||||
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
|
||||
* 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)
|
||||
|
||||
@ -3997,7 +3997,7 @@ end
|
||||
|
||||
// Always generate outer initialization code, because even if there were no scripts,
|
||||
// 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()
|
||||
}
|
||||
@ -4845,12 +4845,12 @@ end
|
||||
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.
|
||||
def shortName = mapName.replaceAll(/[\s-]*[23][dD][-0-9]*$/, '').take(16)
|
||||
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
|
||||
if (initScript)
|
||||
|
@ -1164,12 +1164,23 @@ grabSegment: !zone
|
||||
; Input: None
|
||||
; Output: Y-reg = segment grabbed
|
||||
; Note: Does not disturb X reg
|
||||
ldy unusedSeg ; first unused segment
|
||||
beq .fail ; ran out?
|
||||
lda #1 ; if we run out, we will try one reclaim
|
||||
sta .reclaimFlg
|
||||
.try ldy unusedSeg ; first unused segment
|
||||
beq .many ; ran out?
|
||||
lda tSegLink,y ; no, grab next segment in list
|
||||
sta unusedSeg ; that is now first unused
|
||||
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
|
||||
.reclaimFlg !byte 0
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
releaseSegment: !zone
|
||||
@ -1302,6 +1313,9 @@ dispatch:
|
||||
+ cmp #QUEUE_LOAD
|
||||
bne +
|
||||
jmp mem_queueLoad
|
||||
+ cmp #FIND_IN_MEM
|
||||
bne +
|
||||
jmp mem_find
|
||||
+ cmp #LOCK_MEMORY
|
||||
bne +
|
||||
jmp mem_lock
|
||||
@ -1791,6 +1805,11 @@ mem_calcFree: !zone
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
mem_queueLoad: !zone
|
||||
clc
|
||||
!byte $A5 ; to skip next instructon
|
||||
mem_find:
|
||||
sec
|
||||
ror .findonly
|
||||
stx resType ; save resource type
|
||||
sty resNum ; save resource number
|
||||
cpx #RES_TYPE_MODULE ; loading a module?
|
||||
@ -1822,6 +1841,8 @@ mem_queueLoad: !zone
|
||||
sta tSegRes,x
|
||||
; fall through to re-load the resource
|
||||
.notFound:
|
||||
bit .findonly
|
||||
bmi .nullret
|
||||
ldx resType ; restore res type
|
||||
ldy resNum ; and number
|
||||
lda #QUEUE_LOAD ; set to re-try same operation
|
||||
@ -1837,12 +1858,18 @@ mem_queueLoad: !zone
|
||||
ora #$80 ; reactivate bytecode if necessary
|
||||
sta tSegType,y
|
||||
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
|
||||
; 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
|
||||
; is a very bad thing (fixups should not be cumulative). So we force both parts out
|
||||
; of memory before proceeding.
|
||||
.reload jsr .scanForBytecode
|
||||
.reload bit .findonly
|
||||
bmi .nullret
|
||||
jsr .scanForBytecode
|
||||
jsr .forceFree ; if bytecode without module, forcibly free it
|
||||
jsr .scanForModule
|
||||
jsr .forceFree ; if module without bytecode, forcibly free it
|
||||
@ -1883,6 +1910,7 @@ mem_queueLoad: !zone
|
||||
+ lda #0
|
||||
sta tSegType,x ; force reload so fixup works right
|
||||
++ rts
|
||||
.findonly !byte 0
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
diskLoader: !zone
|
||||
|
@ -339,19 +339,14 @@ ADVANCE_ANIMS = $1C
|
||||
; or main) are processed.
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
CHAIN_LOADER = $1E
|
||||
; Input: X-reg / Y-reg - pointer to loader (X=lo, Y=hi) to add to chain
|
||||
FIND_IN_MEM = $1D
|
||||
; 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
|
||||
; loader (if there is one) will be passed to the new loader with another
|
||||
; 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.
|
||||
; If the given resource is present in memory, mark it as active and return
|
||||
; its address. Otherwise returns 0000.
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
FATAL_ERROR = $1F
|
||||
|
@ -120,7 +120,7 @@ import gamelib
|
||||
predef useMapWindow()#0
|
||||
predef setBigWindow()#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 setStat(player, statName, val)#0
|
||||
predef setWindow(top, bottom, left, right)#0
|
||||
|
@ -95,6 +95,9 @@ byte textClearCountdown = 0
|
||||
export byte isPlural = 0 // valid values: 0 or $40
|
||||
byte inScript = FALSE
|
||||
|
||||
byte scriptModule = 0
|
||||
byte prevScriptModule = 0
|
||||
|
||||
export word skyNum = 9
|
||||
export word groundNum = 10
|
||||
export byte portraitNum = 0
|
||||
@ -2627,17 +2630,14 @@ end
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Get a key and dispatch it to a command. Then do it again, forever.
|
||||
def kbdLoop()#0
|
||||
word key, func
|
||||
byte xreg, tmp
|
||||
word key, func, tmp
|
||||
byte xreg
|
||||
xreg = getXReg()
|
||||
while TRUE
|
||||
// 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.
|
||||
tmp = getXReg()
|
||||
if tmp <> xreg
|
||||
printHex(xreg<<8 | tmp)
|
||||
fatal("xRegChg")
|
||||
fin
|
||||
if tmp <> xreg; printHex(xreg<<8 | tmp); fatal("xRegChg"); fin
|
||||
key = getUpperKey()
|
||||
if key >= 0 and key < $60
|
||||
func = cmdTbl[key]
|
||||
@ -2649,12 +2649,14 @@ def kbdLoop()#0
|
||||
func()
|
||||
fin
|
||||
fin
|
||||
if q_mapNum
|
||||
setMap(q_mapIs3D, q_mapNum, q_x, q_y, q_dir)
|
||||
q_mapNum = 0
|
||||
if q_mapNum; setMap(q_mapIs3D, q_mapNum, q_x, q_y, q_dir); q_mapNum = 0; fin
|
||||
if needRender; doRender(); fin
|
||||
if prevScriptModule
|
||||
if prevScriptModule <> scriptModule
|
||||
tmp = mmgr(FIND_IN_MEM, prevScriptModule<<8 | RES_TYPE_MODULE)
|
||||
if tmp; mmgr(FREE_MEMORY, tmp); fin
|
||||
fin
|
||||
if needRender
|
||||
doRender()
|
||||
prevScriptModule = 0
|
||||
fin
|
||||
loop
|
||||
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
|
||||
// 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
|
||||
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)
|
||||
triggerOriginX = trigTbl=>0
|
||||
triggerOriginY = trigTbl=>2
|
||||
|
@ -61,7 +61,7 @@ const CALC_FREE = $19
|
||||
const DEBUG_MEM = $1A
|
||||
const CHECK_MEM = $1B
|
||||
const ADVANCE_ANIMS = $1C
|
||||
const CHAIN_LOADER = $1E
|
||||
const FIND_IN_MEM = $1D
|
||||
const FATAL_ERROR = $1F
|
||||
const HEAP_SET = $20
|
||||
const HEAP_ADD_TYPE = $21
|
||||
|
@ -88,6 +88,8 @@ def kbdTeleport()#1
|
||||
dir = getDir()
|
||||
printf3("Current: X=%d Y=%d Facing=%d\n", x, y, dir)
|
||||
|
||||
d3 = mapIs3D
|
||||
num = mapNum
|
||||
printf1("3D [%d]: ", mapIs3D)
|
||||
d3 = parseDecWithDefault(readStr(), mapIs3D)
|
||||
if d3 > 1; d3 = 1; fin
|
||||
|
Loading…
Reference in New Issue
Block a user