Implementing new game / load game screen.

This commit is contained in:
Martin Haye 2016-06-24 05:58:30 -07:00
parent 17793d011f
commit 45ab9bafe2
8 changed files with 122 additions and 56 deletions

View File

@ -2362,7 +2362,7 @@ end
// If we preserved a previous save game, copy it to the new image. // If we preserved a previous save game, copy it to the new image.
def prevSave = new File("build/prevGame/game.1.save.\$f1") def prevSave = new File("build/prevGame/game.1.save.\$f1")
if (prevSave.exists()) if (prevSave.exists())
Files.copy(prevSave.toPath(), new File("build/root/game.1.save.\$f1").toPath()) copyIfNewer(prevSave, new File("build/root/game.1.save.\$f1"))
// Decompress the base image. // Decompress the base image.
// No need to delete old file; that was done by outer-level code. // No need to delete old file; that was done by outer-level code.

View File

@ -855,12 +855,19 @@ heapSet: !zone
; Good to go. Record the start and end pages ; Good to go. Record the start and end pages
lda pTmp+1 lda pTmp+1
sta heapStartPg sta heapStartPg
tax
sta heapTop+1 sta heapTop+1
lda tSegAdrHi,y lda tSegAdrHi,y
sta heapEndPg sta heapEndPg
lda #0 ldy #0
sta heapTop sta heapTop
sta nTypes sty nTypes
lda targetAddr+1 ; see if heap top was specified
beq + ; no, default to empty heap
tax ; yes, use specified address
ldy targetAddr
+ stx heapTop+1 ; set heap top
sty heapTop
; fall through to: ; fall through to:
; Zero memory heapTop.heapEnd ; Zero memory heapTop.heapEnd
heapClr: !zone heapClr: !zone
@ -1243,13 +1250,8 @@ heapCollect: !zone
jsr gc2_sweep ; sweep them into one place jsr gc2_sweep ; sweep them into one place
jsr gc3_fix ; adjust all pointers jsr gc3_fix ; adjust all pointers
jsr heapClr ; and clear newly freed space jsr heapClr ; and clear newly freed space
lda #0 ; heap end lo always 0 ldx heapTop ; return new top-of-heap in x=lo/y=hi
sec ldy heapTop+1
sbc heapTop ; calculate new free space
tax
lda heapEndPg ; hi byte too
sbc heapTop+1
tay ; free space to X=lo/Y=hi
rts rts
.partOpen: .partOpen:
jsr inlineFatal : !text "NdClose",0 jsr inlineFatal : !text "NdClose",0

View File

@ -361,7 +361,8 @@ HEAP_INTERN = $23
HEAP_COLLECT = $24 HEAP_COLLECT = $24
; Input: None. ; Input: None.
; ;
; Output: X-reg(lo) / Y-reg(hi): free space in heap after collection ; Output: X-reg(lo) / Y-reg(hi): new top of heap after collection. If you
; need to know free space, subtract this from the end-of-heap.
; ;
; Traces objects in the heap to determine which ones are "live", that is, ; Traces objects in the heap to determine which ones are "live", that is,
; reachable from the very first object allocated. By convention, that first ; reachable from the very first object allocated. By convention, that first

View File

