Match overlay portion of FAT

This commit is contained in:
Aetias
2023-10-22 08:01:33 +02:00
parent e6f2b7c31c
commit 075fd200fe
+58 -27
View File
@@ -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);