Working on getting script to resume after combat.

This commit is contained in:
Martin Haye 2016-06-30 08:36:46 -07:00
parent cf0c3d3ac1
commit f1fbd7bd8c
7 changed files with 96 additions and 30 deletions

View File

@ -2905,7 +2905,7 @@ end
{
assert blk.field.size() == 1
def code = getSingle(blk.field, 'CODE')
outIndented("queueCombat(${escapeString(code)}); return\n")
outIndented("scriptCombat(${escapeString(code)}); return\n")
}
def packTeleport(blk)

View File

@ -161,9 +161,7 @@ relocate:
lda .st4+2
cmp #$E0
bcc +
lda #"b"
jsr cout
brk ; mem mgr got too big!
+internalErr 'N' ; mem mgr got too big!
+
; Patch PLASMA's memory accessors to gain access to writing main LC, and
@ -451,6 +449,7 @@ loMemBegin: !pseudopc $800 {
jmp __prY
jmp __crout
jmp __waitKey
jmp __internalErr
j_init:
bit setLcRW+lcBank1 ; switch in mem mgr
@ -782,6 +781,17 @@ __waitKey: !zone {
jmp iorest
}
; Support for very compact abort in the case of internal errors. Prints
; a single-character code as a fatal error.
__internalErr: !zone {
+prStr : !text $8D,"err=",0
tsx
jsr _getStackByte
jsr cout
jsr inlineFatal : !text "Internal",0
}
!macro callMLI cmd, parms {
lda #cmd
ldx #<parms
@ -897,8 +907,7 @@ heapAddType: !zone
ldy nTypes
cpy #MAX_TYPES
bmi +
+prChr 'T'
brk
+internalErr 'T'
+ sta typeTblH,y ; addr hi
sta .ld+2
txa ; addr lo
@ -1496,13 +1505,11 @@ saneCheck: !zone {
lda $BF00
cmp #$4C
beq +
+prChr 'S'
brk
+internalErr 'S'
+ lda $E1
cmp #$BE
bcc +
+prChr 's'
brk
+internalErr 's'
+ rts
}
@ -1817,11 +1824,13 @@ shared_byteCodeAlso:
rts
+ lda #RES_TYPE_BYTECODE
sta resType
lda tSegRes,x
sta resNum
lda #1
sta isAuxCmd
jsr scanForResource
bne +
brk ; it better be present!
+internalErr 'b' ; it better be present!
+ lda tSegType,x
rts
@ -2462,8 +2471,7 @@ lz4Decompress: !zone
pla ; toss unused match length
!if DO_COMP_CHECKSUMS { jsr .verifyCksum }
+ rts ; all done!
.endBad +prChr 'O' ; diagnostic letter
brk ; barf out
.endBad +internalErr 'O' ; barf out
; Now that we've finished with the literals, decode the match section
.decodeMatch:
+LOAD_YSRC ; grab first byte of match offset
@ -2550,7 +2558,7 @@ lz4Decompress: !zone
}
cmp checksum ; get computed checksum
beq + ; should be zero, because compressor stores checksum byte as part of stream
brk ; checksum doesn't match -- abort!
+internalErr 'C' ; checksum doesn't match -- abort!
+ rts
}
@ -2670,7 +2678,7 @@ doAllFixups: !zone
sta isAuxCmd
jsr scanForResource
bne + ; we better find it
brk
.barf +internalErr 'F'
+ lda tSegAdrLo,x ; get the segment's address
sta .mainBase ; and save it
lda tSegAdrHi,x ; hi byte too
@ -2681,8 +2689,7 @@ doAllFixups: !zone
sta resType
inc isAuxCmd ; it'll be in aux mem
jsr scanForResource
bne + ; we better find it
brk
beq .barf ; we better find it
+ lda tSegAdrLo,x
sta .auxBase
lda tSegAdrHi,x

View File