@ -11,6 +11,9 @@
include "gamelib.plh" include "gamelib.plh"
include "playtype.plh" include "playtype.plh"
include "diskops.plh" include "diskops.plh"
include "gen_modules.plh"
include "gen_players.plh"
include "gen_globalScripts.plh"
// ProDOS MLI constants // ProDOS MLI constants
const MLI_QUIT = $65 const MLI_QUIT = $65
@ -42,8 +45,8 @@ word global
// Exported functions go here. First a predef for each one, then a table with function pointers // Exported functions go here. First a predef for each one, then a table with function pointers
// in the same order as the constants are defined in the the header. // in the same order as the constants are defined in the the header.
predef _saveGame, _loadGame predef _saveGame, _loadGame, _newOrLoadGame
word[] funcTbl = @_saveGame, @_loadGame word[] funcTbl = @_saveGame, @_loadGame, @_newOrLoadGame
byte[] game1_filename = "GAME.1.SAVE" byte[] game1_filename = "GAME.1.SAVE"
@ -140,6 +143,14 @@ asm mliStub
rts rts
end end
///////////////////////////////////////////////////////////////////////////////////////////////////
// Clear the text-mode screen, and put the cursor there.
// Params: None
asm home
+asmPlasm 0
jmp home
end
/////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////
def callMLI(cmd, p_params) def callMLI(cmd, p_params)
byte err byte err
@ -163,6 +174,10 @@ end
/////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////
def _saveGame() def _saveGame()
// Perform garbage collection and record the size of the heap so we can restore it correctly
global=>w_heapSize = mmgr(HEAP_COLLECT, 0) - HEAP_BOTTOM
printf1("heapSize=$%x\n", global=>w_heapSize)
// Copy data to main memory // Copy data to main memory
mmgr(FINISH_LOAD, WITH_CLOSE) mmgr(FINISH_LOAD, WITH_CLOSE)
showMapName("Saving game...") showMapName("Saving game...")
@ -196,20 +211,15 @@ def _saveGame()
diskActivity(0) diskActivity(0)
end end
/////////////////////////////////////////////////////////////////////////////////////////////////// def loadInternal()
def _loadGame() word p_loaded
diskActivity($FF)
mmgr(FINISH_LOAD, WITH_CLOSE) mmgr(FINISH_LOAD, WITH_CLOSE)
showMapName("Loading game...")
// Open the file // Open the file
diskActivity($FF)
^$4000 = 0 // so 3D engine knows we overwrite HGR page 2, even if we fail
open_filename = @game1_filename open_filename = @game1_filename
open_buffer = $5000 open_buffer = $5000
if callMLI(MLI_OPEN, @open_params) > 0 if callMLI(MLI_OPEN, @open_params) > 0
showMapName("Not found.") return FALSE
getUpperKey()
else else
// Read the game data from it // Read the game data from it
read_fileref = open_fileref read_fileref = open_fileref
@ -222,11 +232,60 @@ def _loadGame()
guaranteeMLI(MLI_CLOSE, @close_params) guaranteeMLI(MLI_CLOSE, @close_params)
fin fin
// Init the heap with the correct size
p_loaded = $4000
printf1("Loaded heap size: $%x\n", p_loaded=>w_heapSize)
initHeap(p_loaded=>w_heapSize)
// Now copy the data back up to the heap space, and we're done // Now copy the data back up to the heap space, and we're done
printf1("y before=%d\n", global=>w_mapY)
copyHeap(1) // main to aux copyHeap(1) // main to aux
printf1("y after=%d\n", global=>w_mapY) return TRUE
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def _loadGame()
diskActivity($FF)
showMapName("Loading game...")
// Open the file
^$4000 = 0 // so 3D engine knows we overwrite HGR page 2, even if we fail
if !loadInternal()
diskActivity(0) diskActivity(0)
showMapName("Not found.")
getUpperKey()
else
diskActivity(0)
fin
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def _newOrLoadGame()
word playersModule, globalScriptsModule
byte key
home()
^$c053
^$25 = 20
puts("\n N)ew game, or L)oad last game? ")
while TRUE
key = rdkey() & $7F
home()
^$c052
if key > $60; key = key - $20; fin
if key == 'N'
initHeap(0) // initially empty heap
global = getGlobals()
playersModule = mmgr(QUEUE_LOAD, MODULE_GEN_PLAYERS<<8 | RES_TYPE_MODULE)
globalScriptsModule = mmgr(QUEUE_LOAD, MODULE_GEN_GLOBAL_SCRIPTS<<8 | RES_TYPE_MODULE)
mmgr(FINISH_LOAD, LEAVE_OPEN)
playersModule()=>makeInitialParty()
globalScriptsModule()=>sc_newGame()
return 1
elsif key == 'L' and loadInternal()
return 0
fin
beep()
loop
end end
/////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -11,3 +11,4 @@
// Each module-exported function needs its own constant, 0..n // Each module-exported function needs its own constant, 0..n
const diskops_saveGame = 0 const diskops_saveGame = 0
const diskops_loadGame = 2 const diskops_loadGame = 2
const diskops_newOrLoadGame = 4

