Adding disk limit and copyright message. Also fixed some plural matching problems.

This commit is contained in:
Martin Haye 2020-06-15 07:21:37 -07:00
parent d3cfca29eb
commit 72f9827229
4 changed files with 141 additions and 101 deletions

View File

@ -138,6 +138,7 @@ class A2PackPartitions
def stories = [:] // story text to story.num, story.text
def storyPartition = 0
def lootCodes = [:] // loot code to loot.num
def diskLimit = 0
def automapExitTile = -1
def maxMapSections = 0
@ -150,7 +151,8 @@ class A2PackPartitions
def requiredGlobalScripts = ["New Game", "Help",
"Combat win", "Combat intro", "Combat prompt", "Enemy intro", "Death",
"Level XP", "Level SP"]
"Level XP", "Level SP",
"Disk limit", "Copyright"]
def globalScripts = [:]
def lastSysModule
@ -2833,9 +2835,27 @@ class A2PackPartitions
return script.block.mutation.arg.size()
}
def recordDiskLimit(script) {
if (script.block.size() != 0) {
def proc = script.block[0]
if (proc.value.size() > 0) {
assert proc.value[0].@name == "RETURN"
assert proc.value[0].block.size() == 1
def expr = proc.value[0].block[0]
assert expr.@type == 'math_number'
def field = expr.field
assert field.size() == 1
assert field[0].@name == "NUM"
diskLimit = field[0].text().toInteger()
}
}
}
def recordGlobalScripts(dataIn) {
dataIn.global.scripts.script.each {
globalScripts[humanNameToSymbol(it.@name, false)] = countArgs(it)
if (it.@name.equalsIgnoreCase("Disk limit"))
recordDiskLimit(it)
}
requiredGlobalScripts.each { humanName ->
def name = humanNameToSymbol(humanName, false)
@ -3437,7 +3457,7 @@ class A2PackPartitions
def triggerItem = row.@"Trigger-Item"?.trim()
if (triggerItem) {
triggerItem = triggerItem.toLowerCase()
assert itemNameToFunc.containsKey(triggerItem) : "unrecognized item '$triggerItem'"
assert itemNameToFunc.containsKey(toSingular(triggerItem)) : "unrecognized item '$triggerItem'"
}
assert (triggerFlag || triggerItem) : "Quest step requires either Trigger-Flag or Trigger-Item, or both"
@ -3725,7 +3745,7 @@ class A2PackPartitions
name = p1
num = p2.toInteger()
}
def itemFunc = itemNameToFunc[name]
def itemFunc = itemNameToFunc[toSingular(name)]
assert itemFunc : "Can't locate item '$name'"
if (num > 1)
out.println(" addToList(@p=>p_items, setItemCount(createItem($itemFunc), $num))")
@ -3792,6 +3812,14 @@ class A2PackPartitions
out.println("end\n")
}
def toSingular(rawName)
{
def name = rawName.toLowerCase().trim()
name = name.replaceAll(/\((\w+)\/\w+\)/, '$1')
name = name.replaceAll(/\(\w+\)/, '')
return name
}
def allItemFuncs(sheets)
{
def funcs = []
@ -3808,7 +3836,7 @@ class A2PackPartitions
// Global mapping of item name to function, so that give/take functions can create items.
funcs.each { typeName, func, index, row ->
itemNameToFunc[row.@name.trim().toLowerCase()] = func
itemNameToFunc[toSingular(row.@name)] = func
}
// And return the funcs.
@ -4200,8 +4228,8 @@ end
assert totalSize < 256 : "too many maps"
out.println("byte[] mapSizes = $totalSize // overall buffer size")
mapSizes.sort().each { triple ->
out.println(String.format("byte = \$%02X, \$%02X",
(triple[0] == '3D' ? 0x80 : 0) | triple[1], triple[2]))
def num = (triple[0] == '3D' ? 0x80 : 0) | triple[1]
out.println(String.format("byte = \$%02X, \$%02X", num, triple[2]))
}
}
replaceIfDiff("build/src/plasma/gen_mapsizes.pla")
@ -4827,7 +4855,8 @@ end
def packBlock(blk)
{
withContext("${blk.@type}") {
def ctx = blk.@type
withContext(ctx) {
switch (blk.@type)
{
case 'text_print':
@ -4945,7 +4974,8 @@ end
else {
// For general expressions instead of literal strings, we can't do
// any fancy breaking-up business. Just pack.
outIndented(finishWithNewline ? 'scriptDisplayStrNL(' : 'scriptDisplayStr(')
def caller = finishWithNewline ? 'scriptDisplayStrNL(' : 'scriptDisplayStr('
outIndented(caller)
packExpr(valBlk[0])
out << ")\n"
}
@ -5032,7 +5062,7 @@ end
def packGiveItem(blk)
{
def name = getSingle(blk.field, 'NAME').text().trim()
def itemNum = itemNameToFunc[name.toLowerCase()]
def itemNum = itemNameToFunc[toSingular(name)]
assert itemNum : "Can't locate item '$name'"
outIndented("giveItemToParty(createItem($itemNum), @scriptDisplayStr)\n")
}
@ -5040,7 +5070,7 @@ end
def packTakeItem(blk)
{
def name = getSingle(blk.field, 'NAME').text().trim()
assert itemNameToFunc.containsKey(name.toLowerCase()) : "Can't locate item '$name'"
assert itemNameToFunc.containsKey(toSingular(name)) : "Can't locate item '$name'"
outIndented("takeItemFromParty(${escapeString(name)})\n")
}
@ -5319,7 +5349,7 @@ end
def packHasItem(blk)
{
def name = getSingle(blk.field, "NAME").text().trim()
assert itemNameToFunc.containsKey(name.toLowerCase()) : "Can't locate item '$name'"
assert itemNameToFunc.containsKey(toSingular(name)) : "Can't locate item '$name'"
out << "partyHasItem(${escapeString(name)})"
}
@ -5468,12 +5498,12 @@ end
def packSetFullscreen(blk)
{
def imgName = getSingle(blk.field, 'NAME').text()
if (!frames.containsKey(imgName)) {
if (!frames.containsKey(imgName.toLowerCase())) {
printWarning "full screen image '$imgName' not found; skipping set_fullscreen."
return
}
outIndented("loadFrameImg(PF${humanNameToSymbol(imgName, false)})\n")
addMapDep("frame", imgName)
outIndented("loadFrameImg(PF${humanNameToSymbol(imgName.toLowerCase(), false)})\n")
addMapDep("frame", imgName.toLowerCase())
}
def packClrPortrait(blk)

View File

@ -284,6 +284,10 @@ def _startup()#1
// Also the automap marking queue/flush code.
pMarks = mmgr(QUEUE_LOAD, CODE_MARKS<<8 | RES_TYPE_CODE)
// And the global funcs we'll need for the title screen
mmgr(QUEUE_LOAD, GS_DISK_LIMIT<<8 | RES_TYPE_MODULE)
mmgr(QUEUE_LOAD, GS_COPYRIGHT<<8 | RES_TYPE_MODULE)
mmgr(FINISH_LOAD, 0)
// Move the marks code up to its out-of-the-way corner of RAM
@ -309,6 +313,9 @@ def _startup()#1
auxMmgr(LOCK_MEMORY, pResourceIndex)
mmgr(FINISH_LOAD, 0)
// Record the disk limit
diskLimit = callGlobalFunc(GS_DISK_LIMIT, 0, 0, 0)
// All done.
return 0
end
@ -368,7 +375,9 @@ 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")
// Print out the heap fullness, for later debugging
printf1("Heap %d%%\n", curHeapPct)
end
///////////////////////////////////////////////////////////////////////////////////////////////////
@ -495,10 +504,14 @@ end
///////////////////////////////////////////////////////////////////////////////////////////////////
def importGame()#1
textHome
^$c053
^$25 = 20
puts("\n Insert disk for import")
pressAnyKey()
if gameExists()
loadInternal()
^$25 = 20
puts("\n Game imported.")
reinsert()
_saveGame()
@ -620,9 +633,51 @@ def newGame()#0
heapCollect()
end
///////////////////////////////////////////////////////////////////////////////////////////////////
// Print version, right-justified in graphics mode and in a protected text area
def printVersion(windowWidth)#0
word p
byte len
buildString()
if recordMode
puts("recording")
else
printChar('V')
p = pResourceIndex
len = readAuxByte(p)
while len
p++; printChar(readAuxByte(p)); len--
loop
fin
p = finishString(FALSE)
// Save text cursor, and print at bottom of text window
^$23 = 24 // full height window
^$25 = 22
crout()
^$24 = 25 // Text X here
puts(p)
// And print in graphics mode too
rightJustifyStr(p, windowWidth)
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def showCopyrightAndVer()#0
setWindow(181, 192, 28, 252)
clearWindow()
rawDisplayStr("^J") // down one line for nice-looking spacing from graphics
callGlobalFunc(GS_COPYRIGHT, 0, 0 ,0)
rawDisplayStr("^N")
setWindow(182, 192, 28, 252)
printVersion(224) // win width
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def _newOrLoadGame(ask)#1
byte key, existing
word p, ret
existing = gameExists()
if existing and !ask
@ -632,30 +687,51 @@ def _newOrLoadGame(ask)#1
// Pause a bit so the player can see the full title screen in all its glory
pause(3000)
while TRUE
textHome()
^$25 = 20
puts("\n Game: N)ew, ")
^$23 = 24 // Full text window until we're done
showCopyrightAndVer
ret = -1
while ret < 0
// Establish a window at the bottom
setWindow(171, 182, 56, 224)
clearWindow()
// Prompt the user for the main game options
buildString()
puts("^JGame: N)ew, ")
if existing; puts("L)oad, "); fin
puts("I)mport?")
key = getTextKey() // soundKey()
puts("I)mport?^N")
p = finishString(FALSE)
centerStr(p, 168)
puts(p) // display on text screen too, since Jace looks for Import prompt there.
// Get their choice and act on it
key = getUpperKey()
clearWindow
when key
is 'N'
newGame(); return 1
newGame(); ret = 1; break
is 'L'
if gameExists
if loadInternal(); return 0; fin
if loadInternal(); ret = 0; break; fin
else
beep
fin
break
is 'I'
if importGame(); return 0; fin
if importGame(); ret = 0; break; fin
is 18 // ctrl-R
setRecordMode(1)
wend
loop
return 0
// Brand future text screens with the version (adjust window to protect it)
^$23 = 23
textHome
// All done
return ret
end
///////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -90,6 +90,7 @@ import gamelib
predef pause(count)#1
predef payGold(amount)#1
predef percentToRatio(pct)#1
predef printChar(ch)#0
predef printf1(fmt, arg1)#0
predef printf2(fmt, arg1, arg2)#0
predef printf3(fmt, arg1, arg2, arg3)#0
@ -175,6 +176,8 @@ import gamelib
byte lampFrame
word lampDir
byte needRender
byte diskLimit
byte curHeapPct
/////////// Shared string constants //////////////

View File

@ -117,7 +117,7 @@ export word pResourceIndex = NULL
export word pGlobalTileset = NULL
export byte curMapPartition = 0
export word typeHash = 0
word curHeapPct = 0
export byte curHeapPct = 0
byte lastMoveDir = $FF
// Queue setMap / teleport / start_encounter, since otherwise script might be replaced while executing
@ -192,6 +192,8 @@ word lastTick = 0
export byte recordMode = 0
word recordSeed
export byte diskLimit = 0
///////////////////////////////////////////////////////////////////////////////////////////////////
// Definitions used by assembly code
asm _defs
@ -750,7 +752,7 @@ end
///////////////////////////////////////////////////////////////////////////////////////////////////
// Print a single character
asm printChar(ch)#0
export asm printChar(ch)#0
+asmPlasmNoRet 1
ora #$80
jmp _safeCout
@ -1683,80 +1685,12 @@ export def setGround(num)#0
fin
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def printAtBottom(str, textX, botLeft, botRight, strX)#0
byte cv
word origX, origY, origTop, origBottom, origLeft, origRight
// Save text cursor, and print at bottom of text window
cv = ^$25
^$23 = 24 // full height window
^$25 = 22
crout()
^$24 = textX
puts(str)
^$23 = 23 // shrink window to protect version num
^$25 = cv-1
crout()
// Save graphics cursor and window
origX, origY = getCursor()
origTop, origBottom, origLeft, origRight = getWindow()
// Establish new graphics window, clear it, and display the string
setWindow(183, 192, botLeft, botRight)
clearWindow()
rawDisplayStr("^T") // do not use printf variants, since it might overwrite str
rawDisplayStr(convert3Dec(strX))
rawDisplayStr(str)
if mapIs3D and texturesLoaded; copyWindow(0); fin
// Restore original graphics cursor and window
setWindow(origTop, origBottom, origLeft, origRight)
setCursor(origX, origY)
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def printHeapPct()#0
word str, len
str = sprintf1("%d%%", curHeapPct)
len = calcWidth(str)
printAtBottom(str, 36, 240, 268, (28-len) >> 1) // center
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def printVersion()#0
word p
byte len
if !pResourceIndex; return; fin
buildString()
if recordMode
puts("recording")
else
printChar('V')
p = pResourceIndex
len = readAuxByte(p)
while len
p++; printChar(readAuxByte(p)); len--
loop
fin
p = finishString(FALSE)
len = calcWidth(p)
printAtBottom(p, 25, 154, 154 + len + 9, 3)
printHeapPct()
end
///////////////////////////////////////////////////////////////////////////////////////////////////
export def heapCollect()#0
word pct
mmgr(CHECK_MEM, 0)
global=>w_heapSize = mmgr(HEAP_COLLECT, 0) - HEAP_BOTTOM
pct = min(99, max(0, ((global=>w_heapSize / 10) * 100) / (HEAP_SIZE / 10)))
if pct <> curHeapPct
curHeapPct = pct
printHeapPct()
fin
curHeapPct = min(99, max(0, ((global=>w_heapSize / 10) * 100) / (HEAP_SIZE / 10)))
end
///////////////////////////////////////////////////////////////////////////////////////////////////
@ -1795,9 +1729,6 @@ export def loadFrameImg(img)#0
// And show the first frame of the screen image
^EMUSIG_FULL_COLOR
showAnimFrame()
// Brand the image with the version number
printVersion()
else
curFullscreenImg = NULL
anyAnims = FALSE
@ -3537,8 +3468,8 @@ end
///////////////////////////////////////////////////////////////////////////////////////////////////
export def setStoryMode(enable)#0
// Story mode only exists on 800K or hard drive builds
if !isFloppyVer
// Story mode only exists on 800K or hard drive builds, and not the disk-limited ones.
if !isFloppyVer and !diskLimit
storyMode = enable
if enable
loadEngine(MOD_STORY)