From 07eaa3b2c64e14533d603a8283b78374af0824a7 Mon Sep 17 00:00:00 2001 From: Aetias Date: Sun, 15 Oct 2023 23:54:12 +0200 Subject: [PATCH] Convert indentation to spaces --- tools/rom/build.c | 648 ++++++++++++++++++++++---------------------- tools/rom/extract.c | 230 ++++++++-------- tools/rom/files.h | 220 +++++++-------- tools/rom/rom.h | 28 +- tools/rom/util.h | 22 +- 5 files changed, 575 insertions(+), 573 deletions(-) diff --git a/tools/rom/build.c b/tools/rom/build.c index 44977b88..65ebaf16 100644 --- a/tools/rom/build.c +++ b/tools/rom/build.c @@ -114,235 +114,235 @@ void InitHeader(Header *pHeader, const BuildInfo *info) { } bool AppendFile(FILE *fpRom, const char *filePath, size_t *pAddress, uint32_t *pFileSize) { - assert(readBuffer != NULL); + assert(readBuffer != NULL); - FILE *fp = fopen(filePath, "rb"); - if (fp == NULL) FATAL("Failed to open file '%s'\n", filePath); - fseek(fp, 0, SEEK_END); - size_t size = ftell(fp); - fseek(fp, 0, SEEK_SET); - - size_t bytesWritten = 0; - while (bytesWritten < size) { - size_t bytesRead = fread(readBuffer, 1, BUFFER_SIZE, fp); - if (bytesRead == 0) FATAL("Failed to read from file '%s'\n", filePath); - if (fwrite(readBuffer, bytesRead, 1, fpRom) != 1) FATAL("Failed to write file '%s' to output ROM\n", filePath); - bytesWritten += bytesRead; - } - fclose(fp); + FILE *fp = fopen(filePath, "rb"); + if (fp == NULL) FATAL("Failed to open file '%s'\n", filePath); + fseek(fp, 0, SEEK_END); + size_t size = ftell(fp); + fseek(fp, 0, SEEK_SET); + + size_t bytesWritten = 0; + while (bytesWritten < size) { + size_t bytesRead = fread(readBuffer, 1, BUFFER_SIZE, fp); + if (bytesRead == 0) FATAL("Failed to read from file '%s'\n", filePath); + if (fwrite(readBuffer, bytesRead, 1, fpRom) != 1) FATAL("Failed to write file '%s' to output ROM\n", filePath); + bytesWritten += bytesRead; + } + fclose(fp); - *pAddress += size; - if (pFileSize != NULL) *pFileSize = size; - return true; + *pAddress += size; + if (pFileSize != NULL) *pFileSize = size; + return true; } bool Align(size_t alignment, FILE *fpRom, size_t *pAddress) { - assert((alignment & (alignment - 1)) == 0); + assert((alignment & (alignment - 1)) == 0); - size_t mask = alignment - 1; - size_t address = ftell(fpRom); - size_t nextAddr = (address + mask) & ~mask; - while (address < nextAddr) { - if (fputc(0xff, fpRom) == -1) FATAL("Failed to pad output ROM at address 0x%x\n", address); - address += 1; - } + size_t mask = alignment - 1; + size_t address = ftell(fpRom); + size_t nextAddr = (address + mask) & ~mask; + while (address < nextAddr) { + if (fputc(0xff, fpRom) == -1) FATAL("Failed to pad output ROM at address 0x%x\n", address); + address += 1; + } *pAddress = address; - return true; + return true; } bool WriteArm9Overlays(FILE *fpRom, size_t *pAddress, size_t *pNumOverlays, FatEntry *entries, size_t maxEntries) { - size_t address = *pAddress; - uint32_t ovNum = 0; - char fileName[32]; + 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"); + if (chdir(OVERLAYS_SUBDIR) != 0) FATAL("Failed to enter overlays directory '" OVERLAYS_SUBDIR "'\n"); - while (true) { - sprintf(fileName, "ov%02d.lz", ovNum); - if (!Align(512, fpRom, &address)) return false; - size_t startOffset = address; - if (!AppendFile(fpRom, fileName, &address, NULL)) break; - entries[ovNum].startOffset = startOffset; - entries[ovNum].endOffset = address; + while (true) { + sprintf(fileName, "ov%02d.lz", ovNum); + if (!Align(512, fpRom, &address)) return false; + size_t startOffset = address; + if (!AppendFile(fpRom, fileName, &address, NULL)) break; + entries[ovNum].startOffset = startOffset; + entries[ovNum].endOffset = address; ovNum += 1; - } + } - if (chdir("..") != 0) FATAL("Failed to leave overlays directory '" OVERLAYS_SUBDIR "'\n"); + if (chdir("..") != 0) FATAL("Failed to leave overlays directory '" OVERLAYS_SUBDIR "'\n"); - *pAddress = address; - *pNumOverlays = ovNum; - return true; + *pAddress = address; + *pNumOverlays = ovNum; + return true; } typedef struct { - FntEntry *table; - uint16_t tableSize; - uint16_t tableMax; + FntEntry *table; + uint16_t tableSize; + uint16_t tableMax; - uint16_t nextFileId; - uint16_t parentId; + uint16_t nextFileId; + uint16_t parentId; - uint8_t *subtable; - size_t subtableSize; - size_t subtableMax; + uint8_t *subtable; + size_t subtableSize; + size_t subtableMax; } FntContext; bool GrowFntTable(FntContext *pContext, size_t minEntries) { - FntContext ctx; - memcpy(&ctx, pContext, sizeof(ctx)); + FntContext ctx; + memcpy(&ctx, pContext, sizeof(ctx)); - if (minEntries <= ctx.tableMax) return true; - while (minEntries > ctx.tableMax) { - ctx.tableMax *= 2; - } + if (minEntries <= ctx.tableMax) return true; + while (minEntries > ctx.tableMax) { + ctx.tableMax *= 2; + } - FntEntry *newTable = realloc(ctx.table, ctx.tableMax * sizeof(FntEntry)); - if (newTable == NULL) FATAL("Failed to reallocate FNT table to %d entries\n", ctx.tableMax); - ctx.table = newTable; + FntEntry *newTable = realloc(ctx.table, ctx.tableMax * sizeof(FntEntry)); + if (newTable == NULL) FATAL("Failed to reallocate FNT table to %d entries\n", ctx.tableMax); + ctx.table = newTable; - memcpy(pContext, &ctx, sizeof(ctx)); - return true; + memcpy(pContext, &ctx, sizeof(ctx)); + return true; } bool GrowFntSubtable(FntContext *pContext, size_t growSize) { - FntContext ctx; - memcpy(&ctx, pContext, sizeof(ctx)); + FntContext ctx; + memcpy(&ctx, pContext, sizeof(ctx)); - if (ctx.subtableSize + growSize < ctx.subtableMax) return true; - while (ctx.subtableSize + growSize >= ctx.subtableMax) { - ctx.subtableMax *= 2; - } + if (ctx.subtableSize + growSize < ctx.subtableMax) return true; + while (ctx.subtableSize + growSize >= ctx.subtableMax) { + ctx.subtableMax *= 2; + } - uint8_t *newTable = realloc(ctx.subtable, ctx.subtableMax); - if (newTable == NULL) FATAL("Failed to reallocate FNT subtable to %d bytes\n", ctx.subtableMax); - ctx.subtable = newTable; + uint8_t *newTable = realloc(ctx.subtable, ctx.subtableMax); + if (newTable == NULL) FATAL("Failed to reallocate FNT subtable to %d bytes\n", ctx.subtableMax); + ctx.subtable = newTable; - memcpy(pContext, &ctx, sizeof(ctx)); - return true; + memcpy(pContext, &ctx, sizeof(ctx)); + return true; } bool WriteFntSubtable(FileTree *tree, FntContext *pContext) { - FntContext ctx; - memcpy(&ctx, pContext, sizeof(ctx)); - size_t subtableStart = ctx.subtableSize; + FntContext ctx; + memcpy(&ctx, pContext, sizeof(ctx)); + size_t subtableStart = ctx.subtableSize; - // Create initial subtable entries - size_t numFiles = 0; - for (size_t i = 0; i < tree->numChildren; ++i) { - FileTree *child = &tree->children[i]; - FntSubEntry *entry = child->entry; - if (!entry->isSubdir) numFiles += 1; + // Create initial subtable entries + size_t numFiles = 0; + for (size_t i = 0; i < tree->numChildren; ++i) { + FileTree *child = &tree->children[i]; + FntSubEntry *entry = child->entry; + if (!entry->isSubdir) numFiles += 1; - size_t entrySize = sizeof(*entry) + entry->length + (entry->isSubdir ? 2 : 0); - if (!GrowFntSubtable(&ctx, entrySize)) return false; + size_t entrySize = sizeof(*entry) + entry->length + (entry->isSubdir ? 2 : 0); + if (!GrowFntSubtable(&ctx, entrySize)) return false; - FntSubEntry *dest = (FntSubEntry*) (ctx.subtable + ctx.subtableSize); - memcpy(dest, entry, entrySize); - ctx.subtableSize += entrySize; - } + FntSubEntry *dest = (FntSubEntry*) (ctx.subtable + ctx.subtableSize); + memcpy(dest, entry, entrySize); + ctx.subtableSize += entrySize; + } - if (!GrowFntSubtable(&ctx, 1)) return false; - ctx.subtable[ctx.subtableSize] = 0; // End of subtable - ctx.subtableSize += 1; + if (!GrowFntSubtable(&ctx, 1)) return false; + ctx.subtable[ctx.subtableSize] = 0; // End of subtable + ctx.subtableSize += 1; ctx.nextFileId += numFiles; - // Recurse child directories - for (size_t i = 0; i < tree->numChildren; ++i) { - FileTree *child = &tree->children[i]; - FntSubEntry *entry = child->entry; - if (!entry->isSubdir) continue; - uint16_t subdirId = 0xf000 | ctx.tableSize; - WRITE_SUBDIR_ID(entry, subdirId); - child->firstFileId = ctx.nextFileId; - FntEntry mainEntry; - mainEntry.subtableOffset = ctx.subtableSize; // will add main table length later - mainEntry.firstFile = ctx.nextFileId; - mainEntry.parentId = ctx.parentId; - if (!GrowFntTable(&ctx, ctx.tableSize + 1)) return false; - memcpy(&ctx.table[ctx.tableSize], &mainEntry, sizeof(mainEntry)); + // Recurse child directories + for (size_t i = 0; i < tree->numChildren; ++i) { + FileTree *child = &tree->children[i]; + FntSubEntry *entry = child->entry; + if (!entry->isSubdir) continue; + uint16_t subdirId = 0xf000 | ctx.tableSize; + WRITE_SUBDIR_ID(entry, subdirId); + child->firstFileId = ctx.nextFileId; + FntEntry mainEntry; + mainEntry.subtableOffset = ctx.subtableSize; // will add main table length later + mainEntry.firstFile = ctx.nextFileId; + mainEntry.parentId = ctx.parentId; + if (!GrowFntTable(&ctx, ctx.tableSize + 1)) return false; + memcpy(&ctx.table[ctx.tableSize], &mainEntry, sizeof(mainEntry)); ctx.tableSize += 1; - uint16_t oldParentId = ctx.parentId; - ctx.parentId = subdirId; + uint16_t oldParentId = ctx.parentId; + ctx.parentId = subdirId; - char name[128]; - strncpy(name, entry->name, entry->length); + char name[128]; + strncpy(name, entry->name, entry->length); name[entry->length] = '\0'; - if (!WriteFntSubtable(child, &ctx)) return false; + if (!WriteFntSubtable(child, &ctx)) return false; - ctx.parentId = oldParentId; - } + ctx.parentId = oldParentId; + } - // Update subdir IDs - size_t subtableOffset = 0; - for (size_t i = 0; i < tree->numChildren; ++i) { - FileTree *child = &tree->children[i]; - FntSubEntry *entry = child->entry; - size_t entrySize = sizeof(*entry) + entry->length + (entry->isSubdir ? 2 : 0); - memcpy(ctx.subtable + subtableStart + subtableOffset, entry, entrySize); - subtableOffset += entrySize; - } - - memcpy(pContext, &ctx, sizeof(ctx)); - return true; + // Update subdir IDs + size_t subtableOffset = 0; + for (size_t i = 0; i < tree->numChildren; ++i) { + FileTree *child = &tree->children[i]; + FntSubEntry *entry = child->entry; + size_t entrySize = sizeof(*entry) + entry->length + (entry->isSubdir ? 2 : 0); + memcpy(ctx.subtable + subtableStart + subtableOffset, entry, entrySize); + subtableOffset += entrySize; + } + + memcpy(pContext, &ctx, sizeof(ctx)); + return true; } bool WriteFnt(FILE *fpRom, size_t *pAddress, FileTree *pRoot, size_t firstFileId, size_t *pNumFiles) { - size_t address = *pAddress; + size_t address = *pAddress; - FntContext ctx; - ctx.table = malloc(INITIAL_TABLE_SIZE * sizeof(FntEntry)); - if (ctx.table == NULL) FATAL("Failed to allocate FNT table\n"); - ctx.tableSize = 1; - ctx.tableMax = INITIAL_TABLE_SIZE; + FntContext ctx; + ctx.table = malloc(INITIAL_TABLE_SIZE * sizeof(FntEntry)); + if (ctx.table == NULL) FATAL("Failed to allocate FNT table\n"); + ctx.tableSize = 1; + ctx.tableMax = INITIAL_TABLE_SIZE; - ctx.nextFileId = firstFileId; - ctx.parentId = 0xf000; // root directory + ctx.nextFileId = firstFileId; + ctx.parentId = 0xf000; // root directory - ctx.subtable = malloc(INITIAL_SUBTABLE_SIZE); - if (ctx.subtable == NULL) FATAL("Failed to allocate FNT subtable\n"); - ctx.subtableSize = 0; - ctx.subtableMax = INITIAL_SUBTABLE_SIZE; + ctx.subtable = malloc(INITIAL_SUBTABLE_SIZE); + if (ctx.subtable == NULL) FATAL("Failed to allocate FNT subtable\n"); + ctx.subtableSize = 0; + ctx.subtableMax = INITIAL_SUBTABLE_SIZE; ctx.table[0].subtableOffset = 0; // will add main table length later - ctx.table[0].firstFile = firstFileId; - ctx.table[0].parentId = 0; // will be set to number of directories later + ctx.table[0].firstFile = firstFileId; + ctx.table[0].parentId = 0; // will be set to number of directories later - size_t tableStart = address; - if (!WriteFntSubtable(pRoot, &ctx)) return false; + size_t tableStart = address; + if (!WriteFntSubtable(pRoot, &ctx)) return false; - size_t tableLength = ctx.tableSize * sizeof(FntEntry); - for (size_t i = 0; i < ctx.tableSize; ++i) { - ctx.table[i].subtableOffset += tableLength; - } - if (fwrite(ctx.table, sizeof(FntEntry), ctx.tableSize, fpRom) != ctx.tableSize) FATAL("Failed to write FNT table\n"); - address += ctx.tableSize * sizeof(FntEntry); - if (fwrite(ctx.subtable, ctx.subtableSize, 1, fpRom) != 1) FATAL("Failed to write FNT subtables\n"); - address += ctx.subtableSize; + size_t tableLength = ctx.tableSize * sizeof(FntEntry); + for (size_t i = 0; i < ctx.tableSize; ++i) { + ctx.table[i].subtableOffset += tableLength; + } + if (fwrite(ctx.table, sizeof(FntEntry), ctx.tableSize, fpRom) != ctx.tableSize) FATAL("Failed to write FNT table\n"); + address += ctx.tableSize * sizeof(FntEntry); + if (fwrite(ctx.subtable, ctx.subtableSize, 1, fpRom) != 1) FATAL("Failed to write FNT subtables\n"); + address += ctx.subtableSize; - free(ctx.table); - free(ctx.subtable); + free(ctx.table); + free(ctx.subtable); - *pAddress = address; - *pNumFiles = ctx.nextFileId; - return true; + *pAddress = address; + *pNumFiles = ctx.nextFileId; + return true; } bool WriteFat(FILE *fpRom, size_t *pAddress, size_t numFiles) { - size_t address = *pAddress; - size_t fatStart = address; + size_t address = *pAddress; + size_t fatStart = address; - FatEntry blank; - blank.startOffset = 0; - blank.endOffset = 0; - for (size_t i = 0; i < numFiles; ++i) { - if (fwrite(&blank, sizeof(blank), 1, fpRom) != 1) FATAL("Failed to write blank placeholder FAT entry\n"); - } - address += sizeof(blank) * numFiles; + FatEntry blank; + blank.startOffset = 0; + blank.endOffset = 0; + for (size_t i = 0; i < numFiles; ++i) { + if (fwrite(&blank, sizeof(blank), 1, fpRom) != 1) FATAL("Failed to write blank placeholder FAT entry\n"); + } + address += sizeof(blank) * numFiles; - *pAddress = address; - return true; + *pAddress = address; + return true; } bool ReadTitle(const char *language, const char *file, wchar_t *title, size_t titleSize) { @@ -402,45 +402,45 @@ bool WriteBanner(FILE *fpRom, size_t *pAddress) { } bool AppendAssets(FILE *fpRom, size_t *pAddress, const FileTree *tree, FatEntry *entries) { - size_t address = *pAddress; + size_t address = *pAddress; - // Traverse directories - for (size_t i = 0; i < tree->numChildren; ++i) { - FileTree *child = &tree->children[i]; - FntSubEntry *entry = child->entry; - if (!entry->isSubdir) continue; - char name[128]; - strncpy(name, entry->name, entry->length); + // Traverse directories + for (size_t i = 0; i < tree->numChildren; ++i) { + FileTree *child = &tree->children[i]; + FntSubEntry *entry = child->entry; + if (!entry->isSubdir) continue; + char name[128]; + strncpy(name, entry->name, entry->length); name[entry->length] = '\0'; - if (chdir(name) != 0) FATAL("Failed to enter assets directory '%s'\n", name); - if (!AppendAssets(fpRom, &address, child, entries)) return false; - if (chdir("..") != 0) FATAL("Failed to leave assets directory '%s'\n", name); - } - - // Append files - size_t fileId = tree->firstFileId; - for (size_t i = 0; i < tree->numChildren; ++i, ++fileId) { - FileTree *child = &tree->children[i]; - FntSubEntry *entry = child->entry; - if (entry->isSubdir) continue; - char name[128]; - strncpy(name, entry->name, entry->length); + if (chdir(name) != 0) FATAL("Failed to enter assets directory '%s'\n", name); + if (!AppendAssets(fpRom, &address, child, entries)) return false; + if (chdir("..") != 0) FATAL("Failed to leave assets directory '%s'\n", name); + } + + // Append files + size_t fileId = tree->firstFileId; + for (size_t i = 0; i < tree->numChildren; ++i, ++fileId) { + FileTree *child = &tree->children[i]; + FntSubEntry *entry = child->entry; + if (entry->isSubdir) continue; + char name[128]; + strncpy(name, entry->name, entry->length); name[entry->length] = '\0'; - if (!Align(512, fpRom, &address)) return false; - size_t startOffset = address; - if (!AppendFile(fpRom, name, &address, NULL)) return false; - entries[fileId].startOffset = startOffset; - entries[fileId].endOffset = address; - } + if (!Align(512, fpRom, &address)) return false; + size_t startOffset = address; + if (!AppendFile(fpRom, name, &address, NULL)) return false; + entries[fileId].startOffset = startOffset; + entries[fileId].endOffset = address; + } - *pAddress = address; - return true; + *pAddress = address; + return true; } bool RewriteFat(FILE *fpRom, size_t fatStart, const FatEntry *entries, size_t numFiles) { fseek(fpRom, fatStart, SEEK_SET); - if (fwrite(entries, sizeof(*entries), numFiles, fpRom) != numFiles) FATAL("Failed to rewrite FAT table\n"); - fseek(fpRom, 0, SEEK_END); + if (fwrite(entries, sizeof(*entries), numFiles, fpRom) != numFiles) FATAL("Failed to rewrite FAT table\n"); + fseek(fpRom, 0, SEEK_END); } void PrintUsage(const char *program) { @@ -450,7 +450,7 @@ void PrintUsage(const char *program) { "Usage: %s -a BASEDIR -b BUILDDIR -r REGION -o OUTFILE\n" " -a BASEDIR \tBase directory generated by extractrom\n" " -b BUILDDIR\tBuild directory generated by Makefile\n" - " -r REGION \tJ = Japan, E = USA, P = Europe\n" + " -r REGION \tJ = Japan, E = USA, P = Europe\n" " -o OUTFILE \tOutput ROM file\n", program ); @@ -465,7 +465,7 @@ int main(int argc, const char **argv) { const char *baseDir = NULL; const char *buildDir = NULL; const char *romFile = NULL; - Region region = 0; + Region region = 0; for (int i = 1; i < argc; ++i) { if (strcmp(argv[i], "-o") == 0) { if (++i >= argc) { @@ -486,171 +486,173 @@ int main(int argc, const char **argv) { } buildDir = argv[i]; } else if (strcmp(argv[i], "-r") == 0) { - if (++i >= argc) { - fprintf(stderr, "Expected region after -r\n"); - return 1; - } - if (strlen(argv[i]) != 1) { - fprintf(stderr, "Region must be a single character\n"); - return 1; - } - region = argv[i][0]; - } else { + if (++i >= argc) { + fprintf(stderr, "Expected region after -r\n"); + return 1; + } + if (strlen(argv[i]) != 1) { + fprintf(stderr, "Region must be a single character\n"); + return 1; + } + region = argv[i][0]; + } else { fprintf(stderr, "Unknown option '%s'\n", argv[i]); return 1; } } - if (baseDir == NULL) { - PrintUsage(program); - fprintf(stderr, "Please provide a base directory, see usage above\n"); - return 1; - } - if (buildDir == NULL) { - PrintUsage(program); - fprintf(stderr, "Please provide a build directory, see usage above\n"); - return 1; - } - if (region != REGION_JAPAN && region != REGION_USA && region != REGION_EUROPE) { - PrintUsage(program); - fprintf(stderr, "Invalid region '%c', see usage above\n", region); - return 1; - } - if (romFile == NULL) { - PrintUsage(program); - fprintf(stderr, "Please provide an output ROM file, see usage above\n"); - return 1; - } + if (baseDir == NULL) { + PrintUsage(program); + fprintf(stderr, "Please provide a base directory, see usage above\n"); + return 1; + } + if (buildDir == NULL) { + PrintUsage(program); + fprintf(stderr, "Please provide a build directory, see usage above\n"); + return 1; + } + if (region != REGION_JAPAN && region != REGION_USA && region != REGION_EUROPE) { + PrintUsage(program); + fprintf(stderr, "Invalid region '%c', see usage above\n", region); + return 1; + } + if (romFile == NULL) { + PrintUsage(program); + fprintf(stderr, "Please provide an output ROM file, see usage above\n"); + return 1; + } - char rootDir[256]; - if (getcwd(rootDir, sizeof(rootDir)) == NULL) { - fprintf(stderr, "Failed to get root directory\n"); - return 1; - } + char rootDir[256]; + if (getcwd(rootDir, sizeof(rootDir)) == NULL) { + fprintf(stderr, "Failed to get root directory\n"); + return 1; + } - FILE *fpRom = fopen(romFile, "wb"); - if (fpRom == NULL) { - fprintf(stderr, "Failed to open output ROM file '%s'\n", romFile); - return 1; - } - - readBuffer = malloc(BUFFER_SIZE); - if (readBuffer == NULL) { - fprintf(stderr, "Failed to allocate read buffer to %d bytes\n", BUFFER_SIZE); - return 1; - } + FILE *fpRom = fopen(romFile, "wb"); + if (fpRom == NULL) { + fprintf(stderr, "Failed to open output ROM file '%s'\n", romFile); + return 1; + } + + readBuffer = malloc(BUFFER_SIZE); + if (readBuffer == NULL) { + fprintf(stderr, "Failed to allocate read buffer to %d bytes\n", BUFFER_SIZE); + return 1; + } GenerateCrcTable(); - BuildInfo info; - info.region = region; - size_t address = 0; + BuildInfo info; + info.region = region; + size_t address = 0; - Header header; - InitHeader(&header, &info); + Header header; + InitHeader(&header, &info); - if (fwrite(&header, sizeof(header), 1, fpRom) != 1) { - fprintf(stderr, "Failed to write NDS header\n"); - return 1; - } - address += sizeof(header); + if (fwrite(&header, sizeof(header), 1, fpRom) != 1) { + fprintf(stderr, "Failed to write NDS header\n"); + return 1; + } + address += sizeof(header); - if (chdir(buildDir) != 0) { - fprintf(stderr, "Failed to enter build directory '%s'\n", buildDir); - return 1; - } + if (chdir(buildDir) != 0) { + fprintf(stderr, "Failed to enter build directory '%s'\n", buildDir); + return 1; + } - if (!Align(512, fpRom, &address)) return 1; - header.arm9.offset = address; - if (!AppendFile(fpRom, ARM9_PROGRAM_FILE, &address, &header.arm9.size)) return 1; - if (!AppendFile(fpRom, ARM9_FOOTER_FILE, &address, NULL)) return 1; + if (!Align(512, fpRom, &address)) return 1; + header.arm9.offset = address; + if (!AppendFile(fpRom, ARM9_PROGRAM_FILE, &address, &header.arm9.size)) return 1; + if (!AppendFile(fpRom, ARM9_FOOTER_FILE, &address, NULL)) return 1; - if (!Align(512, fpRom, &address)) return 1; - header.arm9Overlays.offset = address; - if (!AppendFile(fpRom, ARM9_OVERLAY_TABLE_FILE, &address, &header.arm9Overlays.size)) return 1; + if (!Align(512, fpRom, &address)) return 1; + header.arm9Overlays.offset = address; + if (!AppendFile(fpRom, ARM9_OVERLAY_TABLE_FILE, &address, &header.arm9Overlays.size)) return 1; - FatEntry overlayEntries[MAX_OVERLAYS]; - size_t numOverlays = 0; - if (!WriteArm9Overlays(fpRom, &address, &numOverlays, overlayEntries, MAX_OVERLAYS)) return 1; + FatEntry overlayEntries[MAX_OVERLAYS]; + size_t numOverlays = 0; + if (!WriteArm9Overlays(fpRom, &address, &numOverlays, overlayEntries, MAX_OVERLAYS)) return 1; - if (chdir(rootDir) != 0) { - fprintf(stderr, "Failed to leave build directory '%s'\n", buildDir); - return 1; - } + if (chdir(rootDir) != 0) { + fprintf(stderr, "Failed to leave build directory '%s'\n", buildDir); + return 1; + } - if (chdir(baseDir) != 0) { - fprintf(stderr, "Failed to enter base directory '%s'\n", baseDir); - return 1; - } + if (chdir(baseDir) != 0) { + fprintf(stderr, "Failed to enter base directory '%s'\n", baseDir); + return 1; + } - if (!Align(512, fpRom, &address)) return 1; - header.arm7.offset = address; - if (!AppendFile(fpRom, ARM7_PROGRAM_FILE, &address, &header.arm7.size)) return 1; + if (!Align(512, fpRom, &address)) return 1; + header.arm7.offset = address; + if (!AppendFile(fpRom, ARM7_PROGRAM_FILE, &address, &header.arm7.size)) return 1; - if (chdir(ASSETS_SUBDIR) != 0) { - fprintf(stderr, "Failed to enter assets directory '" ASSETS_SUBDIR "'\n"); - return 1; - } + if (chdir(ASSETS_SUBDIR) != 0) { + fprintf(stderr, "Failed to enter assets directory '" ASSETS_SUBDIR "'\n"); + return 1; + } - FileTree root; - if (!MakeFileTree(&root)) return false; - if (!SortFileTree(&root)) return false; + FileTree root; + if (!MakeFileTree(&root)) return false; + if (!SortFileTree(&root)) return false; - if (!Align(512, fpRom, &address)) return 1; - size_t numFiles = 0; - header.fileNames.offset = address; - if (!WriteFnt(fpRom, &address, &root, numOverlays, &numFiles)) return 1; - header.fileNames.size = address - header.fileNames.offset; + if (!Align(512, fpRom, &address)) return 1; + size_t numFiles = 0; + header.fileNames.offset = address; + if (!WriteFnt(fpRom, &address, &root, numOverlays, &numFiles)) return 1; + header.fileNames.size = address - header.fileNames.offset; - if (!Align(512, fpRom, &address)) return 1; - header.fileAllocs.offset = address; - if (!WriteFat(fpRom, &address, numFiles)) return 1; - header.fileAllocs.size = address - header.fileAllocs.offset; + if (!Align(512, fpRom, &address)) return 1; + header.fileAllocs.offset = address; + if (!WriteFat(fpRom, &address, numFiles)) return 1; + header.fileAllocs.size = address - header.fileAllocs.offset; FatEntry *fatEntries = malloc(numFiles * sizeof(FatEntry)); memcpy(fatEntries, overlayEntries, numOverlays * sizeof(*fatEntries)); - if (chdir("..") != 0) { - fprintf(stderr, "Failed to leave assets directory '" ASSETS_SUBDIR "'\n"); - return 1; - } + if (chdir("..") != 0) { + fprintf(stderr, "Failed to leave assets directory '" ASSETS_SUBDIR "'\n"); + return 1; + } if (!Align(512, fpRom, &address)) return false; header.bannerOffset = address; if (!WriteBanner(fpRom, &address)) return false; - if (chdir(ASSETS_SUBDIR) != 0) { - fprintf(stderr, "Failed to enter assets directory '" ASSETS_SUBDIR "'\n"); - return 1; - } + if (chdir(ASSETS_SUBDIR) != 0) { + fprintf(stderr, "Failed to enter assets directory '" ASSETS_SUBDIR "'\n"); + return 1; + } - if (!Align(512, fpRom, &address)) return false; - if (!AppendAssets(fpRom, &address, &root, fatEntries)) return false; + if (!Align(512, fpRom, &address)) return false; + if (!AppendAssets(fpRom, &address, &root, fatEntries)) return false; if (!RewriteFat(fpRom, header.fileAllocs.offset, fatEntries, numFiles)) free(fatEntries); - if (!FreeFileTree(&root)) return false; + if (!FreeFileTree(&root)) return false; - if (chdir("..") != 0) { - fprintf(stderr, "Failed to leave assets directory '" ASSETS_SUBDIR "'\n"); - return 1; - } + if (chdir("..") != 0) { + fprintf(stderr, "Failed to leave assets directory '" ASSETS_SUBDIR "'\n"); + return 1; + } - if (chdir(rootDir) != 0) { - fprintf(stderr, "Failed to leave base directory '%s'\n", baseDir); - return 1; - } - + if (chdir(rootDir) != 0) { + fprintf(stderr, "Failed to leave base directory '%s'\n", baseDir); + return 1; + } + header.romSize = address; header.capacity = 15 - __builtin_clz(header.romSize); - size_t romEnd = 1 << (17 + header.capacity); - if (!Align(romEnd, fpRom, &address)) return 1; + size_t romEnd = 1 << (17 + header.capacity); + if (!Align(romEnd, fpRom, &address)) return 1; - fseek(fpRom, 0, SEEK_SET); - if (fwrite(&header, sizeof(header), 1, fpRom) != 1) { - fprintf(stderr, "Failed to rewrite header\n"); - return 1; - } + header.headerCrc = Crc(&header, offsetof(Header, headerCrc)); - free(readBuffer); - fclose(fpRom); + fseek(fpRom, 0, SEEK_SET); + if (fwrite(&header, sizeof(header), 1, fpRom) != 1) { + fprintf(stderr, "Failed to rewrite header\n"); + return 1; + } + + free(readBuffer); + fclose(fpRom); } diff --git a/tools/rom/extract.c b/tools/rom/extract.c index 33165cef..6e8dd445 100644 --- a/tools/rom/extract.c +++ b/tools/rom/extract.c @@ -11,123 +11,123 @@ #define VERSION "1.0" bool MakeDir(const char *dir) { - struct stat dirStat; - if (stat(dir, &dirStat) != 0) { - if (mkdir(dir, 0777) != 0) FATAL("Failed to make directory '%s'\n", dir); - return true; - } - if (!S_ISDIR(dirStat.st_mode)) FATAL("Could not make directory '%s' due to a file with the same name\n"); - return true; + struct stat dirStat; + if (stat(dir, &dirStat) != 0) { + if (mkdir(dir, 0777) != 0) FATAL("Failed to make directory '%s'\n", dir); + return true; + } + if (!S_ISDIR(dirStat.st_mode)) FATAL("Could not make directory '%s' due to a file with the same name\n"); + return true; } bool CheckRegion(const Header *pHeader, BuildInfo *pInfo) { - Region region = pHeader->gamecode[3]; - if ( - memcmp(pHeader->gamecode, GAMECODE_PREFIX, 3) != 0 || ( - region != REGION_JAPAN && - region != REGION_USA && - region != REGION_EUROPE - ) - ) { - FATAL("Invalid gamecode prefix '%.4s'\n", pHeader->gamecode); - } + Region region = pHeader->gamecode[3]; + if ( + memcmp(pHeader->gamecode, GAMECODE_PREFIX, 3) != 0 || ( + region != REGION_JAPAN && + region != REGION_USA && + region != REGION_EUROPE + ) + ) { + FATAL("Invalid gamecode prefix '%.4s'\n", pHeader->gamecode); + } - pInfo->region = region; - return true; + pInfo->region = region; + return true; } bool ExtractArm7(const uint8_t *rom, ProgramOffset *pArm7) { - FILE *fp = fopen(ARM7_PROGRAM_FILE, "wb"); - if (fp == NULL) FATAL("Failed to create ARM7 program '" ARM7_PROGRAM_FILE "'\n"); - if (fwrite(rom + pArm7->offset, pArm7->size, 1, fp) != 1) FATAL("Failed to write ARM7 program '" ARM7_PROGRAM_FILE "'\n"); - fclose(fp); - return true; + FILE *fp = fopen(ARM7_PROGRAM_FILE, "wb"); + if (fp == NULL) FATAL("Failed to create ARM7 program '" ARM7_PROGRAM_FILE "'\n"); + if (fwrite(rom + pArm7->offset, pArm7->size, 1, fp) != 1) FATAL("Failed to write ARM7 program '" ARM7_PROGRAM_FILE "'\n"); + fclose(fp); + return true; } bool ExtractTitle(const char *language, const char *file, const wchar_t *title, size_t titleSize) { char buf[1024]; - FILE *fp = fopen(file, "wb"); - if (fp == NULL) FATAL("Failed to create %s banner title '%s'\n", language, file); + FILE *fp = fopen(file, "wb"); + if (fp == NULL) FATAL("Failed to create %s banner title '%s'\n", language, file); - size_t resultSize = 0; - if (!WcharToUtf8((wchar_t*) title, titleSize, buf, sizeof(buf), &resultSize)) return false; - if (fputs(buf, fp) == -1) FATAL("Failed to write %s banner title '%s'\n", language, file); - fclose(fp); - return true; + size_t resultSize = 0; + if (!WcharToUtf8((wchar_t*) title, titleSize, buf, sizeof(buf), &resultSize)) return false; + if (fputs(buf, fp) == -1) FATAL("Failed to write %s banner title '%s'\n", language, file); + fclose(fp); + return true; } bool ExtractBanner(const Banner *pBanner, const BuildInfo *pInfo) { - if (!MakeDir(BANNER_SUBDIR)) return 1; + if (!MakeDir(BANNER_SUBDIR)) return 1; - FILE *fp; + FILE *fp; - fp = fopen(ICON_BITMAP_FILE, "wb"); - if (fp == NULL) FATAL("Failed to create banner icon bitmap '" ICON_BITMAP_FILE "'\n"); - if (fwrite(pBanner->iconBitmap, sizeof(pBanner->iconBitmap), 1, fp) != 1) { - FATAL("Failed to write banner icon bitmap '" ICON_BITMAP_FILE "'\n"); - } - fclose(fp); - - fp = fopen(ICON_PALETTE_FILE, "wb"); - if (fp == NULL) FATAL("Failed to create banner icon palette '" ICON_PALETTE_FILE "'\n"); - if (fwrite(pBanner->iconPalette, sizeof(pBanner->iconPalette), 1, fp) != 1) { - FATAL("Failed to write banner icon palette '" ICON_PALETTE_FILE "'\n"); - } - fclose(fp); + fp = fopen(ICON_BITMAP_FILE, "wb"); + if (fp == NULL) FATAL("Failed to create banner icon bitmap '" ICON_BITMAP_FILE "'\n"); + if (fwrite(pBanner->iconBitmap, sizeof(pBanner->iconBitmap), 1, fp) != 1) { + FATAL("Failed to write banner icon bitmap '" ICON_BITMAP_FILE "'\n"); + } + fclose(fp); + + fp = fopen(ICON_PALETTE_FILE, "wb"); + if (fp == NULL) FATAL("Failed to create banner icon palette '" ICON_PALETTE_FILE "'\n"); + if (fwrite(pBanner->iconPalette, sizeof(pBanner->iconPalette), 1, fp) != 1) { + FATAL("Failed to write banner icon palette '" ICON_PALETTE_FILE "'\n"); + } + fclose(fp); - if (!ExtractTitle("Japanese", TITLE_JAP_FILE, pBanner->japaneseTitle, sizeof(pBanner->japaneseTitle))) return false; - if (!ExtractTitle("English", TITLE_ENG_FILE, pBanner->englishTitle, sizeof(pBanner->englishTitle))) return false; - if (!ExtractTitle("French", TITLE_FRE_FILE, pBanner->frenchTitle, sizeof(pBanner->frenchTitle))) return false; - if (!ExtractTitle("German", TITLE_GER_FILE, pBanner->germanTitle, sizeof(pBanner->germanTitle))) return false; - if (!ExtractTitle("Italian", TITLE_ITA_FILE, pBanner->italianTitle, sizeof(pBanner->italianTitle))) return false; - if (!ExtractTitle("Spanish", TITLE_SPA_FILE, pBanner->spanishTitle, sizeof(pBanner->spanishTitle))) return false; + if (!ExtractTitle("Japanese", TITLE_JAP_FILE, pBanner->japaneseTitle, sizeof(pBanner->japaneseTitle))) return false; + if (!ExtractTitle("English", TITLE_ENG_FILE, pBanner->englishTitle, sizeof(pBanner->englishTitle))) return false; + if (!ExtractTitle("French", TITLE_FRE_FILE, pBanner->frenchTitle, sizeof(pBanner->frenchTitle))) return false; + if (!ExtractTitle("German", TITLE_GER_FILE, pBanner->germanTitle, sizeof(pBanner->germanTitle))) return false; + if (!ExtractTitle("Italian", TITLE_ITA_FILE, pBanner->italianTitle, sizeof(pBanner->italianTitle))) return false; + if (!ExtractTitle("Spanish", TITLE_SPA_FILE, pBanner->spanishTitle, sizeof(pBanner->spanishTitle))) return false; - return true; + return true; } bool ExtractAssets(const uint8_t *rom, const uint8_t *fatStart, const uint8_t *fntStart, const FntEntry *pFntEntry) { - const uint8_t *subEntryAddr = fntStart + pFntEntry->subtableOffset; - const FntSubEntry *pSubEntry = (const FntSubEntry*) subEntryAddr; - uint16_t fileId = pFntEntry->firstFile; - while(pSubEntry->length > 0) { - char name[128]; - memcpy(name, pSubEntry->name, pSubEntry->length); - name[pSubEntry->length] = '\0'; - - if (!pSubEntry->isSubdir) { - printf("File '%s'\n", name); + const uint8_t *subEntryAddr = fntStart + pFntEntry->subtableOffset; + const FntSubEntry *pSubEntry = (const FntSubEntry*) subEntryAddr; + uint16_t fileId = pFntEntry->firstFile; + while(pSubEntry->length > 0) { + char name[128]; + memcpy(name, pSubEntry->name, pSubEntry->length); + name[pSubEntry->length] = '\0'; + + if (!pSubEntry->isSubdir) { + printf("File '%s'\n", name); - const FatEntry *pFatEntry = (const FatEntry*) fatStart + fileId; - size_t fileSize = pFatEntry->endOffset - pFatEntry->startOffset; - const uint8_t *pFileBytes = rom + pFatEntry->startOffset; + const FatEntry *pFatEntry = (const FatEntry*) fatStart + fileId; + size_t fileSize = pFatEntry->endOffset - pFatEntry->startOffset; + const uint8_t *pFileBytes = rom + pFatEntry->startOffset; - FILE *fp = fopen(name, "wb"); - if (fp == NULL) FATAL("Failed to open assets file '%s'\n", name); - if (fwrite(pFileBytes, fileSize, 1, fp) != 1) FATAL("Failed to write to assets file '%s'\n", name); - fclose(fp); + FILE *fp = fopen(name, "wb"); + if (fp == NULL) FATAL("Failed to open assets file '%s'\n", name); + if (fwrite(pFileBytes, fileSize, 1, fp) != 1) FATAL("Failed to write to assets file '%s'\n", name); + fclose(fp); - subEntryAddr += sizeof(FntSubEntry) + pSubEntry->length; - pSubEntry = (const FntSubEntry*) subEntryAddr; - ++fileId; - continue; - } + subEntryAddr += sizeof(FntSubEntry) + pSubEntry->length; + pSubEntry = (const FntSubEntry*) subEntryAddr; + ++fileId; + continue; + } - printf("Dir '%s'\n", name); - if (!MakeDir(name)) return false; - if (chdir(name) != 0) FATAL("Failed to enter assets subdirectory '%s'\n", name); - - uint16_t subdirId = READ_SUBDIR_ID(pSubEntry); - uint16_t subdirIndex = subdirId & 0xfff; - if (!ExtractAssets(rom, fatStart, fntStart, (FntEntry*) fntStart + subdirIndex)) return false; + printf("Dir '%s'\n", name); + if (!MakeDir(name)) return false; + if (chdir(name) != 0) FATAL("Failed to enter assets subdirectory '%s'\n", name); + + uint16_t subdirId = READ_SUBDIR_ID(pSubEntry); + uint16_t subdirIndex = subdirId & 0xfff; + if (!ExtractAssets(rom, fatStart, fntStart, (FntEntry*) fntStart + subdirIndex)) return false; - printf("Leave '%s'\n", name); + printf("Leave '%s'\n", name); - if (chdir("..") != 0) FATAL("Failed to leave assets subdirectory '%s'\n", name); - subEntryAddr += sizeof(FntSubEntry) + pSubEntry->length + sizeof(subdirId); - pSubEntry = (const FntSubEntry*) subEntryAddr; - } + if (chdir("..") != 0) FATAL("Failed to leave assets subdirectory '%s'\n", name); + subEntryAddr += sizeof(FntSubEntry) + pSubEntry->length + sizeof(subdirId); + pSubEntry = (const FntSubEntry*) subEntryAddr; + } - return true; + return true; } void PrintUsage(const char *program) { @@ -185,7 +185,7 @@ int main(int argc, const char **argv) { } fseek(fpRom, 0, SEEK_END); size_t romSize = ftell(fpRom); - fseek(fpRom, 0, SEEK_SET); + fseek(fpRom, 0, SEEK_SET); uint8_t *rom = malloc(romSize); if (rom == NULL) { fprintf(stderr, "Failed to allocate buffer for '%s'\n", romFile); @@ -198,36 +198,36 @@ int main(int argc, const char **argv) { fclose(fpRom); Header *pHeader = (Header*) rom; - BuildInfo info; - if (!CheckRegion(pHeader, &info)) return 1; - if (!MakeDir(outDir)) return 1; - if (chdir(outDir) != 0) { - fprintf(stderr, "Failed to enter output directory '%s'\n", outDir); - return 1; - } + BuildInfo info; + if (!CheckRegion(pHeader, &info)) return 1; + if (!MakeDir(outDir)) return 1; + if (chdir(outDir) != 0) { + fprintf(stderr, "Failed to enter output directory '%s'\n", outDir); + return 1; + } - if (!ExtractArm7(rom, &pHeader->arm7)) return 1; + if (!ExtractArm7(rom, &pHeader->arm7)) return 1; Banner *pBanner = (Banner*) (rom + pHeader->bannerOffset); - if (!ExtractBanner(pBanner, &info)) return 1; + if (!ExtractBanner(pBanner, &info)) return 1; - if (!MakeDir(ASSETS_SUBDIR)) return 1; - if (chdir(ASSETS_SUBDIR) != 0) { - fprintf(stderr, "Failed to enter assets directory '" ASSETS_SUBDIR "'\n"); - return 1; - } - const uint8_t *fntStart = rom + pHeader->fileNames.offset; - const uint8_t *fatStart = rom + pHeader->fileAllocs.offset; - if (!ExtractAssets(rom, fatStart, fntStart, (FntEntry*) fntStart)) return 1; - if (chdir("..") != 0) { - fprintf(stderr, "Failed to leave assets directory '" ASSETS_SUBDIR "'\n"); - return 1; - } - - if (chdir("..") != 0) { - fprintf(stderr, "Failed to leave output directory '%s'\n", outDir); - return 1; - } + if (!MakeDir(ASSETS_SUBDIR)) return 1; + if (chdir(ASSETS_SUBDIR) != 0) { + fprintf(stderr, "Failed to enter assets directory '" ASSETS_SUBDIR "'\n"); + return 1; + } + const uint8_t *fntStart = rom + pHeader->fileNames.offset; + const uint8_t *fatStart = rom + pHeader->fileAllocs.offset; + if (!ExtractAssets(rom, fatStart, fntStart, (FntEntry*) fntStart)) return 1; + if (chdir("..") != 0) { + fprintf(stderr, "Failed to leave assets directory '" ASSETS_SUBDIR "'\n"); + return 1; + } + + if (chdir("..") != 0) { + fprintf(stderr, "Failed to leave output directory '%s'\n", outDir); + return 1; + } free(rom); } diff --git a/tools/rom/files.h b/tools/rom/files.h index 2dd5ca34..f59eddcb 100644 --- a/tools/rom/files.h +++ b/tools/rom/files.h @@ -5,141 +5,141 @@ #include "rom.h" typedef struct FileTree { - struct FileTree *children; - uint16_t numChildren; - uint16_t maxChildren; - uint16_t firstFileId; - FntSubEntry *entry; + struct FileTree *children; + uint16_t numChildren; + uint16_t maxChildren; + uint16_t firstFileId; + FntSubEntry *entry; } FileTree; bool MakeFileTree(FileTree *pTree); bool IterFiles(bool (*callback)(const char *name, bool isDir, void*), void *userData) { #ifdef _WIN32 - WIN32_FIND_DATAA findData; - HANDLE hFind = FindFirstFileA("*", &findData); - if (hFind == INVALID_HANDLE_VALUE) FATAL("Failed to open directory to iterate files\n"); - do { - const char *name = findData.cFileName; + WIN32_FIND_DATAA findData; + HANDLE hFind = FindFirstFileA("*", &findData); + if (hFind == INVALID_HANDLE_VALUE) FATAL("Failed to open directory to iterate files\n"); + do { + const char *name = findData.cFileName; if (strcmp(name, ".") == 0) continue; if (strcmp(name, "..") == 0) continue; - bool isDir = (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0; - if (!callback(name, isDir, userData)) return false; - } while (FindNextFileA(hFind, &findData)); - FindClose(hFind); + bool isDir = (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0; + if (!callback(name, isDir, userData)) return false; + } while (FindNextFileA(hFind, &findData)); + FindClose(hFind); #elif __linux__ - DIR *dir = opendir("."); - struct dirent entry; - while ((entry = readdir(dir)) != NULL) { - const char *name = entry->d_name; - bool isDir = entry->d_type == DT_DIR; - if (!callback(name, isDir, userData)) return false; - } - closedir(dir); + DIR *dir = opendir("."); + struct dirent entry; + while ((entry = readdir(dir)) != NULL) { + const char *name = entry->d_name; + bool isDir = entry->d_type == DT_DIR; + if (!callback(name, isDir, userData)) return false; + } + closedir(dir); #endif } bool _GrowFileTreeChildren(FileTree *pTree, size_t minChildren) { - FileTree tree; - memcpy(&tree, pTree, sizeof(tree)); - if (tree.maxChildren >= minChildren) return true; + FileTree tree; + memcpy(&tree, pTree, sizeof(tree)); + if (tree.maxChildren >= minChildren) return true; - size_t newSize = tree.maxChildren; - if (newSize == 0) newSize = minChildren; - while (newSize < minChildren) newSize *= 2; - if (tree.children == NULL) { - FileTree *children = malloc(newSize * sizeof(FileTree)); - if (children == NULL) FATAL("Failed to allocate file tree children\n"); - tree.children = children; - } else { - FileTree *children = realloc(tree.children, newSize * sizeof(FileTree)); - if (children == NULL) FATAL("Failed to reallocate file tree children\n"); - tree.children = children; - } - tree.maxChildren = newSize; + size_t newSize = tree.maxChildren; + if (newSize == 0) newSize = minChildren; + while (newSize < minChildren) newSize *= 2; + if (tree.children == NULL) { + FileTree *children = malloc(newSize * sizeof(FileTree)); + if (children == NULL) FATAL("Failed to allocate file tree children\n"); + tree.children = children; + } else { + FileTree *children = realloc(tree.children, newSize * sizeof(FileTree)); + if (children == NULL) FATAL("Failed to reallocate file tree children\n"); + tree.children = children; + } + tree.maxChildren = newSize; - memcpy(pTree, &tree, sizeof(tree)); - return true; + memcpy(pTree, &tree, sizeof(tree)); + return true; } bool _FileTreeFileCallback(const char *name, bool isDir, void *userData) { - FileTree *pTree = (FileTree*) userData; - size_t nameLength = strlen(name); + FileTree *pTree = (FileTree*) userData; + size_t nameLength = strlen(name); - if (isDir) { - FntSubEntry *entry = malloc(sizeof(FntSubEntry) + nameLength + 2); - if (entry == NULL) FATAL("Failed to allocate FNT sub entry for directory '%s'\n", name); - entry->isSubdir = true; - entry->length = nameLength; - memcpy(entry->name, name, nameLength); - WRITE_SUBDIR_ID(entry, 0); + if (isDir) { + FntSubEntry *entry = malloc(sizeof(FntSubEntry) + nameLength + 2); + if (entry == NULL) FATAL("Failed to allocate FNT sub entry for directory '%s'\n", name); + entry->isSubdir = true; + entry->length = nameLength; + memcpy(entry->name, name, nameLength); + WRITE_SUBDIR_ID(entry, 0); - if (chdir(name) != 0) FATAL("Failed to enter directory '%s'\n", name); + if (chdir(name) != 0) FATAL("Failed to enter directory '%s'\n", name); - FileTree child; - if (!MakeFileTree(&child)) return false; - child.entry = entry; - if (!_GrowFileTreeChildren(pTree, pTree->numChildren + 1)) return false; - memcpy(&pTree->children[pTree->numChildren], &child, sizeof(child)); - pTree->numChildren += 1; + FileTree child; + if (!MakeFileTree(&child)) return false; + child.entry = entry; + if (!_GrowFileTreeChildren(pTree, pTree->numChildren + 1)) return false; + memcpy(&pTree->children[pTree->numChildren], &child, sizeof(child)); + pTree->numChildren += 1; - if (chdir("..") != 0) FATAL("Failed to leave directory '%s'\n", name); - } else { - FntSubEntry *entry = malloc(sizeof(FntSubEntry) + nameLength); - if (entry == NULL) FATAL("Failed to allocate FNT sub entry for file '%s'\n", name); - entry->isSubdir = false; - entry->length = nameLength; - memcpy(entry->name, name, nameLength); + if (chdir("..") != 0) FATAL("Failed to leave directory '%s'\n", name); + } else { + FntSubEntry *entry = malloc(sizeof(FntSubEntry) + nameLength); + if (entry == NULL) FATAL("Failed to allocate FNT sub entry for file '%s'\n", name); + entry->isSubdir = false; + entry->length = nameLength; + memcpy(entry->name, name, nameLength); - FileTree child; - child.children = NULL; - child.numChildren = 0; - child.maxChildren = 0; - child.firstFileId = 0; - child.entry = entry; - if (!_GrowFileTreeChildren(pTree, pTree->numChildren + 1)) return false; - memcpy(&pTree->children[pTree->numChildren], &child, sizeof(child)); - pTree->numChildren += 1; - } + FileTree child; + child.children = NULL; + child.numChildren = 0; + child.maxChildren = 0; + child.firstFileId = 0; + child.entry = entry; + if (!_GrowFileTreeChildren(pTree, pTree->numChildren + 1)) return false; + memcpy(&pTree->children[pTree->numChildren], &child, sizeof(child)); + pTree->numChildren += 1; + } return true; } bool MakeFileTree(FileTree *pTree) { - FileTree tree; + FileTree tree; tree.children = NULL; - tree.numChildren = 0; - tree.maxChildren = 0; - if (!_GrowFileTreeChildren(&tree, 64)) return false; - tree.entry = NULL; + tree.numChildren = 0; + tree.maxChildren = 0; + if (!_GrowFileTreeChildren(&tree, 64)) return false; + tree.entry = NULL; - if (!IterFiles(_FileTreeFileCallback, &tree)) return false; - memcpy(pTree, &tree, sizeof(tree)); - return true; + if (!IterFiles(_FileTreeFileCallback, &tree)) return false; + memcpy(pTree, &tree, sizeof(tree)); + return true; } bool FreeFileTree(FileTree *pTree) { - for (size_t i = 0; i < pTree->numChildren; ++i) { - if (!FreeFileTree(&pTree->children[i])) return false; - } - if (pTree->children != NULL) { - free(pTree->children); - pTree->children = NULL; - } - pTree->numChildren = 0; - pTree->maxChildren = 0; - if (pTree->entry != NULL) { - free(pTree->entry); - pTree->entry = NULL; - } + for (size_t i = 0; i < pTree->numChildren; ++i) { + if (!FreeFileTree(&pTree->children[i])) return false; + } + if (pTree->children != NULL) { + free(pTree->children); + pTree->children = NULL; + } + pTree->numChildren = 0; + pTree->maxChildren = 0; + if (pTree->entry != NULL) { + free(pTree->entry); + pTree->entry = NULL; + } return true; } int CompareFileTree(const void *a, const void *b) { - FileTree *treeA = (FileTree*) a; - FileTree *treeB = (FileTree*) b; - size_t lenA = treeA->entry->length; - size_t lenB = treeB->entry->length; - size_t minSize = (lenA < lenB) ? lenA : lenB; + FileTree *treeA = (FileTree*) a; + FileTree *treeB = (FileTree*) b; + size_t lenA = treeA->entry->length; + size_t lenB = treeB->entry->length; + size_t minSize = (lenA < lenB) ? lenA : lenB; const char *nameA = treeA->entry->name; const char *nameB = treeB->entry->name; @@ -148,23 +148,23 @@ int CompareFileTree(const void *a, const void *b) { const char chB = tolower(nameB[i]); if (chA != chB) return chA - chB; } - if (lenA < lenB) return -1; - if (lenA > lenB) return 1; - return 0; + if (lenA < lenB) return -1; + if (lenA > lenB) return 1; + return 0; } bool SortFileTree(FileTree *pTree) { if (pTree->numChildren <= 1) return true; - FileTree tree; - memcpy(&tree, pTree, sizeof(tree)); + FileTree tree; + memcpy(&tree, pTree, sizeof(tree)); - qsort(tree.children, tree.numChildren, sizeof(*tree.children), CompareFileTree); - for (size_t i = 0; i < tree.numChildren; ++i) { - if (!SortFileTree(&tree.children[i])) return false; - } + qsort(tree.children, tree.numChildren, sizeof(*tree.children), CompareFileTree); + for (size_t i = 0; i < tree.numChildren; ++i) { + if (!SortFileTree(&tree.children[i])) return false; + } - memcpy(pTree, &tree, sizeof(tree)); - return true; + memcpy(pTree, &tree, sizeof(tree)); + return true; } #endif diff --git a/tools/rom/rom.h b/tools/rom/rom.h index 2ea778d9..38e96d96 100644 --- a/tools/rom/rom.h +++ b/tools/rom/rom.h @@ -80,29 +80,29 @@ typedef struct { } Banner; typedef struct { - /* 0 */ uint32_t subtableOffset; - /* 4 */ uint16_t firstFile; - /* 6 */ uint16_t parentId; - /* 8 */ + /* 0 */ uint32_t subtableOffset; + /* 4 */ uint16_t firstFile; + /* 6 */ uint16_t parentId; + /* 8 */ } FntEntry; typedef struct { - /* 0.0 */ uint8_t length : 7; - /* 0.7 */ bool isSubdir : 1; - /* 1.0 */ char name[]; - // If isSubdir - /* 1.0 + length */ // uint16_t subdirId; - /* 1.0 + length + 2 */ - // Else - /* 1.0 + length */ + /* 0.0 */ uint8_t length : 7; + /* 0.7 */ bool isSubdir : 1; + /* 1.0 */ char name[]; + // If isSubdir + /* 1.0 + length */ // uint16_t subdirId; + /* 1.0 + length + 2 */ + // Else + /* 1.0 + length */ } FntSubEntry; #define READ_SUBDIR_ID(entry) READ16(entry + sizeof(*entry) + entry->length); #define WRITE_SUBDIR_ID(entry,id) WRITE16(entry + sizeof(*entry) + entry->length, id) typedef struct { - /* 0 */ uint32_t startOffset; - /* 4 */ uint32_t endOffset; + /* 0 */ uint32_t startOffset; + /* 4 */ uint32_t endOffset; } FatEntry; #endif diff --git a/tools/rom/util.h b/tools/rom/util.h index a6d0e207..4d67c5d8 100644 --- a/tools/rom/util.h +++ b/tools/rom/util.h @@ -28,18 +28,18 @@ bool WcharToUtf8(wchar_t *in, size_t inSize, char *out, size_t outSize, size_t *pResultSize) { #ifdef _WIN32 - size_t resultSize = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, in, inSize / sizeof(wchar_t), out, outSize, NULL, NULL); - if (resultSize == 0) FATAL("Failed to convert to UTF-8\n"); - *pResultSize = resultSize; - return true; + size_t resultSize = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, in, inSize / sizeof(wchar_t), out, outSize, NULL, NULL); + if (resultSize == 0) FATAL("Failed to convert to UTF-8\n"); + *pResultSize = resultSize; + return true; #elif __linux__ - iconv_t convDesc = iconv_open("UTF-16", "UTF-8"); - if (convDesc == -1) FATAL("Failed to get conversion description to UTF-8\n"); - size_t remainingBytes = outSize; - if (iconv(convDesc, &in, &inSize, &out, &remainingBytes) == -1) FATAL("Failed to convert to UTF-8\n"); - if (inSize > 0) FATAL("Some characters were not converted to UTF-8\n"); - *pResultSize = outSize - remainingBytes; - return true; + iconv_t convDesc = iconv_open("UTF-16", "UTF-8"); + if (convDesc == -1) FATAL("Failed to get conversion description to UTF-8\n"); + size_t remainingBytes = outSize; + if (iconv(convDesc, &in, &inSize, &out, &remainingBytes) == -1) FATAL("Failed to convert to UTF-8\n"); + if (inSize > 0) FATAL("Some characters were not converted to UTF-8\n"); + *pResultSize = outSize - remainingBytes; + return true; #endif }