View File

@ -57,6 +57,10 @@ const HEAP_COLLECT = $24
const WITH_CLOSE = 0 const WITH_CLOSE = 0
const LEAVE_OPEN = 1 const LEAVE_OPEN = 1
// Heap location in memory
const HEAP_BOTTOM = $F000
const HEAP_SIZE = $800
/////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////
// Shared library routines // Shared library routines
const gameLibVecs = $1F00 const gameLibVecs = $1F00
@ -117,8 +121,8 @@ const makeModifier = gameLibVecs + 3*52
const randomFromArray = gameLibVecs + 3*53 const randomFromArray = gameLibVecs + 3*53
const calcPlayerArmor = gameLibVecs + 3*54 const calcPlayerArmor = gameLibVecs + 3*54
const diskActivity = gameLibVecs + 3*55 const diskActivity = gameLibVecs + 3*55
const UNUSED_FN_56 = gameLibVecs + 3*56 const rdkey = gameLibVecs + 3*56
const UNUSED_FN_57 = gameLibVecs + 3*57 const initHeap = gameLibVecs + 3*57
const UNUSED_FN_58 = gameLibVecs + 3*58 const UNUSED_FN_58 = gameLibVecs + 3*58
const UNUSED_FN_59 = gameLibVecs + 3*59 const UNUSED_FN_59 = gameLibVecs + 3*59
const UNUSED_FN_60 = gameLibVecs + 3*60 const UNUSED_FN_60 = gameLibVecs + 3*60

View File

