@gaialabs/core 0.2.12 → 0.2.14
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 +346 -277
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +840 -823
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +840 -823
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +346 -276
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -935,10 +935,12 @@ var ProcessorStateManager = class {
|
|
|
935
935
|
var RomDataReader = class {
|
|
936
936
|
romData;
|
|
937
937
|
position;
|
|
938
|
-
|
|
938
|
+
offset;
|
|
939
|
+
constructor(romData, offset = 0) {
|
|
939
940
|
if (!romData) throw new Error("romData cannot be null");
|
|
940
941
|
this.romData = romData;
|
|
941
942
|
this.position = 0;
|
|
943
|
+
this.offset = offset;
|
|
942
944
|
}
|
|
943
945
|
readByte() {
|
|
944
946
|
return this.romData[this.position++];
|
|
@@ -1096,7 +1098,7 @@ var RomProcessingConstants = class RomProcessingConstants {
|
|
|
1096
1098
|
* BlockReader specific constants
|
|
1097
1099
|
*/
|
|
1098
1100
|
var BlockReaderConstants = class {
|
|
1099
|
-
static REF_SEARCH_MAX_RANGE =
|
|
1101
|
+
static REF_SEARCH_MAX_RANGE = 896;
|
|
1100
1102
|
static BANK_MASK_CHECK = 64;
|
|
1101
1103
|
static BYTE_DELIMITER_THRESHOLD = 256;
|
|
1102
1104
|
static BANK_HIGH_MEMORY_1 = 126;
|
|
@@ -1670,31 +1672,63 @@ var ChunkFile = class {
|
|
|
1670
1672
|
mnemonics;
|
|
1671
1673
|
group;
|
|
1672
1674
|
scene;
|
|
1673
|
-
|
|
1675
|
+
base;
|
|
1676
|
+
referenceManager;
|
|
1677
|
+
constructor(type, name, size = 0, location = 0) {
|
|
1678
|
+
this.type = type;
|
|
1674
1679
|
this.name = name;
|
|
1675
1680
|
this.size = size;
|
|
1676
1681
|
this.location = location;
|
|
1677
1682
|
this.mnemonics = {};
|
|
1678
1683
|
this.compressed = type.compressed;
|
|
1679
|
-
|
|
1684
|
+
}
|
|
1685
|
+
enrichWithRawDataFromDbFile(file, rom, compression) {
|
|
1686
|
+
this.upper = file.upper ?? this.upper;
|
|
1687
|
+
this.size = file.end - file.start;
|
|
1688
|
+
this.location = file.start;
|
|
1689
|
+
this.base = file.base ?? this.type.base ?? this.base;
|
|
1690
|
+
this.group = file.group ?? this.group;
|
|
1691
|
+
this.scene = file.scene ?? this.scene;
|
|
1692
|
+
this.compressed = file.compressed;
|
|
1693
|
+
let start = this.location;
|
|
1694
|
+
let header = null;
|
|
1695
|
+
const fileType = this.type;
|
|
1696
|
+
if (fileType.header) {
|
|
1697
|
+
header = new Uint8Array(rom.slice(start, start + fileType.header));
|
|
1698
|
+
start += fileType.header;
|
|
1699
|
+
}
|
|
1700
|
+
let length = this.size;
|
|
1701
|
+
let fileData;
|
|
1702
|
+
if (this.compressed === true && compression) {
|
|
1703
|
+
const expanded = compression.expand(rom, start, length);
|
|
1704
|
+
fileData = combineHeader(expanded, 0, expanded.length, header, fileType.type);
|
|
1705
|
+
} else {
|
|
1706
|
+
if (this.compressed !== void 0) {
|
|
1707
|
+
start += 2;
|
|
1708
|
+
length -= 2;
|
|
1709
|
+
}
|
|
1710
|
+
fileData = combineHeader(rom, start, length, header, fileType.type);
|
|
1711
|
+
}
|
|
1712
|
+
this.rawData = fileData;
|
|
1713
|
+
this.size = fileData.length;
|
|
1714
|
+
}
|
|
1715
|
+
enrichWithAsmBlocksFromDbBlock(block, memoryMode) {
|
|
1716
|
+
this.group = block.group;
|
|
1717
|
+
this.scene = block.scene;
|
|
1718
|
+
this.parts = [];
|
|
1719
|
+
this.size = 0;
|
|
1720
|
+
if (!block.parts?.length) throw new Error(`Block ${block.name} has no parts`);
|
|
1721
|
+
this.location = block.parts[0].start;
|
|
1722
|
+
this.bank = block.movable ? void 0 : memoryMode === MemoryMapMode.Lo ? this.location >> 15 : this.location >> 16;
|
|
1723
|
+
this.transforms = block.transforms;
|
|
1724
|
+
this.postProcess = block.postProcess;
|
|
1725
|
+
for (const part of block.parts) {
|
|
1726
|
+
const asmBlock = new AsmBlock(part.start, part.end - part.start, false, part.name, part.type || void 0, part.bank);
|
|
1727
|
+
this.size += asmBlock.size;
|
|
1728
|
+
this.parts.push(asmBlock);
|
|
1729
|
+
}
|
|
1680
1730
|
}
|
|
1681
1731
|
};
|
|
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
1732
|
function combineHeader(data, position, length, header, type) {
|
|
1699
1733
|
let totalLength = length + (header ? header.length : 0);
|
|
1700
1734
|
if (type === BinType.Palette && length < 512) totalLength += 512 - length;
|
|
@@ -1710,48 +1744,6 @@ function combineHeader(data, position, length, header, type) {
|
|
|
1710
1744
|
return result;
|
|
1711
1745
|
}
|
|
1712
1746
|
/**
|
|
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
1747
|
* Chunk file utilities
|
|
1756
1748
|
*/
|
|
1757
1749
|
var ChunkFileUtils = class {
|
|
@@ -1773,16 +1765,11 @@ var ChunkFileUtils = class {
|
|
|
1773
1765
|
* Calculate the total size of all blocks
|
|
1774
1766
|
*/
|
|
1775
1767
|
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
1768
|
let size = 0;
|
|
1785
|
-
|
|
1769
|
+
if (chunkFile.rawData) {
|
|
1770
|
+
size = chunkFile.rawData.length;
|
|
1771
|
+
if (chunkFile.type.header === -2 || chunkFile.compressed === false) size += 2;
|
|
1772
|
+
} else if (chunkFile.parts) for (let x = 0; x < chunkFile.parts.length; x++) {
|
|
1786
1773
|
const block = chunkFile.parts[x];
|
|
1787
1774
|
if (x > 0 && !block.label) break;
|
|
1788
1775
|
size += block.size || 0;
|
|
@@ -1801,7 +1788,7 @@ var ChunkFileUtils = class {
|
|
|
1801
1788
|
block,
|
|
1802
1789
|
part
|
|
1803
1790
|
];
|
|
1804
|
-
for (const otherBlock of root) if (otherBlock !== block) {
|
|
1791
|
+
for (const otherBlock of root) if (otherBlock !== block && !otherBlock.type.struct) {
|
|
1805
1792
|
const [otherIsInside, otherPart] = this.isInsideWithPart(otherBlock, location);
|
|
1806
1793
|
if (otherIsInside) return [
|
|
1807
1794
|
true,
|
|
@@ -1938,6 +1925,7 @@ var ReferenceManager = class {
|
|
|
1938
1925
|
structTable = /* @__PURE__ */ new Map();
|
|
1939
1926
|
markerTable = /* @__PURE__ */ new Map();
|
|
1940
1927
|
nameTable = /* @__PURE__ */ new Map();
|
|
1928
|
+
fileTable = /* @__PURE__ */ new Map();
|
|
1941
1929
|
root;
|
|
1942
1930
|
constructor(root) {
|
|
1943
1931
|
if (!root) throw new Error("root cannot be null");
|
|
@@ -2007,7 +1995,7 @@ var ReferenceManager = class {
|
|
|
2007
1995
|
}
|
|
2008
1996
|
resolveName(location, type, isBranch) {
|
|
2009
1997
|
const prefix = Address.codeFromType(type);
|
|
2010
|
-
let name;
|
|
1998
|
+
let name = null;
|
|
2011
1999
|
let label = null;
|
|
2012
2000
|
let resolvedLocation = location;
|
|
2013
2001
|
const rewrite = this.root.rewrites[location];
|
|
@@ -2016,9 +2004,8 @@ var ReferenceManager = class {
|
|
|
2016
2004
|
resolvedLocation = result.location;
|
|
2017
2005
|
label = result.label;
|
|
2018
2006
|
}
|
|
2019
|
-
|
|
2020
|
-
if (
|
|
2021
|
-
else name = isBranch ? this.createBranchLabel(resolvedLocation) : this.findClosestReference(resolvedLocation) || this.createFallbackName(resolvedLocation);
|
|
2007
|
+
name = this.nameTable.get(resolvedLocation) || null;
|
|
2008
|
+
if (!name) name = isBranch ? this.createBranchLabel(resolvedLocation) : this.findClosestReference(resolvedLocation) || this.createFallbackName(resolvedLocation);
|
|
2022
2009
|
return `${prefix || ""}${name}${label || ""}`;
|
|
2023
2010
|
}
|
|
2024
2011
|
findClosestReference(location) {
|
|
@@ -2120,6 +2107,10 @@ var StackOperations = class {
|
|
|
2120
2107
|
case "XBA":
|
|
2121
2108
|
this.handleExchangeBytes();
|
|
2122
2109
|
break;
|
|
2110
|
+
case "RTL":
|
|
2111
|
+
case "RTS":
|
|
2112
|
+
this._blockReader._referenceManager.tryAddStruct(this._blockReader._romDataReader.position, "Code");
|
|
2113
|
+
break;
|
|
2123
2114
|
}
|
|
2124
2115
|
}
|
|
2125
2116
|
handleAccumulatorPush() {
|
|
@@ -2169,7 +2160,16 @@ var CopCommandProcessor = class {
|
|
|
2169
2160
|
* Parses a COP command based on its definition
|
|
2170
2161
|
*/
|
|
2171
2162
|
parseCopCommand(copDef, operands) {
|
|
2172
|
-
|
|
2163
|
+
let parts = copDef.parts;
|
|
2164
|
+
if (copDef.conditions) for (const condition of copDef.conditions) {
|
|
2165
|
+
let value = this._romDataReader.romData[this._romDataReader.position + condition.offset];
|
|
2166
|
+
if (condition.value >= 256) value |= this._romDataReader.romData[this._romDataReader.position + condition.offset + 1] << 8;
|
|
2167
|
+
if (value === condition.value) {
|
|
2168
|
+
parts = condition.parts;
|
|
2169
|
+
break;
|
|
2170
|
+
}
|
|
2171
|
+
}
|
|
2172
|
+
for (let partStr of parts) {
|
|
2173
2173
|
let bank = null;
|
|
2174
2174
|
const bankHintIx = partStr.indexOf("$");
|
|
2175
2175
|
if (bankHintIx > 0) {
|
|
@@ -2352,6 +2352,7 @@ var AddressingModeHandler = class {
|
|
|
2352
2352
|
if (address.isROM) {
|
|
2353
2353
|
const wrapper = new LocationWrapper(address.toLocation(), AddressType.Address);
|
|
2354
2354
|
if (this.isJumpInstruction(mnemonic)) this._blockReader.noteType(wrapper.location, "Code", false, reg);
|
|
2355
|
+
if (mnemonic === "JML") this._blockReader._referenceManager.tryAddStruct(this._dataReader.position, "Code");
|
|
2355
2356
|
operands.push(wrapper);
|
|
2356
2357
|
} else operands.push(address);
|
|
2357
2358
|
}
|
|
@@ -2390,12 +2391,13 @@ var AddressingModeHandler = class {
|
|
|
2390
2391
|
const isPush = this.isPushInstruction(mnemonic);
|
|
2391
2392
|
if (isPush) refLoc++;
|
|
2392
2393
|
const isJump = isPush || isIndexedIndirect || this.isJumpInstruction(mnemonic);
|
|
2393
|
-
const addr = new Address(xBank1 ?? (isJump ? Address.resolveBank(this._dataReader.position, registers.mode) : dataBank) ?? 129, refLoc, registers.mode);
|
|
2394
|
+
const addr = new Address(xBank1 ?? (isJump ? Address.resolveBank(this._dataReader.position, registers.mode) : dataBank) ?? this._blockReader._root.config.defaultBank ?? 129, refLoc, registers.mode);
|
|
2394
2395
|
if (addr.isROM) {
|
|
2395
2396
|
const wrapper = new LocationWrapper(addr.toLocation(), AddressType.Offset);
|
|
2396
2397
|
if (isJump) {
|
|
2397
2398
|
const type = isIndexedIndirect ? "&Code" : "Code";
|
|
2398
2399
|
const name = this._blockReader.noteType(wrapper.location, type, isPush, registers);
|
|
2400
|
+
if (mnemonic === "JMP") this._blockReader._referenceManager.tryAddStruct(this._dataReader.position, "Code");
|
|
2399
2401
|
if (isPush) {
|
|
2400
2402
|
operands.push(`&${name}-1`);
|
|
2401
2403
|
return;
|
|
@@ -3030,10 +3032,11 @@ var StringReader = class StringReader {
|
|
|
3030
3032
|
}
|
|
3031
3033
|
parseString(stringType, fixedSize) {
|
|
3032
3034
|
const commands = stringType.commandLookup;
|
|
3033
|
-
stringType.dictionaries;
|
|
3035
|
+
const dictionaries = stringType.dictionaries;
|
|
3034
3036
|
const builder = [];
|
|
3035
3037
|
const strLoc = this._romDataReader.position;
|
|
3036
3038
|
const terminator = stringType.terminator;
|
|
3039
|
+
const modifiers = stringType.modifiers;
|
|
3037
3040
|
let currentLayer = stringType.layers[0];
|
|
3038
3041
|
do {
|
|
3039
3042
|
const c = this._romDataReader.readByte();
|
|
@@ -3041,23 +3044,35 @@ var StringReader = class StringReader {
|
|
|
3041
3044
|
if (stringType.greedyTerminator) while (this._romDataReader.peekByte() === terminator && this._blockReader.partCanContinue()) this._romDataReader.position++;
|
|
3042
3045
|
break;
|
|
3043
3046
|
}
|
|
3044
|
-
|
|
3045
|
-
|
|
3047
|
+
let cmd = void 0;
|
|
3048
|
+
const mod = modifiers ? modifiers[c] : void 0;
|
|
3049
|
+
if (mod) {
|
|
3050
|
+
const next = mod[builder[builder.length - 1]];
|
|
3051
|
+
if (next) builder[builder.length - 1] = next;
|
|
3052
|
+
else builder.push(currentLayer.map[c - (currentLayer.base ?? 0)]);
|
|
3053
|
+
} else if (cmd = commands[c]) {
|
|
3046
3054
|
this.resolveCommand(cmd, builder);
|
|
3047
3055
|
if (cmd.halt) break;
|
|
3048
3056
|
} else {
|
|
3049
3057
|
let found = false;
|
|
3050
|
-
for (const
|
|
3051
|
-
|
|
3052
|
-
|
|
3053
|
-
|
|
3058
|
+
for (const dictionary of Object.values(dictionaries)) if (dictionary.base !== void 0 && c >= dictionary.base && c <= dictionary.base + dictionary.entries.length) {
|
|
3059
|
+
builder.push(dictionary.entries[c - dictionary.base]);
|
|
3060
|
+
found = true;
|
|
3061
|
+
break;
|
|
3062
|
+
}
|
|
3063
|
+
if (!found) {
|
|
3064
|
+
for (const layer of stringType.layers) if (layer.on !== void 0) {
|
|
3065
|
+
if (c === layer.on) {
|
|
3066
|
+
currentLayer = layer;
|
|
3067
|
+
builder.push("[--]");
|
|
3068
|
+
found = true;
|
|
3069
|
+
break;
|
|
3070
|
+
}
|
|
3071
|
+
} else if (layer.base && c >= layer.base && c < layer.base + layer.map.length) {
|
|
3072
|
+
builder.push(layer.map[c - layer.base]);
|
|
3054
3073
|
found = true;
|
|
3055
3074
|
break;
|
|
3056
3075
|
}
|
|
3057
|
-
} else if (layer.base && c >= layer.base && c < layer.base + layer.map.length) {
|
|
3058
|
-
builder.push(layer.map[c - layer.base]);
|
|
3059
|
-
found = true;
|
|
3060
|
-
break;
|
|
3061
3076
|
}
|
|
3062
3077
|
if (!found) {
|
|
3063
3078
|
let index = c - (currentLayer.base ?? 0);
|
|
@@ -3092,7 +3107,7 @@ var StringReader = class StringReader {
|
|
|
3092
3107
|
if (isNaN(sloc)) break;
|
|
3093
3108
|
if (new Address(sloc >> 16 & 255, sloc & 65535, this._blockReader._root.config.memoryMode).isROM) {
|
|
3094
3109
|
this._blockReader.resolveInclude(sloc, false);
|
|
3095
|
-
const name = this._blockReader.resolveName(sloc, AddressType.Unknown, false);
|
|
3110
|
+
const name = this._blockReader._referenceManager.resolveName(sloc, AddressType.Unknown, false);
|
|
3096
3111
|
const opix = indexOfAny(name, RomProcessingConstants.OPERATORS);
|
|
3097
3112
|
if (opix > 0) {
|
|
3098
3113
|
const offsetStr = name.substring(opix + 1);
|
|
@@ -3163,29 +3178,44 @@ var TypeParser = class {
|
|
|
3163
3178
|
if (!parentType) throw new Error(`Unknown type: ${fixedTypeName}`);
|
|
3164
3179
|
const delimiter = parentType.delimiter;
|
|
3165
3180
|
const discOffset = parentType.discriminator;
|
|
3181
|
+
const discLogic = parentType.discriminatorLogic;
|
|
3182
|
+
const nullValue = parentType.null;
|
|
3166
3183
|
const objects = [];
|
|
3184
|
+
if (delimiter === void 0 && this._blockReader.delimiterReached(nullValue)) {
|
|
3185
|
+
objects.push({
|
|
3186
|
+
name: parentType.name,
|
|
3187
|
+
parts: ["null"]
|
|
3188
|
+
});
|
|
3189
|
+
return objects;
|
|
3190
|
+
}
|
|
3167
3191
|
let delReached;
|
|
3168
3192
|
while (!(delReached = this._blockReader.delimiterReached(delimiter))) {
|
|
3169
3193
|
const startPosition = this._romDataReader.position;
|
|
3170
3194
|
let targetType = parentType;
|
|
3171
|
-
if (
|
|
3172
|
-
|
|
3173
|
-
|
|
3174
|
-
|
|
3175
|
-
|
|
3176
|
-
|
|
3177
|
-
|
|
3178
|
-
|
|
3179
|
-
|
|
3180
|
-
|
|
3181
|
-
|
|
3182
|
-
const
|
|
3183
|
-
|
|
3184
|
-
|
|
3185
|
-
|
|
3186
|
-
|
|
3187
|
-
|
|
3188
|
-
|
|
3195
|
+
if (this._blockReader.delimiterReached(nullValue)) objects.push({
|
|
3196
|
+
name: parentType.name,
|
|
3197
|
+
parts: ["null"]
|
|
3198
|
+
});
|
|
3199
|
+
else {
|
|
3200
|
+
if (discOffset !== void 0) {
|
|
3201
|
+
const discPosition = this._romDataReader.position + discOffset;
|
|
3202
|
+
const desc = this._romDataReader.romData[discPosition];
|
|
3203
|
+
targetType = Object.values(this._blockReader._root.structs).find((x) => x.parent === fixedTypeName && (discLogic === "&" ? ((x.discriminator ?? 0) & desc) !== 0 : x.discriminator === desc)) || parentType;
|
|
3204
|
+
if (discOffset === 0 && parentType != targetType && discLogic === "=") this._romDataReader.position++;
|
|
3205
|
+
}
|
|
3206
|
+
const types = targetType.types;
|
|
3207
|
+
if (types && types.length > 0) {
|
|
3208
|
+
const memberCount = types.length;
|
|
3209
|
+
const prevPosition = this._romDataReader.position;
|
|
3210
|
+
const parts = new Array(memberCount);
|
|
3211
|
+
const def = {
|
|
3212
|
+
name: targetType.name,
|
|
3213
|
+
parts
|
|
3214
|
+
};
|
|
3215
|
+
for (let i = 0; i < memberCount; i++) parts[i] = this.parseType(types[i], reg, depth + 1, bank);
|
|
3216
|
+
if (discOffset !== void 0 && discOffset === this._romDataReader.position - prevPosition) this._romDataReader.position++;
|
|
3217
|
+
objects.push(def);
|
|
3218
|
+
} else this._romDataReader.position++;
|
|
3189
3219
|
}
|
|
3190
3220
|
let checkPosition = startPosition;
|
|
3191
3221
|
while (++checkPosition < this._romDataReader.position) {
|
|
@@ -3196,6 +3226,7 @@ var TypeParser = class {
|
|
|
3196
3226
|
}
|
|
3197
3227
|
}
|
|
3198
3228
|
if (!this._blockReader.partCanContinue()) break;
|
|
3229
|
+
if (nullValue !== void 0) break;
|
|
3199
3230
|
}
|
|
3200
3231
|
if (delReached && depth === 0) this._referenceManager.tryAddStruct(this._romDataReader.position, typeName);
|
|
3201
3232
|
return objects;
|
|
@@ -3221,15 +3252,16 @@ var TypeParser = class {
|
|
|
3221
3252
|
}
|
|
3222
3253
|
parseLocation(offset, bank, typeName, addrType) {
|
|
3223
3254
|
if ((bank === void 0 || bank === null) && offset === 0) return new Word(offset);
|
|
3255
|
+
offset -= this._romDataReader.offset;
|
|
3224
3256
|
let adrs;
|
|
3225
3257
|
let loc;
|
|
3226
|
-
if (addrType === AddressType.Location) loc = offset | bank << 16;
|
|
3258
|
+
if (addrType === AddressType.Location || this._romDataReader.offset) loc = offset | bank << 16;
|
|
3227
3259
|
else {
|
|
3228
3260
|
adrs = new Address(bank ?? Address.resolveBank(this._romDataReader.position, this._blockReader._root.config.memoryMode), offset, this._blockReader._root.config.memoryMode);
|
|
3229
3261
|
if (!adrs.isROM) return adrs;
|
|
3230
3262
|
loc = adrs.toLocation();
|
|
3231
3263
|
}
|
|
3232
|
-
if (typeName && !this._blockReader._root.rewrites[loc]) {
|
|
3264
|
+
if (typeName && (this._romDataReader.offset || !this._blockReader._root.rewrites[loc])) {
|
|
3233
3265
|
const oldStruct = this._referenceManager.structTable.get(loc);
|
|
3234
3266
|
if (!oldStruct || oldStruct === "Branch") this._referenceManager.structTable.set(loc, typeName);
|
|
3235
3267
|
const referenceName = `${typeName.toLowerCase()}_${loc.toString(16).toUpperCase().padStart(6, "0")}`;
|
|
@@ -3420,8 +3452,6 @@ var BlockReader = class {
|
|
|
3420
3452
|
this._stringReader = new StringReader(this);
|
|
3421
3453
|
this._asmReader = new AsmReader(this);
|
|
3422
3454
|
this._typeParser = new TypeParser(this);
|
|
3423
|
-
this.initializeOverrides();
|
|
3424
|
-
this.initializeFileReferences();
|
|
3425
3455
|
}
|
|
3426
3456
|
/**
|
|
3427
3457
|
* Processes predefined overrides for registers and bank notes
|
|
@@ -3449,9 +3479,6 @@ var BlockReader = class {
|
|
|
3449
3479
|
/**
|
|
3450
3480
|
* Processes predefined file references
|
|
3451
3481
|
*/
|
|
3452
|
-
initializeFileReferences() {
|
|
3453
|
-
for (const file of this._root.files) this._referenceManager.tryAddName(file.start, file.name);
|
|
3454
|
-
}
|
|
3455
3482
|
/**
|
|
3456
3483
|
* Resolves mnemonic for a given address
|
|
3457
3484
|
*/
|
|
@@ -3471,9 +3498,6 @@ var BlockReader = class {
|
|
|
3471
3498
|
/**
|
|
3472
3499
|
* Resolves name for a location (delegated to ReferenceManager)
|
|
3473
3500
|
*/
|
|
3474
|
-
resolveName(location, type, isBranch) {
|
|
3475
|
-
return this._referenceManager.resolveName(location, type, isBranch);
|
|
3476
|
-
}
|
|
3477
3501
|
/**
|
|
3478
3502
|
* Resolves include for a location
|
|
3479
3503
|
*/
|
|
@@ -3534,6 +3558,7 @@ var BlockReader = class {
|
|
|
3534
3558
|
}
|
|
3535
3559
|
analyzeAndResolve() {
|
|
3536
3560
|
console.log("analyzeAndResolve started");
|
|
3561
|
+
this.initializeOverrides();
|
|
3537
3562
|
this.createChunkFilesFromDatabase();
|
|
3538
3563
|
this.initializeBlocksAndParts();
|
|
3539
3564
|
this.analyzeChunkFiles();
|
|
@@ -3549,9 +3574,12 @@ var BlockReader = class {
|
|
|
3549
3574
|
*/
|
|
3550
3575
|
initializeBlocksAndParts() {
|
|
3551
3576
|
console.log("initializeBlocksAndParts");
|
|
3552
|
-
for (const block of this._enrichedChunks)
|
|
3553
|
-
|
|
3554
|
-
|
|
3577
|
+
for (const block of this._enrichedChunks) {
|
|
3578
|
+
for (const part of block.parts || []) {
|
|
3579
|
+
if (part.structName) this._referenceManager.tryAddStruct(part.location, part.structName);
|
|
3580
|
+
if (part.label) this._referenceManager.tryAddName(part.location, part.label);
|
|
3581
|
+
}
|
|
3582
|
+
this._referenceManager.tryAddName(block.location, block.name);
|
|
3555
3583
|
}
|
|
3556
3584
|
}
|
|
3557
3585
|
/**
|
|
@@ -3648,7 +3676,7 @@ var BlockReader = class {
|
|
|
3648
3676
|
const size = getSize();
|
|
3649
3677
|
const startPos = pos + offset;
|
|
3650
3678
|
const data = getBytes(size);
|
|
3651
|
-
const chunk = new ChunkFile(`sfx${i.toString(16).toUpperCase().padStart(2, "0")}`, size, startPos
|
|
3679
|
+
const chunk = new ChunkFile(fileType, `sfx${i.toString(16).toUpperCase().padStart(2, "0")}`, size, startPos);
|
|
3652
3680
|
chunk.rawData = data;
|
|
3653
3681
|
chunk.group = "sfx";
|
|
3654
3682
|
this._enrichedChunks.push(chunk);
|
|
@@ -3659,7 +3687,9 @@ var BlockReader = class {
|
|
|
3659
3687
|
*/
|
|
3660
3688
|
createChunkFilesFromDbFiles() {
|
|
3661
3689
|
for (const dbFile of this._root.files) {
|
|
3662
|
-
const
|
|
3690
|
+
const fileType = this._root.fileTypes[dbFile.type];
|
|
3691
|
+
const chunkFile = new ChunkFile(fileType, dbFile.name);
|
|
3692
|
+
chunkFile.enrichWithRawDataFromDbFile(dbFile, this._romDataReader.romData, this._root.compression);
|
|
3663
3693
|
this._enrichedChunks.push(chunkFile);
|
|
3664
3694
|
}
|
|
3665
3695
|
}
|
|
@@ -3669,7 +3699,8 @@ var BlockReader = class {
|
|
|
3669
3699
|
createChunkFilesFromDbBlocks() {
|
|
3670
3700
|
const fileType = Object.values(this._root.fileTypes).find((x) => x.isBlock);
|
|
3671
3701
|
for (const block of this._root.blocks) {
|
|
3672
|
-
const chunkFile =
|
|
3702
|
+
const chunkFile = new ChunkFile(fileType, block.name);
|
|
3703
|
+
chunkFile.enrichWithAsmBlocksFromDbBlock(block, this._root.config.memoryMode);
|
|
3673
3704
|
this._enrichedChunks.push(chunkFile);
|
|
3674
3705
|
}
|
|
3675
3706
|
}
|
|
@@ -3678,14 +3709,32 @@ var BlockReader = class {
|
|
|
3678
3709
|
*/
|
|
3679
3710
|
analyzeChunkFiles() {
|
|
3680
3711
|
console.log("analyzeChunkFiles");
|
|
3681
|
-
const
|
|
3682
|
-
|
|
3712
|
+
for (const chunkFile of this._enrichedChunks) {
|
|
3713
|
+
if (!chunkFile.type.isBlock) continue;
|
|
3714
|
+
chunkFile.referenceManager = this._referenceManager;
|
|
3683
3715
|
this._currentChunk = chunkFile;
|
|
3684
3716
|
for (const asmBlock of chunkFile.parts || []) {
|
|
3685
3717
|
this._currentAsmBlock = asmBlock;
|
|
3686
3718
|
this.processPart(asmBlock);
|
|
3687
3719
|
}
|
|
3688
3720
|
}
|
|
3721
|
+
const oldState = this._referenceManager;
|
|
3722
|
+
const oldReader = this._romDataReader;
|
|
3723
|
+
const oldTypeParser = this._typeParser;
|
|
3724
|
+
for (const chunkFile of this._enrichedChunks) {
|
|
3725
|
+
if (!chunkFile.type.struct) continue;
|
|
3726
|
+
this._currentChunk = chunkFile;
|
|
3727
|
+
const asmBlock = new AsmBlock(0, chunkFile.size, false, chunkFile.name, chunkFile.type.struct);
|
|
3728
|
+
chunkFile.parts = [asmBlock];
|
|
3729
|
+
this._currentAsmBlock = asmBlock;
|
|
3730
|
+
this._referenceManager = chunkFile.referenceManager = new ReferenceManager(this._root);
|
|
3731
|
+
this._romDataReader = new RomDataReader(chunkFile.rawData, chunkFile.base ?? 0);
|
|
3732
|
+
this._typeParser = new TypeParser(this);
|
|
3733
|
+
this.processPart(asmBlock);
|
|
3734
|
+
}
|
|
3735
|
+
this._referenceManager = oldState;
|
|
3736
|
+
this._romDataReader = oldReader;
|
|
3737
|
+
this._typeParser = oldTypeParser;
|
|
3689
3738
|
}
|
|
3690
3739
|
/**
|
|
3691
3740
|
* Resolves references in assembly ChunkFiles only
|
|
@@ -3693,8 +3742,9 @@ var BlockReader = class {
|
|
|
3693
3742
|
resolveReferences() {
|
|
3694
3743
|
console.log("resolveReferences");
|
|
3695
3744
|
for (const chunkFile of this._enrichedChunks) {
|
|
3745
|
+
if (!chunkFile.type.isBlock) continue;
|
|
3696
3746
|
this._currentChunk = chunkFile;
|
|
3697
|
-
for (const asmBlock of chunkFile.parts
|
|
3747
|
+
for (const asmBlock of chunkFile.parts) {
|
|
3698
3748
|
this._currentAsmBlock = asmBlock;
|
|
3699
3749
|
this.resolveObject(asmBlock.objList, false);
|
|
3700
3750
|
}
|
|
@@ -3884,6 +3934,7 @@ var BlockWriter = class {
|
|
|
3884
3934
|
generateAsm(block) {
|
|
3885
3935
|
if (!block.parts) throw new Error("Invalid block structure for generateAsm");
|
|
3886
3936
|
const lines = [];
|
|
3937
|
+
this._referenceManager = block.referenceManager;
|
|
3887
3938
|
if (block.bank !== void 0) lines.push(`?BANK ${block.bank.toString(16).toUpperCase().padStart(2, "0")}`);
|
|
3888
3939
|
const includes = ChunkFileUtils.getIncludes(block);
|
|
3889
3940
|
if (includes && includes.length > 0) {
|
|
@@ -3928,11 +3979,11 @@ var BlockWriter = class {
|
|
|
3928
3979
|
}
|
|
3929
3980
|
if (typeof obj === "number") {
|
|
3930
3981
|
if (op.mode === "Immediate") return obj;
|
|
3931
|
-
return this.
|
|
3982
|
+
return this._referenceManager.resolveName(obj, AddressType.Address, isBranch);
|
|
3932
3983
|
}
|
|
3933
3984
|
if (this.getObjectType(obj) === ObjectType.LocationWrapper) {
|
|
3934
3985
|
const lw = obj;
|
|
3935
|
-
return this.
|
|
3986
|
+
return this._referenceManager.resolveName(lw.location, lw.type, isBranch);
|
|
3936
3987
|
}
|
|
3937
3988
|
if (this.getObjectType(obj) === ObjectType.Address) {
|
|
3938
3989
|
const addr = obj;
|
|
@@ -3984,10 +4035,10 @@ var BlockWriter = class {
|
|
|
3984
4035
|
objLines = this.writeOpArray(obj, depth);
|
|
3985
4036
|
break;
|
|
3986
4037
|
case ObjectType.LocationWrapper:
|
|
3987
|
-
objLines = [this.
|
|
4038
|
+
objLines = [this._referenceManager.resolveName(obj.location, obj.type, isBranch)];
|
|
3988
4039
|
break;
|
|
3989
4040
|
case ObjectType.Address:
|
|
3990
|
-
objLines = isArray ? [`$#${obj.
|
|
4041
|
+
objLines = isArray ? [`$#${obj.toString()}`] : [`$${obj.toString()}`];
|
|
3991
4042
|
break;
|
|
3992
4043
|
case ObjectType.ByteArray:
|
|
3993
4044
|
objLines = [`#${Array.from(obj).map((b) => b.toString(16).toUpperCase().padStart(2, "0")).join("")}`];
|
|
@@ -4047,14 +4098,14 @@ var BlockWriter = class {
|
|
|
4047
4098
|
this._isInline = true;
|
|
4048
4099
|
let first = true;
|
|
4049
4100
|
for (const op of opList) {
|
|
4050
|
-
if (first
|
|
4051
|
-
else {
|
|
4101
|
+
if (!first || depth > 0) {
|
|
4052
4102
|
const labelResult = this._referenceManager.tryGetName(op.location);
|
|
4053
4103
|
if (labelResult.found) {
|
|
4054
4104
|
lines.push("");
|
|
4055
4105
|
lines.push(` ${labelResult.referenceName}:`);
|
|
4056
4106
|
}
|
|
4057
4107
|
}
|
|
4108
|
+
first = false;
|
|
4058
4109
|
let opLine = ` ${op.mnem} `;
|
|
4059
4110
|
if (op.copDef) {
|
|
4060
4111
|
opLine += `[${op.copDef.name}]`;
|
|
@@ -4102,7 +4153,7 @@ var BlockWriter = class {
|
|
|
4102
4153
|
const adrs = new Address(rawAddr >> 16 & 255, rawAddr & 65535, this._blockReader._root.config.memoryMode);
|
|
4103
4154
|
const addressType = char === "^" ? AddressType.Offset : AddressType.Address;
|
|
4104
4155
|
let name = "";
|
|
4105
|
-
if (adrs.isROM) name = this.
|
|
4156
|
+
if (adrs.isROM) name = this._referenceManager.resolveName(adrs.toLocation(), addressType, false);
|
|
4106
4157
|
else if (addressType === AddressType.Offset) name = adrs.offset.toString(16).toUpperCase().padStart(4, "0");
|
|
4107
4158
|
else name = adrs.toString();
|
|
4108
4159
|
str = str.replace(str.substring(ix, ix + 7), name);
|
|
@@ -4244,8 +4295,8 @@ var RomLayout = class RomLayout {
|
|
|
4244
4295
|
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);
|
|
4245
4296
|
}) : [];
|
|
4246
4297
|
this.unmatchedFiles = files.filter((x) => (x.size || 0) > 0).filter((x) => this.sfxPackType === "Individual" || x.type.type !== "Sound").sort((a, b) => {
|
|
4247
|
-
const aAsm = a.
|
|
4248
|
-
const bAsm = b.
|
|
4298
|
+
const aAsm = a.rawData ? 1 : 0;
|
|
4299
|
+
const bAsm = b.rawData ? 1 : 0;
|
|
4249
4300
|
if (aAsm !== bAsm) return aAsm - bAsm;
|
|
4250
4301
|
if (b.size !== a.size) return b.size - a.size;
|
|
4251
4302
|
if (a.location !== b.location) return a.location - b.location;
|
|
@@ -4295,7 +4346,7 @@ var RomLayout = class RomLayout {
|
|
|
4295
4346
|
start += RomProcessingConstants.PAGE_SIZE;
|
|
4296
4347
|
page++;
|
|
4297
4348
|
if (offset) {
|
|
4298
|
-
const newFile = new ChunkFile(
|
|
4349
|
+
const newFile = new ChunkFile(Object.values(this.root.fileTypes).find((x) => x.type === BinType.Binary), file.name + "_2", file.size, file.location);
|
|
4299
4350
|
const end = file.rawData.length - offset;
|
|
4300
4351
|
newFile.rawData = file.rawData.slice(end);
|
|
4301
4352
|
newFile.size = newFile.rawData.length;
|
|
@@ -4385,107 +4436,13 @@ var RomLayout = class RomLayout {
|
|
|
4385
4436
|
}
|
|
4386
4437
|
};
|
|
4387
4438
|
|
|
4388
|
-
//#endregion
|
|
4389
|
-
//#region src/rom/rebuild/processor.ts
|
|
4390
|
-
/**
|
|
4391
|
-
* ROM rebuild processor
|
|
4392
|
-
* Converted from ext/GaiaLib/Rom/Rebuild/RomProcessor.cs
|
|
4393
|
-
*/
|
|
4394
|
-
var RomProcessor = class RomProcessor {
|
|
4395
|
-
writer;
|
|
4396
|
-
constructor(writer) {
|
|
4397
|
-
this.writer = writer;
|
|
4398
|
-
}
|
|
4399
|
-
async repack(allFiles, modules) {
|
|
4400
|
-
const patches = [];
|
|
4401
|
-
const asmFiles = [];
|
|
4402
|
-
const compression = this.writer.root.compression;
|
|
4403
|
-
const canCompress = !!compression;
|
|
4404
|
-
const conditionFiles = [];
|
|
4405
|
-
if (modules) conditionFiles.push(...modules);
|
|
4406
|
-
for (const file of allFiles) {
|
|
4407
|
-
if (file.type.type === "Patch") patches.push(file);
|
|
4408
|
-
else if (file.type.type !== "Assembly") {
|
|
4409
|
-
if (file.compressed === true && canCompress) if (this.writer.root.config.uncompress) file.compressed = false;
|
|
4410
|
-
else {
|
|
4411
|
-
let newData = compression.compact(file.rawData, file.type.header);
|
|
4412
|
-
if (file.type.header) newData = new Uint8Array([...file.rawData.slice(0, file.type.header), ...newData]);
|
|
4413
|
-
file.rawData = newData;
|
|
4414
|
-
file.size = newData.length;
|
|
4415
|
-
}
|
|
4416
|
-
continue;
|
|
4417
|
-
}
|
|
4418
|
-
asmFiles.push(file);
|
|
4419
|
-
conditionFiles.push(file.name);
|
|
4420
|
-
}
|
|
4421
|
-
for (const file of asmFiles) {
|
|
4422
|
-
const { blocks, includes, reqBank } = new Assembler(this.writer.root, file.textData, conditionFiles).parseAssembly();
|
|
4423
|
-
file.parts = blocks;
|
|
4424
|
-
file.includes = includes;
|
|
4425
|
-
file.bank = reqBank ?? void 0;
|
|
4426
|
-
}
|
|
4427
|
-
RomProcessor.applyPatches(asmFiles, patches);
|
|
4428
|
-
for (const file of allFiles) ChunkFileUtils.calculateSize(file);
|
|
4429
|
-
const pages = new RomLayout(allFiles, this.writer.root).organize();
|
|
4430
|
-
for (const file of asmFiles) ChunkFileUtils.rebase(file);
|
|
4431
|
-
const masterLookup = /* @__PURE__ */ new Map();
|
|
4432
|
-
for (const f of asmFiles) {
|
|
4433
|
-
const includeBlocks = asmFiles.filter((x) => f.includes?.has(x.name.toUpperCase())).flatMap((x) => x.parts).filter((b) => !!b.label);
|
|
4434
|
-
f.includeLookup = /* @__PURE__ */ new Map();
|
|
4435
|
-
for (const b of includeBlocks) if (b.label) f.includeLookup.set(b.label.toUpperCase(), b);
|
|
4436
|
-
for (const b of f.parts) if (b.label) {
|
|
4437
|
-
const nameUpper = b.label.toUpperCase();
|
|
4438
|
-
masterLookup.set(nameUpper, b.location);
|
|
4439
|
-
f.includeLookup.set(nameUpper, b);
|
|
4440
|
-
}
|
|
4441
|
-
}
|
|
4442
|
-
const fileLookup = /* @__PURE__ */ new Map();
|
|
4443
|
-
for (const f of allFiles) fileLookup.set(f.name.toUpperCase(), f.location);
|
|
4444
|
-
this.writer.allocate(pages);
|
|
4445
|
-
for (const file of allFiles) await this.writer.writeFile(file, fileLookup);
|
|
4446
|
-
return masterLookup;
|
|
4447
|
-
}
|
|
4448
|
-
static applyPatches(asmFiles, patches) {
|
|
4449
|
-
for (const patch of patches.filter((x) => x.includes && x.includes.size > 0)) {
|
|
4450
|
-
let file = null;
|
|
4451
|
-
let dstIx = -1;
|
|
4452
|
-
const inc = asmFiles.filter((x) => patch.includes.has(x.name.toUpperCase()));
|
|
4453
|
-
for (let ix = 0; patch.parts && ix < patch.parts.length;) {
|
|
4454
|
-
const block = patch.parts[ix];
|
|
4455
|
-
let match = null;
|
|
4456
|
-
if (block.label) for (const i of inc) {
|
|
4457
|
-
if (!i.parts) continue;
|
|
4458
|
-
for (let y = 0; y < i.parts.length; y++) {
|
|
4459
|
-
const check = i.parts[y];
|
|
4460
|
-
if (check.label === block.label) {
|
|
4461
|
-
file = i;
|
|
4462
|
-
dstIx = y;
|
|
4463
|
-
match = check;
|
|
4464
|
-
break;
|
|
4465
|
-
}
|
|
4466
|
-
}
|
|
4467
|
-
}
|
|
4468
|
-
if (match) file.parts[dstIx++] = block;
|
|
4469
|
-
else if (dstIx >= 0) file.parts.splice(dstIx++, 0, block);
|
|
4470
|
-
else {
|
|
4471
|
-
ix++;
|
|
4472
|
-
continue;
|
|
4473
|
-
}
|
|
4474
|
-
file.includes = file.includes || /* @__PURE__ */ new Set();
|
|
4475
|
-
file.includes.add(patch.name.toUpperCase());
|
|
4476
|
-
patch.parts.splice(ix, 1);
|
|
4477
|
-
}
|
|
4478
|
-
}
|
|
4479
|
-
}
|
|
4480
|
-
};
|
|
4481
|
-
|
|
4482
4439
|
//#endregion
|
|
4483
4440
|
//#region src/rom/rebuild/writer.ts
|
|
4484
4441
|
/**
|
|
4485
4442
|
* ROM writer (binary)
|
|
4486
4443
|
* Converted from ext/GaiaLib/Rom/Rebuild/RomWriter.cs (subset: binary write only)
|
|
4487
4444
|
*/
|
|
4488
|
-
var RomWriter = class {
|
|
4445
|
+
var RomWriter = class RomWriter {
|
|
4489
4446
|
bpsPath;
|
|
4490
4447
|
outBuffer;
|
|
4491
4448
|
romSize;
|
|
@@ -4640,7 +4597,7 @@ var RomWriter = class {
|
|
|
4640
4597
|
}
|
|
4641
4598
|
} else if (file.parts && file.parts.length > 0) {
|
|
4642
4599
|
if (file.parts[0].location !== file.location && (file.location || 0) !== 0) throw new Error("Assembly was not based properly");
|
|
4643
|
-
|
|
4600
|
+
RomWriter.parseAssembly(this.root, file.parts, fileLookup, file.includeLookup, this.outBuffer, void 0);
|
|
4644
4601
|
}
|
|
4645
4602
|
return pos - start;
|
|
4646
4603
|
}
|
|
@@ -4652,12 +4609,10 @@ var RomWriter = class {
|
|
|
4652
4609
|
* Parse assembly blocks and write binary data to output buffer
|
|
4653
4610
|
* Converted from ext/GaiaLib/Rom/Rebuild/RomWriter.cs ParseAssembly method
|
|
4654
4611
|
*/
|
|
4655
|
-
parseAssembly(blocks, fileLookup, includeLookup) {
|
|
4612
|
+
static parseAssembly(root, blocks, fileLookup, includeLookup, outBuffer, addrOffset) {
|
|
4656
4613
|
if (!blocks) throw new Error("Assembly has not been parsed");
|
|
4657
|
-
const buf = this.outBuffer;
|
|
4658
4614
|
let bix = 0;
|
|
4659
4615
|
for (const block of blocks) {
|
|
4660
|
-
let oldPos = null;
|
|
4661
4616
|
let position = block.location;
|
|
4662
4617
|
const objList = block.objList;
|
|
4663
4618
|
let oix = 0;
|
|
@@ -4672,13 +4627,13 @@ var RomWriter = class {
|
|
|
4672
4627
|
continue;
|
|
4673
4628
|
} else if (currentObj instanceof Op) {
|
|
4674
4629
|
const op = currentObj;
|
|
4675
|
-
|
|
4630
|
+
outBuffer[position++] = op.code & 255;
|
|
4676
4631
|
opos += op.size;
|
|
4677
4632
|
for (const operand of op.operands) processObject(operand, op);
|
|
4678
4633
|
break;
|
|
4679
4634
|
} else if (currentObj instanceof Uint8Array) {
|
|
4680
4635
|
const arr = currentObj;
|
|
4681
|
-
for (let i = 0; i < arr.length; i++)
|
|
4636
|
+
for (let i = 0; i < arr.length; i++) outBuffer[position + i] = arr[i];
|
|
4682
4637
|
position += arr.length;
|
|
4683
4638
|
opos += arr.length;
|
|
4684
4639
|
break;
|
|
@@ -4690,7 +4645,7 @@ var RomWriter = class {
|
|
|
4690
4645
|
if (ix > 0) label = label.substring(ix);
|
|
4691
4646
|
let loc;
|
|
4692
4647
|
const isRelative = parentOp && (parentOp.mode === "PCRelative" || parentOp.mode === "PCRelativeLong");
|
|
4693
|
-
const operatorIdx =
|
|
4648
|
+
const operatorIdx = RomWriter.indexOfAny(label, RomProcessingConstants.OPERATORS);
|
|
4694
4649
|
let offset = null;
|
|
4695
4650
|
let useMarker = false;
|
|
4696
4651
|
if (operatorIdx > 0) {
|
|
@@ -4739,12 +4694,13 @@ var RomWriter = class {
|
|
|
4739
4694
|
if (offset !== null) loc += offset;
|
|
4740
4695
|
else if (useMarker && target instanceof AsmBlock) {
|
|
4741
4696
|
let markerOffset = 0;
|
|
4742
|
-
for (const part of target.objList) if (
|
|
4697
|
+
for (const part of target.objList) if (RomWriter.isStringMarker(part)) {
|
|
4743
4698
|
loc += markerOffset;
|
|
4744
4699
|
break;
|
|
4745
4700
|
} else markerOffset += RomProcessingConstants.getSize(part);
|
|
4746
4701
|
}
|
|
4747
|
-
if (
|
|
4702
|
+
if (addrOffset !== void 0) loc += addrOffset;
|
|
4703
|
+
else if (!isRelative && type !== AddressType.Location) loc = Address.fromLocation(loc, root.config.memoryMode, root.config.cpuMode).toInt();
|
|
4748
4704
|
switch (type) {
|
|
4749
4705
|
case AddressType.Offset:
|
|
4750
4706
|
case AddressType.WRelative:
|
|
@@ -4769,7 +4725,7 @@ var RomWriter = class {
|
|
|
4769
4725
|
} else if (currentObj instanceof TypedNumber) {
|
|
4770
4726
|
let value = currentObj.value;
|
|
4771
4727
|
for (let i = 0; i < currentObj.size; i++) {
|
|
4772
|
-
|
|
4728
|
+
outBuffer[position++] = value & 255;
|
|
4773
4729
|
value >>= 8;
|
|
4774
4730
|
}
|
|
4775
4731
|
break;
|
|
@@ -4777,26 +4733,26 @@ var RomWriter = class {
|
|
|
4777
4733
|
const num = currentObj;
|
|
4778
4734
|
const size = parentOp?.size ?? 0;
|
|
4779
4735
|
if (num <= 255 && size <= 2) {
|
|
4780
|
-
|
|
4736
|
+
outBuffer[position] = num & 255;
|
|
4781
4737
|
position++;
|
|
4782
4738
|
} else if (num <= 65535 && size <= 3) {
|
|
4783
|
-
|
|
4784
|
-
|
|
4739
|
+
outBuffer[position] = num & 255;
|
|
4740
|
+
outBuffer[position + 1] = num >> 8 & 255;
|
|
4785
4741
|
position += 2;
|
|
4786
4742
|
} else if (num <= 16777215 && size <= 4) {
|
|
4787
|
-
|
|
4788
|
-
|
|
4789
|
-
|
|
4743
|
+
outBuffer[position] = num & 255;
|
|
4744
|
+
outBuffer[position + 1] = num >> 8 & 255;
|
|
4745
|
+
outBuffer[position + 2] = num >> 16 & 255;
|
|
4790
4746
|
position += 3;
|
|
4791
4747
|
} else {
|
|
4792
|
-
|
|
4793
|
-
|
|
4794
|
-
|
|
4795
|
-
|
|
4748
|
+
outBuffer[position] = num & 255;
|
|
4749
|
+
outBuffer[position + 1] = num >> 8 & 255;
|
|
4750
|
+
outBuffer[position + 2] = num >> 16 & 255;
|
|
4751
|
+
outBuffer[position + 3] = num >> 24 & 255;
|
|
4796
4752
|
position += 4;
|
|
4797
4753
|
}
|
|
4798
4754
|
break;
|
|
4799
|
-
} else if (
|
|
4755
|
+
} else if (RomWriter.isStringMarker(currentObj)) break;
|
|
4800
4756
|
else throw new Error(`Unable to process '${currentObj}'`);
|
|
4801
4757
|
};
|
|
4802
4758
|
for (const obj of objList) {
|
|
@@ -4809,21 +4765,121 @@ var RomWriter = class {
|
|
|
4809
4765
|
/**
|
|
4810
4766
|
* Helper method to find index of any character from an array in a string
|
|
4811
4767
|
*/
|
|
4812
|
-
indexOfAny(str, chars) {
|
|
4768
|
+
static indexOfAny(str, chars) {
|
|
4813
4769
|
for (let i = 0; i < str.length; i++) if (chars.includes(str[i])) return i;
|
|
4814
4770
|
return -1;
|
|
4815
4771
|
}
|
|
4816
4772
|
/**
|
|
4817
4773
|
* Helper method to check if an object is a StringMarker
|
|
4818
4774
|
*/
|
|
4819
|
-
isStringMarker(obj) {
|
|
4775
|
+
static isStringMarker(obj) {
|
|
4820
4776
|
return typeof obj === "object" && obj !== null && "offset" in obj;
|
|
4821
4777
|
}
|
|
4822
|
-
isTableEntry(obj) {
|
|
4778
|
+
static isTableEntry(obj) {
|
|
4823
4779
|
return typeof obj === "object" && obj !== null && "location" in obj && "object" in obj;
|
|
4824
4780
|
}
|
|
4825
4781
|
};
|
|
4826
4782
|
|
|
4783
|
+
//#endregion
|
|
4784
|
+
//#region src/rom/rebuild/processor.ts
|
|
4785
|
+
/**
|
|
4786
|
+
* ROM rebuild processor
|
|
4787
|
+
* Converted from ext/GaiaLib/Rom/Rebuild/RomProcessor.cs
|
|
4788
|
+
*/
|
|
4789
|
+
var RomProcessor = class RomProcessor {
|
|
4790
|
+
writer;
|
|
4791
|
+
constructor(writer) {
|
|
4792
|
+
this.writer = writer;
|
|
4793
|
+
}
|
|
4794
|
+
async repack(allFiles, modules) {
|
|
4795
|
+
const patches = [];
|
|
4796
|
+
const asmFiles = [];
|
|
4797
|
+
const compression = this.writer.root.compression;
|
|
4798
|
+
const canCompress = !!compression;
|
|
4799
|
+
const conditionFiles = [];
|
|
4800
|
+
if (modules) conditionFiles.push(...modules);
|
|
4801
|
+
const dummyMap = /* @__PURE__ */ new Map();
|
|
4802
|
+
for (const file of allFiles) {
|
|
4803
|
+
conditionFiles.push(file.name);
|
|
4804
|
+
if (file.type.isPatch) {
|
|
4805
|
+
patches.push(file);
|
|
4806
|
+
asmFiles.push(file);
|
|
4807
|
+
} else if (file.type.isBlock) asmFiles.push(file);
|
|
4808
|
+
else if (!file.type.struct) continue;
|
|
4809
|
+
const { blocks, includes, reqBank } = new Assembler(this.writer.root, file.textData, conditionFiles).parseAssembly();
|
|
4810
|
+
file.parts = blocks;
|
|
4811
|
+
file.includes = includes;
|
|
4812
|
+
file.bank = reqBank ?? void 0;
|
|
4813
|
+
if (file.type.struct) {
|
|
4814
|
+
file.includeLookup = /* @__PURE__ */ new Map();
|
|
4815
|
+
for (const b of file.parts) if (b.label) file.includeLookup.set(b.label.toUpperCase(), b);
|
|
4816
|
+
file.rawData = void 0;
|
|
4817
|
+
file.rawData = new Uint8Array(ChunkFileUtils.calculateSize(file));
|
|
4818
|
+
RomWriter.parseAssembly(this.writer.root, file.parts, dummyMap, file.includeLookup, file.rawData, file.type.base ?? 0);
|
|
4819
|
+
}
|
|
4820
|
+
}
|
|
4821
|
+
for (const file of allFiles) if (file.compressed === true && canCompress) if (this.writer.root.config.uncompress) file.compressed = false;
|
|
4822
|
+
else {
|
|
4823
|
+
let newData = compression.compact(file.rawData, file.type.header);
|
|
4824
|
+
if (file.type.header) newData = new Uint8Array([...file.rawData.slice(0, file.type.header), ...newData]);
|
|
4825
|
+
file.rawData = newData;
|
|
4826
|
+
file.size = newData.length;
|
|
4827
|
+
}
|
|
4828
|
+
RomProcessor.applyPatches(asmFiles, patches);
|
|
4829
|
+
for (const file of allFiles) ChunkFileUtils.calculateSize(file);
|
|
4830
|
+
const pages = new RomLayout(allFiles, this.writer.root).organize();
|
|
4831
|
+
for (const file of asmFiles) ChunkFileUtils.rebase(file);
|
|
4832
|
+
const masterLookup = /* @__PURE__ */ new Map();
|
|
4833
|
+
for (const f of asmFiles) {
|
|
4834
|
+
const includeBlocks = asmFiles.filter((x) => f.includes?.has(x.name.toUpperCase())).flatMap((x) => x.parts).filter((b) => !!b.label);
|
|
4835
|
+
f.includeLookup = /* @__PURE__ */ new Map();
|
|
4836
|
+
for (const b of includeBlocks) if (b.label) f.includeLookup.set(b.label.toUpperCase(), b);
|
|
4837
|
+
for (const b of f.parts) if (b.label) {
|
|
4838
|
+
const nameUpper = b.label.toUpperCase();
|
|
4839
|
+
masterLookup.set(nameUpper, b.location);
|
|
4840
|
+
f.includeLookup.set(nameUpper, b);
|
|
4841
|
+
}
|
|
4842
|
+
}
|
|
4843
|
+
const fileLookup = /* @__PURE__ */ new Map();
|
|
4844
|
+
for (const f of allFiles) fileLookup.set(f.name.toUpperCase(), f.location);
|
|
4845
|
+
this.writer.allocate(pages);
|
|
4846
|
+
for (const file of allFiles) await this.writer.writeFile(file, fileLookup);
|
|
4847
|
+
return masterLookup;
|
|
4848
|
+
}
|
|
4849
|
+
static applyPatches(asmFiles, patches) {
|
|
4850
|
+
for (const patch of patches.filter((x) => x.includes && x.includes.size > 0)) {
|
|
4851
|
+
let file = null;
|
|
4852
|
+
let dstIx = -1;
|
|
4853
|
+
const inc = asmFiles.filter((x) => patch.includes.has(x.name.toUpperCase()));
|
|
4854
|
+
for (let ix = 0; patch.parts && ix < patch.parts.length;) {
|
|
4855
|
+
const block = patch.parts[ix];
|
|
4856
|
+
let match = null;
|
|
4857
|
+
if (block.label) for (const i of inc) {
|
|
4858
|
+
if (!i.parts) continue;
|
|
4859
|
+
for (let y = 0; y < i.parts.length; y++) {
|
|
4860
|
+
const check = i.parts[y];
|
|
4861
|
+
if (check.label === block.label) {
|
|
4862
|
+
file = i;
|
|
4863
|
+
dstIx = y;
|
|
4864
|
+
match = check;
|
|
4865
|
+
break;
|
|
4866
|
+
}
|
|
4867
|
+
}
|
|
4868
|
+
}
|
|
4869
|
+
if (match) file.parts[dstIx++] = block;
|
|
4870
|
+
else if (dstIx >= 0) file.parts.splice(dstIx++, 0, block);
|
|
4871
|
+
else {
|
|
4872
|
+
ix++;
|
|
4873
|
+
continue;
|
|
4874
|
+
}
|
|
4875
|
+
if (!file.includes) file.includes = /* @__PURE__ */ new Set();
|
|
4876
|
+
file.includes.add(patch.name.toUpperCase());
|
|
4877
|
+
patch.parts.splice(ix, 1);
|
|
4878
|
+
}
|
|
4879
|
+
}
|
|
4880
|
+
}
|
|
4881
|
+
};
|
|
4882
|
+
|
|
4827
4883
|
//#endregion
|
|
4828
4884
|
//#region src/rom/rebuild/string-processor.ts
|
|
4829
4885
|
/**
|
|
@@ -5516,10 +5572,7 @@ var DbBlock = class {
|
|
|
5516
5572
|
this.group = data.group ?? void 0;
|
|
5517
5573
|
this.scene = data.scene ?? void 0;
|
|
5518
5574
|
this.parts = (data.parts ?? []).sort((a, b) => {
|
|
5519
|
-
|
|
5520
|
-
const orderB = b.order ?? 0;
|
|
5521
|
-
if (orderA !== orderB) return orderA - orderB;
|
|
5522
|
-
return a.start - b.start;
|
|
5575
|
+
return (a.order ?? a.start ?? 0) - (b.order ?? b.start ?? 0);
|
|
5523
5576
|
});
|
|
5524
5577
|
this.transforms = data.transforms ?? [];
|
|
5525
5578
|
this.postProcess = data.postProcess ?? void 0;
|
|
@@ -5539,6 +5592,7 @@ var DbFile = class {
|
|
|
5539
5592
|
upper;
|
|
5540
5593
|
group;
|
|
5541
5594
|
scene;
|
|
5595
|
+
base;
|
|
5542
5596
|
constructor(data) {
|
|
5543
5597
|
if (!data.name) throw new Error("Name is required");
|
|
5544
5598
|
if (!data.type) throw new Error("Type is required");
|
|
@@ -5552,6 +5606,7 @@ var DbFile = class {
|
|
|
5552
5606
|
this.upper = data.upper ?? void 0;
|
|
5553
5607
|
this.group = data.group || void 0;
|
|
5554
5608
|
this.scene = data.scene || void 0;
|
|
5609
|
+
this.base = data.base ?? void 0;
|
|
5555
5610
|
}
|
|
5556
5611
|
};
|
|
5557
5612
|
var DbFileType = class {
|
|
@@ -5562,17 +5617,21 @@ var DbFileType = class {
|
|
|
5562
5617
|
isBlock;
|
|
5563
5618
|
header;
|
|
5564
5619
|
compressed;
|
|
5620
|
+
struct;
|
|
5621
|
+
base;
|
|
5565
5622
|
constructor(data) {
|
|
5566
|
-
|
|
5567
|
-
|
|
5568
|
-
|
|
5623
|
+
if (!data.name) throw new Error("Name is required");
|
|
5624
|
+
if (!data.extension) throw new Error("Extension is required");
|
|
5625
|
+
if (!data.type) throw new Error("Type is required");
|
|
5626
|
+
this.name = data.name;
|
|
5627
|
+
this.extension = data.extension;
|
|
5628
|
+
this.type = data.type;
|
|
5569
5629
|
this.isPatch = data.isPatch ?? false;
|
|
5570
5630
|
this.isBlock = data.isBlock ?? false;
|
|
5571
5631
|
this.header = data.header ?? 0;
|
|
5572
5632
|
this.compressed = data.compressed ?? void 0;
|
|
5573
|
-
|
|
5574
|
-
|
|
5575
|
-
if (!this.type) throw new Error("Type is required");
|
|
5633
|
+
this.struct = data.struct ?? void 0;
|
|
5634
|
+
this.base = data.base ?? void 0;
|
|
5576
5635
|
}
|
|
5577
5636
|
};
|
|
5578
5637
|
|
|
@@ -5588,12 +5647,16 @@ var DbStruct = class {
|
|
|
5588
5647
|
parent;
|
|
5589
5648
|
delimiter;
|
|
5590
5649
|
discriminator;
|
|
5650
|
+
discriminatorLogic;
|
|
5651
|
+
null;
|
|
5591
5652
|
constructor(data) {
|
|
5592
5653
|
this.name = data.name ?? "";
|
|
5593
5654
|
this.types = data.types ?? void 0;
|
|
5594
5655
|
this.parent = data.parent ?? void 0;
|
|
5595
5656
|
this.delimiter = data.delimiter ?? void 0;
|
|
5596
5657
|
this.discriminator = data.discriminator ?? void 0;
|
|
5658
|
+
this.discriminatorLogic = data.discriminatorLogic ?? (this.discriminator !== void 0 ? "=" : void 0);
|
|
5659
|
+
this.null = data.null ?? void 0;
|
|
5597
5660
|
if (!this.name) throw new Error("Name is required");
|
|
5598
5661
|
}
|
|
5599
5662
|
};
|
|
@@ -5648,14 +5711,16 @@ var DbStringCommand = class {
|
|
|
5648
5711
|
}
|
|
5649
5712
|
};
|
|
5650
5713
|
var DbStringDictionary = class {
|
|
5714
|
+
base;
|
|
5651
5715
|
command;
|
|
5652
5716
|
commandName;
|
|
5653
5717
|
name;
|
|
5654
5718
|
entries;
|
|
5655
5719
|
constructor(data) {
|
|
5656
|
-
if (typeof data.command !== "number") throw new Error("Command is required");
|
|
5720
|
+
if (typeof data.command !== "number" && typeof data.base !== "number") throw new Error("Command or base is required");
|
|
5657
5721
|
if (!data.name) throw new Error("Name is required");
|
|
5658
5722
|
if (!data.entries || data.entries.length === 0) throw new Error("Entries is required");
|
|
5723
|
+
this.base = data.base ?? void 0;
|
|
5659
5724
|
this.command = data.command ?? void 0;
|
|
5660
5725
|
this.commandName = data.commandName ?? void 0;
|
|
5661
5726
|
this.name = data.name;
|
|
@@ -5676,6 +5741,7 @@ var DbStringType = class {
|
|
|
5676
5741
|
greedyTerminator;
|
|
5677
5742
|
dictionaries;
|
|
5678
5743
|
dictionaryLookup;
|
|
5744
|
+
modifiers;
|
|
5679
5745
|
constructor(data) {
|
|
5680
5746
|
if (!data.name) throw new Error("Name is required");
|
|
5681
5747
|
if (!data.delimiter) throw new Error("Delimiter is required");
|
|
@@ -5696,6 +5762,7 @@ var DbStringType = class {
|
|
|
5696
5762
|
text: z,
|
|
5697
5763
|
id: (y.command ?? 0) << 8 | ix
|
|
5698
5764
|
}))).sort((a, b) => b.text.length - a.text.length);
|
|
5765
|
+
this.modifiers = data.modifiers;
|
|
5699
5766
|
}
|
|
5700
5767
|
};
|
|
5701
5768
|
|
|
@@ -5711,6 +5778,7 @@ var CopDef = class {
|
|
|
5711
5778
|
size;
|
|
5712
5779
|
parts;
|
|
5713
5780
|
halt;
|
|
5781
|
+
conditions;
|
|
5714
5782
|
constructor(data) {
|
|
5715
5783
|
if (!data.name) throw new Error("Name is required");
|
|
5716
5784
|
if (typeof data.id !== "number") throw new Error("ID is required");
|
|
@@ -5719,6 +5787,7 @@ var CopDef = class {
|
|
|
5719
5787
|
this.parts = data.parts ?? [];
|
|
5720
5788
|
this.halt = data.halt ?? false;
|
|
5721
5789
|
this.size = data.size ?? 0;
|
|
5790
|
+
this.conditions = data.conditions ?? [];
|
|
5722
5791
|
}
|
|
5723
5792
|
};
|
|
5724
5793
|
|
|
@@ -6101,7 +6170,7 @@ var DbRootUtils = class {
|
|
|
6101
6170
|
const cfg = module.config;
|
|
6102
6171
|
const compression = cfg.compression ? CompressionAlgorithms[cfg.compression]() : void 0;
|
|
6103
6172
|
const baseRomChunks = module.baseRomFiles ?? module.supaBaseRomFiles?.map((file) => {
|
|
6104
|
-
const chunkFile = new ChunkFile(file.
|
|
6173
|
+
const chunkFile = new ChunkFile(fileTypeLookup[file.type], file.name);
|
|
6105
6174
|
if (file.isText) {
|
|
6106
6175
|
chunkFile.textData = file.text ?? void 0;
|
|
6107
6176
|
chunkFile.size = file.text?.length ?? 0;
|
|
@@ -6112,7 +6181,7 @@ var DbRootUtils = class {
|
|
|
6112
6181
|
return chunkFile;
|
|
6113
6182
|
});
|
|
6114
6183
|
const projectChunks = module.projectFiles ?? module.supaProjectFiles?.map((file) => {
|
|
6115
|
-
const chunkFile = new ChunkFile(file.
|
|
6184
|
+
const chunkFile = new ChunkFile(fileTypeLookup[file.type], file.name);
|
|
6116
6185
|
chunkFile.group = file.module ?? void 0;
|
|
6117
6186
|
if (file.isText) {
|
|
6118
6187
|
chunkFile.textData = file.text ?? void 0;
|
|
@@ -6164,9 +6233,9 @@ var DbRootUtils = class {
|
|
|
6164
6233
|
const type = root.fileExtLookup[entry.extension];
|
|
6165
6234
|
if (!type) continue;
|
|
6166
6235
|
const existing = chunkFiles.find((x) => x.name === entry.name && x.type.type === type.type);
|
|
6167
|
-
const chunkFile = existing ?? new ChunkFile(entry.name
|
|
6236
|
+
const chunkFile = existing ?? new ChunkFile(type, entry.name);
|
|
6168
6237
|
if (group) chunkFile.group = group;
|
|
6169
|
-
if (chunkFile.type.
|
|
6238
|
+
if (chunkFile.type.isBlock || chunkFile.type.isPatch || chunkFile.type.struct) {
|
|
6170
6239
|
const chunkData = await readFileAsText(entry.path);
|
|
6171
6240
|
chunkFile.textData = chunkData;
|
|
6172
6241
|
chunkFile.size = chunkData.length;
|
|
@@ -6195,7 +6264,7 @@ var DbRootUtils = class {
|
|
|
6195
6264
|
const ext = block.type.extension;
|
|
6196
6265
|
const filePath = `${outPath}/${block.group ? block.group + "/" : ""}${block.scene ? block.scene + "/" : ""}${block.name}${ext ? "." + ext : ""}`;
|
|
6197
6266
|
if (block.parts?.length) {
|
|
6198
|
-
|
|
6267
|
+
block.textData = writer.generateAsm(block);
|
|
6199
6268
|
await saveFileAsText(filePath, block.textData);
|
|
6200
6269
|
} else {
|
|
6201
6270
|
if (!block.rawData) continue;
|
|
@@ -7113,6 +7182,7 @@ async function summaryFromSupabaseByProject(projectName) {
|
|
|
7113
7182
|
notes,
|
|
7114
7183
|
gameRomId,
|
|
7115
7184
|
platformBranchId,
|
|
7185
|
+
fileTypes,
|
|
7116
7186
|
createdAt,
|
|
7117
7187
|
updatedAt,
|
|
7118
7188
|
gameRom:GameRom!inner(
|
|
@@ -7223,10 +7293,10 @@ var RomGenerator = class {
|
|
|
7223
7293
|
if (!this.sourceData) throw new Error("Source data not initialized");
|
|
7224
7294
|
const reader = new BlockReader(this.sourceData, this.dbRoot);
|
|
7225
7295
|
const chunkFiles = reader.analyzeAndResolve();
|
|
7226
|
-
const asmFiles = chunkFiles.filter((b) => b.type.
|
|
7296
|
+
const asmFiles = chunkFiles.filter((b) => b.type.isBlock);
|
|
7227
7297
|
const patchFiles = [];
|
|
7228
7298
|
const writer = new BlockWriter(reader);
|
|
7229
|
-
for (const block of
|
|
7299
|
+
for (const block of chunkFiles) if (block.parts?.length) block.textData = writer.generateAsm(block);
|
|
7230
7300
|
for (const chunkFile of this.dbRoot.baseRomFiles) this.applyPatchFile(chunkFile, chunkFiles, asmFiles, patchFiles);
|
|
7231
7301
|
const moduleLookup = this.applyProjectInit(chunkFiles, asmFiles, patchFiles);
|
|
7232
7302
|
if (unshiftManualFiles) for (const file of manualFiles ?? []) this.applyPatchFile(file, chunkFiles, asmFiles, patchFiles);
|
|
@@ -7251,7 +7321,7 @@ var RomGenerator = class {
|
|
|
7251
7321
|
const existing = chunkFiles.find((x) => x.name === chunkFile.name);
|
|
7252
7322
|
if (chunkFile.textData) if (existing) existing.textData = chunkFile.textData;
|
|
7253
7323
|
else {
|
|
7254
|
-
if (chunkFile.type.
|
|
7324
|
+
if (chunkFile.type.isPatch) patchFiles.push(chunkFile);
|
|
7255
7325
|
asmFiles.push(chunkFile);
|
|
7256
7326
|
chunkFiles.push(chunkFile);
|
|
7257
7327
|
}
|
|
@@ -7502,5 +7572,5 @@ const snes = {
|
|
|
7502
7572
|
const isPlatformNode = typeof process !== "undefined" && process.versions?.node;
|
|
7503
7573
|
|
|
7504
7574
|
//#endregion
|
|
7505
|
-
export { Address, AddressSpace, AddressType, AddressingModeHandler, AsmBlock, AsmBlockUtils, AsmReader, Assembler, AssemblerState, BinType, BitStream, BlockReader, BlockReaderConstants, BlockWriter, Byte, ChunkFile, ChunkFileUtils, CompressionAlgorithms, CompressionRegistry, CopCommandProcessor, CopDef, CpuMode, DbAddressingMode, DbBlock, DbFile, DbFileType, DbGroup, DbHeader, DbHeaderPart, DbOverride, DbPart, DbRootUtils, DbScene, DbStringCommand, DbStringDictionary, DbStringType, DbStruct, DbTransform, LocationWrapper, Long, MapExt, MemberType, MemoryMapMode, ObjectType, Op, OpCode, OperationContext, PostProcessor, ProcessorStateManager, QuintetLZ, ReferenceManager, RegisterType, Registers, RomDataReader, RomGenerator, RomLayout, RomProcessingConstants, RomProcessor, RomState, RomStateUtils, RomWriter, SortedMap, SpriteFrame, SpriteGroup, SpriteMap, SpritePart, Stack, StackOperations, StatusFlags, StringProcessor, StringReader, StringSizeComparer, SupabaseErrorCode, SupabaseFromError, TableEntry, TransformProcessor, TypeParser, TypedNumber, Word, XformType, base64ToUint8Array, binaryToUtf8String, bytesToHex, clamp, crc32_buffer, crc32_text_utf16, crc32_text_utf8,
|
|
7575
|
+
export { Address, AddressSpace, AddressType, AddressingModeHandler, AsmBlock, AsmBlockUtils, AsmReader, Assembler, AssemblerState, BinType, BitStream, BlockReader, BlockReaderConstants, BlockWriter, Byte, ChunkFile, ChunkFileUtils, CompressionAlgorithms, CompressionRegistry, CopCommandProcessor, CopDef, CpuMode, DbAddressingMode, DbBlock, DbFile, DbFileType, DbGroup, DbHeader, DbHeaderPart, DbOverride, DbPart, DbRootUtils, DbScene, DbStringCommand, DbStringDictionary, DbStringType, DbStruct, DbTransform, LocationWrapper, Long, MapExt, MemberType, MemoryMapMode, ObjectType, Op, OpCode, OperationContext, PostProcessor, ProcessorStateManager, QuintetLZ, ReferenceManager, RegisterType, Registers, RomDataReader, RomGenerator, RomLayout, RomProcessingConstants, RomProcessor, RomState, RomStateUtils, RomWriter, SortedMap, SpriteFrame, SpriteGroup, SpriteMap, SpritePart, Stack, StackOperations, StatusFlags, StringProcessor, StringReader, StringSizeComparer, SupabaseErrorCode, SupabaseFromError, TableEntry, TransformProcessor, TypeParser, TypedNumber, Word, XformType, base64ToUint8Array, binaryToUtf8String, bytesToHex, clamp, combineHeader, crc32_buffer, crc32_text_utf16, crc32_text_utf8, createDbPath, createSupabaseClient, createTempDirectory, decodeBase64, decodeBase64String, decodeDataString, encodeBase64, encodeBase64String, fileExists, fromSupabaseByGameRom, fromSupabaseById, fromSupabaseByName, fromSupabaseByProject, getDirectory, getEnvVar, getNestedProperty, getSupabaseClient, hexToBytes, hexToUint8Array, indexOfAny, isPlatformNode, isValidBase64, listDirectory, readFileAsBinary, readFileAsText, readJsonFile, removeDirectory, resetSupabaseClient, saveFileAsBinary, saveFileAsText, snes, summaryFromSupabaseByProject, uint8ArrayToBase64, validateEnvironmentVariables };
|
|
7506
7576
|
//# sourceMappingURL=index.mjs.map
|