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.
def prevSave = new File("build/prevGame/game.1.save.\$f1")
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.
// 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
lda pTmp+1
sta heapStartPg
tax
sta heapTop+1
lda tSegAdrHi,y
sta heapEndPg
lda #0
ldy #0
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:
; Zero memory heapTop.heapEnd
heapClr: !zone
@ -1243,13 +1250,8 @@ heapCollect: !zone
jsr gc2_sweep ; sweep them into one place
jsr gc3_fix ; adjust all pointers
jsr heapClr ; and clear newly freed space
lda #0 ; heap end lo always 0
sec
sbc heapTop ; calculate new free space
tax
lda heapEndPg ; hi byte too
sbc heapTop+1
tay ; free space to X=lo/Y=hi
ldx heapTop ; return new top-of-heap in x=lo/y=hi
ldy heapTop+1
rts
.partOpen:
jsr inlineFatal : !text "NdClose",0

View File

@ -361,7 +361,8 @@ HEAP_INTERN = $23
HEAP_COLLECT = $24
; 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,
; reachable from the very first object allocated. By convention, that first

View File

@ -11,6 +11,9 @@
include "gamelib.plh"
include "playtype.plh"
include "diskops.plh"
include "gen_modules.plh"
include "gen_players.plh"
include "gen_globalScripts.plh"
// ProDOS MLI constants
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
// in the same order as the constants are defined in the the header.
predef _saveGame, _loadGame
word[] funcTbl = @_saveGame, @_loadGame
predef _saveGame, _loadGame, _newOrLoadGame
word[] funcTbl = @_saveGame, @_loadGame, @_newOrLoadGame
byte[] game1_filename = "GAME.1.SAVE"
@ -140,6 +143,14 @@ asm mliStub
rts
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)
byte err
@ -163,6 +174,10 @@ end
///////////////////////////////////////////////////////////////////////////////////////////////////
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
mmgr(FINISH_LOAD, WITH_CLOSE)
showMapName("Saving game...")
@ -196,20 +211,15 @@ def _saveGame()
diskActivity(0)
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def _loadGame()
diskActivity($FF)
def loadInternal()
word p_loaded
mmgr(FINISH_LOAD, WITH_CLOSE)
showMapName("Loading game...")
// 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_buffer = $5000
if callMLI(MLI_OPEN, @open_params) > 0
showMapName("Not found.")
getUpperKey()
return FALSE
else
// Read the game data from it
read_fileref = open_fileref
@ -222,11 +232,60 @@ def _loadGame()
guaranteeMLI(MLI_CLOSE, @close_params)
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
printf1("y before=%d\n", global=>w_mapY)
copyHeap(1) // main to aux
printf1("y after=%d\n", global=>w_mapY)
diskActivity(0)
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)
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
///////////////////////////////////////////////////////////////////////////////////////////////////

View File

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

View File

@ -57,6 +57,10 @@ const HEAP_COLLECT = $24
const WITH_CLOSE = 0
const LEAVE_OPEN = 1
// Heap location in memory
const HEAP_BOTTOM = $F000
const HEAP_SIZE = $800
///////////////////////////////////////////////////////////////////////////////////////////////////
// Shared library routines
const gameLibVecs = $1F00
@ -117,8 +121,8 @@ const makeModifier = gameLibVecs + 3*52
const randomFromArray = gameLibVecs + 3*53
const calcPlayerArmor = gameLibVecs + 3*54
const diskActivity = gameLibVecs + 3*55
const UNUSED_FN_56 = gameLibVecs + 3*56
const UNUSED_FN_57 = gameLibVecs + 3*57
const rdkey = gameLibVecs + 3*56
const initHeap = gameLibVecs + 3*57
const UNUSED_FN_58 = gameLibVecs + 3*58
const UNUSED_FN_59 = gameLibVecs + 3*59
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 expandVec = $2000 // aux mem (only for raycaster)
const fontEngine = $E000 // main mem
const heapStart = $F000 // main mem
const heapSize = $800
///////////////////////////////////////////////////////////////////////////////////////////////////
// Other constants
@ -38,7 +35,6 @@ include "playtype.plh"
include "gen_images.plh"
include "gen_modules.plh"
include "gen_enemies.plh"
include "gen_globalScripts.plh"
include "gen_players.plh"
include "combat.plh"
include "party.plh"
@ -112,6 +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
word gameLib_addrs = @_setScriptInfo, @_scriptDisplayStr, @_scriptDisplayStrNL, @_getYN
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 = @_pause, @_tossStrings, @_showMapName, @_setMapWindow
word = @_makeModifier, @_randomFromArray, @_calcPlayerArmor, @_diskActivity
word = @_rdkey, @_initHeap
word = 0 // end of library functions
@ -505,7 +503,7 @@ end
///////////////////////////////////////////////////////////////////////////////////////////////////
// Get a character from the keyboard
asm rdkey
asm _rdkey
+asmPlasm 0
jmp rdkey
end
@ -2060,14 +2058,17 @@ def loadTitle()
end
///////////////////////////////////////////////////////////////////////////////////////////////////
// Set up the small-object heap
def initHeap()
// Set up the small-object heap. Set loadedSize to zero on initial, or non-zero for loaded game.
def _initHeap(loadedSize)
byte i
mmgr(SET_MEM_TARGET, heapStart)
mmgr(REQUEST_MEMORY, heapSize)
mmgr(LOCK_MEMORY, heapStart)
mmgr(HEAP_SET, heapStart)
mmgr(SET_MEM_TARGET, HEAP_BOTTOM)
mmgr(REQUEST_MEMORY, HEAP_SIZE)
mmgr(LOCK_MEMORY, HEAP_BOTTOM)
if loadedSize <> 0
mmgr(SET_MEM_TARGET, HEAP_BOTTOM + loadedSize)
fin
mmgr(HEAP_SET, HEAP_BOTTOM)
i = 0
while typeTbls[i]
mmgr(HEAP_ADD_TYPE, typeTbls[i])
@ -2133,34 +2134,29 @@ def _calcPlayerArmor(player)
end
///////////////////////////////////////////////////////////////////////////////////////////////////
// Create the party
def initParty()
word playerScripts, itemScripts, globalScripts
def startGame()
word p_module
// Create the initial party
playerScripts = mmgr(QUEUE_LOAD, MODULE_GEN_PLAYERS<<8 | RES_TYPE_MODULE)
// Create a new game or load an existing one
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)
playerScripts()=>makeInitialParty()
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
mapNum = q_mapNum
q_mapNum = 0
initMap(q_x, q_y, q_dir)
if p_module()=>diskops_newOrLoadGame()
mapIs3D = q_mapIs3D
mapNum = q_mapNum
q_mapNum = 0
initMap(q_x, q_y, q_dir)
else
restoreMapPos()
fin
end
///////////////////////////////////////////////////////////////////////////////////////////////////
// Main code.
//
setLibVecs()
initHeap()
loadTitle()
initParty()
startGame()
kbdLoop()
done

View File

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