Skip to content

Commit

Permalink
Parse the texts in scripts according to the language 🔠.
Browse files Browse the repository at this point in the history
  • Loading branch information
gmarty committed May 28, 2024
1 parent cb1ab7a commit be45be7
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 45 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down
4 changes: 2 additions & 2 deletions src/components/ScriptCodeInstruction.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ const ScriptCodeInstruction = ({ command }) => {
const args = prettifyArguments(command);

return (
<span>
<pre>
<span className="text-primary-600 dark:text-primary-300">
(${opCode}) {instruction}
</span>{' '}
Expand All @@ -131,7 +131,7 @@ const ScriptCodeInstruction = ({ command }) => {
{i < args.length - 1 ? <span className={'opacity-50'}>, </span> : ''}
</span>
))}
</span>
</pre>
);
};

Expand Down
2 changes: 1 addition & 1 deletion src/lib/parser/parseRom.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down
11 changes: 9 additions & 2 deletions src/lib/parser/parseRooms.js
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,7 @@ const parseRooms = (arrayBuffer, i = 0, offset = 0, characters = {}) => {
objectOffs + objectScriptStart,
objectOffs + objectScriptStart + objectSize,
),
characters,
);

const script = parseScriptCode(scriptOffsParser, 0, 0);
Expand Down Expand Up @@ -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);
}

Expand Down
4 changes: 2 additions & 2 deletions src/lib/parser/parseScript.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
42 changes: 5 additions & 37 deletions src/lib/parser/parseScriptCode.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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:
Expand All @@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -927,7 +895,7 @@ const parseScriptCode = (parser, startAddress, parentOffset = 0) => {

scriptRow.push(parser.getUint8());

scriptRow.push(`"${getString(parser)}"`);
scriptRow.push(`"${parser.getString()}"`);
}
break;
}
Expand Down Expand Up @@ -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;
Expand Down
59 changes: 59 additions & 0 deletions src/lib/parser/parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 += `<Var[${this.getUint8()}]>`;
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);
}
Expand Down

0 comments on commit be45be7

Please sign in to comment.