mirror of
https://github.com/badvision/lawless-legends.git
synced 2024-08-16 14:29:00 +00:00
Implementing new game / load game screen.
This commit is contained in:
parent
17793d011f
commit
45ab9bafe2
@ -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.
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user