@ -16,9 +16,6 @@ const seed = $4E // Incremented continuously by keyboard read routi
const displayEngine = $6000 // main mem (raycaster and tile engine at same location) const displayEngine = $6000 // main mem (raycaster and tile engine at same location)
const expandVec = $2000 // aux mem (only for raycaster) const expandVec = $2000 // aux mem (only for raycaster)
const fontEngine = $E000 // main mem const fontEngine = $E000 // main mem
const heapStart = $F000 // main mem
const heapSize = $800
/////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////
// Other constants // Other constants
@ -38,7 +35,6 @@ include "playtype.plh"
include "gen_images.plh" include "gen_images.plh"
include "gen_modules.plh" include "gen_modules.plh"
include "gen_enemies.plh" include "gen_enemies.plh"
include "gen_globalScripts.plh"
include "gen_players.plh" include "gen_players.plh"
include "combat.plh" include "combat.plh"
include "party.plh" include "party.plh"
@ -112,6 +108,7 @@ predef _reboot, _brk, _encodeDice, _rollDice
predef _setPlural, _getStringResponse, _streqi, _addEncounterZone, _fatal predef _setPlural, _getStringResponse, _streqi, _addEncounterZone, _fatal
predef _pause, _tossStrings, _showMapName, _setMapWindow predef _pause, _tossStrings, _showMapName, _setMapWindow
predef _makeModifier, _randomFromArray, _calcPlayerArmor, _diskActivity predef _makeModifier, _randomFromArray, _calcPlayerArmor, _diskActivity
predef _rdkey, _initHeap
word gameLib_addrs = @_setScriptInfo, @_scriptDisplayStr, @_scriptDisplayStrNL, @_getYN word gameLib_addrs = @_setScriptInfo, @_scriptDisplayStr, @_scriptDisplayStrNL, @_getYN
word = @_queue_setMap, @_setSky, @_setGround, @_queue_teleport, @_setPortrait, @_clearPortrait word = @_queue_setMap, @_setSky, @_setGround, @_queue_teleport, @_setPortrait, @_clearPortrait
@ -127,6 +124,7 @@ word = @_reboot, @_brk, @_encodeDice, @_rollDice
word = @_setPlural, @_getStringResponse, @_streqi, @_addEncounterZone, @_fatal word = @_setPlural, @_getStringResponse, @_streqi, @_addEncounterZone, @_fatal
word = @_pause, @_tossStrings, @_showMapName, @_setMapWindow word = @_pause, @_tossStrings, @_showMapName, @_setMapWindow
word = @_makeModifier, @_randomFromArray, @_calcPlayerArmor, @_diskActivity word = @_makeModifier, @_randomFromArray, @_calcPlayerArmor, @_diskActivity
word = @_rdkey, @_initHeap
word = 0 // end of library functions word = 0 // end of library functions
@ -505,7 +503,7 @@ end
/////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////
// Get a character from the keyboard // Get a character from the keyboard
asm rdkey asm _rdkey
+asmPlasm 0 +asmPlasm 0
jmp rdkey jmp rdkey
end end
@ -2060,14 +2058,17 @@ def loadTitle()
end end
/////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////
// Set up the small-object heap // Set up the small-object heap. Set loadedSize to zero on initial, or non-zero for loaded game.
def initHeap() def _initHeap(loadedSize)
byte i byte i
mmgr(SET_MEM_TARGET, heapStart) mmgr(SET_MEM_TARGET, HEAP_BOTTOM)
mmgr(REQUEST_MEMORY, heapSize) mmgr(REQUEST_MEMORY, HEAP_SIZE)
mmgr(LOCK_MEMORY, heapStart) mmgr(LOCK_MEMORY, HEAP_BOTTOM)
mmgr(HEAP_SET, heapStart) if loadedSize <> 0
mmgr(SET_MEM_TARGET, HEAP_BOTTOM + loadedSize)
fin
mmgr(HEAP_SET, HEAP_BOTTOM)
i = 0 i = 0
while typeTbls[i] while typeTbls[i]
mmgr(HEAP_ADD_TYPE, typeTbls[i]) mmgr(HEAP_ADD_TYPE, typeTbls[i])
@ -2133,34 +2134,29 @@ def _calcPlayerArmor(player)
end end
/////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////
// Create the party def startGame()
def initParty() word p_module
word playerScripts, itemScripts, globalScripts
// Create the initial party // Create a new game or load an existing one
playerScripts = mmgr(QUEUE_LOAD, MODULE_GEN_PLAYERS<<8 | RES_TYPE_MODULE) mmgr(START_LOAD, 1) // code is in partition 1
p_module = mmgr(QUEUE_LOAD, MODULE_DISKOPS<<8 | RES_TYPE_MODULE)
mmgr(FINISH_LOAD, LEAVE_OPEN) mmgr(FINISH_LOAD, LEAVE_OPEN)
playerScripts()=>makeInitialParty() if p_module()=>diskops_newOrLoadGame()
mmgr(FREE_MEMORY, playerScripts)
// And run the new-game script
globalScripts = mmgr(QUEUE_LOAD, MODULE_GEN_GLOBAL_SCRIPTS<<8 | RES_TYPE_MODULE)
mmgr(FINISH_LOAD, LEAVE_OPEN)
globalScripts()=>sc_newGame()
mmgr(FREE_MEMORY, globalScripts)
mapIs3D = q_mapIs3D mapIs3D = q_mapIs3D
mapNum = q_mapNum mapNum = q_mapNum
q_mapNum = 0 q_mapNum = 0
initMap(q_x, q_y, q_dir) initMap(q_x, q_y, q_dir)
else
restoreMapPos()
fin
end end
/////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////
// Main code. // Main code.
// //
setLibVecs() setLibVecs()
initHeap()
loadTitle() loadTitle()
initParty() startGame()
kbdLoop() kbdLoop()
done done

View File

@ -25,6 +25,9 @@ struc Global
word w_mapX word w_mapX
word w_mapY word w_mapY
byte b_mapDir byte b_mapDir
// Heap size for restoring saved game
word w_heapSize
end end
const PLAYER_FLAG_NPC = $01 const PLAYER_FLAG_NPC = $01