From be45be74b80a846dca5b989a67daeface368061f Mon Sep 17 00:00:00 2001 From: edo999 Date: Tue, 28 May 2024 18:09:26 +0100 Subject: [PATCH] =?UTF-8?q?Parse=20the=20texts=20in=20scripts=20according?= =?UTF-8?q?=20to=20the=20language=20=F0=9F=94=A0.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 +- src/components/ScriptCodeInstruction.js | 4 +- src/lib/parser/parseRom.js | 2 +- src/lib/parser/parseRooms.js | 11 ++++- src/lib/parser/parseScript.js | 4 +- src/lib/parser/parseScriptCode.js | 42 +++--------------- src/lib/parser/parser.js | 59 +++++++++++++++++++++++++ 7 files changed, 79 insertions(+), 45 deletions(-) diff --git a/package.json b/package.json index 2cf7468..96d00ca 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "scumm-nes", - "version": "0.2.1", + "version": "0.2.2", "description": "An app to explore and modify the game Maniac Mansion on NES.", "author": "edo999@gmail.com", "license": "BlueOak-1.0.0", diff --git a/src/components/ScriptCodeInstruction.js b/src/components/ScriptCodeInstruction.js index f99a037..9c8e104 100644 --- a/src/components/ScriptCodeInstruction.js +++ b/src/components/ScriptCodeInstruction.js @@ -121,7 +121,7 @@ const ScriptCodeInstruction = ({ command }) => { const args = prettifyArguments(command); return ( - +
       
         (${opCode}) {instruction}
       {' '}
@@ -131,7 +131,7 @@ const ScriptCodeInstruction = ({ command }) => {
           {i < args.length - 1 ? ,  : ''}
         
       ))}
