summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tools/rom/build.c85
1 files changed, 58 insertions, 27 deletions
diff --git a/tools/rom/build.c b/tools/rom/build.c
index 0e9e47f6..cbefc6d8 100644
--- a/tools/rom/build.c
+++ b/tools/rom/build.c
@@ -220,9 +220,15 @@ bool Align(size_t alignment, FILE *fpRom, size_t *pAddress) {
return true;
}
-// Writes the ARM9 overlay table and returns the entries to `*pEntries`. `*pEntries` is allocated using `malloc`, so remember
-// to `free` it.
-bool WriteArm9OverlayTable(FILE *fpRom, size_t *pAddress, Header *pHeader, const char *overlayDataFile, OverlayEntry **pEntries) {
+bool WriteArm9OverlayTable(
+ FILE *fpRom,
+ size_t *pAddress,
+ Header *pHeader,
+ const char *overlayDataFile,
+ OverlayEntry **pEntries,
+ OverlayData **pData,
+ size_t *pNumOverlays
+) {
size_t address = *pAddress;
FILE *fp = fopen(ARM9_OVERLAY_TABLE_FILE, "rb");
@@ -232,7 +238,7 @@ bool WriteArm9OverlayTable(FILE *fpRom, size_t *pAddress, Header *pHeader, const
if (tableSize % sizeof(OverlayEntry) != 0) {
FATAL("ARM9 overlay table has an invalid size (entries must be %d bytes long)\n", sizeof(OverlayEntry));
}
- size_t numEntries = tableSize / sizeof(OverlayEntry);
+ size_t numOverlays = tableSize / sizeof(OverlayEntry);
fseek(fp, 0, SEEK_SET);
OverlayEntry *entries = malloc(tableSize);
@@ -244,8 +250,8 @@ bool WriteArm9OverlayTable(FILE *fpRom, size_t *pAddress, Header *pHeader, const
if (fp == NULL) FATAL("Failed to open ARM9 overlay data file '%s'\n", overlayDataFile);
fseek(fp, 0, SEEK_END);
size_t dataSize = ftell(fp);
- if (dataSize != numEntries * sizeof(OverlayData)) {
- FATAL("ARM9 data file has an invalid size (expected %d entries with %d bytes each)\n", numEntries, sizeof(OverlayData));
+ if (dataSize != numOverlays * sizeof(OverlayData)) {
+ FATAL("ARM9 overlay data file has an invalid size (expected %d overlays with %d bytes each)\n", numOverlays, sizeof(OverlayData));
}
fseek(fp, 0, SEEK_SET);
@@ -253,43 +259,50 @@ bool WriteArm9OverlayTable(FILE *fpRom, size_t *pAddress, Header *pHeader, const
if (data == NULL) FATAL("Failed to allocate array for ARM9 overlay data entries\n");
if (fread(data, dataSize, 1, fp) != 1) FATAL("Failed to read ARM9 overlay data '%s'\n", overlayDataFile);
fclose(fp);
- for (size_t i = 0; i < numEntries; ++i) {
+ for (size_t i = 0; i < numOverlays; ++i) {
entries[i].fileId = data[i].fileId;
}
- free(data);
if (fwrite(entries, tableSize, 1, fpRom) != 1) FATAL("Failed to write ARM9 overlay table\n");
*pAddress = address;
*pEntries = entries;
+ *pData = data;
+ *pNumOverlays = numOverlays;
pHeader->arm9Overlays.size = tableSize;
return true;
}
-bool WriteArm9Overlays(FILE *fpRom, size_t *pAddress, size_t *pNumOverlays, FatEntry *fatEntries, OverlayEntry *table) {
+bool WriteArm9OverlayFiles(
+ FILE *fpRom,
+ size_t *pAddress,
+ size_t numOverlays,
+ FatEntry *fatEntries,
+ OverlayEntry *table,
+ const OverlayData *data
+) {
size_t address = *pAddress;
- uint32_t ovNum = 0;
char fileName[32];
if (chdir(OVERLAYS_SUBDIR) != 0) FATAL("Failed to enter overlays directory '" OVERLAYS_SUBDIR "'\n");
- while (true) {
+ for (size_t ovNum = 0; ovNum < numOverlays; ++ovNum) {
sprintf(fileName, "ov%02d.lz", ovNum);
if (!Align(512, fpRom, &address)) return false;
size_t startOffset = address;
uint32_t fileSize = 0;
- if (!AppendFile(fpRom, fileName, &address, &fileSize)) break;
+ if (!AppendFile(fpRom, fileName, &address, &fileSize)) return false;
table[ovNum].compressedSize = fileSize;
table[ovNum].isCompressed = true;
- fatEntries[ovNum].startOffset = startOffset;
- fatEntries[ovNum].endOffset = address;
- ovNum += 1;
+ uint32_t fileId = data[ovNum].fileId;
+ if (fileId >= MAX_OVERLAYS) FATAL("Overlay %d's file ID (%d) exceeds the maximum %d\n", ovNum, fileId, MAX_OVERLAYS);
+ fatEntries[fileId].startOffset = startOffset;
+ fatEntries[fileId].endOffset = address;
}
if (chdir("..") != 0) FATAL("Failed to leave overlays directory '" OVERLAYS_SUBDIR "'\n");
*pAddress = address;
- *pNumOverlays = ovNum;
return true;
}
@@ -301,6 +314,31 @@ bool RewriteArm9OverlayTable(FILE *fpRom, const Header *header, OverlayEntry *en
return true;
}
+bool WriteArm9Overlays(
+ FILE *fpRom,
+ size_t *pAddress,
+ Header *pHeader,
+ const char *overlayDataFile,
+ FatEntry *fatEntries,
+ size_t *pNumOverlays
+) {
+ size_t address = *pAddress;
+
+ OverlayEntry *entries;
+ OverlayData *data;
+ size_t numOverlays;
+ if (!WriteArm9OverlayTable(fpRom, &address, pHeader, overlayDataFile, &entries, &data, &numOverlays)) return false;
+ if (!WriteArm9OverlayFiles(fpRom, &address, numOverlays, fatEntries, entries, data)) return false;
+ if (!RewriteArm9OverlayTable(fpRom, pHeader, entries, numOverlays)) return false;
+
+ free(data);
+ free(entries);
+
+ *pAddress = address;
+ *pNumOverlays = numOverlays;
+ return true;
+}
+
typedef struct {
FntEntry *table;
uint16_t tableSize;
@@ -804,20 +842,13 @@ int main(int argc, const char **argv) {
if (!AppendFile(fpRom, ARM9_FOOTER_FILE, &address, NULL)) return 1;
- // --------------------- Write ARM9 overlay table ---------------------
+ // --------------------- Write ARM9 overlay table and overlay files ---------------------
if (!Align(512, fpRom, &address)) return 1;
header.arm9Overlays.offset = address;
- OverlayEntry *arm9overlays;
- if (!WriteArm9OverlayTable(fpRom, &address, &header, arm9overlayDataFile, &arm9overlays)) return 1;
- FreeFullPath(&arm9overlayDataFile);
-
-
- // --------------------- Write ARM9 overlays ---------------------
- FatEntry overlayEntries[MAX_OVERLAYS];
size_t numOverlays = 0;
- if (!WriteArm9Overlays(fpRom, &address, &numOverlays, overlayEntries, arm9overlays)) return 1;
- if (!RewriteArm9OverlayTable(fpRom, &header, arm9overlays, numOverlays)) return 1;
- free(arm9overlays);
+ FatEntry overlayEntries[MAX_OVERLAYS];
+ if (!WriteArm9Overlays(fpRom, &address, &header, arm9overlayDataFile, overlayEntries, &numOverlays)) return 1;
+ FreeFullPath(&arm9overlayDataFile);
if (chdir(rootDir) != 0) {
fprintf(stderr, "Failed to leave build directory '%s'\n", buildDir);