Make buildrom run without errors

This commit is contained in:
Aetias
2023-10-15 11:37:48 +02:00
parent 69641043ba
commit 3b81b5158d
5 changed files with 61 additions and 32 deletions
+35 -19
View File
@@ -146,6 +146,7 @@ bool Align(size_t alignment, FILE *fpRom, size_t *pAddress) {
if (fputc(0xff, fpRom) == -1) FATAL("Failed to pad output ROM at address 0x%x\n", address);
address += 1;
}
*pAddress = address;
return true;
}
@@ -160,9 +161,10 @@ bool WriteArm9Overlays(FILE *fpRom, size_t *pAddress, size_t *pNumOverlays, FatE
sprintf(fileName, "ov%02d.lz", ovNum);
if (!Align(256, fpRom, &address)) return false;
size_t startOffset = address;
if (!AppendFile(fpRom, fileName, &address, NULL)) return false;
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");
@@ -243,6 +245,8 @@ bool WriteFntSubtable(FileTree *tree, FntContext *pContext) {
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];
@@ -257,13 +261,14 @@ bool WriteFntSubtable(FileTree *tree, FntContext *pContext) {
mainEntry.parentId = ctx.parentId;
if (!GrowFntTable(&ctx, ctx.tableSize + 1)) return false;
memcpy(&ctx.table[ctx.tableSize], &mainEntry, sizeof(mainEntry));
ctx.tableSize += 1;
ctx.nextFileId += numFiles;
uint16_t oldParentId = ctx.parentId;
ctx.parentId = subdirId;
char name[128];
strncpy(name, entry->name, entry->length);
name[entry->length] = '\0';
if (!WriteFntSubtable(child, &ctx)) return false;
ctx.parentId = oldParentId;
@@ -289,7 +294,7 @@ bool WriteFnt(FILE *fpRom, size_t *pAddress, FileTree *pRoot, size_t firstFileId
FntContext ctx;
ctx.table = malloc(INITIAL_TABLE_SIZE * sizeof(FntEntry));
if (ctx.table == NULL) FATAL("Failed to allocate FNT table\n");
ctx.tableSize = 0;
ctx.tableSize = 1;
ctx.tableMax = INITIAL_TABLE_SIZE;
ctx.nextFileId = firstFileId;
@@ -300,10 +305,9 @@ bool WriteFnt(FILE *fpRom, size_t *pAddress, FileTree *pRoot, size_t firstFileId
ctx.subtableSize = 0;
ctx.subtableMax = INITIAL_SUBTABLE_SIZE;
FntEntry rootEntry;
rootEntry.subtableOffset = 0; // will add main table length later
rootEntry.firstFile = firstFileId;
rootEntry.parentId = 0; // will be set to number of directories later
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
size_t tableStart = address;
if (!WriteFntSubtable(pRoot, &ctx)) return false;
@@ -341,6 +345,7 @@ bool AppendAssets(FILE *fpRom, size_t *pAddress, const FileTree *tree, FatContex
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, &ctx)) return false;
if (chdir("..") != 0) FATAL("Failed to leave assets directory '%s'\n", name);
@@ -354,6 +359,7 @@ bool AppendAssets(FILE *fpRom, size_t *pAddress, const FileTree *tree, FatContex
if (entry->isSubdir) continue;
char name[128];
strncpy(name, entry->name, entry->length);
name[entry->length] = '\0';
if (!Align(256, fpRom, &address)) return false;
size_t startOffset = address;
if (!AppendFile(fpRom, name, &address, NULL)) return false;
@@ -400,11 +406,11 @@ void PrintUsage(const char *program) {
printf(
"buildrom " VERSION "\n"
"\n"
"Usage: %s -a ASSETSDIR -b BUILDDIR -r REGION -o OUTFILE\n"
" -a ASSETSDIR\tAssets directory generated by extractrom\n"
" -b BUILDDIR \tBuild directory generated by Makefile\n"
" -r REGION \tJ = Japan, E = USA, P = Europe\n"
" -o OUTFILE \tOutput ROM file\n",
"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"
" -o OUTFILE \tOutput ROM file\n",
program
);
}
@@ -415,7 +421,7 @@ int main(int argc, const char **argv) {
PrintUsage(program);
return 0;
}
const char *assetsDir = NULL;
const char *baseDir = NULL;
const char *buildDir = NULL;
const char *romFile = NULL;
Region region = 0;
@@ -431,7 +437,7 @@ int main(int argc, const char **argv) {
fprintf(stderr, "Expected pathname after -a\n");
return 1;
}
assetsDir = argv[i];
baseDir = argv[i];
} else if (strcmp(argv[i], "-b") == 0) {
if (++i >= argc) {
fprintf(stderr, "Expected pathname after -b\n");
@@ -453,9 +459,9 @@ int main(int argc, const char **argv) {
return 1;
}
}
if (assetsDir == NULL) {
if (baseDir == NULL) {
PrintUsage(program);
fprintf(stderr, "Please provide an assets directory, see usage above\n");
fprintf(stderr, "Please provide a base directory, see usage above\n");
return 1;
}
if (buildDir == NULL) {
@@ -530,8 +536,8 @@ int main(int argc, const char **argv) {
return 1;
}
if (chdir(assetsDir) != 0) {
fprintf(stderr, "Failed to enter assets directory '%s'\n", assetsDir);
if (chdir(baseDir) != 0) {
fprintf(stderr, "Failed to enter base directory '%s'\n", baseDir);
return 1;
}
@@ -539,6 +545,11 @@ int main(int argc, const char **argv) {
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;
}
FileTree root;
if (!MakeFileTree(&root)) return false;
if (!SortFileTree(&root)) return false;
@@ -556,8 +567,13 @@ int main(int argc, const char **argv) {
if (!FreeFileTree(&root)) return false;
if (chdir("..") != 0) {
fprintf(stderr, "Failed to leave assets directory '" ASSETS_SUBDIR "'\n");
return 1;
}
if (chdir(rootDir) != 0) {
fprintf(stderr, "Failed to leave assets directory '%s'\n", assetsDir);
fprintf(stderr, "Failed to leave base directory '%s'\n", baseDir);
return 1;
}
+17 -4
View File
@@ -21,6 +21,8 @@ bool IterFiles(bool (*callback)(const char *name, bool isDir, void*), void *user
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));
@@ -40,7 +42,7 @@ bool IterFiles(bool (*callback)(const char *name, bool isDir, void*), void *user
bool _GrowFileTreeChildren(FileTree *pTree, size_t minChildren) {
FileTree tree;
memcpy(&tree, pTree, sizeof(tree));
if (tree.numChildren >= minChildren) return true;
if (tree.maxChildren >= minChildren) return true;
size_t newSize = tree.maxChildren;
if (newSize == 0) newSize = minChildren;
@@ -77,6 +79,7 @@ bool _FileTreeFileCallback(const char *name, bool isDir, void *userData) {
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;
@@ -98,12 +101,14 @@ bool _FileTreeFileCallback(const char *name, bool isDir, void *userData) {
memcpy(&pTree->children[pTree->numChildren], &child, sizeof(child));
pTree->numChildren += 1;
}
return true;
}
bool MakeFileTree(FileTree *pTree) {
FileTree tree;
tree.maxChildren = 0;
tree.children = NULL;
tree.numChildren = 0;
tree.maxChildren = 0;
if (!_GrowFileTreeChildren(&tree, 64)) return false;
tree.entry = NULL;
@@ -126,6 +131,7 @@ bool FreeFileTree(FileTree *pTree) {
free(pTree->entry);
pTree->entry = NULL;
}
return true;
}
int CompareFileTree(const void *a, const void *b) {
@@ -134,14 +140,21 @@ int CompareFileTree(const void *a, const void *b) {
size_t lenA = treeA->entry->length;
size_t lenB = treeB->entry->length;
size_t minSize = (lenA < lenB) ? lenA : lenB;
int cmp = strncmp(treeA->entry->name, treeB->entry->name, minSize);
if (cmp != 0) return cmp;
const char *nameA = treeA->entry->name;
const char *nameB = treeB->entry->name;
for (size_t i = 0; i < minSize; ++i) {
const char chA = tolower(nameA[i]);
const char chB = tolower(nameB[i]);
if (chA != chB) return chA - chB;
}
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));
+1 -1
View File
@@ -17,7 +17,7 @@
#define ASSETS_SUBDIR "assets"
#define ARM9_PROGRAM_FILE "arm9.lz"
#define ARM9_FOOTER_FILE "footer.bin"
#define ARM9_FOOTER_FILE "arm9_footer.bin"
#define ARM9_OVERLAY_TABLE_FILE "arm9_ovt.bin"
#define OVERLAYS_SUBDIR "overlays"
+2 -2
View File
@@ -47,8 +47,8 @@ typedef struct {
/* 0084 */ uint32_t headerSize;
/* 0088 */ uint32_t autoloadParamsOffset;
/* 008c */ uint8_t reserved1[0x8];
/* 0094 */ uint32_t romEnd;
/* 0096 */ uint32_t rwEnd;
/* 0094 */ uint16_t romEnd;
/* 0096 */ uint16_t rwEnd;
/* 0098 */ uint8_t reserved2[0x18];
/* 00b0 */ uint8_t reserved3[0x10];
/* 00c0 */ uint8_t logo[0x9c];
+6 -6
View File
@@ -7,12 +7,12 @@
#define FATAL(...) do { fprintf(stderr, __VA_ARGS__); return false; } while (0)
#define WRITE16(buf,val) do { ((char*) buf)[0] = (val) & 0xFF; ((char*) buf)[1] = ((val) >> 8) & 0xFF; } while (0)
#define WRITE24(buf,val) do { ((char*) buf)[0] = (val) & 0xFF; ((char*) buf)[1] = ((val) >> 8) & 0xFF; ((char*) buf)[2] = ((val) >> 16) & 0xFF; } while (0)
#define WRITE32(buf,val) do { ((char*) buf)[0] = (val) & 0xFF; ((char*) buf)[1] = ((val) >> 8) & 0xFF; ((char*) buf)[2] = ((val) >> 16) & 0xFF; ((char*) buf)[3] = ((val) >> 24) & 0xFF; } while (0)
#define READ16(buf) (((char*) buf)[0] | (((char*) buf)[1] << 8))
#define READ24(buf) (((char*) buf)[0] | (((char*) buf)[1] << 8) | (((char*) buf)[2] << 16))
#define READ32(buf) (((char*) buf)[0] | (((char*) buf)[1] << 8) | (((char*) buf)[2] << 16) | (((char*) buf)[3] << 24))
#define WRITE16(buf,val) do { ((uint8_t*) buf)[0] = (val) & 0xFF; ((uint8_t*) buf)[1] = ((val) >> 8) & 0xFF; } while (0)
#define WRITE24(buf,val) do { ((uint8_t*) buf)[0] = (val) & 0xFF; ((uint8_t*) buf)[1] = ((val) >> 8) & 0xFF; ((uint8_t*) buf)[2] = ((val) >> 16) & 0xFF; } while (0)
#define WRITE32(buf,val) do { ((uint8_t*) buf)[0] = (val) & 0xFF; ((uint8_t*) buf)[1] = ((val) >> 8) & 0xFF; ((uint8_t*) buf)[2] = ((val) >> 16) & 0xFF; ((uint8_t*) buf)[3] = ((val) >> 24) & 0xFF; } while (0)
#define READ16(buf) (((uint8_t*) buf)[0] | (((uint8_t*) buf)[1] << 8))
#define READ24(buf) (((uint8_t*) buf)[0] | (((uint8_t*) buf)[1] << 8) | (((uint8_t*) buf)[2] << 16))
#define READ32(buf) (((uint8_t*) buf)[0] | (((uint8_t*) buf)[1] << 8) | (((uint8_t*) buf)[2] << 16) | (((uint8_t*) buf)[3] << 24))
#ifdef _WIN32
# include <Windows.h>