也是对比修改,最重要的是把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}`);
const enc = new TextEncoder();
const size = Symbol("length");
//const size = Symbol("length");
const concatUnit = 10240;
const align = (n, base) => base * Math.floor((n + base - 1) / base);
const size = new WeakMap()
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) {
let n = new (Object.getPrototypeOf(a).constructor)(align(len, concatUnit) * 2);
n.set(a, 0);
n.set(b, a[size]);
n[size] = len;
n.set(b, sizea);
size.set(n, len);
return n;
}
else {
a.set(b, a[size]);
a[size] = len;
a.set(b, sizea);
size.set(a, len);
return a;
}
}
const getnametable = list => list.reduce((r, { serial, cheat }, idx, arr) => {
const val = serial.slice(0, -1);
//console.log("looping", val, r[4], r[2], cheat.length)
const size1 = size.get(r[1]);
if (val != r[4]) {
if (r[1][size] > 0 && r[2] - r[1].at(r[1][size] - 1) > r[3])
r[3] = r[2] - r[1].at(r[1][size] - 1);
if (size1 > 0 && r[2] - r[1].at(size1 - 1) > r[3])
r[3] = r[2] - r[1].at(size1 - 1);
r[0] = concat(r[0], enc.encode(val))
r[1] = concat(r[1], [r[2]]);
r[4] = val;
}
r[2] = r[2] + cheat.length;
if (idx + 1 == arr.length) {
if (r[2] - r[1].at(r[1][size] - 1) > r[3])
r[3] = r[2] - r[1].at(r[1][size] - 1);
if (r[2] - r[1].at(size1 - 1) > r[3])
r[3] = r[2] - r[1].at(size1 - 1);
r[1] = concat(r[1], [r[2]]);
}
return r;
@ -52,7 +55,7 @@ const format = valid => {
const expandcheat = (list, base) => list.reduce((r, { cheat, serial }) => {
const val = serial.charCodeAt(3);
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[1] = concat(r[1], bin);
return r;
@ -62,7 +65,7 @@ const format = valid => {
const linkbuffer = (arr, ...l) => {
for (let i of l) {
const arrBa = arr[i];
arr[i] = arrBa.slice(0, arrBa[size]);
arr[i] = arrBa.slice(0, size.get(arrBa));
}
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 PASSHOLE = ["text", "off"]
const space = " ".charCodeAt();
const tab = "\t".charCodeAt();
const space = " ";
const tab = "\t";
const hex = "0123456789abcdef";
const zero = "0".charCodeAt();
const nine = "9".charCodeAt();
const a = "a".charCodeAt();
@ -40,8 +41,7 @@ const read = (cht, info, order) => {
let locks = [], currlock = null, retval = [];
const merge_str = String.fromCharCode.bind(String);
const token_str = () => { const r = merge_str.apply(null, token); return (token.length = 0, r); }
const token_str = () => { const r = token.join(""); return (token = [], r); }
const error = msg => { throw new SyntaxError(`${msg} at line: ${line} in lock ${currlock?.name}`) }
const incr = ch => {
switch (ch) {
@ -101,7 +101,7 @@ const read = (cht, info, order) => {
currlock.keys = [new Array()];
}
else if (state == READ_LOCK) {
token.push(ch.charCodeAt());
token.push(ch);
}
else if (state == WAIT_PART) {}
else if (state == NEED_PART) state = WAIT_PART;
@ -119,7 +119,7 @@ const read = (cht, info, order) => {
state = READ_KEY;
}
else if (state == READ_LOCK) {
token.push(ch.charCodeAt());
token.push(ch);
}
else if (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());
}
else if (state == READ_LOCK) {
token.push(ch.charCodeAt());
token.push(ch);
}
else if (state == READ_HOLE) {// MULTILINE KEY
let { name, cmd } = currlock.holes.pop();
@ -159,29 +159,22 @@ const read = (cht, info, order) => {
break;
case " ":
if (state == READ_LOCK || state == READ_HOLE) {
token.push(ch.charCodeAt());
}
else if (state == READ_KEY) {
if (currlock.name.toLowerCase() == "gameinfo") {
token.push(ch.charCodeAt());
}
token.push(ch);
}
else if (state == READ_KEY) {}
else if (state == WAIT_PART) {}
else if (state == NEED_PART) state = WAIT_PART;
break;
default:
if (state == READ_LOCK || state == READ_HOLE) {
token.push(ch.charCodeAt());
token.push(ch);
}
else if (state == READ_KEY) {
let digit = ch.toLowerCase().charCodeAt();
if ((zero <= digit && digit <= nine) ||
(a <= digit && digit <= f) ||
currlock.name.toLowerCase() == "gameinfo" ||
if (hex.includes(ch.toLowerCase()) ||
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 == NEED_PART) state = WAIT_PART;
@ -218,16 +211,14 @@ const assembleCheat = (list, dup, hole) => {
else return n;
};
const addrval = list.reduce((r, command) => {
let [taddr, ...vals] = command;
let addr = fromTaddr(taddr);
vals.forEach((val, pos) => {
let dest = addr + pos;
let value = parseInt(val, 16);
r.set(dest, value);
});
let addr = fromTaddr(command[0]);
let len = command.length - 1;
for( let pos=0; pos < len; ++pos) {
r.set(addr+pos, parseInt(command[pos+1], 16))
}
return r;
}, 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]) => {
dup.set(addr, hole);
if (arr.length == 0) {
@ -242,7 +233,11 @@ const assembleCheat = (list, dup, hole) => {
}
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) => {

View File

@ -1,24 +1,17 @@
const {Worker, isMainThread, parentPort, workerData} = require("worker_threads");
const readCht = require("./cht");
const { accessSync, readFileSync } = require("fs");
const { readFileSync } = require("fs");
const ncpu = require("os").availableParallelism();
const loadcheat = (order, serial, title, file) => {
try{
accessSync( file );
}
catch( e ) {
return {serial}
}
try {
const chtfile = readFileSync(file, {encoding: "utf-8"});
const cheat = readCht(chtfile, { serial }, order);
return { serial, cheat }
}
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 }
}
}