Added import-game function.

This commit is contained in:
Martin Haye 2017-08-14 08:01:31 -07:00
parent 4cf10aba0a
commit 9c45ed0fb5
4 changed files with 98 additions and 51 deletions

View File

@ -1621,6 +1621,8 @@ class A2PackPartitions
name:"resourceIndex", buf:code["resourceIndex"].buf]
part.chunks[["code", "resourceIndex"]] = chunk
part.spaceUsed += calcChunkLen(chunk)
return combinedVersion
}
def fillAllDisks()
@ -1674,7 +1676,7 @@ class A2PackPartitions
assert allMaps.isEmpty : "All data must fit within $MAX_DISKS disks."
// Add the special resource index to disk 1
addResourceIndex(partChunks[0])
def gameVersion = addResourceIndex(partChunks[0])
// And write out each disk
partChunks.each { part ->
@ -1686,6 +1688,8 @@ class A2PackPartitions
def spaceUsed = part.spaceUsed // use var to avoid gigantic assert fail msg
assert spaceUsed == partFile.length()
}
println "Game version: V $gameVersion"
}
def writePartition(stream, partNum, chunks)
@ -3252,7 +3256,7 @@ end
def createHddImage()
{
println "Creating hdd image."
//println "Creating hdd image."
// Copy the combined core executable to the output directory
copyIfNewer(new File("build/src/core/build/LEGENDOS.SYSTEM.sys#2000"),
@ -3277,7 +3281,7 @@ end
def createFloppyImages()
{
println "Creating floppy images."
//println "Creating floppy images."
// We'll be copying stuff from the hdd directory
def hddDir = new File("build/root")

View File

@ -37,6 +37,7 @@ predef _newOrLoadGame(ask)#1
word[] funcTbl = @_saveGame, @_loadGame, @_newOrLoadGame
byte[] game1_filename = "GAME.1.SAVE"
byte[] legendos_filename = "LEGENDOS.SYSTEM"
///////////////////////////////////////////////////////////////////////////////////////////////////
// Definitions used by assembly code
@ -223,15 +224,20 @@ def _rwGame(cmd)#0
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def _saveGame()#1
def saveInternal()#0
// 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
// Copy data to main memory, and write it out.
showMapName("Saving game...")
memcpy(HEAP_BOTTOM, LOAD_SAVE_BUF, HEAP_SIZE) // LC to low mem
_rwGame(RWTS_WRITE)
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def _saveGame()#1
showMapName("Saving game...")
saveInternal()
return 0
end
@ -246,9 +252,8 @@ def loadInternal()#1
p_loaded = LOAD_SAVE_BUF
if p_loaded=>w_heapSize == 0
return FALSE // no game saved yet
fin
if p_loaded=>w_heapSize < 100 or p_loaded=>w_heapSize > HEAP_SIZE
fatal("Corrupt game file.")
elsif p_loaded=>w_heapSize < 100 or p_loaded=>w_heapSize > HEAP_SIZE or p_loaded=>w_typeHash <> typeHash
fatal("Incompatible game file.")
fin
memcpy(LOAD_SAVE_BUF, HEAP_BOTTOM, HEAP_SIZE) // low mem to LC
initHeap(p_loaded=>w_heapSize)
@ -270,6 +275,67 @@ def _loadGame()#1
return 0
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def gameExists()#1
word p_loaded
// Load first part of save game into mem... 1 block should be plenty to verify it's real.
if callProRWTS(RWTS_READ | RWTS_OPENDIR, @game1_filename, LOAD_SAVE_BUF, 512) == 0
// If heap size is reasonable and type hash matches, chances are high that it's a real save game.
p_loaded = LOAD_SAVE_BUF
if p_loaded=>w_heapSize >= 100 and p_loaded=>w_heapSize <= HEAP_SIZE and p_loaded=>w_typeHash == typeHash
return TRUE
fin
fin
return FALSE
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def getTextKey()#1
byte key
^$c053
key = getUpperKey()
^$c052
textHome()
^$25 = 20
return key
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def pressAnyKey()#0
puts("\n and press any key to continue.")
getTextKey()
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def reinsert()#0
while TRUE
puts(" Re-insert disk 1")
pressAnyKey()
if callProRWTS(RWTS_READ | RWTS_OPENDIR, @legendos_filename, LOAD_SAVE_BUF, 512) == 0
break
fin
puts("\n ")
beep()
loop
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def importGame()#1
puts("\n Insert disk for import")
pressAnyKey()
if gameExists()
loadInternal()
puts("\n Game imported.")
reinsert()
saveInternal()
return TRUE
fin
puts("\n Not found.")
reinsert()
return FALSE
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def isNameChar(ch)
when ch
@ -352,52 +418,30 @@ def newGame()#0
fin
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def gameExists()#1
word p_loaded
// Load first part of save game into mem... 1 block should be plenty to verify it's real.
if callProRWTS(RWTS_READ | RWTS_OPENDIR, @game1_filename, LOAD_SAVE_BUF, 512) == 0
// If heap size is reasonable, assume it's a real save game. (Hash will be checked if the
// user chooses to actually load the game)
p_loaded = LOAD_SAVE_BUF
if p_loaded=>w_heapSize >= 100 and p_loaded=>w_heapSize <= HEAP_SIZE
return TRUE
fin
fin
return FALSE
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def _newOrLoadGame(ask)#1
byte key
if !gameExists()
newGame(); return 1
elsif !ask
loadInternal(); return 0
fin
if !ask
loadInternal()
return 0
fin
textHome()
^$c053
^$25 = 20
puts("\n N)ew game, or L)oad last game? ")
while TRUE
key = getUpperKey()
if key == 'N'
^$c052
newGame()
return 1
elsif key == 'L'
^$c052
if loadInternal()
return 0
fin
fin
textHome()
^$25 = 20
puts("\n Game: N)ew, L)oad, I)mport?")
key = getTextKey()
when key
is 'N'
newGame(); return 1
is 'L'
if loadInternal(); return 0; fin
break
is 'I'
if importGame(); return 0; fin
wend
beep()
loop
return 0

View File

@ -148,6 +148,7 @@ import gamelib
word groundNum
byte portraitNum
word pGodModule
word typeHash
/////////// Shared string constants //////////////

View File

@ -97,6 +97,7 @@ word pResourceIndex = NULL
word pGlobalTileset = NULL
byte curMapPartition = 0
export word pGodModule = NULL
export word typeHash = 0
// Queue setMap / teleport / start_encounter, since otherwise script might be replaced while executing
byte q_mapIs3D = 0
@ -1688,11 +1689,11 @@ end
///////////////////////////////////////////////////////////////////////////////////////////////////
export def loadMainFrameImg()#0
loadFrameImg(mapIs3D+2)
if curFullscreenImg
auxMmgr(FREE_MEMORY, curFullscreenImg)
curFullscreenImg = NULL
fin
loadFrameImg(mapIs3D+2)
end
///////////////////////////////////////////////////////////////////////////////////////////////////
@ -2725,7 +2726,6 @@ end
// Set up the small-object heap. Set loadedSize to zero on initial, or non-zero for loaded game.
export def initHeap(loadedSize)#0
byte i
word typeHash
if !heapLocked
mmgr(SET_MEM_TARGET, HEAP_BOTTOM)
@ -2743,12 +2743,8 @@ export def initHeap(loadedSize)#0
mmgr(HEAP_ADD_TYPE, typeTbls[i])
i = i+1
loop
typeHash = hashBuffer(@typeTbl_Global, @typeTbls - @typeTbl_Global) ^ HEAP_BOTTOM
if loadedSize <> 0
global = HEAP_BOTTOM
if global=>w_typeHash <> typeHash
fatal("Incompatible saved game")
fin
else
global = mmgr(HEAP_ALLOC, TYPE_GLOBAL)
global=>w_typeHash = typeHash
@ -3104,6 +3100,8 @@ end
def startGame(ask)#0
word p_module
typeHash = hashBuffer(@typeTbl_Global, @typeTbls - @typeTbl_Global) ^ HEAP_BOTTOM
// Create a new game or load an existing one
mmgr(START_LOAD, 1) // code is in partition 1
p_module = mmgr(QUEUE_LOAD, MOD_DISKOPS<<8 | RES_TYPE_MODULE)