From f1fbd7bd8ce543aece8cb7ee15e578828bf6a08d Mon Sep 17 00:00:00 2001 From: Martin Haye Date: Thu, 30 Jun 2016 08:36:46 -0700 Subject: [PATCH] Working on getting script to resume after combat. --- .../src/org/demo/PackPartitions.groovy | 2 +- Platform/Apple/virtual/src/core/mem.s | 39 +++++++++------- Platform/Apple/virtual/src/include/mem.i | 6 +++ Platform/Apple/virtual/src/plasma/combat.pla | 18 +++++--- Platform/Apple/virtual/src/plasma/gamelib.plh | 2 +- .../Apple/virtual/src/plasma/gameloop.pla | 45 ++++++++++++++++--- Platform/Apple/virtual/src/raycast/render.s | 14 ++++++ 7 files changed, 96 insertions(+), 30 deletions(-) diff --git a/Platform/Apple/tools/PackPartitions/src/org/demo/PackPartitions.groovy b/Platform/Apple/tools/PackPartitions/src/org/demo/PackPartitions.groovy index c7c1242f..d6a155db 100644 --- a/Platform/Apple/tools/PackPartitions/src/org/demo/PackPartitions.groovy +++ b/Platform/Apple/tools/PackPartitions/src/org/demo/PackPartitions.groovy @@ -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) diff --git a/Platform/Apple/virtual/src/core/mem.s b/Platform/Apple/virtual/src/core/mem.s index f9d56554..91ec3590 100644 --- a/Platform/Apple/virtual/src/core/mem.s +++ b/Platform/Apple/virtual/src/core/mem.s @@ -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 #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) diff --git a/Platform/Apple/virtual/src/plasma/gamelib.plh b/Platform/Apple/virtual/src/plasma/gamelib.plh index 56b98ac1..9d72c5ec 100644 --- a/Platform/Apple/virtual/src/plasma/gamelib.plh +++ b/Platform/Apple/virtual/src/plasma/gamelib.plh @@ -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 diff --git a/Platform/Apple/virtual/src/plasma/gameloop.pla b/Platform/Apple/virtual/src/plasma/gameloop.pla index 7534864f..33bf22f6 100644 --- a/Platform/Apple/virtual/src/plasma/gameloop.pla +++ b/Platform/Apple/virtual/src/plasma/gameloop.pla @@ -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 /////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/Platform/Apple/virtual/src/raycast/render.s b/Platform/Apple/virtual/src/raycast/render.s index 27a23a58..347588de 100644 --- a/Platform/Apple/virtual/src/raycast/render.s +++ b/Platform/Apple/virtual/src/raycast/render.s @@ -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