Basics of storybook packing now operational.

This commit is contained in:
Martin Haye 2019-01-10 09:45:40 -08:00
parent 6455a56f30
commit 63f40d60b5
9 changed files with 704 additions and 206 deletions

View File

@ -87,9 +87,9 @@
<block type="events_start_encounter"></block>
</category>
<category name="Text">
<block type="text_window"></block>
<!--<block type="text_window"></block>-->
<block type="text_clear_window"></block>
<block type="text_moveto"></block>
<!--<block type="text_moveto"></block>-->
<block type="text_print"></block>
<block type="text_print">
<value name="VALUE">
@ -106,9 +106,26 @@
</block>
</value>
</block>
<block type="text_storybook">
<value name="INTRO">
<block type="text">
<field name="TEXT"></field>
</block>
</value>
<value name="SHORT">
<block type="text">
<field name="TEXT"></field>
</block>
</value>
<value name="LONG">
<block type="text">
<field name="TEXT"></field>
</block>
</value>
</block>
<block type="text_getanykey"></block>
<block type="text_mode"></block>
<block type="text_scroll"></block>
<!--<block type="text_mode"></block>-->
<!--<block type="text_scroll"></block>-->
<block type="text"></block>
<block type="text_getstring"></block>
<block type="text_getnumber"></block>

View File

