Replaced random number generator. Made good progress on record mode.

This commit is contained in:
Martin Haye 2019-04-24 06:33:18 -07:00
parent ff6c08b9d7
commit 32021f42fa
3 changed files with 90 additions and 60 deletions

View File

@ -44,7 +44,8 @@ predef _startup()#1
predef _saveGame()#1 predef _saveGame()#1
predef _loadGame()#1 predef _loadGame()#1
predef _newOrLoadGame(ask)#1 predef _newOrLoadGame(ask)#1
word[] funcTbl = @_startup, @_saveGame, @_loadGame, @_newOrLoadGame predef _checkAutomap()#1 // TEMPORARY - FIXME FOO
word[] funcTbl = @_startup, @_saveGame, @_loadGame, @_newOrLoadGame, @_checkAutomap
byte[] game1_filename = "GAME.1.SAVE" byte[] game1_filename = "GAME.1.SAVE"
byte[] legendos_filename = "LEGENDOS.SYSTEM" byte[] legendos_filename = "LEGENDOS.SYSTEM"
@ -327,18 +328,6 @@ def _rwGame(cmd)#0
loop loop
end end
///////////////////////////////////////////////////////////////////////////////////////////////////
def _saveGame()#1
// Perform garbage collection and record the size of the heap so we can restore it correctly
// (also does a CHECK_MEM to be sure we never save corrupted heap)
heapCollect()
// Copy data to main memory, and write it out.
memcpy(HEAP_BOTTOM, LOAD_SAVE_BUF, HEAP_SIZE, 0) // LC to low mem
_rwGame(RWTS_WRITE)
return 0
end
/////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////
def readDiskMarks()#1 def readDiskMarks()#1
word size word size
@ -380,6 +369,28 @@ def checkMarks()#0
loop loop
if sp <> limit; err = 'D'; fin if sp <> limit; err = 'D'; fin
if err; printf1("code=%c\n", err); fatal("corrupt automap"); fin if err; printf1("code=%c\n", err); fatal("corrupt automap"); fin
puts("Marks checked.\n")
end
///////////////////////////////////////////////////////////////////////////////////////////////////
// TEMPORARY FOR DISK MARK CHECKING - FIXME FOO
def _checkAutomap()#1
readDiskMarks; checkMarks
return 0
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def _saveGame()#1
// Perform garbage collection and record the size of the heap so we can restore it correctly
// (also does a CHECK_MEM to be sure we never save corrupted heap)
heapCollect()
readDiskMarks; checkMarks // TEMPORARY - FIXME FOO
// Copy data to main memory, and write it out.
memcpy(HEAP_BOTTOM, LOAD_SAVE_BUF, HEAP_SIZE, 0) // LC to low mem
_rwGame(RWTS_WRITE)
return 0
end end
/////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -13,3 +13,4 @@ const diskops_startup = 0
const diskops_saveGame = 2 const diskops_saveGame = 2
const diskops_loadGame = 4 const diskops_loadGame = 4
const diskops_newOrLoadGame = 6 const diskops_newOrLoadGame = 6
const diskops_checkAutomap = 8 // TEMPORARY - FIXME FOO

View File