@ -407,6 +407,7 @@ _prX = _prA+3
_prY = _prX+3
_crout = _prY+3
_waitKey = _crout+3
_internalErr = _waitKey+3
; Debug macros
!macro prStr {
@ -490,3 +491,8 @@ _waitKey = _crout+3
!macro waitKey {
jsr _waitKey
}
!macro internalErr chr {
jsr _internalErr
!byte chr
}

View File

@ -490,10 +490,13 @@ def startCombat(mapCode)
n = getUpperKey()
if n == 'B'
displayStr("\n\nBattle! \n")
return TRUE
return 1
elsif n == 'F'
displayStr("\n\nCoward. ")
return FALSE
return 0
// Secret option for testing: just win
elsif n == '#'
return 99
fin
beep()
loop
@ -501,12 +504,17 @@ def startCombat(mapCode)
end
///////////////////////////////////////////////////////////////////////////////////////////////////
// Returns: zero if fled, non-zero if won
def _combat_zoneEncounter(s_encZone)
word p
byte answer
// Show portrait and threat details, find out if player wants to fight (vs. run)
if !startCombat(s_encZone); return; fin
answer = startCombat(s_encZone)
if !answer; return 0; fin
if answer == 99
global=>p_enemyGroups = NULL // results in no living enemies, or "win"
fin
// Do each round of combat until player wins, loses, or flees
while TRUE
@ -548,11 +556,11 @@ def _combat_zoneEncounter(s_encZone)
wend
getUpperKey()
// Note: no need to clear heap -- the caller does that.
return
return 1
elsif isFleeing
displayStr("\nYou have fled.")
// Note: no need to clear heap -- the caller does that.
return
return 0
fin
if canFight(p)

View File

@ -128,7 +128,7 @@ const calcPlayerArmor = gameLibVecs + 3*54
const diskActivity = gameLibVecs + 3*55
const rdkey = gameLibVecs + 3*56
const initHeap = gameLibVecs + 3*57
const queueCombat = gameLibVecs + 3*58
const scriptCombat = gameLibVecs + 3*58
const UNUSED_FN_59 = gameLibVecs + 3*59
const UNUSED_FN_60 = gameLibVecs + 3*60
const UNUSED_FN_61 = gameLibVecs + 3*61

View File

@ -70,6 +70,7 @@ word triggerTbl
word cmdTbl[96] // ASCII $00..$5F
byte frameLoaded = 0
byte heapLocked = FALSE
byte skipScripts = FALSE
// Queue setMap / teleport / start_encounter, since otherwise script might be replaced while executing
byte q_mapIs3D = 0
@ -107,7 +108,7 @@ predef _reboot, _brk, _encodeDice, _rollDice
predef _setPlural, _getStringResponse, _streqi, _addEncounterZone, _fatal
predef _pause, _tossStrings, _showMapName, _setMapWindow
predef _makeModifier, _randomFromArray, _calcPlayerArmor, _diskActivity
predef _rdkey, _initHeap, _queueCombat
predef _rdkey, _initHeap, _scriptCombat
word gameLib_addrs = @_setScriptInfo, @_scriptDisplayStr, @_scriptDisplayStrNL, @_getYN
word = @_queue_setMap, @_setSky, @_setGround, @_queue_teleport, @_setPortrait, @_clearPortrait
@ -123,7 +124,7 @@ word = @_reboot, @_brk, @_encodeDice, @_rollDice
word = @_setPlural, @_getStringResponse, @_streqi, @_addEncounterZone, @_fatal
word = @_pause, @_tossStrings, @_showMapName, @_setMapWindow
word = @_makeModifier, @_randomFromArray, @_calcPlayerArmor, @_diskActivity
word = @_rdkey, @_initHeap, @_queueCombat
word = @_rdkey, @_initHeap, @_scriptCombat
word = 0 // end of library functions
@ -213,6 +214,10 @@ asm texControl // params: load (1=load, 0=unload)
+asmPlasm 1
jmp $601B
end
asm getMapScript // params: none
+asmPlasm 0
jmp $601E
end
///////////////////////////////////////////////////////////////////////////////////////////////////
asm setAuxCopy
@ -1283,7 +1288,11 @@ def checkScripts(x, y)
if x == ^p
script = p=>1
setWindow2()
skipScripts = FALSE
script()
// Some scripts need to suppress running of any further scripts on the square
// because they swapped out the render engine.
if skipScripts; return TRUE; fin
anyTriggered = TRUE
fin
p = p + 3
@ -1907,19 +1916,41 @@ def _streqi(a, b)
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def _queueCombat(mapCode)
// Put it on the heap long enough to make it through the transition to the combat engine.
// It'll get collected on the first GC because there's no global pointer to it, which is fine.
q_encounter = mmgr(HEAP_INTERN, mapCode)
// Called by user-defined map scripts to initiate a combat encounter.
def _scriptCombat(mapCode)
word pScripts
// Lock the currently running script in memory so combat engine doesn't destroy our calling
// context.
if renderLoaded
pScripts = getMapScript()
mmgr(LOCK_MEMORY, pScripts)
else
pScripts = NULL
fin
// Also suppress running further scripts on this tile, since we're going to switch out the
// rendering engine.
skipScripts = TRUE
// Now run the combat
doCombat(mapCode)
// Unlock the script module so it can get freed a the natural time (when it's done)
if pScripts
mmgr(UNLOCK_MEMORY, pScripts)
fin
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def doCombat(mapCode)
word result
// Handled in a separate module. Clear enemies out of the heap when finished.
loadEngine(MODULE_COMBAT)=>combat_zoneEncounter(mapCode)
result = loadEngine(MODULE_COMBAT)=>combat_zoneEncounter(mapCode)
global=>p_enemyGroups = NULL
mmgr(HEAP_COLLECT, 0)
restoreMapPos()
return result
end
///////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -30,6 +30,7 @@ start:
jmp pl_setColor ; params: slot (0=sky/1=ground), color (0-15); return: nothing
jmp pl_render ; params: none
jmp pl_texControl ; params: 0=unload textures, 1=load textures
jmp pl_getScripts ; params: none
; Conditional assembly flags
DOUBLE_BUFFER = 1 ; whether to double-buffer
@ -74,6 +75,7 @@ nMapSprites: !byte 0 ; number of sprite entries on map to fix up
nextLink: !byte 0 ; next link to allocate
plasmaStk: !byte 0
nTextures: !byte 0
scripts: !word 0 ; pointer to loaded scripts module
skyColorEven: !byte $20
skyColorOdd: !byte $22
@ -1579,6 +1581,8 @@ loadTextures: !zone
jsr mainLoader ; queue script to load
stx .scInit+1 ; store its location so we call its init...
sty .scInit+2 ; ...after it loads of course.
stx scripts
sty scripts+1
lda #0 ; now comes the list of textures.
sta txNum
.lup: jsr .get ; get texture resource number
@ -2033,6 +2037,16 @@ pl_setColor: !zone
sta skyColorOdd,x
rts
;-------------------------------------------------------------------------------
; Called by PLASMA code to get the currently loaded scripts module
; Parameters: None
; Returns: A pointer to the loaded script module
pl_getScripts: !zone {
lda scripts
ldy scripts+1
rts
}
;-------------------------------------------------------------------------------
; The real action
pl_initMap: !zone