@gaialabs/core 0.2.11 → 0.2.13
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/index.cjs +334 -283
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +743 -736
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +743 -736
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +334 -282
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -936,10 +936,12 @@ var ProcessorStateManager = class {
|
|
|
936
936
|
var RomDataReader = class {
|
|
937
937
|
romData;
|
|
938
938
|
position;
|
|
939
|
-
|
|
939
|
+
offset;
|
|
940
|
+
constructor(romData, offset = 0) {
|
|
940
941
|
if (!romData) throw new Error("romData cannot be null");
|
|
941
942
|
this.romData = romData;
|
|
942
943
|
this.position = 0;
|
|
944
|
+
this.offset = offset;
|
|
943
945
|
}
|
|
944
946
|
readByte() {
|
|
945
947
|
return this.romData[this.position++];
|
|
@@ -1247,6 +1249,7 @@ let MemberType = /* @__PURE__ */ function(MemberType) {
|
|
|
1247
1249
|
MemberType["Address"] = "Address";
|
|
1248
1250
|
MemberType["Binary"] = "Binary";
|
|
1249
1251
|
MemberType["Code"] = "Code";
|
|
1252
|
+
MemberType["Branch"] = "Branch";
|
|
1250
1253
|
MemberType["Location"] = "Location";
|
|
1251
1254
|
return MemberType;
|
|
1252
1255
|
}({});
|
|
@@ -1670,31 +1673,63 @@ var ChunkFile = class {
|
|
|
1670
1673
|
mnemonics;
|
|
1671
1674
|
group;
|
|
1672
1675
|
scene;
|
|
1673
|
-
|
|
1676
|
+
base;
|
|
1677
|
+
referenceManager;
|
|
1678
|
+
constructor(type, name, size = 0, location = 0) {
|
|
1679
|
+
this.type = type;
|
|
1674
1680
|
this.name = name;
|
|
1675
1681
|
this.size = size;
|
|
1676
1682
|
this.location = location;
|
|
1677
1683
|
this.mnemonics = {};
|
|
1678
1684
|
this.compressed = type.compressed;
|
|
1679
|
-
|
|
1685
|
+
}
|
|
1686
|
+
enrichWithRawDataFromDbFile(file, rom, compression) {
|
|
1687
|
+
this.upper = file.upper ?? this.upper;
|
|
1688
|
+
this.size = file.end - file.start;
|
|
1689
|
+
this.location = file.start;
|
|
1690
|
+
this.base = file.base ?? this.type.base ?? this.base;
|
|
1691
|
+
this.group = file.group ?? this.group;
|
|
1692
|
+
this.scene = file.scene ?? this.scene;
|
|
1693
|
+
this.compressed = file.compressed;
|
|
1694
|
+
let start = this.location;
|
|
1695
|
+
let header = null;
|
|
1696
|
+
const fileType = this.type;
|
|
1697
|
+
if (fileType.header) {
|
|
1698
|
+
header = new Uint8Array(rom.slice(start, start + fileType.header));
|
|
1699
|
+
start += fileType.header;
|
|
1700
|
+
}
|
|
1701
|
+
let length = this.size;
|
|
1702
|
+
let fileData;
|
|
1703
|
+
if (this.compressed === true && compression) {
|
|
1704
|
+
const expanded = compression.expand(rom, start, length);
|
|
1705
|
+
fileData = combineHeader(expanded, 0, expanded.length, header, fileType.type);
|
|
1706
|
+
} else {
|
|
1707
|
+
if (this.compressed !== void 0) {
|
|
1708
|
+
start += 2;
|
|
1709
|
+
length -= 2;
|
|
1710
|
+
}
|
|
1711
|
+
fileData = combineHeader(rom, start, length, header, fileType.type);
|
|
1712
|
+
}
|
|
1713
|
+
this.rawData = fileData;
|
|
1714
|
+
this.size = fileData.length;
|
|
1715
|
+
}
|
|
1716
|
+
enrichWithAsmBlocksFromDbBlock(block, memoryMode) {
|
|
1717
|
+
this.group = block.group;
|
|
1718
|
+
this.scene = block.scene;
|
|
1719
|
+
this.parts = [];
|
|
1720
|
+
this.size = 0;
|
|
1721
|
+
if (!block.parts?.length) throw new Error(`Block ${block.name} has no parts`);
|
|
1722
|
+
this.location = block.parts[0].start;
|
|
1723
|
+
this.bank = block.movable ? void 0 : memoryMode === MemoryMapMode.Lo ? this.location >> 15 : this.location >> 16;
|
|
1724
|
+
this.transforms = block.transforms;
|
|
1725
|
+
this.postProcess = block.postProcess;
|
|
1726
|
+
for (const part of block.parts) {
|
|
1727
|
+
const asmBlock = new AsmBlock(part.start, part.end - part.start, false, part.name, part.type || void 0, part.bank);
|
|
1728
|
+
this.size += asmBlock.size;
|
|
1729
|
+
this.parts.push(asmBlock);
|
|
1730
|
+
}
|
|
1680
1731
|
}
|
|
1681
1732
|
};
|
|
1682
|
-
function createChunkFileFromDbFile(rom, compression, dbFile, fileType) {
|
|
1683
|
-
const chunkFile = new ChunkFile(dbFile.name, dbFile.end - dbFile.start, dbFile.start, fileType);
|
|
1684
|
-
chunkFile.compressed = dbFile.compressed;
|
|
1685
|
-
chunkFile.upper = dbFile.upper;
|
|
1686
|
-
chunkFile.group = dbFile.group;
|
|
1687
|
-
chunkFile.scene = dbFile.scene;
|
|
1688
|
-
enrichWithRawDataFromDbFile(rom, chunkFile, compression, dbFile, fileType);
|
|
1689
|
-
return chunkFile;
|
|
1690
|
-
}
|
|
1691
|
-
function createChunkFileFromDbBlock(block, fileType, memoryMode) {
|
|
1692
|
-
const chunkFile = new ChunkFile(block.name, 0, 0, fileType);
|
|
1693
|
-
chunkFile.group = block.group;
|
|
1694
|
-
chunkFile.scene = block.scene;
|
|
1695
|
-
enrichWithPartsFromDbBlock(chunkFile, block, memoryMode);
|
|
1696
|
-
return chunkFile;
|
|
1697
|
-
}
|
|
1698
1733
|
function combineHeader(data, position, length, header, type) {
|
|
1699
1734
|
let totalLength = length + (header ? header.length : 0);
|
|
1700
1735
|
if (type === BinType.Palette && length < 512) totalLength += 512 - length;
|
|
@@ -1710,48 +1745,6 @@ function combineHeader(data, position, length, header, type) {
|
|
|
1710
1745
|
return result;
|
|
1711
1746
|
}
|
|
1712
1747
|
/**
|
|
1713
|
-
* Enriches ChunkFile with raw binary data from DbFile
|
|
1714
|
-
*/
|
|
1715
|
-
function enrichWithRawDataFromDbFile(rom, chunkFile, compression, dbFile, fileType) {
|
|
1716
|
-
let start = dbFile.start;
|
|
1717
|
-
let header = null;
|
|
1718
|
-
if (fileType.header) {
|
|
1719
|
-
header = new Uint8Array(rom.slice(start, start + fileType.header));
|
|
1720
|
-
start += fileType.header;
|
|
1721
|
-
}
|
|
1722
|
-
let length = dbFile.end - start;
|
|
1723
|
-
let fileData;
|
|
1724
|
-
if (dbFile.compressed === true && compression) {
|
|
1725
|
-
const expanded = compression.expand(rom, start, length);
|
|
1726
|
-
fileData = combineHeader(expanded, 0, expanded.length, header, fileType.type);
|
|
1727
|
-
} else {
|
|
1728
|
-
if (dbFile.compressed !== void 0) {
|
|
1729
|
-
start += 2;
|
|
1730
|
-
length -= 2;
|
|
1731
|
-
}
|
|
1732
|
-
fileData = combineHeader(rom, start, length, header, fileType.type);
|
|
1733
|
-
}
|
|
1734
|
-
chunkFile.rawData = fileData;
|
|
1735
|
-
chunkFile.size = fileData.length;
|
|
1736
|
-
}
|
|
1737
|
-
/**
|
|
1738
|
-
* Enriches ChunkFile with AsmBlock parts from DbBlock
|
|
1739
|
-
*/
|
|
1740
|
-
function enrichWithPartsFromDbBlock(chunkFile, block, memoryMode) {
|
|
1741
|
-
chunkFile.parts = [];
|
|
1742
|
-
chunkFile.size = 0;
|
|
1743
|
-
if (!block.parts?.length) throw new Error(`Block ${block.name} has no parts`);
|
|
1744
|
-
chunkFile.location = block.parts[0].start;
|
|
1745
|
-
chunkFile.bank = block.movable ? void 0 : memoryMode === MemoryMapMode.Lo ? chunkFile.location >> 15 : chunkFile.location >> 16;
|
|
1746
|
-
chunkFile.transforms = block.transforms;
|
|
1747
|
-
chunkFile.postProcess = block.postProcess;
|
|
1748
|
-
for (const part of block.parts) {
|
|
1749
|
-
const asmBlock = new AsmBlock(part.start, part.end - part.start, false, part.name, part.type || void 0, part.bank);
|
|
1750
|
-
chunkFile.size += asmBlock.size;
|
|
1751
|
-
chunkFile.parts.push(asmBlock);
|
|
1752
|
-
}
|
|
1753
|
-
}
|
|
1754
|
-
/**
|
|
1755
1748
|
* Chunk file utilities
|
|
1756
1749
|
*/
|
|
1757
1750
|
var ChunkFileUtils = class {
|
|
@@ -1773,16 +1766,11 @@ var ChunkFileUtils = class {
|
|
|
1773
1766
|
* Calculate the total size of all blocks
|
|
1774
1767
|
*/
|
|
1775
1768
|
static calculateSize(chunkFile) {
|
|
1776
|
-
if (!chunkFile.parts) {
|
|
1777
|
-
let size = chunkFile.rawData?.length ?? chunkFile.size;
|
|
1778
|
-
if (chunkFile.type.header === -2 || chunkFile.compressed === false) {
|
|
1779
|
-
size += 2;
|
|
1780
|
-
chunkFile.size = size;
|
|
1781
|
-
}
|
|
1782
|
-
return size;
|
|
1783
|
-
}
|
|
1784
1769
|
let size = 0;
|
|
1785
|
-
|
|
1770
|
+
if (chunkFile.rawData) {
|
|
1771
|
+
size = chunkFile.rawData.length;
|
|
1772
|
+
if (chunkFile.type.header === -2 || chunkFile.compressed === false) size += 2;
|
|
1773
|
+
} else if (chunkFile.parts) for (let x = 0; x < chunkFile.parts.length; x++) {
|
|
1786
1774
|
const block = chunkFile.parts[x];
|
|
1787
1775
|
if (x > 0 && !block.label) break;
|
|
1788
1776
|
size += block.size || 0;
|
|
@@ -1801,7 +1789,7 @@ var ChunkFileUtils = class {
|
|
|
1801
1789
|
block,
|
|
1802
1790
|
part
|
|
1803
1791
|
];
|
|
1804
|
-
for (const otherBlock of root) if (otherBlock !== block) {
|
|
1792
|
+
for (const otherBlock of root) if (otherBlock !== block && !otherBlock.type.struct) {
|
|
1805
1793
|
const [otherIsInside, otherPart] = this.isInsideWithPart(otherBlock, location);
|
|
1806
1794
|
if (otherIsInside) return [
|
|
1807
1795
|
true,
|
|
@@ -1987,6 +1975,7 @@ var ReferenceManager = class {
|
|
|
1987
1975
|
}
|
|
1988
1976
|
createTypeName(type, location) {
|
|
1989
1977
|
let name = type.toLowerCase();
|
|
1978
|
+
if (name === "branch") name = "loc";
|
|
1990
1979
|
while (name.length > 0 && BlockReaderConstants.POINTER_CHARACTERS.includes(name[0])) name = name.substring(1) + "_list";
|
|
1991
1980
|
return `${name}_${location.toString(16).toUpperCase().padStart(6, "0")}`;
|
|
1992
1981
|
}
|
|
@@ -2364,6 +2353,7 @@ var AddressingModeHandler = class {
|
|
|
2364
2353
|
}
|
|
2365
2354
|
handlePCRelativeMode(operands, nextAddress, reg, isLong) {
|
|
2366
2355
|
const relative = isLong ? nextAddress + this._dataReader.readShort() : nextAddress + this._dataReader.readSByte();
|
|
2356
|
+
this._blockReader._referenceManager.tryAddStruct(relative, "Branch");
|
|
2367
2357
|
this._blockReader.updateRegisterState(relative, reg);
|
|
2368
2358
|
operands.push(new LocationWrapper(relative, isLong ? AddressType.WRelative : AddressType.Relative));
|
|
2369
2359
|
}
|
|
@@ -2987,7 +2977,7 @@ var StringReader = class StringReader {
|
|
|
2987
2977
|
this._romDataReader = blockReader._romDataReader;
|
|
2988
2978
|
}
|
|
2989
2979
|
resolveCommand(cmd, builder) {
|
|
2990
|
-
if (cmd.dictionary) builder.push(cmd.dictionary.
|
|
2980
|
+
if (cmd.dictionary) builder.push(`[${cmd.dictionary.commandName ?? cmd.dictionary.command?.toString(16).padEnd(2, "0").toUpperCase()}:${this._romDataReader.readByte().toString(16).padEnd(2, "0").toUpperCase()}]`);
|
|
2991
2981
|
else if (cmd.types && cmd.types.length > 0) {
|
|
2992
2982
|
builder.push(`[${cmd.name}`);
|
|
2993
2983
|
let first = true;
|
|
@@ -3028,7 +3018,7 @@ var StringReader = class StringReader {
|
|
|
3028
3018
|
}
|
|
3029
3019
|
parseString(stringType, fixedSize) {
|
|
3030
3020
|
const commands = stringType.commandLookup;
|
|
3031
|
-
|
|
3021
|
+
stringType.dictionaries;
|
|
3032
3022
|
const builder = [];
|
|
3033
3023
|
const strLoc = this._romDataReader.position;
|
|
3034
3024
|
const terminator = stringType.terminator;
|
|
@@ -3045,23 +3035,17 @@ var StringReader = class StringReader {
|
|
|
3045
3035
|
if (cmd.halt) break;
|
|
3046
3036
|
} else {
|
|
3047
3037
|
let found = false;
|
|
3048
|
-
for (const
|
|
3049
|
-
|
|
3050
|
-
|
|
3051
|
-
|
|
3052
|
-
}
|
|
3053
|
-
if (!found) {
|
|
3054
|
-
for (const layer of stringType.layers) if (layer.on !== void 0) {
|
|
3055
|
-
if (c === layer.on) {
|
|
3056
|
-
currentLayer = layer;
|
|
3057
|
-
found = true;
|
|
3058
|
-
break;
|
|
3059
|
-
}
|
|
3060
|
-
} else if (layer.base && c >= layer.base && c < layer.base + layer.map.length) {
|
|
3061
|
-
builder.push(layer.map[c - layer.base]);
|
|
3038
|
+
for (const layer of stringType.layers) if (layer.on !== void 0) {
|
|
3039
|
+
if (c === layer.on) {
|
|
3040
|
+
currentLayer = layer;
|
|
3041
|
+
builder.push("[--]");
|
|
3062
3042
|
found = true;
|
|
3063
3043
|
break;
|
|
3064
3044
|
}
|
|
3045
|
+
} else if (layer.base && c >= layer.base && c < layer.base + layer.map.length) {
|
|
3046
|
+
builder.push(layer.map[c - layer.base]);
|
|
3047
|
+
found = true;
|
|
3048
|
+
break;
|
|
3065
3049
|
}
|
|
3066
3050
|
if (!found) {
|
|
3067
3051
|
let index = c - (currentLayer.base ?? 0);
|
|
@@ -3090,28 +3074,26 @@ var StringReader = class StringReader {
|
|
|
3090
3074
|
let str = sw.string;
|
|
3091
3075
|
let ix = indexOfAny(str, StringReader.STRING_REFERENCE_CHARACTERS);
|
|
3092
3076
|
while (ix >= 0) {
|
|
3093
|
-
if (ix + 6
|
|
3094
|
-
|
|
3095
|
-
|
|
3096
|
-
|
|
3097
|
-
|
|
3098
|
-
|
|
3099
|
-
|
|
3100
|
-
|
|
3101
|
-
|
|
3102
|
-
|
|
3103
|
-
|
|
3104
|
-
|
|
3105
|
-
|
|
3106
|
-
|
|
3107
|
-
|
|
3108
|
-
|
|
3109
|
-
|
|
3110
|
-
|
|
3111
|
-
|
|
3112
|
-
|
|
3113
|
-
}
|
|
3114
|
-
}
|
|
3077
|
+
if (ix + 6 >= str.length) break;
|
|
3078
|
+
const hexStr = str.substring(ix + 1, ix + 7);
|
|
3079
|
+
const sloc = parseInt(hexStr, 16);
|
|
3080
|
+
if (isNaN(sloc)) break;
|
|
3081
|
+
if (new Address(sloc >> 16 & 255, sloc & 65535, this._blockReader._root.config.memoryMode).isROM) {
|
|
3082
|
+
this._blockReader.resolveInclude(sloc, false);
|
|
3083
|
+
const name = this._blockReader._referenceManager.resolveName(sloc, AddressType.Unknown, false);
|
|
3084
|
+
const opix = indexOfAny(name, RomProcessingConstants.OPERATORS);
|
|
3085
|
+
if (opix > 0) {
|
|
3086
|
+
const offsetStr = name.substring(opix + 1);
|
|
3087
|
+
let offset;
|
|
3088
|
+
if (offsetStr === "M") offset = this._blockReader._referenceManager.markerTable.get(sloc) || 0;
|
|
3089
|
+
else offset = parseInt(offsetStr, 16) || 0;
|
|
3090
|
+
if (name[opix] === "-") offset = -offset;
|
|
3091
|
+
name.substring(0, opix);
|
|
3092
|
+
const target = sloc - offset;
|
|
3093
|
+
const [isOutside, block, part] = ChunkFileUtils.isOutsideWithPart(this._blockReader._enrichedChunks, this._blockReader._currentChunk, sloc);
|
|
3094
|
+
if (part != null) {
|
|
3095
|
+
const entry = part.objList?.find((x) => typeof x === "object" && x !== null && "location" in x && "object" in x && x.location === target);
|
|
3096
|
+
if (entry && entry.object) entry.object.marker = offset;
|
|
3115
3097
|
}
|
|
3116
3098
|
}
|
|
3117
3099
|
}
|
|
@@ -3161,7 +3143,8 @@ var TypeParser = class {
|
|
|
3161
3143
|
case MemberType.Address: return this.parseLocation(this._romDataReader.readUShort(), this._romDataReader.readByte(), null, AddressType.Address);
|
|
3162
3144
|
case MemberType.Location: return this.parseLocation(this._romDataReader.readUShort(), this._romDataReader.readByte(), null, AddressType.Location);
|
|
3163
3145
|
case MemberType.Binary: return this.parseBinary(fixedSize);
|
|
3164
|
-
case MemberType.Code:
|
|
3146
|
+
case MemberType.Code:
|
|
3147
|
+
case MemberType.Branch: return this.parseCode(reg);
|
|
3165
3148
|
default: throw new Error("Invalid member type");
|
|
3166
3149
|
}
|
|
3167
3150
|
const parentType = this._blockReader._root.structs[fixedTypeName];
|
|
@@ -3195,7 +3178,7 @@ var TypeParser = class {
|
|
|
3195
3178
|
let checkPosition = startPosition;
|
|
3196
3179
|
while (++checkPosition < this._romDataReader.position) {
|
|
3197
3180
|
const struct = this._referenceManager.tryGetStruct(checkPosition);
|
|
3198
|
-
if (struct.found && struct.chunkType !== "Code") {
|
|
3181
|
+
if (struct.found && struct.chunkType !== "Code" && struct.chunkType !== "Branch") {
|
|
3199
3182
|
this._romDataReader.position = checkPosition;
|
|
3200
3183
|
break;
|
|
3201
3184
|
}
|
|
@@ -3226,16 +3209,18 @@ var TypeParser = class {
|
|
|
3226
3209
|
}
|
|
3227
3210
|
parseLocation(offset, bank, typeName, addrType) {
|
|
3228
3211
|
if ((bank === void 0 || bank === null) && offset === 0) return new Word(offset);
|
|
3212
|
+
offset -= this._romDataReader.offset;
|
|
3229
3213
|
let adrs;
|
|
3230
3214
|
let loc;
|
|
3231
|
-
if (addrType === AddressType.Location) loc = offset | bank << 16;
|
|
3215
|
+
if (addrType === AddressType.Location || this._romDataReader.offset) loc = offset | bank << 16;
|
|
3232
3216
|
else {
|
|
3233
3217
|
adrs = new Address(bank ?? Address.resolveBank(this._romDataReader.position, this._blockReader._root.config.memoryMode), offset, this._blockReader._root.config.memoryMode);
|
|
3234
3218
|
if (!adrs.isROM) return adrs;
|
|
3235
3219
|
loc = adrs.toLocation();
|
|
3236
3220
|
}
|
|
3237
|
-
if (typeName && !this._blockReader._root.rewrites[loc]) {
|
|
3238
|
-
this._referenceManager.
|
|
3221
|
+
if (typeName && (this._romDataReader.offset || !this._blockReader._root.rewrites[loc])) {
|
|
3222
|
+
const oldStruct = this._referenceManager.structTable.get(loc);
|
|
3223
|
+
if (!oldStruct || oldStruct === "Branch") this._referenceManager.structTable.set(loc, typeName);
|
|
3239
3224
|
const referenceName = `${typeName.toLowerCase()}_${loc.toString(16).toUpperCase().padStart(6, "0")}`;
|
|
3240
3225
|
this._referenceManager.tryAddName(loc, referenceName);
|
|
3241
3226
|
}
|
|
@@ -3246,7 +3231,10 @@ var TypeParser = class {
|
|
|
3246
3231
|
let first = true;
|
|
3247
3232
|
while (this._romDataReader.position < this._blockReader._partEnd) {
|
|
3248
3233
|
if (first) first = false;
|
|
3249
|
-
else
|
|
3234
|
+
else {
|
|
3235
|
+
const struct = this._referenceManager.structTable.get(this._romDataReader.position);
|
|
3236
|
+
if (struct && struct !== "Branch") break;
|
|
3237
|
+
}
|
|
3250
3238
|
if (reg) this._blockReader.hydrateRegisters(reg);
|
|
3251
3239
|
const op = this._blockReader._asmReader.parseAsm(reg);
|
|
3252
3240
|
opList.push(op);
|
|
@@ -3421,8 +3409,6 @@ var BlockReader = class {
|
|
|
3421
3409
|
this._stringReader = new StringReader(this);
|
|
3422
3410
|
this._asmReader = new AsmReader(this);
|
|
3423
3411
|
this._typeParser = new TypeParser(this);
|
|
3424
|
-
this.initializeOverrides();
|
|
3425
|
-
this.initializeFileReferences();
|
|
3426
3412
|
}
|
|
3427
3413
|
/**
|
|
3428
3414
|
* Processes predefined overrides for registers and bank notes
|
|
@@ -3472,9 +3458,6 @@ var BlockReader = class {
|
|
|
3472
3458
|
/**
|
|
3473
3459
|
* Resolves name for a location (delegated to ReferenceManager)
|
|
3474
3460
|
*/
|
|
3475
|
-
resolveName(location, type, isBranch) {
|
|
3476
|
-
return this._referenceManager.resolveName(location, type, isBranch);
|
|
3477
|
-
}
|
|
3478
3461
|
/**
|
|
3479
3462
|
* Resolves include for a location
|
|
3480
3463
|
*/
|
|
@@ -3493,7 +3476,8 @@ var BlockReader = class {
|
|
|
3493
3476
|
* Notes a type at a location and manages chunk references
|
|
3494
3477
|
*/
|
|
3495
3478
|
noteType(loc, type, silent = false, reg) {
|
|
3496
|
-
this._referenceManager.
|
|
3479
|
+
const oldStruct = this._referenceManager.structTable.get(loc);
|
|
3480
|
+
if (!oldStruct || oldStruct === "Branch") this._referenceManager.structTable.set(loc, type);
|
|
3497
3481
|
const nameResult = this._referenceManager.tryGetName(loc);
|
|
3498
3482
|
let name;
|
|
3499
3483
|
if (!nameResult.found) {
|
|
@@ -3533,10 +3517,14 @@ var BlockReader = class {
|
|
|
3533
3517
|
return this._romDataReader.position < this._partEnd && !this._referenceManager.containsStruct(this._romDataReader.position);
|
|
3534
3518
|
}
|
|
3535
3519
|
analyzeAndResolve() {
|
|
3520
|
+
console.log("analyzeAndResolve started");
|
|
3521
|
+
this.initializeOverrides();
|
|
3522
|
+
this.initializeFileReferences();
|
|
3536
3523
|
this.createChunkFilesFromDatabase();
|
|
3537
3524
|
this.initializeBlocksAndParts();
|
|
3538
3525
|
this.analyzeChunkFiles();
|
|
3539
3526
|
this.resolveReferences();
|
|
3527
|
+
console.log("analyzeAndResolve complete");
|
|
3540
3528
|
return this._enrichedChunks;
|
|
3541
3529
|
}
|
|
3542
3530
|
/**
|
|
@@ -3546,6 +3534,7 @@ var BlockReader = class {
|
|
|
3546
3534
|
* Initializes blocks and parts with base references
|
|
3547
3535
|
*/
|
|
3548
3536
|
initializeBlocksAndParts() {
|
|
3537
|
+
console.log("initializeBlocksAndParts");
|
|
3549
3538
|
for (const block of this._enrichedChunks) for (const part of block.parts || []) {
|
|
3550
3539
|
if (part.structName) this._referenceManager.tryAddStruct(part.location, part.structName);
|
|
3551
3540
|
if (part.label) this._referenceManager.tryAddName(part.location, part.label);
|
|
@@ -3600,6 +3589,7 @@ var BlockReader = class {
|
|
|
3600
3589
|
* Creates ChunkFile objects from database structure
|
|
3601
3590
|
*/
|
|
3602
3591
|
createChunkFilesFromDatabase() {
|
|
3592
|
+
console.log("createChunkFilesFromDatabase");
|
|
3603
3593
|
this._enrichedChunks = [];
|
|
3604
3594
|
this.createChunkFilesFromSfx();
|
|
3605
3595
|
this.createChunkFilesFromDbFiles();
|
|
@@ -3644,7 +3634,7 @@ var BlockReader = class {
|
|
|
3644
3634
|
const size = getSize();
|
|
3645
3635
|
const startPos = pos + offset;
|
|
3646
3636
|
const data = getBytes(size);
|
|
3647
|
-
const chunk = new ChunkFile(`sfx${i.toString(16).toUpperCase().padStart(2, "0")}`, size, startPos
|
|
3637
|
+
const chunk = new ChunkFile(fileType, `sfx${i.toString(16).toUpperCase().padStart(2, "0")}`, size, startPos);
|
|
3648
3638
|
chunk.rawData = data;
|
|
3649
3639
|
chunk.group = "sfx";
|
|
3650
3640
|
this._enrichedChunks.push(chunk);
|
|
@@ -3655,7 +3645,9 @@ var BlockReader = class {
|
|
|
3655
3645
|
*/
|
|
3656
3646
|
createChunkFilesFromDbFiles() {
|
|
3657
3647
|
for (const dbFile of this._root.files) {
|
|
3658
|
-
const
|
|
3648
|
+
const fileType = this._root.fileTypes[dbFile.type];
|
|
3649
|
+
const chunkFile = new ChunkFile(fileType, dbFile.name);
|
|
3650
|
+
chunkFile.enrichWithRawDataFromDbFile(dbFile, this._romDataReader.romData, this._root.compression);
|
|
3659
3651
|
this._enrichedChunks.push(chunkFile);
|
|
3660
3652
|
}
|
|
3661
3653
|
}
|
|
@@ -3665,7 +3657,8 @@ var BlockReader = class {
|
|
|
3665
3657
|
createChunkFilesFromDbBlocks() {
|
|
3666
3658
|
const fileType = Object.values(this._root.fileTypes).find((x) => x.isBlock);
|
|
3667
3659
|
for (const block of this._root.blocks) {
|
|
3668
|
-
const chunkFile =
|
|
3660
|
+
const chunkFile = new ChunkFile(fileType, block.name);
|
|
3661
|
+
chunkFile.enrichWithAsmBlocksFromDbBlock(block, this._root.config.memoryMode);
|
|
3669
3662
|
this._enrichedChunks.push(chunkFile);
|
|
3670
3663
|
}
|
|
3671
3664
|
}
|
|
@@ -3673,22 +3666,43 @@ var BlockReader = class {
|
|
|
3673
3666
|
* Analyzes only assembly ChunkFiles (those with parts from DbBlocks)
|
|
3674
3667
|
*/
|
|
3675
3668
|
analyzeChunkFiles() {
|
|
3676
|
-
|
|
3677
|
-
for (const chunkFile of
|
|
3669
|
+
console.log("analyzeChunkFiles");
|
|
3670
|
+
for (const chunkFile of this._enrichedChunks) {
|
|
3671
|
+
if (!chunkFile.type.isBlock) continue;
|
|
3672
|
+
chunkFile.referenceManager = this._referenceManager;
|
|
3678
3673
|
this._currentChunk = chunkFile;
|
|
3679
3674
|
for (const asmBlock of chunkFile.parts || []) {
|
|
3680
3675
|
this._currentAsmBlock = asmBlock;
|
|
3681
3676
|
this.processPart(asmBlock);
|
|
3682
3677
|
}
|
|
3683
3678
|
}
|
|
3679
|
+
const oldState = this._referenceManager;
|
|
3680
|
+
const oldReader = this._romDataReader;
|
|
3681
|
+
const oldTypeParser = this._typeParser;
|
|
3682
|
+
for (const chunkFile of this._enrichedChunks) {
|
|
3683
|
+
if (!chunkFile.type.struct) continue;
|
|
3684
|
+
this._currentChunk = chunkFile;
|
|
3685
|
+
const asmBlock = new AsmBlock(0, chunkFile.size, false, chunkFile.name, chunkFile.type.struct);
|
|
3686
|
+
chunkFile.parts = [asmBlock];
|
|
3687
|
+
this._currentAsmBlock = asmBlock;
|
|
3688
|
+
this._referenceManager = chunkFile.referenceManager = new ReferenceManager(this._root);
|
|
3689
|
+
this._romDataReader = new RomDataReader(chunkFile.rawData, chunkFile.base ?? 0);
|
|
3690
|
+
this._typeParser = new TypeParser(this);
|
|
3691
|
+
this.processPart(asmBlock);
|
|
3692
|
+
}
|
|
3693
|
+
this._referenceManager = oldState;
|
|
3694
|
+
this._romDataReader = oldReader;
|
|
3695
|
+
this._typeParser = oldTypeParser;
|
|
3684
3696
|
}
|
|
3685
3697
|
/**
|
|
3686
3698
|
* Resolves references in assembly ChunkFiles only
|
|
3687
3699
|
*/
|
|
3688
3700
|
resolveReferences() {
|
|
3701
|
+
console.log("resolveReferences");
|
|
3689
3702
|
for (const chunkFile of this._enrichedChunks) {
|
|
3703
|
+
if (!chunkFile.type.isBlock) continue;
|
|
3690
3704
|
this._currentChunk = chunkFile;
|
|
3691
|
-
for (const asmBlock of chunkFile.parts
|
|
3705
|
+
for (const asmBlock of chunkFile.parts) {
|
|
3692
3706
|
this._currentAsmBlock = asmBlock;
|
|
3693
3707
|
this.resolveObject(asmBlock.objList, false);
|
|
3694
3708
|
}
|
|
@@ -3878,6 +3892,7 @@ var BlockWriter = class {
|
|
|
3878
3892
|
generateAsm(block) {
|
|
3879
3893
|
if (!block.parts) throw new Error("Invalid block structure for generateAsm");
|
|
3880
3894
|
const lines = [];
|
|
3895
|
+
this._referenceManager = block.referenceManager;
|
|
3881
3896
|
if (block.bank !== void 0) lines.push(`?BANK ${block.bank.toString(16).toUpperCase().padStart(2, "0")}`);
|
|
3882
3897
|
const includes = ChunkFileUtils.getIncludes(block);
|
|
3883
3898
|
if (includes && includes.length > 0) {
|
|
@@ -3922,11 +3937,11 @@ var BlockWriter = class {
|
|
|
3922
3937
|
}
|
|
3923
3938
|
if (typeof obj === "number") {
|
|
3924
3939
|
if (op.mode === "Immediate") return obj;
|
|
3925
|
-
return this.
|
|
3940
|
+
return this._referenceManager.resolveName(obj, AddressType.Address, isBranch);
|
|
3926
3941
|
}
|
|
3927
3942
|
if (this.getObjectType(obj) === ObjectType.LocationWrapper) {
|
|
3928
3943
|
const lw = obj;
|
|
3929
|
-
return this.
|
|
3944
|
+
return this._referenceManager.resolveName(lw.location, lw.type, isBranch);
|
|
3930
3945
|
}
|
|
3931
3946
|
if (this.getObjectType(obj) === ObjectType.Address) {
|
|
3932
3947
|
const addr = obj;
|
|
@@ -3978,7 +3993,7 @@ var BlockWriter = class {
|
|
|
3978
3993
|
objLines = this.writeOpArray(obj, depth);
|
|
3979
3994
|
break;
|
|
3980
3995
|
case ObjectType.LocationWrapper:
|
|
3981
|
-
objLines = [this.
|
|
3996
|
+
objLines = [this._referenceManager.resolveName(obj.location, obj.type, isBranch)];
|
|
3982
3997
|
break;
|
|
3983
3998
|
case ObjectType.Address:
|
|
3984
3999
|
objLines = isArray ? [`$#${obj.offset.toString(16).toUpperCase().padStart(4, "0")}`] : [`$${obj.toString()}`];
|
|
@@ -4096,7 +4111,7 @@ var BlockWriter = class {
|
|
|
4096
4111
|
const adrs = new Address(rawAddr >> 16 & 255, rawAddr & 65535, this._blockReader._root.config.memoryMode);
|
|
4097
4112
|
const addressType = char === "^" ? AddressType.Offset : AddressType.Address;
|
|
4098
4113
|
let name = "";
|
|
4099
|
-
if (adrs.isROM) name = this.
|
|
4114
|
+
if (adrs.isROM) name = this._referenceManager.resolveName(adrs.toLocation(), addressType, false);
|
|
4100
4115
|
else if (addressType === AddressType.Offset) name = adrs.offset.toString(16).toUpperCase().padStart(4, "0");
|
|
4101
4116
|
else name = adrs.toString();
|
|
4102
4117
|
str = str.replace(str.substring(ix, ix + 7), name);
|
|
@@ -4113,10 +4128,10 @@ var BlockWriter = class {
|
|
|
4113
4128
|
let six = 0;
|
|
4114
4129
|
let mix = 0;
|
|
4115
4130
|
while (mix < marker) if (str[six] === "[") {
|
|
4116
|
-
const eix = str.indexOf("]",
|
|
4117
|
-
const parts = str.substring(six, eix).split(/[,: ]/);
|
|
4131
|
+
const eix = str.indexOf("]", six);
|
|
4132
|
+
const parts = str.substring(six + 1, eix).split(/[,: ]/);
|
|
4118
4133
|
const cmd = stringObj.type.commands[parts[0]];
|
|
4119
|
-
if (cmd
|
|
4134
|
+
if (cmd) for (const t of cmd.types) switch (t) {
|
|
4120
4135
|
case MemberType.Byte:
|
|
4121
4136
|
mix += 1;
|
|
4122
4137
|
break;
|
|
@@ -4133,6 +4148,7 @@ var BlockWriter = class {
|
|
|
4133
4148
|
break;
|
|
4134
4149
|
default: throw new Error("Unsupported member type");
|
|
4135
4150
|
}
|
|
4151
|
+
else mix += parts.length - 1;
|
|
4136
4152
|
six = eix + 1;
|
|
4137
4153
|
mix++;
|
|
4138
4154
|
} else {
|
|
@@ -4141,6 +4157,18 @@ var BlockWriter = class {
|
|
|
4141
4157
|
}
|
|
4142
4158
|
str = str.substring(0, six) + "[::]" + str.substring(six);
|
|
4143
4159
|
}
|
|
4160
|
+
const dictionaries = stringObj.type.dictionaries;
|
|
4161
|
+
for (const dictionary of Object.values(dictionaries)) {
|
|
4162
|
+
const commandName = `[${dictionary.commandName ?? dictionary.command?.toString(16).padEnd(2, "0").toUpperCase()}:`;
|
|
4163
|
+
let cmdIx;
|
|
4164
|
+
while ((cmdIx = str.indexOf(commandName)) >= 0) {
|
|
4165
|
+
const endIx = str.indexOf("]", cmdIx);
|
|
4166
|
+
const strIx = parseInt(str.substring(cmdIx + commandName.length, endIx), 16);
|
|
4167
|
+
const newText = dictionary.entries[strIx];
|
|
4168
|
+
str = str.substring(0, cmdIx) + newText + str.substring(endIx + 1);
|
|
4169
|
+
}
|
|
4170
|
+
}
|
|
4171
|
+
str = str.replace(/\[--\]/g, "");
|
|
4144
4172
|
const sizeParam = stringObj.fixedSize ? `(${stringObj.fixedSize})` : "";
|
|
4145
4173
|
return [`${refChar}${str}${refChar}${sizeParam}`];
|
|
4146
4174
|
}
|
|
@@ -4225,8 +4253,8 @@ var RomLayout = class RomLayout {
|
|
|
4225
4253
|
return parseInt(a.name.substring(a.name.length - 2, a.name.length), 16) - parseInt(b.name.substring(b.name.length - 2, b.name.length), 16);
|
|
4226
4254
|
}) : [];
|
|
4227
4255
|
this.unmatchedFiles = files.filter((x) => (x.size || 0) > 0).filter((x) => this.sfxPackType === "Individual" || x.type.type !== "Sound").sort((a, b) => {
|
|
4228
|
-
const aAsm = a.
|
|
4229
|
-
const bAsm = b.
|
|
4256
|
+
const aAsm = a.rawData ? 1 : 0;
|
|
4257
|
+
const bAsm = b.rawData ? 1 : 0;
|
|
4230
4258
|
if (aAsm !== bAsm) return aAsm - bAsm;
|
|
4231
4259
|
if (b.size !== a.size) return b.size - a.size;
|
|
4232
4260
|
if (a.location !== b.location) return a.location - b.location;
|
|
@@ -4276,7 +4304,7 @@ var RomLayout = class RomLayout {
|
|
|
4276
4304
|
start += RomProcessingConstants.PAGE_SIZE;
|
|
4277
4305
|
page++;
|
|
4278
4306
|
if (offset) {
|
|
4279
|
-
const newFile = new ChunkFile(
|
|
4307
|
+
const newFile = new ChunkFile(Object.values(this.root.fileTypes).find((x) => x.type === BinType.Binary), file.name + "_2", file.size, file.location);
|
|
4280
4308
|
const end = file.rawData.length - offset;
|
|
4281
4309
|
newFile.rawData = file.rawData.slice(end);
|
|
4282
4310
|
newFile.size = newFile.rawData.length;
|
|
@@ -4366,106 +4394,13 @@ var RomLayout = class RomLayout {
|
|
|
4366
4394
|
}
|
|
4367
4395
|
};
|
|
4368
4396
|
|
|
4369
|
-
//#endregion
|
|
4370
|
-
//#region src/rom/rebuild/processor.ts
|
|
4371
|
-
/**
|
|
4372
|
-
* ROM rebuild processor
|
|
4373
|
-
* Converted from ext/GaiaLib/Rom/Rebuild/RomProcessor.cs
|
|
4374
|
-
*/
|
|
4375
|
-
var RomProcessor = class RomProcessor {
|
|
4376
|
-
writer;
|
|
4377
|
-
constructor(writer) {
|
|
4378
|
-
this.writer = writer;
|
|
4379
|
-
}
|
|
4380
|
-
async repack(allFiles) {
|
|
4381
|
-
const patches = [];
|
|
4382
|
-
const asmFiles = [];
|
|
4383
|
-
const compression = this.writer.root.compression;
|
|
4384
|
-
const canCompress = !!compression;
|
|
4385
|
-
const conditionFiles = [];
|
|
4386
|
-
for (const file of allFiles) {
|
|
4387
|
-
if (file.type.type === "Patch") patches.push(file);
|
|
4388
|
-
else if (file.type.type !== "Assembly") {
|
|
4389
|
-
if (file.compressed === true && canCompress) if (this.writer.root.config.uncompress) file.compressed = false;
|
|
4390
|
-
else {
|
|
4391
|
-
let newData = compression.compact(file.rawData, file.type.header);
|
|
4392
|
-
if (file.type.header) newData = new Uint8Array([...file.rawData.slice(0, file.type.header), ...newData]);
|
|
4393
|
-
file.rawData = newData;
|
|
4394
|
-
file.size = newData.length;
|
|
4395
|
-
}
|
|
4396
|
-
continue;
|
|
4397
|
-
}
|
|
4398
|
-
asmFiles.push(file);
|
|
4399
|
-
conditionFiles.push(file.name);
|
|
4400
|
-
}
|
|
4401
|
-
for (const file of asmFiles) {
|
|
4402
|
-
const { blocks, includes, reqBank } = new Assembler(this.writer.root, file.textData, conditionFiles).parseAssembly();
|
|
4403
|
-
file.parts = blocks;
|
|
4404
|
-
file.includes = includes;
|
|
4405
|
-
file.bank = reqBank ?? void 0;
|
|
4406
|
-
}
|
|
4407
|
-
RomProcessor.applyPatches(asmFiles, patches);
|
|
4408
|
-
for (const file of allFiles) ChunkFileUtils.calculateSize(file);
|
|
4409
|
-
const pages = new RomLayout(allFiles, this.writer.root).organize();
|
|
4410
|
-
for (const file of asmFiles) ChunkFileUtils.rebase(file);
|
|
4411
|
-
const masterLookup = /* @__PURE__ */ new Map();
|
|
4412
|
-
for (const f of asmFiles) {
|
|
4413
|
-
const includeBlocks = asmFiles.filter((x) => f.includes?.has(x.name.toUpperCase())).flatMap((x) => x.parts).filter((b) => !!b.label);
|
|
4414
|
-
f.includeLookup = /* @__PURE__ */ new Map();
|
|
4415
|
-
for (const b of includeBlocks) if (b.label) f.includeLookup.set(b.label.toUpperCase(), b);
|
|
4416
|
-
for (const b of f.parts) if (b.label) {
|
|
4417
|
-
const nameUpper = b.label.toUpperCase();
|
|
4418
|
-
masterLookup.set(nameUpper, b.location);
|
|
4419
|
-
f.includeLookup.set(nameUpper, b);
|
|
4420
|
-
}
|
|
4421
|
-
}
|
|
4422
|
-
const fileLookup = /* @__PURE__ */ new Map();
|
|
4423
|
-
for (const f of allFiles) fileLookup.set(f.name.toUpperCase(), f.location);
|
|
4424
|
-
this.writer.allocate(pages);
|
|
4425
|
-
for (const file of allFiles) await this.writer.writeFile(file, fileLookup);
|
|
4426
|
-
return masterLookup;
|
|
4427
|
-
}
|
|
4428
|
-
static applyPatches(asmFiles, patches) {
|
|
4429
|
-
for (const patch of patches.filter((x) => x.includes && x.includes.size > 0)) {
|
|
4430
|
-
let file = null;
|
|
4431
|
-
let dstIx = -1;
|
|
4432
|
-
const inc = asmFiles.filter((x) => patch.includes.has(x.name.toUpperCase()));
|
|
4433
|
-
for (let ix = 0; patch.parts && ix < patch.parts.length;) {
|
|
4434
|
-
const block = patch.parts[ix];
|
|
4435
|
-
let match = null;
|
|
4436
|
-
if (block.label) for (const i of inc) {
|
|
4437
|
-
if (!i.parts) continue;
|
|
4438
|
-
for (let y = 0; y < i.parts.length; y++) {
|
|
4439
|
-
const check = i.parts[y];
|
|
4440
|
-
if (check.label === block.label) {
|
|
4441
|
-
file = i;
|
|
4442
|
-
dstIx = y;
|
|
4443
|
-
match = check;
|
|
4444
|
-
break;
|
|
4445
|
-
}
|
|
4446
|
-
}
|
|
4447
|
-
}
|
|
4448
|
-
if (match) file.parts[dstIx++] = block;
|
|
4449
|
-
else if (dstIx >= 0) file.parts.splice(dstIx++, 0, block);
|
|
4450
|
-
else {
|
|
4451
|
-
ix++;
|
|
4452
|
-
continue;
|
|
4453
|
-
}
|
|
4454
|
-
file.includes = file.includes || /* @__PURE__ */ new Set();
|
|
4455
|
-
file.includes.add(patch.name.toUpperCase());
|
|
4456
|
-
patch.parts.splice(ix, 1);
|
|
4457
|
-
}
|
|
4458
|
-
}
|
|
4459
|
-
}
|
|
4460
|
-
};
|
|
4461
|
-
|
|
4462
4397
|
//#endregion
|
|
4463
4398
|
//#region src/rom/rebuild/writer.ts
|
|
4464
4399
|
/**
|
|
4465
4400
|
* ROM writer (binary)
|
|
4466
4401
|
* Converted from ext/GaiaLib/Rom/Rebuild/RomWriter.cs (subset: binary write only)
|
|
4467
4402
|
*/
|
|
4468
|
-
var RomWriter = class {
|
|
4403
|
+
var RomWriter = class RomWriter {
|
|
4469
4404
|
bpsPath;
|
|
4470
4405
|
outBuffer;
|
|
4471
4406
|
romSize;
|
|
@@ -4473,8 +4408,8 @@ var RomWriter = class {
|
|
|
4473
4408
|
constructor(root) {
|
|
4474
4409
|
this.root = root;
|
|
4475
4410
|
}
|
|
4476
|
-
async repack(files) {
|
|
4477
|
-
const masterLookup = await new RomProcessor(this).repack(files);
|
|
4411
|
+
async repack(files, modules) {
|
|
4412
|
+
const masterLookup = await new RomProcessor(this).repack(files, modules);
|
|
4478
4413
|
this.writeHeaders(masterLookup);
|
|
4479
4414
|
return this.outBuffer;
|
|
4480
4415
|
}
|
|
@@ -4620,7 +4555,7 @@ var RomWriter = class {
|
|
|
4620
4555
|
}
|
|
4621
4556
|
} else if (file.parts && file.parts.length > 0) {
|
|
4622
4557
|
if (file.parts[0].location !== file.location && (file.location || 0) !== 0) throw new Error("Assembly was not based properly");
|
|
4623
|
-
|
|
4558
|
+
RomWriter.parseAssembly(this.root, file.parts, fileLookup, file.includeLookup, this.outBuffer, void 0);
|
|
4624
4559
|
}
|
|
4625
4560
|
return pos - start;
|
|
4626
4561
|
}
|
|
@@ -4632,12 +4567,10 @@ var RomWriter = class {
|
|
|
4632
4567
|
* Parse assembly blocks and write binary data to output buffer
|
|
4633
4568
|
* Converted from ext/GaiaLib/Rom/Rebuild/RomWriter.cs ParseAssembly method
|
|
4634
4569
|
*/
|
|
4635
|
-
parseAssembly(blocks, fileLookup, includeLookup) {
|
|
4570
|
+
static parseAssembly(root, blocks, fileLookup, includeLookup, outBuffer, addrOffset) {
|
|
4636
4571
|
if (!blocks) throw new Error("Assembly has not been parsed");
|
|
4637
|
-
const buf = this.outBuffer;
|
|
4638
4572
|
let bix = 0;
|
|
4639
4573
|
for (const block of blocks) {
|
|
4640
|
-
let oldPos = null;
|
|
4641
4574
|
let position = block.location;
|
|
4642
4575
|
const objList = block.objList;
|
|
4643
4576
|
let oix = 0;
|
|
@@ -4652,13 +4585,13 @@ var RomWriter = class {
|
|
|
4652
4585
|
continue;
|
|
4653
4586
|
} else if (currentObj instanceof Op) {
|
|
4654
4587
|
const op = currentObj;
|
|
4655
|
-
|
|
4588
|
+
outBuffer[position++] = op.code & 255;
|
|
4656
4589
|
opos += op.size;
|
|
4657
4590
|
for (const operand of op.operands) processObject(operand, op);
|
|
4658
4591
|
break;
|
|
4659
4592
|
} else if (currentObj instanceof Uint8Array) {
|
|
4660
4593
|
const arr = currentObj;
|
|
4661
|
-
for (let i = 0; i < arr.length; i++)
|
|
4594
|
+
for (let i = 0; i < arr.length; i++) outBuffer[position + i] = arr[i];
|
|
4662
4595
|
position += arr.length;
|
|
4663
4596
|
opos += arr.length;
|
|
4664
4597
|
break;
|
|
@@ -4670,7 +4603,7 @@ var RomWriter = class {
|
|
|
4670
4603
|
if (ix > 0) label = label.substring(ix);
|
|
4671
4604
|
let loc;
|
|
4672
4605
|
const isRelative = parentOp && (parentOp.mode === "PCRelative" || parentOp.mode === "PCRelativeLong");
|
|
4673
|
-
const operatorIdx =
|
|
4606
|
+
const operatorIdx = RomWriter.indexOfAny(label, RomProcessingConstants.OPERATORS);
|
|
4674
4607
|
let offset = null;
|
|
4675
4608
|
let useMarker = false;
|
|
4676
4609
|
if (operatorIdx > 0) {
|
|
@@ -4719,12 +4652,13 @@ var RomWriter = class {
|
|
|
4719
4652
|
if (offset !== null) loc += offset;
|
|
4720
4653
|
else if (useMarker && target instanceof AsmBlock) {
|
|
4721
4654
|
let markerOffset = 0;
|
|
4722
|
-
for (const part of target.objList) if (
|
|
4655
|
+
for (const part of target.objList) if (RomWriter.isStringMarker(part)) {
|
|
4723
4656
|
loc += markerOffset;
|
|
4724
4657
|
break;
|
|
4725
4658
|
} else markerOffset += RomProcessingConstants.getSize(part);
|
|
4726
4659
|
}
|
|
4727
|
-
if (
|
|
4660
|
+
if (addrOffset !== void 0) loc += addrOffset;
|
|
4661
|
+
else if (!isRelative && type !== AddressType.Location) loc = Address.fromLocation(loc, root.config.memoryMode, root.config.cpuMode).toInt();
|
|
4728
4662
|
switch (type) {
|
|
4729
4663
|
case AddressType.Offset:
|
|
4730
4664
|
case AddressType.WRelative:
|
|
@@ -4749,7 +4683,7 @@ var RomWriter = class {
|
|
|
4749
4683
|
} else if (currentObj instanceof TypedNumber) {
|
|
4750
4684
|
let value = currentObj.value;
|
|
4751
4685
|
for (let i = 0; i < currentObj.size; i++) {
|
|
4752
|
-
|
|
4686
|
+
outBuffer[position++] = value & 255;
|
|
4753
4687
|
value >>= 8;
|
|
4754
4688
|
}
|
|
4755
4689
|
break;
|
|
@@ -4757,26 +4691,26 @@ var RomWriter = class {
|
|
|
4757
4691
|
const num = currentObj;
|
|
4758
4692
|
const size = parentOp?.size ?? 0;
|
|
4759
4693
|
if (num <= 255 && size <= 2) {
|
|
4760
|
-
|
|
4694
|
+
outBuffer[position] = num & 255;
|
|
4761
4695
|
position++;
|
|
4762
4696
|
} else if (num <= 65535 && size <= 3) {
|
|
4763
|
-
|
|
4764
|
-
|
|
4697
|
+
outBuffer[position] = num & 255;
|
|
4698
|
+
outBuffer[position + 1] = num >> 8 & 255;
|
|
4765
4699
|
position += 2;
|
|
4766
4700
|
} else if (num <= 16777215 && size <= 4) {
|
|
4767
|
-
|
|
4768
|
-
|
|
4769
|
-
|
|
4701
|
+
outBuffer[position] = num & 255;
|
|
4702
|
+
outBuffer[position + 1] = num >> 8 & 255;
|
|
4703
|
+
outBuffer[position + 2] = num >> 16 & 255;
|
|
4770
4704
|
position += 3;
|
|
4771
4705
|
} else {
|
|
4772
|
-
|
|
4773
|
-
|
|
4774
|
-
|
|
4775
|
-
|
|
4706
|
+
outBuffer[position] = num & 255;
|
|
4707
|
+
outBuffer[position + 1] = num >> 8 & 255;
|
|
4708
|
+
outBuffer[position + 2] = num >> 16 & 255;
|
|
4709
|
+
outBuffer[position + 3] = num >> 24 & 255;
|
|
4776
4710
|
position += 4;
|
|
4777
4711
|
}
|
|
4778
4712
|
break;
|
|
4779
|
-
} else if (
|
|
4713
|
+
} else if (RomWriter.isStringMarker(currentObj)) break;
|
|
4780
4714
|
else throw new Error(`Unable to process '${currentObj}'`);
|
|
4781
4715
|
};
|
|
4782
4716
|
for (const obj of objList) {
|
|
@@ -4789,21 +4723,121 @@ var RomWriter = class {
|
|
|
4789
4723
|
/**
|
|
4790
4724
|
* Helper method to find index of any character from an array in a string
|
|
4791
4725
|
*/
|
|
4792
|
-
indexOfAny(str, chars) {
|
|
4726
|
+
static indexOfAny(str, chars) {
|
|
4793
4727
|
for (let i = 0; i < str.length; i++) if (chars.includes(str[i])) return i;
|
|
4794
4728
|
return -1;
|
|
4795
4729
|
}
|
|
4796
4730
|
/**
|
|
4797
4731
|
* Helper method to check if an object is a StringMarker
|
|
4798
4732
|
*/
|
|
4799
|
-
isStringMarker(obj) {
|
|
4733
|
+
static isStringMarker(obj) {
|
|
4800
4734
|
return typeof obj === "object" && obj !== null && "offset" in obj;
|
|
4801
4735
|
}
|
|
4802
|
-
isTableEntry(obj) {
|
|
4736
|
+
static isTableEntry(obj) {
|
|
4803
4737
|
return typeof obj === "object" && obj !== null && "location" in obj && "object" in obj;
|
|
4804
4738
|
}
|
|
4805
4739
|
};
|
|
4806
4740
|
|
|
4741
|
+
//#endregion
|
|
4742
|
+
//#region src/rom/rebuild/processor.ts
|
|
4743
|
+
/**
|
|
4744
|
+
* ROM rebuild processor
|
|
4745
|
+
* Converted from ext/GaiaLib/Rom/Rebuild/RomProcessor.cs
|
|
4746
|
+
*/
|
|
4747
|
+
var RomProcessor = class RomProcessor {
|
|
4748
|
+
writer;
|
|
4749
|
+
constructor(writer) {
|
|
4750
|
+
this.writer = writer;
|
|
4751
|
+
}
|
|
4752
|
+
async repack(allFiles, modules) {
|
|
4753
|
+
const patches = [];
|
|
4754
|
+
const asmFiles = [];
|
|
4755
|
+
const compression = this.writer.root.compression;
|
|
4756
|
+
const canCompress = !!compression;
|
|
4757
|
+
const conditionFiles = [];
|
|
4758
|
+
if (modules) conditionFiles.push(...modules);
|
|
4759
|
+
const dummyMap = /* @__PURE__ */ new Map();
|
|
4760
|
+
for (const file of allFiles) {
|
|
4761
|
+
conditionFiles.push(file.name);
|
|
4762
|
+
if (file.type.isPatch) {
|
|
4763
|
+
patches.push(file);
|
|
4764
|
+
asmFiles.push(file);
|
|
4765
|
+
} else if (file.type.isBlock) asmFiles.push(file);
|
|
4766
|
+
else if (!file.type.struct) continue;
|
|
4767
|
+
const { blocks, includes, reqBank } = new Assembler(this.writer.root, file.textData, conditionFiles).parseAssembly();
|
|
4768
|
+
file.parts = blocks;
|
|
4769
|
+
file.includes = includes;
|
|
4770
|
+
file.bank = reqBank ?? void 0;
|
|
4771
|
+
if (file.type.struct) {
|
|
4772
|
+
file.includeLookup = /* @__PURE__ */ new Map();
|
|
4773
|
+
for (const b of file.parts) if (b.label) file.includeLookup.set(b.label.toUpperCase(), b);
|
|
4774
|
+
file.rawData = void 0;
|
|
4775
|
+
file.rawData = new Uint8Array(ChunkFileUtils.calculateSize(file));
|
|
4776
|
+
RomWriter.parseAssembly(this.writer.root, file.parts, dummyMap, file.includeLookup, file.rawData, file.type.base ?? 0);
|
|
4777
|
+
}
|
|
4778
|
+
}
|
|
4779
|
+
for (const file of allFiles) if (file.compressed === true && canCompress) if (this.writer.root.config.uncompress) file.compressed = false;
|
|
4780
|
+
else {
|
|
4781
|
+
let newData = compression.compact(file.rawData, file.type.header);
|
|
4782
|
+
if (file.type.header) newData = new Uint8Array([...file.rawData.slice(0, file.type.header), ...newData]);
|
|
4783
|
+
file.rawData = newData;
|
|
4784
|
+
file.size = newData.length;
|
|
4785
|
+
}
|
|
4786
|
+
RomProcessor.applyPatches(asmFiles, patches);
|
|
4787
|
+
for (const file of allFiles) ChunkFileUtils.calculateSize(file);
|
|
4788
|
+
const pages = new RomLayout(allFiles, this.writer.root).organize();
|
|
4789
|
+
for (const file of asmFiles) ChunkFileUtils.rebase(file);
|
|
4790
|
+
const masterLookup = /* @__PURE__ */ new Map();
|
|
4791
|
+
for (const f of asmFiles) {
|
|
4792
|
+
const includeBlocks = asmFiles.filter((x) => f.includes?.has(x.name.toUpperCase())).flatMap((x) => x.parts).filter((b) => !!b.label);
|
|
4793
|
+
f.includeLookup = /* @__PURE__ */ new Map();
|
|
4794
|
+
for (const b of includeBlocks) if (b.label) f.includeLookup.set(b.label.toUpperCase(), b);
|
|
4795
|
+
for (const b of f.parts) if (b.label) {
|
|
4796
|
+
const nameUpper = b.label.toUpperCase();
|
|
4797
|
+
masterLookup.set(nameUpper, b.location);
|
|
4798
|
+
f.includeLookup.set(nameUpper, b);
|
|
4799
|
+
}
|
|
4800
|
+
}
|
|
4801
|
+
const fileLookup = /* @__PURE__ */ new Map();
|
|
4802
|
+
for (const f of allFiles) fileLookup.set(f.name.toUpperCase(), f.location);
|
|
4803
|
+
this.writer.allocate(pages);
|
|
4804
|
+
for (const file of allFiles) await this.writer.writeFile(file, fileLookup);
|
|
4805
|
+
return masterLookup;
|
|
4806
|
+
}
|
|
4807
|
+
static applyPatches(asmFiles, patches) {
|
|
4808
|
+
for (const patch of patches.filter((x) => x.includes && x.includes.size > 0)) {
|
|
4809
|
+
let file = null;
|
|
4810
|
+
let dstIx = -1;
|
|
4811
|
+
const inc = asmFiles.filter((x) => patch.includes.has(x.name.toUpperCase()));
|
|
4812
|
+
for (let ix = 0; patch.parts && ix < patch.parts.length;) {
|
|
4813
|
+
const block = patch.parts[ix];
|
|
4814
|
+
let match = null;
|
|
4815
|
+
if (block.label) for (const i of inc) {
|
|
4816
|
+
if (!i.parts) continue;
|
|
4817
|
+
for (let y = 0; y < i.parts.length; y++) {
|
|
4818
|
+
const check = i.parts[y];
|
|
4819
|
+
if (check.label === block.label) {
|
|
4820
|
+
file = i;
|
|
4821
|
+
dstIx = y;
|
|
4822
|
+
match = check;
|
|
4823
|
+
break;
|
|
4824
|
+
}
|
|
4825
|
+
}
|
|
4826
|
+
}
|
|
4827
|
+
if (match) file.parts[dstIx++] = block;
|
|
4828
|
+
else if (dstIx >= 0) file.parts.splice(dstIx++, 0, block);
|
|
4829
|
+
else {
|
|
4830
|
+
ix++;
|
|
4831
|
+
continue;
|
|
4832
|
+
}
|
|
4833
|
+
file.includes = file.includes || /* @__PURE__ */ new Set();
|
|
4834
|
+
file.includes.add(patch.name.toUpperCase());
|
|
4835
|
+
patch.parts.splice(ix, 1);
|
|
4836
|
+
}
|
|
4837
|
+
}
|
|
4838
|
+
}
|
|
4839
|
+
};
|
|
4840
|
+
|
|
4807
4841
|
//#endregion
|
|
4808
4842
|
//#region src/rom/rebuild/string-processor.ts
|
|
4809
4843
|
/**
|
|
@@ -4962,7 +4996,6 @@ var StringProcessor = class {
|
|
|
4962
4996
|
break;
|
|
4963
4997
|
case MemberType.Offset:
|
|
4964
4998
|
case MemberType.Address:
|
|
4965
|
-
this.flushBuffer(stringType, false);
|
|
4966
4999
|
this.context.currentBlock.objList.push(parts[pix]);
|
|
4967
5000
|
this.context.currentBlock.size += cmd.types[y] === MemberType.Offset ? 2 : 3;
|
|
4968
5001
|
break;
|
|
@@ -5520,6 +5553,7 @@ var DbFile = class {
|
|
|
5520
5553
|
upper;
|
|
5521
5554
|
group;
|
|
5522
5555
|
scene;
|
|
5556
|
+
base;
|
|
5523
5557
|
constructor(data) {
|
|
5524
5558
|
if (!data.name) throw new Error("Name is required");
|
|
5525
5559
|
if (!data.type) throw new Error("Type is required");
|
|
@@ -5533,6 +5567,7 @@ var DbFile = class {
|
|
|
5533
5567
|
this.upper = data.upper ?? void 0;
|
|
5534
5568
|
this.group = data.group || void 0;
|
|
5535
5569
|
this.scene = data.scene || void 0;
|
|
5570
|
+
this.base = data.base ?? void 0;
|
|
5536
5571
|
}
|
|
5537
5572
|
};
|
|
5538
5573
|
var DbFileType = class {
|
|
@@ -5543,17 +5578,21 @@ var DbFileType = class {
|
|
|
5543
5578
|
isBlock;
|
|
5544
5579
|
header;
|
|
5545
5580
|
compressed;
|
|
5581
|
+
struct;
|
|
5582
|
+
base;
|
|
5546
5583
|
constructor(data) {
|
|
5547
|
-
|
|
5548
|
-
|
|
5549
|
-
|
|
5584
|
+
if (!data.name) throw new Error("Name is required");
|
|
5585
|
+
if (!data.extension) throw new Error("Extension is required");
|
|
5586
|
+
if (!data.type) throw new Error("Type is required");
|
|
5587
|
+
this.name = data.name;
|
|
5588
|
+
this.extension = data.extension;
|
|
5589
|
+
this.type = data.type;
|
|
5550
5590
|
this.isPatch = data.isPatch ?? false;
|
|
5551
5591
|
this.isBlock = data.isBlock ?? false;
|
|
5552
5592
|
this.header = data.header ?? 0;
|
|
5553
5593
|
this.compressed = data.compressed ?? void 0;
|
|
5554
|
-
|
|
5555
|
-
|
|
5556
|
-
if (!this.type) throw new Error("Type is required");
|
|
5594
|
+
this.struct = data.struct ?? void 0;
|
|
5595
|
+
this.base = data.base ?? void 0;
|
|
5557
5596
|
}
|
|
5558
5597
|
};
|
|
5559
5598
|
|
|
@@ -5629,21 +5668,18 @@ var DbStringCommand = class {
|
|
|
5629
5668
|
}
|
|
5630
5669
|
};
|
|
5631
5670
|
var DbStringDictionary = class {
|
|
5632
|
-
base;
|
|
5633
|
-
range;
|
|
5634
5671
|
command;
|
|
5672
|
+
commandName;
|
|
5635
5673
|
name;
|
|
5636
5674
|
entries;
|
|
5637
5675
|
constructor(data) {
|
|
5638
|
-
if (typeof data.
|
|
5676
|
+
if (typeof data.command !== "number") throw new Error("Command is required");
|
|
5639
5677
|
if (!data.name) throw new Error("Name is required");
|
|
5640
5678
|
if (!data.entries || data.entries.length === 0) throw new Error("Entries is required");
|
|
5641
|
-
this.base = data.base ?? void 0;
|
|
5642
|
-
this.range = data.range ?? 0;
|
|
5643
5679
|
this.command = data.command ?? void 0;
|
|
5680
|
+
this.commandName = data.commandName ?? void 0;
|
|
5644
5681
|
this.name = data.name;
|
|
5645
5682
|
this.entries = data.entries;
|
|
5646
|
-
if (this.base !== void 0) this.range = this.base + this.entries.length;
|
|
5647
5683
|
}
|
|
5648
5684
|
};
|
|
5649
5685
|
/**
|
|
@@ -5678,7 +5714,7 @@ var DbStringType = class {
|
|
|
5678
5714
|
}, {});
|
|
5679
5715
|
this.dictionaryLookup = Object.values(this.dictionaries).flatMap((y) => y.entries.map((z, ix) => ({
|
|
5680
5716
|
text: z,
|
|
5681
|
-
id: (y.command ?? 0) << 8 |
|
|
5717
|
+
id: (y.command ?? 0) << 8 | ix
|
|
5682
5718
|
}))).sort((a, b) => b.text.length - a.text.length);
|
|
5683
5719
|
}
|
|
5684
5720
|
};
|
|
@@ -6085,7 +6121,7 @@ var DbRootUtils = class {
|
|
|
6085
6121
|
const cfg = module.config;
|
|
6086
6122
|
const compression = cfg.compression ? CompressionAlgorithms[cfg.compression]() : void 0;
|
|
6087
6123
|
const baseRomChunks = module.baseRomFiles ?? module.supaBaseRomFiles?.map((file) => {
|
|
6088
|
-
const chunkFile = new ChunkFile(file.
|
|
6124
|
+
const chunkFile = new ChunkFile(fileTypeLookup[file.type], file.name);
|
|
6089
6125
|
if (file.isText) {
|
|
6090
6126
|
chunkFile.textData = file.text ?? void 0;
|
|
6091
6127
|
chunkFile.size = file.text?.length ?? 0;
|
|
@@ -6096,7 +6132,7 @@ var DbRootUtils = class {
|
|
|
6096
6132
|
return chunkFile;
|
|
6097
6133
|
});
|
|
6098
6134
|
const projectChunks = module.projectFiles ?? module.supaProjectFiles?.map((file) => {
|
|
6099
|
-
const chunkFile = new ChunkFile(file.
|
|
6135
|
+
const chunkFile = new ChunkFile(fileTypeLookup[file.type], file.name);
|
|
6100
6136
|
chunkFile.group = file.module ?? void 0;
|
|
6101
6137
|
if (file.isText) {
|
|
6102
6138
|
chunkFile.textData = file.text ?? void 0;
|
|
@@ -6140,7 +6176,7 @@ var DbRootUtils = class {
|
|
|
6140
6176
|
projectFiles: projectChunks
|
|
6141
6177
|
};
|
|
6142
6178
|
}
|
|
6143
|
-
static async applyFolder(root, folderPath, sourceFiles = []) {
|
|
6179
|
+
static async applyFolder(root, folderPath, sourceFiles = [], group) {
|
|
6144
6180
|
const chunkFiles = sourceFiles;
|
|
6145
6181
|
const folderEntries = await listDirectory(folderPath, { recursive: true });
|
|
6146
6182
|
for (const entry of folderEntries) {
|
|
@@ -6148,8 +6184,9 @@ var DbRootUtils = class {
|
|
|
6148
6184
|
const type = root.fileExtLookup[entry.extension];
|
|
6149
6185
|
if (!type) continue;
|
|
6150
6186
|
const existing = chunkFiles.find((x) => x.name === entry.name && x.type.type === type.type);
|
|
6151
|
-
const chunkFile = existing ?? new ChunkFile(entry.name
|
|
6152
|
-
if (
|
|
6187
|
+
const chunkFile = existing ?? new ChunkFile(type, entry.name);
|
|
6188
|
+
if (group) chunkFile.group = group;
|
|
6189
|
+
if (chunkFile.type.isBlock || chunkFile.type.isPatch || chunkFile.type.struct) {
|
|
6153
6190
|
const chunkData = await readFileAsText(entry.path);
|
|
6154
6191
|
chunkFile.textData = chunkData;
|
|
6155
6192
|
chunkFile.size = chunkData.length;
|
|
@@ -6178,7 +6215,7 @@ var DbRootUtils = class {
|
|
|
6178
6215
|
const ext = block.type.extension;
|
|
6179
6216
|
const filePath = `${outPath}/${block.group ? block.group + "/" : ""}${block.scene ? block.scene + "/" : ""}${block.name}${ext ? "." + ext : ""}`;
|
|
6180
6217
|
if (block.parts?.length) {
|
|
6181
|
-
|
|
6218
|
+
block.textData = writer.generateAsm(block);
|
|
6182
6219
|
await saveFileAsText(filePath, block.textData);
|
|
6183
6220
|
} else {
|
|
6184
6221
|
if (!block.rawData) continue;
|
|
@@ -7096,6 +7133,7 @@ async function summaryFromSupabaseByProject(projectName) {
|
|
|
7096
7133
|
notes,
|
|
7097
7134
|
gameRomId,
|
|
7098
7135
|
platformBranchId,
|
|
7136
|
+
fileTypes,
|
|
7099
7137
|
createdAt,
|
|
7100
7138
|
updatedAt,
|
|
7101
7139
|
gameRom:GameRom!inner(
|
|
@@ -7179,6 +7217,20 @@ var RomGenerator = class {
|
|
|
7179
7217
|
this.projectName = projectName;
|
|
7180
7218
|
this.crc = crc;
|
|
7181
7219
|
}
|
|
7220
|
+
async validateAndLoad(sourceData, gameModule, baseRomPath, modulePath) {
|
|
7221
|
+
const calc = crc32_buffer(sourceData);
|
|
7222
|
+
if (this.crc !== calc) return false;
|
|
7223
|
+
this.dbRoot = DbRootUtils.fromGameModule(gameModule);
|
|
7224
|
+
let moduleFiles = [];
|
|
7225
|
+
for (const entry of await listDirectory(modulePath)) {
|
|
7226
|
+
if (!entry.isDirectory) continue;
|
|
7227
|
+
moduleFiles.push(...await DbRootUtils.applyFolder(this.dbRoot, entry.path, [], entry.name));
|
|
7228
|
+
}
|
|
7229
|
+
this.dbRoot.baseRomFiles = await DbRootUtils.applyFolder(this.dbRoot, baseRomPath);
|
|
7230
|
+
this.dbRoot.projectFiles = moduleFiles;
|
|
7231
|
+
this.sourceData = sourceData;
|
|
7232
|
+
return true;
|
|
7233
|
+
}
|
|
7182
7234
|
async validateAndDownload(sourceData) {
|
|
7183
7235
|
const calc = crc32_buffer(sourceData);
|
|
7184
7236
|
if (this.crc !== calc) return false;
|
|
@@ -7192,16 +7244,16 @@ var RomGenerator = class {
|
|
|
7192
7244
|
if (!this.sourceData) throw new Error("Source data not initialized");
|
|
7193
7245
|
const reader = new BlockReader(this.sourceData, this.dbRoot);
|
|
7194
7246
|
const chunkFiles = reader.analyzeAndResolve();
|
|
7195
|
-
const asmFiles = chunkFiles.filter((b) => b.type.
|
|
7247
|
+
const asmFiles = chunkFiles.filter((b) => b.type.isBlock);
|
|
7196
7248
|
const patchFiles = [];
|
|
7197
7249
|
const writer = new BlockWriter(reader);
|
|
7198
|
-
for (const block of
|
|
7250
|
+
for (const block of chunkFiles) if (block.parts?.length) block.textData = writer.generateAsm(block);
|
|
7199
7251
|
for (const chunkFile of this.dbRoot.baseRomFiles) this.applyPatchFile(chunkFile, chunkFiles, asmFiles, patchFiles);
|
|
7200
7252
|
const moduleLookup = this.applyProjectInit(chunkFiles, asmFiles, patchFiles);
|
|
7201
7253
|
if (unshiftManualFiles) for (const file of manualFiles ?? []) this.applyPatchFile(file, chunkFiles, asmFiles, patchFiles);
|
|
7202
7254
|
for (const module of modules) for (const file of moduleLookup.get(module)) this.applyPatchFile(file, chunkFiles, asmFiles, patchFiles);
|
|
7203
7255
|
if (!unshiftManualFiles) for (const file of manualFiles ?? []) this.applyPatchFile(file, chunkFiles, asmFiles, patchFiles);
|
|
7204
|
-
return await new RomWriter(this.dbRoot).repack(chunkFiles);
|
|
7256
|
+
return await new RomWriter(this.dbRoot).repack(chunkFiles, modules);
|
|
7205
7257
|
}
|
|
7206
7258
|
applyProjectInit(chunkFiles, asmFiles, patchFiles) {
|
|
7207
7259
|
const moduleLookup = /* @__PURE__ */ new Map();
|
|
@@ -7220,7 +7272,7 @@ var RomGenerator = class {
|
|
|
7220
7272
|
const existing = chunkFiles.find((x) => x.name === chunkFile.name);
|
|
7221
7273
|
if (chunkFile.textData) if (existing) existing.textData = chunkFile.textData;
|
|
7222
7274
|
else {
|
|
7223
|
-
if (chunkFile.type.
|
|
7275
|
+
if (chunkFile.type.isPatch) patchFiles.push(chunkFile);
|
|
7224
7276
|
asmFiles.push(chunkFile);
|
|
7225
7277
|
chunkFiles.push(chunkFile);
|
|
7226
7278
|
}
|
|
@@ -7555,11 +7607,10 @@ exports.base64ToUint8Array = base64ToUint8Array;
|
|
|
7555
7607
|
exports.binaryToUtf8String = binaryToUtf8String;
|
|
7556
7608
|
exports.bytesToHex = bytesToHex;
|
|
7557
7609
|
exports.clamp = clamp;
|
|
7610
|
+
exports.combineHeader = combineHeader;
|
|
7558
7611
|
exports.crc32_buffer = crc32_buffer;
|
|
7559
7612
|
exports.crc32_text_utf16 = crc32_text_utf16;
|
|
7560
7613
|
exports.crc32_text_utf8 = crc32_text_utf8;
|
|
7561
|
-
exports.createChunkFileFromDbBlock = createChunkFileFromDbBlock;
|
|
7562
|
-
exports.createChunkFileFromDbFile = createChunkFileFromDbFile;
|
|
7563
7614
|
exports.createDbPath = createDbPath;
|
|
7564
7615
|
exports.createSupabaseClient = createSupabaseClient;
|
|
7565
7616
|
exports.createTempDirectory = createTempDirectory;
|