roomie 1.1.2 → 1.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/roomie.d.ts CHANGED
@@ -63,6 +63,7 @@ export declare class Roomie extends EventEmitter {
63
63
  constructor(path?: string);
64
64
  private detectSystemFromPath;
65
65
  private readGameCode;
66
+ private getN64String;
66
67
  private computeRegion;
67
68
  private computeSfcInfo;
68
69
  private _name;
package/dist/roomie.js CHANGED
@@ -53,13 +53,44 @@ export class Roomie extends EventEmitter {
53
53
  if (system === "gb" && b.length >= 0x0143) {
54
54
  return b.subarray(0x013F, 0x0143).toString("ascii");
55
55
  }
56
- if (system === "n64" && b.length >= 0x2F) {
57
- return b.subarray(0x20, 0x2F).toString("ascii").trim();
56
+ if (system === "n64" && b.length >= 0x3F) {
57
+ return this.getN64String(0x3B, 4).trim();
58
58
  }
59
59
  }
60
60
  catch { }
61
61
  return undefined;
62
62
  }
63
+ getN64String(offset, length) {
64
+ const b = this._rom;
65
+ if (b.length < offset + length)
66
+ return "";
67
+ const magic = b.readUInt32BE(0);
68
+ // native big endian (z64)
69
+ if (magic === 0x80371240) {
70
+ return b.subarray(offset, offset + length).toString("ascii");
71
+ }
72
+ // byte-swapped (v64)
73
+ if (magic === 0x37804012) {
74
+ const out = Buffer.alloc(length);
75
+ for (let i = 0; i < length; i += 2) {
76
+ out[i] = b[offset + i + 1];
77
+ out[i + 1] = b[offset + i];
78
+ }
79
+ return out.toString("ascii");
80
+ }
81
+ // little-endian (n64)
82
+ if (magic === 0x40123780) {
83
+ const out = Buffer.alloc(length);
84
+ for (let i = 0; i < length; i += 4) {
85
+ out[i] = b[offset + i + 3];
86
+ out[i + 1] = b[offset + i + 2];
87
+ out[i + 2] = b[offset + i + 1];
88
+ out[i + 3] = b[offset + i];
89
+ }
90
+ return out.toString("ascii");
91
+ }
92
+ return b.subarray(offset, offset + length).toString("ascii");
93
+ }
63
94
  computeRegion(system, gameCode) {
64
95
  switch (system) {
65
96
  case "nds":
@@ -89,10 +120,9 @@ export class Roomie extends EventEmitter {
89
120
  }
90
121
  return undefined;
91
122
  case "n64":
92
- // N64 region code at offset 0x3E in some ROMs (common practice)
93
123
  if (this._rom.length > 0x3E) {
94
- const regionByte = this._rom[0x3E];
95
- // Map region byte to region string (basic example)
124
+ const id = this.getN64String(0x3B, 4);
125
+ const regionByte = id.charCodeAt(3);
96
126
  const regionMap = {
97
127
  0x44: "USA",
98
128
  0x45: "Europe",
@@ -194,8 +224,8 @@ export class Roomie extends EventEmitter {
194
224
  }
195
225
  break;
196
226
  case "n64":
197
- if (b.length >= 0x20) {
198
- return b.subarray(0x20, 0x34).toString("ascii").replace(/\0/g, "").trim();
227
+ if (b.length >= 0x34) {
228
+ return this.getN64String(0x20, 20).replace(/\0/g, "").trim();
199
229
  }
200
230
  break;
201
231
  case "nes":
@@ -249,8 +279,8 @@ export class Roomie extends EventEmitter {
249
279
  }
250
280
  break;
251
281
  case "n64":
252
- if (b.length >= 0x2F) {
253
- return b.subarray(0x20, 0x2F).toString("ascii").trim();
282
+ if (b.length >= 0x3F) {
283
+ return this.getN64String(0x3B, 4).trim();
254
284
  }
255
285
  break;
256
286
  }
@@ -585,7 +615,7 @@ export class Roomie extends EventEmitter {
585
615
  info.n64 = {
586
616
  name: this._name(),
587
617
  country: this._region(),
588
- version: this._rom.length > 0x3F ? this._rom[0x3F].toString() : undefined,
618
+ version: this._rom.length > 0x3F ? this.getN64String(0x3B, 5).slice(4) : undefined,
589
619
  };
590
620
  }
591
621
  else {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "roomie",
3
- "version": "1.1.2",
3
+ "version": "1.1.3",
4
4
  "description": "ROM metadata helper",
5
5
  "license": "MIT",
6
6
  "type": "module",