Fixed hashing function which was allowing loading of incompatible games. Added basic clock advancing.

This commit is contained in:
Martin Haye 2018-01-09 10:02:28 -08:00
parent c85c153363
commit de5a6bef25
3 changed files with 159 additions and 67 deletions

View File

@ -394,6 +394,7 @@ def newGame()#0
initHeap(0) // initially empty heap
global->b_curAvatar = BASE_AVATAR
global=>w_combatPauseCt = DEFAULT_COMBAT_PAUSE_CT
global->b_hour = 12 // start at high noon
mmgr(START_LOAD, 1) // players module and new game module both in partition 1
playersModule = mmgr(QUEUE_LOAD, MOD_GEN_PLAYERS<<8 | RES_TYPE_MODULE)
newGameModule = mmgr(QUEUE_LOAD, GS_NEW_GAME<<8 | RES_TYPE_MODULE)
@ -415,24 +416,29 @@ end
///////////////////////////////////////////////////////////////////////////////////////////////////
def _newOrLoadGame(ask)#1
byte key
byte key, existing
if !gameExists()
newGame(); return 1
elsif !ask
existing = gameExists()
if existing and !ask
loadInternal(); return 0
fin
while TRUE
textHome()
^$25 = 20
puts("\n Game: N)ew, L)oad, I)mport?")
puts("\n Game: N)ew, ")
if existing; puts("L)oad, "); fin
puts("I)mport?")
key = getTextKey()
when key
is 'N'
newGame(); return 1
is 'L'
if loadInternal(); return 0; fin
if gameExists
if loadInternal(); return 0; fin
else
beep
fin
break
is 'I'
if importGame(); return 0; fin

View File