@ -507,6 +507,22 @@ if (typeof Mythos === "undefined") {
this.setTooltip('Print text and leave cursor at end of last printed character');
}
};
Blockly.Blocks['text_storybook'] = {
init: function () {
this.setHelpUrl(Mythos.helpUrl);
this.setColour(54);
this.setPreviousStatement(true);
this.setNextStatement(true);
this.appendValueInput("INTRO")
.appendField("Storybook: intro");
this.appendValueInput("SHORT")
.appendField("short text");
this.appendValueInput("LONG")
.appendField("long text");
this.setOutput(false);
this.setTooltip('Show story text (floppy ver = intro+short, else intro+long)');
}
};
Blockly.Blocks['text_getanykey'] = {
init: function () {
this.setHelpUrl(Mythos.helpUrl);

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +1,8 @@
build.xml.data.CRC32=5246bcd2
build.xml.script.CRC32=43b3eb1f
build.xml.stylesheet.CRC32=8064a381@1.68.1.46
build.xml.stylesheet.CRC32=f85dc8f2@1.89.1.48
# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
nbproject/build-impl.xml.data.CRC32=5246bcd2
nbproject/build-impl.xml.script.CRC32=0f1cf190
nbproject/build-impl.xml.stylesheet.CRC32=876e7a8f@1.74.1.48
nbproject/build-impl.xml.script.CRC32=e3651c5a
nbproject/build-impl.xml.stylesheet.CRC32=3a2fa800@1.89.1.48

View File

@ -19,8 +19,12 @@ build.test.results.dir=${build.dir}/test/results
#debug.transport=dt_socket
debug.classpath=\
${run.classpath}
debug.modulepath=\
${run.modulepath}
debug.test.classpath=\
${run.test.classpath}
debug.test.modulepath=\
${run.test.modulepath}
# This directory is removed when the project is cleaned:
dist.dir=dist
dist.jar=${dist.dir}/A2Copy.jar
@ -35,6 +39,8 @@ javac.classpath=\
# Space-separated list of extra javac options
javac.compilerargs=
javac.deprecation=false
javac.modulepath=
javac.processormodulepath=
javac.processorpath=\
${javac.classpath}
javac.source=1.7
@ -42,6 +48,8 @@ javac.target=1.7
javac.test.classpath=\
${javac.classpath}:\
${build.classes.dir}
javac.test.modulepath=\
${javac.modulepath}
javac.test.processorpath=\
${javac.test.classpath}
javadoc.additionalparam=
@ -67,9 +75,13 @@ run.classpath=\
# You may also define separate properties like run-sys-prop.name=value instead of -Dname=value.
# To set system properties for unit tests define test-sys-prop.name=value:
run.jvmargs=
run.modulepath=\
${javac.modulepath}
run.test.classpath=\
${javac.test.classpath}:\
${build.test.classes.dir}
run.test.modulepath=\
${javac.test.modulepath}
source.encoding=UTF-8
src.dir=src
test.src.dir=test

View File

@ -19,8 +19,12 @@ build.test.results.dir=${build.dir}/test/results
#debug.transport=dt_socket
debug.classpath=\
${run.classpath}
debug.modulepath=\
${run.modulepath}
debug.test.classpath=\
${run.test.classpath}
debug.test.modulepath=\
${run.test.modulepath}
# This directory is removed when the project is cleaned:
dist.dir=dist
dist.jar=${dist.dir}/PackPartitions.jar
@ -42,6 +46,8 @@ javac.classpath=\
# Space-separated list of extra javac options
javac.compilerargs=
javac.deprecation=false
javac.modulepath=
javac.processormodulepath=
javac.processorpath=\
${javac.classpath}
javac.source=1.7
@ -49,6 +55,8 @@ javac.target=1.7
javac.test.classpath=\
${javac.classpath}:\
${build.classes.dir}
javac.test.modulepath=\
${javac.modulepath}
javac.test.processorpath=\
${javac.test.classpath}
javadoc.additionalparam=
@ -74,9 +82,13 @@ run.classpath=\
# You may also define separate properties like run-sys-prop.name=value instead of -Dname=value.
# To set system properties for unit tests define test-sys-prop.name=value:
run.jvmargs=
run.modulepath=\
${javac.modulepath}
run.test.classpath=\
${javac.test.classpath}:\
${build.test.classes.dir}
run.test.modulepath=\
${javac.test.modulepath}
source.encoding=UTF-8
src.dir=src
test.src.dir=test

View File

@ -55,12 +55,14 @@ class A2PackPartitions
def TYPE_FIXUP = 10
def TYPE_PORTRAIT = 11
def TYPE_SONG = 12
def TYPE_STORY = 13
static final int FLOPPY_SIZE = 35*8 // good old 140k floppy = 280 blks
static final int AC_KLUDGE = 2 // minus 1 to work around last-block bug in AppleCommander
static final int DOS_OVERHEAD = 3 // only 3 blks overhead! ProRWTS is so freaking amazing.
static final int SAVE_GAME_BYTES = 0x1200
static final int MAX_DISKS = 8 // if more are needed, we'd have to expand the resource index format
static final int CHUNK_HEADER_SIZE = 3
def typeNumToDisplayName = [1: "Code",
2: "2D map",
@ -73,7 +75,8 @@ class A2PackPartitions
9: "Code",
10: "Code",
11: "Portrait image",
12: "Song"]
12: "Song",
13: "Story"]
def typeNameToNum = ["code": TYPE_CODE,
"map2D": TYPE_2D_MAP,
@ -86,7 +89,8 @@ class A2PackPartitions
"bytecode": TYPE_BYTECODE,
"fixup": TYPE_FIXUP,
"portrait": TYPE_PORTRAIT,
"song": TYPE_SONG]
"song": TYPE_SONG,
"story": TYPE_STORY]
def typeNumToName = [1: "code",
2: "map2D",
@ -99,7 +103,8 @@ class A2PackPartitions
9: "bytecode",
10: "fixup",
11: "portrait",
12: "song"]
12: "song",
13: "story"]
def mapNames = [:] // map name (and short name also) to map.2dor3d, map.num
def mapSizes = [] // array of [2dOr3D, mapNum, marksSize]
@ -125,6 +130,8 @@ class A2PackPartitions
def automapTiles = [:] // tile name to tile num
def automapPat = null // regexp Pattern to match script names to automap tiles
def automapSpecials = []
def stories = [:] // story text to story.num, story.text
def storyPartition = 0
def automapExitTile = -1
def maxMapSections = 0
@ -1791,7 +1798,6 @@ class A2PackPartitions
def fillDisk(int partNum, int availBlks, ArrayList<String> maps, Set<String> toDupe)
{
//println "Filling disk $partNum, availBlks=$availBlks"
def CHUNK_HEADER_SIZE = 3
def spaceUsed = CHUNK_HEADER_SIZE
// On disk 1, reserve enough space for the map and portrait index
@ -1946,6 +1952,11 @@ class A2PackPartitions
tmp.put((byte) calcDiskBits(chunkDisks[["portrait", k].toString()]))
}
// Stick on the partition number of the stories (used by non-floppy builds)
tmp.put((byte) 1)
tmp.put((byte) storyPartition)
// Pack it all up into a chunk and add it to the partition.
code["resourceIndex"].buf = compress(unwrapByteBuffer(tmp))
def chunk = [type:TYPE_CODE, num:code["resourceIndex"].num,
name:"resourceIndex", buf:code["resourceIndex"].buf]
@ -1970,6 +1981,7 @@ class A2PackPartitions
recordChunks("module", modules)
recordChunks("bytecode", bytecodes)
recordChunks("fixup", fixups)
recordChunks("story", stories)
// Sort the maps in proper disk order
allMaps << [name:"<root>", order:-999999]
@ -2006,6 +2018,18 @@ class A2PackPartitions
}
assert allMaps.isEmpty : "All data must fit within $MAX_DISKS disks."
// If any stories, add them in a special final chunk.
if (stories.size() > 0) {
storyPartition = partChunks.size() + 1
def chunks = [:] as LinkedHashMap
def spaceUsed = CHUNK_HEADER_SIZE
stories.each { k, v ->
stories[k].buf = compress(stories[k].text.getBytes())
spaceUsed += traceResources(["story", k], chunks)
}
partChunks << [partNum:storyPartition, chunks:chunks, spaceUsed:spaceUsed]
}
// Add the special resource index to disk 1
def gameVersion = addResourceIndex(partChunks[0])
@ -4258,6 +4282,10 @@ end
if (!partFile.exists())
continue
// Skip the story partition (stories only included on 800k and higher builds)
if (i == storyPartition)
continue
// Copy files.
def rootDir = new File("build/root$i")
rootDir.mkdir()
@ -4645,7 +4673,9 @@ end
{
case 'text_print':
case 'text_println':
packTextPrint(blk); break
packTextPrint(blk, 'VALUE'); break
case 'text_storybook':
packStoryBook(blk); break
case 'text_clear_window':
packClearWindow(blk); break
case 'text_getanykey':
@ -4735,14 +4765,8 @@ end
return first
}
def packTextPrint(blk)
def outTextBlock(valBlk, finishWithNewline)
{
if (blk.value.size() == 0) {
printWarning "empty text_print block, skipping."
return
}
def valBlk = getSingle(blk.value, 'VALUE').block
assert valBlk.size() == 1
if (valBlk[0].@type == 'text')
{
// Break up long strings into shorter chunks for PLASMA.
@ -4753,19 +4777,67 @@ end
if (!text || text == "") // interpret lack of text as a single empty string
chunks = [""]
chunks.eachWithIndex { chunk, idx ->
String str = (idx == chunks.size()-1 && blk.@type == 'text_println') ? chunk+"\\n" : chunk
String str = (idx == chunks.size()-1 && finishWithNewline) ? chunk+"\\n" : chunk
outIndented("scriptDisplayStr(" + escapeString(str) + ")\n")
}
}
else {
// For general expressions instead of literal strings, we can't do
// any fancy breaking-up business. Just pack.
outIndented(blk.@type == 'text_println' ? 'scriptDisplayStrNL(' : 'scriptDisplayStr(')
outIndented(finishWithNewline ? 'scriptDisplayStrNL(' : 'scriptDisplayStr(')
packExpr(valBlk[0])
out << ")\n"
}
}
def packTextPrint(blk, valName)
{
if (blk.value.size() == 0) {
printWarning "empty text_print block, skipping."
return
}
def valBlk = getSingle(blk.value, valName).block
assert valBlk.size() == 1
outTextBlock(valBlk, blk.@type == 'text_println')
}
def packStoryBook(blk)
{
assert blk.value[0].@name == 'INTRO'
assert blk.value[1].@name == 'SHORT'
assert blk.value[2].@name == 'LONG'
// First output the shared intro text
outIndented("setStoryMode(TRUE)\n")
outTextBlock(blk.value[0].block, false)
// On floppy builds, follow the intro with just the short text (usually e.g. "read log X")
outIndented("if isFloppyVer\n")
++indent
outTextBlock(blk.value[1].block, false)
--indent
// On 800k or hard drive builds, follow the intro with the full (long) text
def longBlk = blk.value[2].block
assert longBlk.size() == 1
def longText = getSingle(getSingle(longBlk, null, 'text').field, 'TEXT').text()
def longHash = Integer.toString(longText.hashCode(), 36)
def num
if (stories.containsKey(longHash))
num = stories[longHash].num
else {
num = stories.size() + 1
stories[longHash] = [num: num, text: longText]
}
outIndented("else\n")
++indent
outIndented("displayStory($num)\n")
--indent
outIndented("fin\n")
outIndented("setStoryMode(FALSE)\n")
}
def packClearWindow(blk)
{
assert blk.value.size() == 0

View File

@ -43,6 +43,7 @@ import gamelib
predef displayf1(fmt, arg1)#0
predef displayf2(fmt, arg1, arg2)#0
predef displayf3(fmt, arg1, arg2, arg3)#0
predef displayStory(num)#0
predef displayStr(str)#0
predef encodeDice(nDice, dieSize, add)#1
predef equipItem(item)#0
@ -120,6 +121,7 @@ import gamelib
predef setGround(num)#0
predef setIntimateMode(enable)#0
predef setMap(is3D, num, x, y, dir)#0
predef setStoryMode(enable)#0
predef useMapWindow()#0
predef setBigWindow()#0
predef setPortrait(portraitNum)#0
@ -161,6 +163,7 @@ import gamelib
byte curMapPartition
word pResourceIndex
word pGlobalTileset
byte isFloppyVer
/////////// Shared string constants //////////////

View File

@ -100,6 +100,7 @@ byte anyInteraction = FALSE
byte textClearCountdown = 0
export byte isPlural = 0 // valid values: 0 or $40
byte inScript = FALSE
export byte isFloppyVer
byte scriptModule = 0
byte prevScriptModule = 0
@ -3650,6 +3651,16 @@ export def setIntimateMode(enable)#0
fin
end
///////////////////////////////////////////////////////////////////////////////////////////////////
export def setStoryMode(enable)#0
// TODO
end
///////////////////////////////////////////////////////////////////////////////////////////////////
export def displayStory(num)#0
// TODO
end
///////////////////////////////////////////////////////////////////////////////////////////////////
export def benchPlayer()#0
loadEngine(MOD_PARTY)=>party_benchPlayer()