mk64/gfxdsm.js
MegaMech 6e3f6aee63
Matched some funcs (#378)
* Matched code
2023-08-22 19:12:51 -06:00

138 lines
3.6 KiB
JavaScript

#!/bin/node
const fs = require('fs');
const { exit } = require('process');
/**
* Call this script like
*
* node app.js input_file_here output_file_here
*/
if (process.argv.length !== 4 && process.argv.length !== 5 ) {
console.error(`Error! Usage: ./${process.argv[1].split('/').slice(-1)[0]} input_file output_file`)
exit(1);
}
// get the name of the file to read
const f = fs.readFileSync(process.argv[2]);
let type;
if (Number(process.argv[4]) > -1 && Number(process.argv[4]) < 3) {
type = Number(process.argv[4]);
} else {
type = 2;
}
// offset, type
arr = [
{o: "0x0", t: 3},
{o: "0x19D0", t: 0}, // path
{o: "0x1CF8", t: 0}, // more path? or spawn?
// 0x5400
];
let iter = 8;
// spawn, vtx, ptr, gfx
switch(type) {
case 0: // Actor Spawn
iter = 8;
break;
case 1: // Vtx
iter = 16;
break;
case 2: // Ptr Addr
iter = 8;
break;
}
// parse data to s16
function p(offset) {
const byteA = f[offset];
const byteB = f[offset + 1];
let sign = byteA & (1 << 7);
let x = (((byteA & 0xFF) << 8) | (byteB & 0xFF));
if (sign) {
return 0xFFFF0000 | x; // fill in most significant bits with 1's
} else {
return x;
}
}
// parse s8 to hex
function s8(b) {
if (typeof b === "undefined") {
return "";
}
let res = b.toString(16).toUpperCase();
if (res.length == 1) {
return "0x0"+String(res);
}
return "0x"+res;
}
function s32_h(b, offset) { // helper
let str = f[b + offset].toString(16).toUpperCase()
if (str.length == 1) {
return "0"+str;
} else {
return str;
}
}
// parse s32 to hex
function s32(b) {
return res = "0x"+s32_h(b, 0) +
s32_h(b, 1) +
s32_h(b, 2) +
s32_h(b, 3);
}
// lines to output
let k = [];
switch(type) {
case 0:
k.push("struct ActorSpawnData d_course__dl[] = {");
break;
case 1:
k.push("Vtx_t d_course__dl[] = {");
break;
case 2:
k.push("TrackSections d_course__dl[] = {");
break;
}
for (i = 0; i < f.length; i += iter) {
// X Y Z
switch(type) {
case 0: // Spawn location { x, y, z}, { flag }
k.push(" {{ "+p(i + 0)+", "+p(i + 2)+", "+p(i + 4)+" }, { "+p(i + 6)+" }},");
break;
case 1: // Vtx {x, y, z}, { flag }, { t1, t2 }, { r, g, b, a }
k.push(" {{ "+p(i + 0)+", "+p(i + 2)+", "+p(i + 4)+" }, { "+p(i + 6)+" }, { "+p(i + 8)+", "+p(i + 10)+" }, {"+s8(f[i + 12], 16)+", "+s8(f[i + 13], 16)+", "+s8(f[i + 14])+", "+s8(f[i + 15])+" }},");
break;
case 2: // Ptr addr
k.push(" {{ "+s32(i + 0)+" }, { "+s32(i + 4)+" }},");
break;
}
// check if this is a glabel line
//let n = i.match(/glabel D_([0-9A-F]*)$/);
// if it is
//if (n) {
// the number will be in the second? item in the array - convert it to a numbers
// let newLast = Number(`0x${n[1]}`)
//if (last != 0) { // not the first line? add the skip info
// k.push(`.skip ${newLast-last}`) // .skip ##
// k.push('') // blank line
//}
//last = newLast; // save what the last glbael line was
//k.push(i) // glabel D_###
//}
//if (i > 100) {break;}
}
// might need additional logical here to output the last lines after the last glabel?
// for now, just copy the last line from the original file
//k.push(b.slice(-1)[0])
k.push("};");
// write this to the file name in the second arg
//fs.writeFileSync(process.argv[3], k.join("\n")+"\n");
console.log(k.join("\n")+"\n");
exit(0);