@ -28,6 +28,14 @@ const CLOCK_X = 112
const CLOCK_Y = 176
const CLOCK_RADIUS = 14
const CLOCK_ADV_2D_HOURS = 1
const CLOCK_ADV_2D_MINS = 0
const CLOCK_ADV_2D_SECS = 0
const CLOCK_ADV_3D_HOURS = 0
const CLOCK_ADV_3D_MINS = 0
const CLOCK_ADV_3D_SECS = 30
// Max gold
const GOLD_MAX = 20000
@ -129,6 +137,10 @@ byte animDirCt
byte anyAnims = TRUE
word animPauseCt
// Tracking previous clock hands for quick erase/redraw
byte prevClockColor, prevClockHour, prevClockMinute
byte nextSignificantMinute
// Context for lambda functions (in lieu of closures, for now at least)
export word ctx
@ -717,20 +729,24 @@ export asm hashBuffer(ptr, len)#1
lda evalStkL,x ; second arg is length
tax
ldy #0
sty tmp+1
sty tmp
tya
clc
- adc (pTmp),y
ror
ror tmp+1
ror
ror tmp+1
ror
ror tmp+1
iny
- clc
adc (pTmp),y
bcc +
inc tmp
+ lsr
ror tmp
bcc +
ora #$80
+ lsr
ror tmp
bcc +
ora #$80
+ iny
dex
bne -
ldy tmp+1
ldy tmp
rts
end
@ -1924,41 +1940,41 @@ end
///////////////////////////////////////////////////////////////////////////////////////////////////
def showClock()#0
word cursX, cursY, color, hour, min, n, prevColor
word cursX, cursY, color
flipToPage1 // to hide our work in progress on page 2
prevColor = 99
hour = 0
min = 0
while TRUE
drawHands(color, hour, min) // erase
// Show page 1 while we do work on page 2
flipToPage1
min = min + 5
if min > 59
min = min - 60
hour = hour + 1
if hour > 23
hour = 0
fin
fin
// Erase old clock hands if applicable
if prevClockColor <> 99
drawHands(prevClockColor, prevClockHour, prevClockMinute)
fin
color = hour < 6 or hour >= 18 ?? 0 :: $7F
if color <> prevColor
drawCircle(color, CLOCK_RADIUS, CLOCK_X, CLOCK_Y)
prevColor = color
fin
// New color
color = global->b_hour < 6 or global->b_hour >= 18 ?? 0 :: $7F
if color <> prevClockColor
// Draw entire circle in new color
drawCircle(color, CLOCK_RADIUS, CLOCK_X, CLOCK_Y)
else
// Erase old clock hands
drawHands(prevClockColor, prevClockHour, prevClockMinute)
fin
drawHands(color ^ $7F, hour, min)
// Draw new clock hands
drawHands(color ^ $7F, global->b_hour, global->b_minute)
// Copy the image from pg 2 to pg 1
cursX, cursY = getCursor()
setWindow(CLOCK_Y-CLOCK_RADIUS, CLOCK_Y+CLOCK_RADIUS, (CLOCK_X-CLOCK_RADIUS)/7*7, (CLOCK_X+CLOCK_RADIUS+6)/7*7)
copyWindow($60) // page 2 to page 1
setWindow2()
setCursor(cursX, cursY)
// Copy the image from pg 2 to pg 1
cursX, cursY = getCursor()
setWindow(CLOCK_Y-CLOCK_RADIUS, CLOCK_Y+CLOCK_RADIUS, (CLOCK_X-CLOCK_RADIUS)/7*7, (CLOCK_X+CLOCK_RADIUS+6)/7*7)
copyWindow($60) // page 2 to page 1
setWindow2()
setCursor(cursX, cursY)
rdkey()
loop
// And record parameters for erasing the clock hands next time
prevClockColor = color
prevClockHour = global->b_hour
prevClockMinute = global->b_minute
nextSignificantMinute = global->b_minute - (global->b_minute % 5) + 5
end
///////////////////////////////////////////////////////////////////////////////////////////////////
@ -2040,6 +2056,7 @@ def initMap(x, y, dir)#0
curPortrait = NULL
curPortraitNum = 0
curFullscreenImg = NULL
prevClockColor = 99
if mapIs3D
showCompassDir(dir)
showClock()
@ -2107,7 +2124,74 @@ def doRender()#0
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def moveInternal(facingDir, moveDir, beepOK)#1
def advTime(hours, mins, secs)#0
byte redrawClock, runScript
if secs
global->b_second = global->b_second + secs
while global->b_second >= 60
global->b_second = global->b_second - 60
mins++
loop
fin
if mins or hours
redrawClock = FALSE
global->b_minute = global->b_minute + mins
if global->b_minute >= nextSignificantMinute; redrawClock = TRUE; fin
while global->b_minute >= 60
global->b_minute = global->b_minute - 60
hours++
loop
if hours
redrawClock = TRUE
global->b_hour = global->b_hour + hours
while global->b_hour >= 24
global->b_hour = global->b_hour - 24
loop
runScript = TRUE
fin
if mapIs3D and redrawClock
showClock()
fin
fin
if runScript
// TODO: Run time script here
fin
end
///////////////////////////////////////////////////////////////////////////////////////////////////
// Called by scripts to display a string. We set the flag noting that something has been
// displayed, then use an assembly routine to do the work.
export def _scriptDisplayStr(str)#0
if pIntimate
pIntimate=>intimate_displayStr(str)
else
if textClearCountdown; clearTextWindow(); fin
if renderLoaded; flipToPage1(); fin
displayStr(str)
textDrawn = TRUE
fin
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def snooze()#1
advTime(0, 59 - global->b_minute, 60 - global->b_second) // start of next hour
_scriptDisplayStr("Time passes. ")
displayf1("It is now %d:", global->b_hour == 0 ?? 12 :: global->b_hour == 12 ?? 12 :: global->b_hour % 12)
displayf2("%s%d ", global->b_minute < 10 ?? "0" :: "", global->b_minute)
displayf1("%s.\n", global->b_hour < 12 ?? "am" :: "pm")
copyWindow(0)
return 0
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def moveInternal(facingDir, moveDir, beepOK, shouldAdvTime)#1
byte val
word x, y
@ -2126,6 +2210,15 @@ def moveInternal(facingDir, moveDir, beepOK)#1
fin
fin
// Advance time if requested
if shouldAdvTime
if mapIs3D
advTime(CLOCK_ADV_3D_HOURS, CLOCK_ADV_3D_MINS, CLOCK_ADV_3D_SECS)
else
advTime(CLOCK_ADV_2D_HOURS, CLOCK_ADV_2D_MINS, CLOCK_ADV_2D_SECS)
fin
fin
// If we're on a new map tile, run leave handlers from old tile.
if val >= 2
scriptEvent(@S_LEAVE, NULL)
@ -2153,7 +2246,7 @@ end
def moveForward()#1
byte dir
dir = getDir()
return moveInternal(dir, dir, TRUE)
return moveInternal(dir, dir, TRUE, TRUE) // beep ok, adv time
end
///////////////////////////////////////////////////////////////////////////////////////////////////
@ -2171,7 +2264,7 @@ def moveBackward()#1
byte facingDir, moveDir
facingDir = getDir()
moveDir = (facingDir + 8) & 15
moveInternal(facingDir, moveDir, TRUE)
moveInternal(facingDir, moveDir, TRUE, TRUE) // beep ok, adv time
return 0
end
@ -2182,9 +2275,9 @@ export def moveWayBackward()#1
byte facingDir, moveDir
facingDir = getDir()
moveDir = (facingDir + 8) & 15
moveInternal(facingDir, moveDir, FALSE)
moveInternal(facingDir, moveDir, FALSE, TRUE) // no beep, but do adv time
if mapIs3D
moveInternal(facingDir, moveDir, FALSE)
moveInternal(facingDir, moveDir, FALSE, FALSE) // no beep, don't adv time
fin
return 0
end
@ -2211,7 +2304,7 @@ def strafeRight()#1
byte facingDir, moveDir
facingDir = getDir()
moveDir = (facingDir + 4) & 15
return moveInternal(facingDir, moveDir, FALSE)
return moveInternal(facingDir, moveDir, TRUE, TRUE) // beep ok, adv time
end
///////////////////////////////////////////////////////////////////////////////////////////////////
@ -2220,7 +2313,7 @@ def strafeLeft()#1
byte facingDir, moveDir
facingDir = getDir()
moveDir = (facingDir - 4) & 15
return moveInternal(facingDir, moveDir, FALSE)
return moveInternal(facingDir, moveDir, TRUE, TRUE) // beep ok, adv time
end
///////////////////////////////////////////////////////////////////////////////////////////////////
@ -2388,20 +2481,6 @@ export def setScriptInfo(mapName, trigTbl, wdt, hgt)#0
setWindow2()
end
///////////////////////////////////////////////////////////////////////////////////////////////////
// Called by scripts to display a string. We set the flag noting that something has been
// displayed, then use an assembly routine to do the work.
export def _scriptDisplayStr(str)#0
if pIntimate
pIntimate=>intimate_displayStr(str)
else
if textClearCountdown; clearTextWindow(); fin
if renderLoaded; flipToPage1(); fin
displayStr(str)
textDrawn = TRUE
fin
end
///////////////////////////////////////////////////////////////////////////////////////////////////
// Called by scripts to swap a map tile. We set a flag noting we need to re-render, then use an
// assembly routine to do the work.
@ -2867,6 +2946,8 @@ def initCmds()#0
cmdTbl[8] = @rotateLeft // left-arrow
cmdTbl[21] = @rotateRight // right-arrow
cmdTbl[10] = @moveBackward // down-arrow
cmdTbl[' '] = @snooze // space out
else
cmdTbl['W'] = @moveNorth
cmdTbl['D'] = @moveEast

View File

@ -41,6 +41,11 @@ struc Global
// god mode flag
byte b_godmode
// current time of day
byte b_hour
byte b_minute
byte b_second
end
const PLAYER_FLAG_NPC = $01