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 _loadGame()#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[] legendos_filename = "LEGENDOS.SYSTEM"
@ -327,18 +328,6 @@ def _rwGame(cmd)#0
loop
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
word size
@ -380,6 +369,28 @@ def checkMarks()#0
loop
if sp <> limit; err = 'D'; 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
///////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -13,3 +13,4 @@ const diskops_startup = 0
const diskops_saveGame = 2
const diskops_loadGame = 4
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 doRender()#0
predef pause(count)#1
predef printf1(str, arg1)#0
predef printf2(str, arg1, arg2)#0
predef playerDeath()#0
predef startGame(firstTime, ask)#0
@ -197,7 +198,8 @@ export byte[] S_THEIR = "their"
//word startTick = 0
word lastTick = 0
byte recordMode = TRUE
export byte recordMode = FALSE
word recordSeed
///////////////////////////////////////////////////////////////////////////////////////////////////
// Definitions used by assembly code
@ -223,7 +225,7 @@ ysav1 = $35
; 16-bit random number seed - incremented by ROM kbd routine
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.)
; 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
///////////////////////////////////////////////////////////////////////////////////////////////////
// Random number generator
// Adapted from http://codebase64.org/doku.php?id=base:small_fast_16-bit_prng
export asm rand16()#1
// Random number generator. A standard linear congruential prng featuring a full cycle (i.e.
// every value from 1..MAGIC-1 is part of the sequence).
asm internal_rand16()#1
!zone {
+asmPlasmRet 0
lda seed
beq .lowZero ; $0000 and $8000 are special values to test for
; Do a normal shift
ldx #6
lda seed+1
and #$7F ; in case kbd routine has advanced past MAGIC
beq .hiZero
sta seed+1
bne .chk ; always taken
.shift
asl seed
lda seed+1
rol
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
rol seed+1
.chk
lda seed
eor #<magic
sta seed
rts
.lowZero:
sec
sbc #<MAGIC
tay
lda seed+1
beq .doEor ; High byte is also zero, so apply the EOR
; For speed, you could store 'magic' into 'seed' directly
; instead of running the EORs
; 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:
sbc #>MAGIC
bcc .next
sty seed
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
.next
dex
bne .shift
.ret
lda seed
ldy seed+1
rts
.hiZero
lda seed ; zero-check
bne .next
inc seed ; force 0 seed to go to 1
bne .ret ; always taken
}
end
///////////////////////////////////////////////////////////////////////////////////////////////////
@ -1345,6 +1341,17 @@ end
///////////////////////////////////////////////////////////////////////////////////////////////////
// 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.
// 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
def initMap(x, y, dir)#0
word pDiskOps // TEMPORARY - FIXME FOO
// If we have a renderer loaded, let it know to flush automap marks
unloadTextures()
@ -2248,8 +2257,12 @@ def initMap(x, y, dir)#0
mmgr(QUEUE_LOAD, CODE_TILE_ENGINE<<8 | RES_TYPE_CODE)
fin
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)
pDiskOps()=>diskops_checkAutomap() // TEMPORARY - FIXME FOO
mmgr(FREE_MEMORY, pDiskOps) // TEMPORARY - FIXME FOO
// Set up the command table
initCmds()
@ -3172,20 +3185,25 @@ end
///////////////////////////////////////////////////////////////////////////////////////////////////
def toggleGodMode()#1
while ^kbd < 128; loop
if ^kbd == $8F // ctrl-O
^kbdStrobe
while ^kbd < 128; loop
if ^kbd == $84 // ctrl-D
^kbdStrobe
global->b_godmode = !global->b_godmode
byte key
key = getUpperKey
if key == 15 // ctrl-O
key = getUpperKey
if key == 4 or key == 18 // ctrl-D or ctrl-R
flipToPage1()
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
beep; beep
clearTextWindow()
initCmds() // rebuild the command table with new commands
fin
fin
return 0