-    
+    
); }; diff --git a/src/lib/parser/parseRom.js b/src/lib/parser/parseRom.js index a08c90e..2a5d059 100644 --- a/src/lib/parser/parseRom.js +++ b/src/lib/parser/parseRom.js @@ -44,7 +44,7 @@ const parseRom = (arrayBuffer, res) => { const [offset, length] = res.scripts[i]; const resBuffer = arrayBuffer.slice(offset, offset + length); - const script = parseScript(resBuffer, i, offset); + const script = parseScript(resBuffer, i, offset, res.characters); scripts.push(script); } diff --git a/src/lib/parser/parseRooms.js b/src/lib/parser/parseRooms.js index bf5603a..b130127 100644 --- a/src/lib/parser/parseRooms.js +++ b/src/lib/parser/parseRooms.js @@ -282,6 +282,7 @@ const parseRooms = (arrayBuffer, i = 0, offset = 0, characters = {}) => { objectOffs + objectScriptStart, objectOffs + objectScriptStart + objectSize, ), + characters, ); const script = parseScriptCode(scriptOffsParser, 0, 0); @@ -396,13 +397,19 @@ const parseRooms = (arrayBuffer, i = 0, offset = 0, characters = {}) => { let excdScript; if (excdOffs !== 0) { - const excdScriptParser = new Parser(arrayBuffer.slice(excdOffs)); + const excdScriptParser = new Parser( + arrayBuffer.slice(excdOffs), + characters, + ); excdScript = parseScriptCode(excdScriptParser, 0); } let encdScript; if (encdOffs !== 0) { - const encdScriptParser = new Parser(arrayBuffer.slice(encdOffs)); + const encdScriptParser = new Parser( + arrayBuffer.slice(encdOffs), + characters, + ); encdScript = parseScriptCode(encdScriptParser, 0); } diff --git a/src/lib/parser/parseScript.js b/src/lib/parser/parseScript.js index 12b6951..9630dde 100644 --- a/src/lib/parser/parseScript.js +++ b/src/lib/parser/parseScript.js @@ -2,8 +2,8 @@ import parseScriptCode from './parseScriptCode.js'; import Parser from './parser.js'; const assert = console.assert; -const parseScript = (arrayBuffer, i, offset = 0) => { - const parser = new Parser(arrayBuffer); +const parseScript = (arrayBuffer, i, offset = 0, characters = {}) => { + const parser = new Parser(arrayBuffer, characters); const metadata = { id: i, offset, diff --git a/src/lib/parser/parseScriptCode.js b/src/lib/parser/parseScriptCode.js index a57150c..f3a3640 100644 --- a/src/lib/parser/parseScriptCode.js +++ b/src/lib/parser/parseScriptCode.js @@ -43,38 +43,6 @@ const getOffset = (parser, startAddress) => { return hex((currentRow + offset) % 0x10000, 4); }; -const getString = (parser) => { - let str = ''; - let charCode; - do { - charCode = parser.getUint8(); - if (charCode === 0x00) { - break; - } - const flag = (charCode & 0x80) !== 0; - charCode &= 0x7f; - - // TODO: Properly handle escape codes - if (charCode < 8) { - str += `\\u${hex(charCode, 4)}`; - if (charCode > 3) { - str += `\\${parser.getUint8()}`; - } - } else { - if (charCode === '\\' || charCode === '"') { - str += '\\'; - } - } - str += String.fromCharCode(charCode); - - if (flag) { - str += ' '; - } - } while (true); - - return str; -}; - const parseScriptCode = (parser, startAddress, parentOffset = 0) => { const script = []; let stop = false; @@ -281,7 +249,7 @@ const parseScriptCode = (parser, startAddress, parentOffset = 0) => { scriptRow.push(`Color(${value}, ${subOpArg})`); break; case 0x03: - const name = getString(parser); + const name = parser.getString(); scriptRow.push(`Name("${name}")`); break; case 0x04: @@ -300,7 +268,7 @@ const parseScriptCode = (parser, startAddress, parentOffset = 0) => { case 0x94: scriptRow.push(getVariableOrByte(parser, opCode & 0x80)); - scriptRow.push(`"${getString(parser)}"`); + scriptRow.push(`"${parser.getString()}"`); break; // actorFromPos @@ -809,7 +777,7 @@ const parseScriptCode = (parser, startAddress, parentOffset = 0) => { case 0xd4: scriptRow.push(getVariableOrWord(parser, opCode & 0x80)); - const name = getString(parser); + const name = parser.getString(); scriptRow.push(`"${name}"`); break; @@ -927,7 +895,7 @@ const parseScriptCode = (parser, startAddress, parentOffset = 0) => { scriptRow.push(parser.getUint8()); - scriptRow.push(`"${getString(parser)}"`); + scriptRow.push(`"${parser.getString()}"`); } break; } @@ -966,7 +934,7 @@ const parseScriptCode = (parser, startAddress, parentOffset = 0) => { break; case 0xd8: // printEgo - const str = getString(parser); + const str = parser.getString(); scriptRow.push(`"${str}"`); break; diff --git a/src/lib/parser/parser.js b/src/lib/parser/parser.js index a29d31e..f61a3c9 100644 --- a/src/lib/parser/parser.js +++ b/src/lib/parser/parser.js @@ -34,6 +34,65 @@ class Parser { return char; } + getString() { + let str = ''; + let charCode; + do { + charCode = this.getUint8(); + + if (charCode === 0x00) { + break; + } + + const flag = (charCode & 0x80) !== 0; + charCode &= 0x7f; + + if (charCode < 8) { + switch (charCode) { + case 1: + // Line break + str += '<01>\n'; + break; + case 2: + // Used in the dialer room. Beep? + str += '<02>'; + break; + case 3: + // New line + str += '<03>\n'; + break; + case 4: + // Used only in the address sign. + str += ``; + break; + case 0: + case 5: + case 6: + case 7: + throw new Error(`Unknown escape code ${charCode}.`); + default: + break; + } + + continue; + } + + let char = String.fromCodePoint(charCode); + + if (typeof this.#characters[char] === 'string') { + char = this.#characters[char]; + } + + str += char; + + if (flag) { + str += ' '; + } + } while (true); + + return str; + } + peekUint8() { return this.#view.getUint8(this.#ptr); }