也是对比修改,最重要的是把reduce的concat变成两个push并返回原来的数组

This commit is contained in:
root 2024-10-13 00:42:28 +08:00
parent 2bdcee2363
commit effc264d08
3 changed files with 41 additions and 50 deletions

View File

@ -12,38 +12,41 @@ const format = valid => {
console.info(`valid rom has ${valid.length}`); console.info(`valid rom has ${valid.length}`);
const enc = new TextEncoder(); const enc = new TextEncoder();
const size = Symbol("length"); //const size = Symbol("length");
const concatUnit = 10240; const concatUnit = 10240;
const align = (n, base) => base * Math.floor((n + base - 1) / base); const align = (n, base) => base * Math.floor((n + base - 1) / base);
const size = new WeakMap()
const concat = (a, b) => { const concat = (a, b) => {
let len = (a[size] || 0) + b.length; const sizea = size.get(a);
let len = (sizea || 0) + b.length;
if (len > a.length) { if (len > a.length) {
let n = new (Object.getPrototypeOf(a).constructor)(align(len, concatUnit) * 2); let n = new (Object.getPrototypeOf(a).constructor)(align(len, concatUnit) * 2);
n.set(a, 0); n.set(a, 0);
n.set(b, a[size]); n.set(b, sizea);
n[size] = len; size.set(n, len);
return n; return n;
} }
else { else {
a.set(b, a[size]); a.set(b, sizea);
a[size] = len; size.set(a, len);
return a; return a;
} }
} }
const getnametable = list => list.reduce((r, { serial, cheat }, idx, arr) => { const getnametable = list => list.reduce((r, { serial, cheat }, idx, arr) => {
const val = serial.slice(0, -1); const val = serial.slice(0, -1);
//console.log("looping", val, r[4], r[2], cheat.length) //console.log("looping", val, r[4], r[2], cheat.length)
const size1 = size.get(r[1]);
if (val != r[4]) { if (val != r[4]) {
if (r[1][size] > 0 && r[2] - r[1].at(r[1][size] - 1) > r[3]) if (size1 > 0 && r[2] - r[1].at(size1 - 1) > r[3])
r[3] = r[2] - r[1].at(r[1][size] - 1); r[3] = r[2] - r[1].at(size1 - 1);
r[0] = concat(r[0], enc.encode(val)) r[0] = concat(r[0], enc.encode(val))
r[1] = concat(r[1], [r[2]]); r[1] = concat(r[1], [r[2]]);
r[4] = val; r[4] = val;
} }
r[2] = r[2] + cheat.length; r[2] = r[2] + cheat.length;
if (idx + 1 == arr.length) { if (idx + 1 == arr.length) {
if (r[2] - r[1].at(r[1][size] - 1) > r[3]) if (r[2] - r[1].at(size1 - 1) > r[3])
r[3] = r[2] - r[1].at(r[1][size] - 1); r[3] = r[2] - r[1].at(size1 - 1);
r[1] = concat(r[1], [r[2]]); r[1] = concat(r[1], [r[2]]);
} }
return r; return r;
@ -52,7 +55,7 @@ const format = valid => {
const expandcheat = (list, base) => list.reduce((r, { cheat, serial }) => { const expandcheat = (list, base) => list.reduce((r, { cheat, serial }) => {
const val = serial.charCodeAt(3); const val = serial.charCodeAt(3);
return cheat.reduce((r, { id, bin }) => { return cheat.reduce((r, { id, bin }) => {
const off = r[2] + r[1][size]; const off = r[2] + size.get(r[1]);
r[0] = concat(r[0], [val | (off << 3), id]) r[0] = concat(r[0], [val | (off << 3), id])
r[1] = concat(r[1], bin); r[1] = concat(r[1], bin);
return r; return r;
@ -62,7 +65,7 @@ const format = valid => {
const linkbuffer = (arr, ...l) => { const linkbuffer = (arr, ...l) => {
for (let i of l) { for (let i of l) {
const arrBa = arr[i]; const arrBa = arr[i];
arr[i] = arrBa.slice(0, arrBa[size]); arr[i] = arrBa.slice(0, size.get(arrBa));
} }
return arr; return arr;
} }

View File

@ -10,8 +10,9 @@ const NEED_PART = 8
const STATE = ["", "WAIT_LOCK", "READ_LOCK", "WAIT_HOLE", "READ_HOLE", "WAIT_KEY", "READ_KEY"] const STATE = ["", "WAIT_LOCK", "READ_LOCK", "WAIT_HOLE", "READ_HOLE", "WAIT_KEY", "READ_KEY"]
const PASSHOLE = ["text", "off"] const PASSHOLE = ["text", "off"]
const space = " ".charCodeAt(); const space = " ";
const tab = "\t".charCodeAt(); const tab = "\t";
const hex = "0123456789abcdef";
const zero = "0".charCodeAt(); const zero = "0".charCodeAt();
const nine = "9".charCodeAt(); const nine = "9".charCodeAt();
const a = "a".charCodeAt(); const a = "a".charCodeAt();
@ -40,8 +41,7 @@ const read = (cht, info, order) => {
let locks = [], currlock = null, retval = []; let locks = [], currlock = null, retval = [];
const merge_str = String.fromCharCode.bind(String); const token_str = () => { const r = token.join(""); return (token = [], r); }
const token_str = () => { const r = merge_str.apply(null, token); return (token.length = 0, r); }
const error = msg => { throw new SyntaxError(`${msg} at line: ${line} in lock ${currlock?.name}`) } const error = msg => { throw new SyntaxError(`${msg} at line: ${line} in lock ${currlock?.name}`) }
const incr = ch => { const incr = ch => {
switch (ch) { switch (ch) {
@ -101,7 +101,7 @@ const read = (cht, info, order) => {
currlock.keys = [new Array()]; currlock.keys = [new Array()];
} }
else if (state == READ_LOCK) { else if (state == READ_LOCK) {
token.push(ch.charCodeAt()); token.push(ch);
} }
else if (state == WAIT_PART) {} else if (state == WAIT_PART) {}
else if (state == NEED_PART) state = WAIT_PART; else if (state == NEED_PART) state = WAIT_PART;
@ -119,7 +119,7 @@ const read = (cht, info, order) => {
state = READ_KEY; state = READ_KEY;
} }
else if (state == READ_LOCK) { else if (state == READ_LOCK) {
token.push(ch.charCodeAt()); token.push(ch);
} }
else if (state == WAIT_PART) {} else if (state == WAIT_PART) {}
else if (state == NEED_PART) state = WAIT_PART; else if (state == NEED_PART) state = WAIT_PART;
@ -131,7 +131,7 @@ const read = (cht, info, order) => {
currlock.keys.push(new Array()); currlock.keys.push(new Array());
} }
else if (state == READ_LOCK) { else if (state == READ_LOCK) {
token.push(ch.charCodeAt()); token.push(ch);
} }
else if (state == READ_HOLE) {// MULTILINE KEY else if (state == READ_HOLE) {// MULTILINE KEY
let { name, cmd } = currlock.holes.pop(); let { name, cmd } = currlock.holes.pop();
@ -159,29 +159,22 @@ const read = (cht, info, order) => {
break; break;
case " ": case " ":
if (state == READ_LOCK || state == READ_HOLE) { if (state == READ_LOCK || state == READ_HOLE) {
token.push(ch.charCodeAt()); token.push(ch);
}
else if (state == READ_KEY) {
if (currlock.name.toLowerCase() == "gameinfo") {
token.push(ch.charCodeAt());
}
} }
else if (state == READ_KEY) {}
else if (state == WAIT_PART) {} else if (state == WAIT_PART) {}
else if (state == NEED_PART) state = WAIT_PART; else if (state == NEED_PART) state = WAIT_PART;
break; break;
default: default:
if (state == READ_LOCK || state == READ_HOLE) { if (state == READ_LOCK || state == READ_HOLE) {
token.push(ch.charCodeAt()); token.push(ch);
} }
else if (state == READ_KEY) { else if (state == READ_KEY) {
let digit = ch.toLowerCase().charCodeAt(); if (hex.includes(ch.toLowerCase()) ||
if ((zero <= digit && digit <= nine) ||
(a <= digit && digit <= f) ||
currlock.name.toLowerCase() == "gameinfo" ||
currlock.hole.toLowerCase() == "text") { currlock.hole.toLowerCase() == "text") {
token.push(digit); token.push(ch);
} }
else error(`error occur ${ch}[${digit}] on ${STATE[state]}`); else error(`error occur ${ch}[${ch.charCodeAt()}] on ${STATE[state]}`);
} }
else if (state == WAIT_PART) {} else if (state == WAIT_PART) {}
else if (state == NEED_PART) state = WAIT_PART; else if (state == NEED_PART) state = WAIT_PART;
@ -218,16 +211,14 @@ const assembleCheat = (list, dup, hole) => {
else return n; else return n;
}; };
const addrval = list.reduce((r, command) => { const addrval = list.reduce((r, command) => {
let [taddr, ...vals] = command; let addr = fromTaddr(command[0]);
let addr = fromTaddr(taddr); let len = command.length - 1;
vals.forEach((val, pos) => { for( let pos=0; pos < len; ++pos) {
let dest = addr + pos; r.set(addr+pos, parseInt(command[pos+1], 16))
let value = parseInt(val, 16); }
r.set(dest, value);
});
return r; return r;
}, new Map()); }, new Map());
const ordered = [...addrval].sort((a, b) => a[0] - b[0]); const ordered = Array.from(addrval).sort((a, b) => a[0] - b[0]);
const blocks = ordered.reduce((arr, [addr, value]) => { const blocks = ordered.reduce((arr, [addr, value]) => {
dup.set(addr, hole); dup.set(addr, hole);
if (arr.length == 0) { if (arr.length == 0) {
@ -242,7 +233,11 @@ const assembleCheat = (list, dup, hole) => {
} }
return arr; return arr;
}, []); }, []);
return Uint32Array.from(blocks.reduce((r, block) => [...r, block.addr, (block.count << 8) | block.value], [])) return Uint32Array.from(blocks.reduce((r, block) => {
r.push( block.addr );
r.push( (block.count << 8) | block.value )
return r;
}, []))
} }
const pack = (entlist, strlist, idxlist, cmdlist, xvalue) => { const pack = (entlist, strlist, idxlist, cmdlist, xvalue) => {

View File

@ -1,24 +1,17 @@
const {Worker, isMainThread, parentPort, workerData} = require("worker_threads"); const {Worker, isMainThread, parentPort, workerData} = require("worker_threads");
const readCht = require("./cht"); const readCht = require("./cht");
const { accessSync, readFileSync } = require("fs"); const { readFileSync } = require("fs");
const ncpu = require("os").availableParallelism(); const ncpu = require("os").availableParallelism();
const loadcheat = (order, serial, title, file) => { const loadcheat = (order, serial, title, file) => {
try{
accessSync( file );
}
catch( e ) {
return {serial}
}
try { try {
const chtfile = readFileSync(file, {encoding: "utf-8"}); const chtfile = readFileSync(file, {encoding: "utf-8"});
const cheat = readCht(chtfile, { serial }, order); const cheat = readCht(chtfile, { serial }, order);
return { serial, cheat } return { serial, cheat }
} }
catch (e) { catch (e) {
console.log("bad cheat: %s[order=%d]\n%s", title, order, e.stack) //console.log("bad cheat: %s[order=%d]\n%s", title, order, e.stack)
return { serial } return { serial }
} }
} }