@ -75,6 +75,7 @@ predef clearPortrait()#0
predef showMapName(mapName)#0 predef showMapName(mapName)#0
predef doRender()#0 predef doRender()#0
predef pause(count)#1 predef pause(count)#1
predef printf1(str, arg1)#0
predef printf2(str, arg1, arg2)#0 predef printf2(str, arg1, arg2)#0
predef playerDeath()#0 predef playerDeath()#0
predef startGame(firstTime, ask)#0 predef startGame(firstTime, ask)#0
@ -197,7 +198,8 @@ export byte[] S_THEIR = "their"
//word startTick = 0 //word startTick = 0
word lastTick = 0 word lastTick = 0
byte recordMode = TRUE export byte recordMode = FALSE
word recordSeed
/////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////
// Definitions used by assembly code // Definitions used by assembly code
@ -223,7 +225,7 @@ ysav1 = $35
; 16-bit random number seed - incremented by ROM kbd routine ; 16-bit random number seed - incremented by ROM kbd routine
seed = $4E seed = $4E
magic = $2227 ; there are 2048 magic values that work; this one caught my eye. - MH MAGIC = $7FED ; largest prime < $8000
; NOTE ABOUT ABSOLUTE CODE ADDRESSING (e.g. STA .var, JMP .label, etc.) ; NOTE ABOUT ABSOLUTE CODE ADDRESSING (e.g. STA .var, JMP .label, etc.)
; We cannot use it: this code will be preceded by stubs for the PLASMA routines, hence ; We cannot use it: this code will be preceded by stubs for the PLASMA routines, hence
@ -1030,49 +1032,43 @@ export asm rawDisplayStr(pStr)#0
end end
/////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////
// Random number generator // Random number generator. A standard linear congruential prng featuring a full cycle (i.e.
// Adapted from http://codebase64.org/doku.php?id=base:small_fast_16-bit_prng // every value from 1..MAGIC-1 is part of the sequence).
export asm rand16()#1 asm internal_rand16()#1
!zone {
+asmPlasmRet 0 +asmPlasmRet 0
ldx #6
lda seed lda seed+1
beq .lowZero ; $0000 and $8000 are special values to test for and #$7F ; in case kbd routine has advanced past MAGIC
beq .hiZero
; Do a normal shift sta seed+1
bne .chk ; always taken
.shift
asl seed asl seed
lda seed+1 rol seed+1
rol .chk
bcc .noEor
.doEor:
; high byte is in A
eor #>magic
sta seed+1
and #$7F ; keep it positive, because PLASMA does the icky C thing with negative modulo
tay ; for asmPlasm, return hi byte in Y, lo byte in A
lda seed lda seed
eor #<magic sec
sta seed sbc #<MAGIC
rts tay
.lowZero:
lda seed+1 lda seed+1
beq .doEor ; High byte is also zero, so apply the EOR sbc #>MAGIC
; For speed, you could store 'magic' into 'seed' directly bcc .next
; instead of running the EORs sty seed
; wasn't zero, check for $8000
asl
beq .noEor ; if $00 is left after the shift, then it was $80
bcs .doEor ; else, do the EOR based on the carry bit as usual
.noEor:
sta seed+1 sta seed+1
and #$7F ; keep it positive, because PLASMA does the icky C thing with negative modulo .next
tay ; for asmPlasm, return hi byte in Y, lo byte in A dex
bne .shift
.ret
lda seed lda seed
ldy seed+1
rts rts
.hiZero
lda seed ; zero-check
bne .next
inc seed ; force 0 seed to go to 1
bne .ret ; always taken
}
end end
/////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////
@ -1345,6 +1341,17 @@ end
/////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////
// General methods // General methods
export def rand16()#1
word result
if recordMode
*seed = recordSeed
result = internal_rand16()
recordSeed = *seed
return result
fin
return internal_rand16()
end
/////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////
// Fatal error: print message and stop the system. // Fatal error: print message and stop the system.
// Doesn't really return a value, but can be handy for chaining. // Doesn't really return a value, but can be handy for chaining.
@ -2228,6 +2235,8 @@ end
/////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////
// Load code and data, set up everything to display a 2D or 3D map // Load code and data, set up everything to display a 2D or 3D map
def initMap(x, y, dir)#0 def initMap(x, y, dir)#0
word pDiskOps // TEMPORARY - FIXME FOO
// If we have a renderer loaded, let it know to flush automap marks // If we have a renderer loaded, let it know to flush automap marks
unloadTextures() unloadTextures()
@ -2248,8 +2257,12 @@ def initMap(x, y, dir)#0
mmgr(QUEUE_LOAD, CODE_TILE_ENGINE<<8 | RES_TYPE_CODE) mmgr(QUEUE_LOAD, CODE_TILE_ENGINE<<8 | RES_TYPE_CODE)
fin fin
pGlobalTileset = mmgr(QUEUE_LOAD, 1<<8 | RES_TYPE_TILESET) // even in 3d, need tiles for lamp/etc. pGlobalTileset = mmgr(QUEUE_LOAD, 1<<8 | RES_TYPE_TILESET) // even in 3d, need tiles for lamp/etc.
pDiskOps = mmgr(QUEUE_LOAD, MOD_DISKOPS<<8 | RES_TYPE_MODULE) // TEMPORARY - FIXME FOO
mmgr(FINISH_LOAD, 0) mmgr(FINISH_LOAD, 0)
pDiskOps()=>diskops_checkAutomap() // TEMPORARY - FIXME FOO
mmgr(FREE_MEMORY, pDiskOps) // TEMPORARY - FIXME FOO
// Set up the command table // Set up the command table
initCmds() initCmds()
@ -3172,20 +3185,25 @@ end
/////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////
def toggleGodMode()#1 def toggleGodMode()#1
while ^kbd < 128; loop byte key
if ^kbd == $8F // ctrl-O key = getUpperKey
^kbdStrobe if key == 15 // ctrl-O
while ^kbd < 128; loop key = getUpperKey
if ^kbd == $84 // ctrl-D if key == 4 or key == 18 // ctrl-D or ctrl-R
^kbdStrobe
global->b_godmode = !global->b_godmode
flipToPage1() flipToPage1()
clearTextWindow() clearTextWindow()
displayf1("gm:%d\n", global->b_godmode & 1) if key == 4 // ctrl-D
global->b_godmode = !global->b_godmode
displayf1("gm:%d\n", global->b_godmode & 1)
initCmds() // rebuild the command table with new commands
else
recordMode = !recordMode
if recordMode; recordSeed = 1; fin
displayf1("rm:%d\n", recordMode & 1)
fin
textDrawn = TRUE textDrawn = TRUE
beep; beep beep; beep
clearTextWindow() clearTextWindow()
initCmds() // rebuild the command table with new commands
fin fin
fin fin
return 0 return 0