From 65ba8a454fd90bad1da2e70c4d212289ea1d20e7 Mon Sep 17 00:00:00 2001 From: Martin Haye Date: Thu, 13 Jun 2019 08:52:54 -0700 Subject: [PATCH] Lots of additions and fixes for story mode. Mostly working now. --- .../src/org/badvision/A2PackPartitions.groovy | 72 ++++++++++++------- Platform/Apple/virtual/src/font/fontEngine.s | 18 +++-- Platform/Apple/virtual/src/plasma/story.pla | 69 +++++++++++++----- 3 files changed, 110 insertions(+), 49 deletions(-) diff --git a/Platform/Apple/tools/PackPartitions/src/org/badvision/A2PackPartitions.groovy b/Platform/Apple/tools/PackPartitions/src/org/badvision/A2PackPartitions.groovy index 5529bc09..00f54a8f 100644 --- a/Platform/Apple/tools/PackPartitions/src/org/badvision/A2PackPartitions.groovy +++ b/Platform/Apple/tools/PackPartitions/src/org/badvision/A2PackPartitions.groovy @@ -240,6 +240,34 @@ class A2PackPartitions return inStr[0].toUpperCase() + inStr.substring(1) } + // Translate ^M to carriage-return; etc. Used for raw strings e.g. story mode text. + def translateString(inStr) + { + def buf = new StringBuilder() + def prev = '\0' + inStr.eachWithIndex { ch, idx -> + if (ch == '^') { + if (prev == '^') { + buf << ch + ch = 'x' // so next char not treated as special + } + } + else if (prev == '^') { + def cp = Character.codePointAt(ch.toUpperCase(), 0) + // ^A = ctrl-A; ^M = ctrl-M (carriage return); ^Z = ctrl-Z; ^` = space + if (cp > 64 && cp < 97) + buf << String.format("%c", cp - 64) + else + printWarning("Unrecognized control code '^" + ch + "'") + } + else + buf << ch + prev = ch + } + return buf.toString() + } + + // Form a PLASMA-quoted string, and translate ^M to carriage-return; etc. Used for displayStr() etc. def escapeString(inStr) { // Commonly used strings (e.g. event handler names, attributes) @@ -1809,13 +1837,10 @@ class A2PackPartitions + 1 + portraits.size() // number of portraits, then 1 byte per } - if (nWarnings == 0) - { - reportWriter.println "\nDisk $partNum:" - reportWriter.println String.format(" %-22s: %6.1fK", - partNum == 1 ? "LegendOS+overhead" : "overhead", - ((FLOPPY_SIZE-availBlks)*512 + overhead) / 1024.0) - } + reportWriter.println "\nDisk $partNum:" + reportWriter.println String.format(" %-22s: %6.1fK", + partNum == 1 ? "LegendOS+overhead" : "overhead", + ((FLOPPY_SIZE-availBlks)*512 + overhead) / 1024.0) def outChunks = (partNum==1) ? part1Chunks : ([:] as LinkedHashMap) def addedMapNames = [] @@ -1850,13 +1875,11 @@ class A2PackPartitions // After adding the root map, stuff in the most-used portraits onto disk 1 if (mapName == "") { assert partNum == 1 - if (nWarnings == 0) - reportWriter.println String.format(" %-22s: %6.1fK", "base resources", mapSpace / 1024.0) + reportWriter.println String.format(" %-22s: %6.1fK", "base resources", mapSpace / 1024.0) def portraitsSpace = stuffMostUsedPortraits(maps, outChunks, availBlks, spaceUsed) spaceUsed += portraitsSpace blks = calcFileBlks(spaceUsed) - if (nWarnings == 0) - reportWriter.println String.format(" %-22s: %6.1fK", "shared portraits", portraitsSpace / 1024.0) + reportWriter.println String.format(" %-22s: %6.1fK", "shared portraits", portraitsSpace / 1024.0) //println "stuffed most-used portraits for $portraitsSpace bytes, totaling $blks blks." } else { @@ -1866,14 +1889,12 @@ class A2PackPartitions } if (!maps.isEmpty()) maps.addAll(0, readd) // handle maps that need dupe on each data disk - if (nWarnings == 0) { - if (mapsSpaceUsed > 0) { - reportWriter.println String.format(" %-22s: %6.1fK", "maps & resources", mapsSpaceUsed / 1024.0) - addedMapNames.each { reportWriter.println " $it" } - } - reportWriter.println String.format(" %-22s: %6.1fK", "unused", (availBlks*512 - spaceUsed) / 1024.0) - reportWriter.println "Total: 140K" + if (mapsSpaceUsed > 0) { + reportWriter.println String.format(" %-22s: %6.1fK", "maps & resources", mapsSpaceUsed / 1024.0) + addedMapNames.each { reportWriter.println " $it" } } + reportWriter.println String.format(" %-22s: %6.1fK", "unused", (availBlks*512 - spaceUsed) / 1024.0) + reportWriter.println "Total: 140K" return [outChunks, spaceUsed] } @@ -1993,8 +2014,7 @@ class A2PackPartitions 0 } - if (nWarnings == 0) - reportWriter.println "======================== Floppy disk usage ===========================" + reportWriter.println "======================== Floppy disk usage ===========================" // Now fill up disk partitions until we run out of maps. def mapsToDupe = allMaps.grep{ it.name != "" && it.order < 0 }.collect{ it.name }.toSet() @@ -3003,12 +3023,10 @@ class A2PackPartitions fillAllDisks() // Print stats (unless there's a warning, in which case focus the user on that) - if (nWarnings == 0) { - reportSizes() - reportTeleports(dataIn) - reportScriptLocs(dataIn) - reportFlags(dataIn) - } + reportSizes() + reportTeleports(dataIn) + reportScriptLocs(dataIn) + reportFlags(dataIn) if (debugCompression) println "Compression savings: $compressionSavings" @@ -4831,7 +4849,7 @@ end num = stories[longHash].num else { num = stories.size() + 1 - stories[longHash] = [num: num, text: longText] + stories[longHash] = [num: num, text: translateString(longText)] } outIndented("else\n") ++indent diff --git a/Platform/Apple/virtual/src/font/fontEngine.s b/Platform/Apple/virtual/src/font/fontEngine.s index 286ab6ed..6112de0e 100644 --- a/Platform/Apple/virtual/src/font/fontEngine.s +++ b/Platform/Apple/virtual/src/font/fontEngine.s @@ -821,7 +821,17 @@ DoParse STA PrsAdrL STY PrsAdrH LDY #0 ;parse starting at beginning STY TtlWdth - STY Pa_WdCt + ; MH: Added code so that if we're mid-line, assume something + ; was already printed + LDX #1 + LDA CursColL + CMP CursXl + BNE + + LDA CursColH + CMP CursXh + BNE + + DEX ++ STX Pa_WdCt LDA (PrsAdrL),Y ;Get the length STA Pa_Len INY @@ -879,13 +889,13 @@ Pa_ToFr !if DEBUG { +prChr '+' } LDY PrsAdrH ;calc adr of next word that would display LDA PrsAdrL CLC - ADC Pa_iSv + ADC Pa_iBgn BCC + INY + RTS ;and return early without scrolling Pa_CBig LDA Pa_WdCt ;if we didn't print any words yet, then it's BEQ Pa_BgWd ; a word too big for line: split it -Pa_ToF2 LDA #$8D + LDA #$8D STA AscChar JSR TestChr LDY Pa_iBgn @@ -930,7 +940,7 @@ Pa_Dn3 LDY Pa_iSv BMI Pa_Dn3b ; char needs to be printed too INY Pa_Dn3b STY Pa_iBgn - JMP Pa_ToF2 + JMP Pa_ToFr Pa_Dn4 LDY Pa_iSv INY JMP Pa_Lp0 diff --git a/Platform/Apple/virtual/src/plasma/story.pla b/Platform/Apple/virtual/src/plasma/story.pla index 63cd7839..e6637948 100644 --- a/Platform/Apple/virtual/src/plasma/story.pla +++ b/Platform/Apple/virtual/src/plasma/story.pla @@ -80,6 +80,8 @@ def _story_mode(enable, portraitNum)#1 end /////////////////////////////////////////////////////////////////////////////////////////////////// +// Load the full story text onto HGR page 2 so it's easy to use. Sets pStoryCur to the start, and +// pStoryEnd to the end. def loadStory(storyNum)#0 byte storyPart word pAuxText, pEnd, pSrc, pDst, len @@ -92,7 +94,8 @@ def loadStory(storyNum)#0 // to hgr page 2 so it'll be easier to use. pEnd = pAuxText + 2 + (readAuxByte(pAuxText) | (readAuxByte(pAuxText+1) << 8)) pSrc = pAuxText + 2 - pDst = $4000 + if (pEnd - pSrc) > $1FF0; fatal("storySize"); fin + pDst = $4001 pStoryCur = pDst while pSrc < pEnd len = min(127, pEnd - pSrc) @@ -105,27 +108,57 @@ def loadStory(storyNum)#0 auxMmgr(FREE_MEMORY, pAuxText) end +/////////////////////////////////////////////////////////////////////////////////////////////////// +def displayStoryBlock()#1 + word p, pNext, len + byte bak + + while TRUE + p = pStoryCur - 1 + len = pStoryEnd - pStoryCur + if !len; return FALSE; fin + if len > 127 + for len = 127 downto 100 + if ^(pStoryCur + len) == ' '; break; fin + next + fin + bak = ^p + ^p = len + printf2("pStoryCur=$%x len=%x\n", pStoryCur, len) + pNext = displayStrNoScroll(p) + ^p = bak + if pNext + pStoryCur = pNext + break + else + pStoryCur = pStoryCur + len + rdkey + fin + loop + return pStoryCur < pStoryEnd +end + /////////////////////////////////////////////////////////////////////////////////////////////////// // Display story and picture on a blank screen, with blanking follow-up def _story_display(storyNum)#1 - word p + byte c + loadStory(storyNum) - printf2("pStoryCur=$%x pStoryEnd=$%x\n", pStoryCur, pStoryEnd) - p = displayStrNoScroll("\n\nHe heh hee lorem ipsum Blah blah blah. Also blah blah blah blah and blah.") - printf1("p=$%x\n", p) - p = displayStrNoScroll(" Blah blah blah. Blah blah blah blah and blah. Blah blah.") - printf1("p=$%x\n", p) - p = displayStrNoScroll("\n\nHe heh hee lorem ipsum Blah blah blah. Also blah blah blah blah and blah.") - printf1("p=$%x\n", p) - p = displayStrNoScroll(" Blah blah blah. Blah blah blah blah and blah. Blah blah, blah and blah blah ABC ***.") - printf1("p=$%x\n", p) - ^$c051 - rdkey - ^$c050 - setBlock2 - p = displayStrNoScroll("More story goes here. Blah blah blah. Also blah blah blah blah and blah.") - p = displayStrNoScroll(" Blah blah blah. Blah blah blah blah and blah. Blah blah, blah blabh.") - getUpperKey + rawDisplayStr("\n\n") + + while pStoryCur < pStoryEnd + if displayStoryBlock + setBlock2 + displayStoryBlock + fin + + c = getUpperKey + if c == 27 or pStoryCur >= pStoryEnd; break; fin + + clearWindow + setBlock1 + clearWindow + loop return 0 end