Add MSYS support in rom tools

This commit is contained in:
Aetias
2024-02-22 18:20:12 +01:00
parent f3d0b29b42
commit 54eaa5de61
3 changed files with 72 additions and 95 deletions
+20 -56
View File
@@ -367,7 +367,7 @@ bool WriteArm9OverlayFiles(
size_t address = *pAddress;
char fileName[32];
if (chdir(OVERLAYS_SUBDIR) != 0) FATAL("Failed to enter overlays directory '" OVERLAYS_SUBDIR "'\n");
if (!ChangeDir(OVERLAYS_SUBDIR)) return false;
for (size_t ovNum = 0; ovNum < numOverlays; ++ovNum) {
sprintf(fileName, "ov%02ld.lz", ovNum);
@@ -383,7 +383,7 @@ bool WriteArm9OverlayFiles(
fatEntries[fileId].endOffset = address;
}
if (chdir("..") != 0) FATAL("Failed to leave overlays directory '" OVERLAYS_SUBDIR "'\n");
if (!ChangeDir("..")) return false;
*pAddress = address;
return true;
@@ -674,9 +674,9 @@ bool TraverseAndAppendAssets(FILE *fpRom, size_t *pAddress, const FileTree *tree
entries[child->firstFileId].endOffset = address;
continue;
}
if (chdir(name) != 0) FATAL("Failed to enter assets directory '%s'\n", name);
if (!ChangeDir(name)) return false;
if (!TraverseAndAppendAssets(fpRom, &address, child, entries, child->firstFileId)) return false;
if (chdir("..") != 0) FATAL("Failed to leave assets directory '%s'\n", name);
if (!ChangeDir("..")) return false;
}
*pAddress = address;
@@ -711,7 +711,7 @@ bool AppendAssets(
assetsList[listSize] = '\0';
char assetsDir[256];
if (getcwd(assetsDir, sizeof(assetsDir)) == NULL) FATAL("Failed to get assets directory\n");
if (!GetCurrentDir(assetsDir, sizeof(assetsDir))) FATAL("Failed to get assets directory\n");
char *const listEnd = assetsList + listSize;
for (char *path = assetsList, *next; path < listEnd; path = next) {
@@ -723,9 +723,9 @@ bool AppendAssets(
// First file ID of root directory is given from number of overlays
uint16_t firstFileId = subTree->entry == NULL ? numOverlays : subTree->firstFileId;
if (path[1] != '\0' && chdir(&path[1]) != 0) FATAL("Failed to enter assets directory '%s'\n", path);
if (path[1] != '\0' && !ChangeDir(&path[1])) return false;
if (!TraverseAndAppendAssets(fpRom, &address, subTree, entries, firstFileId)) return false;
if (chdir(assetsDir) != 0) FATAL("Failed to leave assets directory '%s'\n", path);
if (!ChangeDir(assetsDir)) return false;
subTree->addedToFat = true;
}
@@ -884,7 +884,7 @@ int main(int argc, char **argv) {
// --------------------- Set up ---------------------
char rootDir[256];
if (getcwd(rootDir, sizeof(rootDir)) == NULL) {
if (!GetCurrentDir(rootDir, sizeof(rootDir))) {
fprintf(stderr, "Failed to get root directory\n");
return 1;
}
@@ -921,23 +921,14 @@ int main(int argc, char **argv) {
// --------------------- Get canonical file paths ---------------------
if (assetsListFile != NULL && !AllocFullPath(assetsListFile, &assetsListFile)) return 1;
if (chdir(baseDir) != 0) {
fprintf(stderr, "Failed to enter base directory '%s'\n", baseDir);
return 1;
}
if (!ChangeDir(baseDir)) return 1;
char *arm9overlayDataFile = NULL;
if (!AllocFullPath(ARM9_OVERLAY_DATA_FILE, &arm9overlayDataFile)) return 1;
if (chdir(rootDir) != 0) {
fprintf(stderr, "Failed to leave base directory '%s'\n", baseDir);
return 1;
}
if (!ChangeDir(rootDir)) return 1;
// --------------------- Write ARM9 program ---------------------
if (chdir(buildDir) != 0) {
fprintf(stderr, "Failed to enter build directory '%s'\n", buildDir);
return 1;
}
if (!ChangeDir(buildDir)) return 1;
if (!Align(512, fpRom, &address)) return 1;
header.arm9.offset = address;
@@ -957,15 +948,9 @@ int main(int argc, char **argv) {
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);
return 1;
}
if (!ChangeDir(rootDir)) return 1;
if (chdir(baseDir) != 0) {
fprintf(stderr, "Failed to enter base directory '%s'\n", baseDir);
return 1;
}
if (!ChangeDir(baseDir)) return 1;
// --------------------- Write ARM7 program ---------------------
@@ -973,10 +958,7 @@ int main(int argc, 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;
}
if (!ChangeDir(ASSETS_SUBDIR)) return 1;
// --------------------- Write file name table (FNT) ---------------------
@@ -999,10 +981,7 @@ int main(int argc, char **argv) {
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 (!ChangeDir("..")) return 1;
// --------------------- Write banner ---------------------
@@ -1010,10 +989,7 @@ int main(int argc, char **argv) {
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 (!ChangeDir(ASSETS_SUBDIR)) return 1;
// --------------------- Write assets ---------------------
@@ -1027,15 +1003,9 @@ int main(int argc, char **argv) {
if (!FreeFileTree(&root)) return false;
if (chdir("..") != 0) {
fprintf(stderr, "Failed to leave assets directory '" ASSETS_SUBDIR "'\n");
return 1;
}
if (!ChangeDir("..")) return 1;
if (chdir(rootDir) != 0) {
fprintf(stderr, "Failed to leave base directory '%s'\n", baseDir);
return 1;
}
if (!ChangeDir(rootDir)) return 1;
// --------------------- Write padding ---------------------
@@ -1049,18 +1019,12 @@ int main(int argc, char **argv) {
char *arm7bios = NULL;
if (arm7biosFile != NULL && !AllocFullPath(arm7biosFile, &arm7bios)) return 1;
if (chdir(buildDir) != 0) {
fprintf(stderr, "Failed to enter build directory '%s'\n", buildDir);
return 1;
}
if (!ChangeDir(buildDir)) return 1;
if (!FinalizeHeader(fpRom, &header, arm7bios, secureArea, &metadata)) return false;
FreeFullPath(&arm7bios);
if (chdir(rootDir) != 0) {
fprintf(stderr, "Failed to leave build directory '%s'\n", buildDir);
return 1;
}
if (!ChangeDir(rootDir)) return 1;
free(readBuffer);
fclose(fpRom);
+6 -28
View File
@@ -24,16 +24,6 @@ void Indent(size_t depth) {
}
}
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", dir);
return true;
}
bool CheckRegion(const Header *pHeader, BuildInfo *pInfo) {
Region region = pHeader->gamecode[3];
if (
@@ -181,7 +171,7 @@ bool ExtractSubtable(
printf("%s {\n", name);
}
if (!MakeDir(name)) return false;
if (chdir(name) != 0) FATAL("Failed to enter assets subdirectory '%s'\n", name);
if (!ChangeDir(name)) return false;
uint16_t subdirId = READ_SUBDIR_ID(pSubEntry);
uint16_t subdirIndex = subdirId & 0xfff;
@@ -205,7 +195,7 @@ bool ExtractSubtable(
printf("}\n");
}
if (chdir("..") != 0) FATAL("Failed to leave assets subdirectory '%s'\n", name);
if (!ChangeDir("..")) return false;
subEntryAddr += sizeof(FntSubEntry) + pSubEntry->length + sizeof(subdirId);
pSubEntry = (const FntSubEntry*) subEntryAddr;
}
@@ -378,10 +368,7 @@ int main(int argc, const char **argv) {
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 (!ChangeDir(outDir)) return 1;
// --------------------- Extract ARM7 program ---------------------
@@ -395,26 +382,17 @@ int main(int argc, const char **argv) {
// --------------------- Extract assets ---------------------
if (!MakeDir(ASSETS_SUBDIR)) return 1;
if (chdir(ASSETS_SUBDIR) != 0) {
fprintf(stderr, "Failed to enter assets directory '" ASSETS_SUBDIR "'\n");
return 1;
}
if (!ChangeDir(ASSETS_SUBDIR)) return 1;
const uint8_t *fntStart = rom + pHeader->fileNames.offset;
const uint8_t *fatStart = rom + pHeader->fileAllocs.offset;
if (!ExtractAssets(rom, fatStart, fntStart)) return 1;
if (chdir("..") != 0) {
fprintf(stderr, "Failed to leave assets directory '" ASSETS_SUBDIR "'\n");
return 1;
}
if (!ChangeDir("..")) return 1;
// --------------------- Extract overlay data ---------------------
if (!ExtractOverlayData(rom, pHeader)) return 1;
if (chdir("..") != 0) {
fprintf(stderr, "Failed to leave output directory '%s'\n", outDir);
return 1;
}
if (!ChangeDir("..")) return 1;
free(rom);
}
+46 -11
View File
@@ -1,5 +1,5 @@
#ifndef __FS_H
#define __FS_H
#ifndef __UTIL_H
#define __UTIL_H
#include <stdbool.h>
#include <stdlib.h>
@@ -16,11 +16,11 @@
#define READ32(buf) (((uint8_t*) buf)[0] | (((uint8_t*) buf)[1] << 8) | (((uint8_t*) buf)[2] << 16) | (((uint8_t*) buf)[3] << 24))
#define REVERSE32(val) ((val >> 24) | ((val & 0xff0000) >> 8) | ((val & 0xff00) << 8) | ((val & 0xff) << 24))
#ifdef _WIN32
#if defined(_WIN32) || defined(__MSYS__)
# define __UTIL_WINDOWS
# include <Windows.h>
# include <sys/stat.h>
# define mkdir(path, mode) mkdir(path)
#elif __linux__
# define __UTIL_LINUX
# include <errno.h>
# include <sys/stat.h>
# include <iconv.h>
@@ -30,13 +30,48 @@
# error "Target platform not supported"
#endif
bool MakeDir(const char *dir) {
#ifdef __UTIL_WINDOWS
if (CreateDirectoryA(dir, NULL)) return true;
if (GetLastError() == ERROR_ALREADY_EXISTS) return true;
FATAL("Failed to make directory '%s'\n", dir);
#elif defined(__UTIL_LINUX)
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", dir);
return true;
#endif
}
bool GetCurrentDir(char *dir, size_t dirSize) {
#ifdef __UTIL_WINDOWS
return GetCurrentDirectory(dirSize, dir) > 0;
#elif defined(__UTIL_LINUX)
return getcwd(dir, dirSize) != NULL;
#endif
}
bool ChangeDir(const char *dir) {
#ifdef __UTIL_WINDOWS
if (SetCurrentDirectory(dir)) return true;
#elif defined(__UTIL_LINUX)
if (chdir(dir) == 0) return true;
#endif
char cwd[256];
if (!GetCurrentDir(cwd, sizeof(cwd))) strcpy(cwd, "[unknown]");
FATAL("Failed to enter directory '%s' from current directory '%s'\n", dir, cwd);
}
bool WcharToUtf8(wchar_t *in, size_t inSize, char *out, size_t outSize, size_t *pResultSize) {
#ifdef _WIN32
#ifdef __UTIL_WINDOWS
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__
#elif defined(__UTIL_LINUX)
iconv_t convDesc = iconv_open("UTF-8", "UTF-16");
if (convDesc == (iconv_t) -1) FATAL("Failed to get conversion description to UTF-8\n");
size_t remainingBytes = outSize;
@@ -50,11 +85,11 @@ bool WcharToUtf8(wchar_t *in, size_t inSize, char *out, size_t outSize, size_t *
}
bool Utf8ToWchar(char *in, size_t inSize, wchar_t *out, size_t outSize) {
#ifdef _WIN32
#ifdef __UTIL_WINDOWS
size_t resultSize = MultiByteToWideChar(CP_UTF8, 0, in, inSize, out, outSize / sizeof(wchar_t));
if (resultSize == 0) FATAL("Failed to convert from UTF-8: %d\n", GetLastError());
return true;
#elif __linux__
#elif defined(__UTIL_LINUX)
iconv_t convDesc = iconv_open("UTF-16", "UTF-8");
if (convDesc == (iconv_t) -1) FATAL("Failed to get conversion description from UTF-8\n");
size_t remainingBytes = outSize;
@@ -74,7 +109,7 @@ bool Utf8ToWchar(char *in, size_t inSize, wchar_t *out, size_t outSize) {
}
bool AllocFullPath(const char *path, char **pFullPath) {
#ifdef _WIN32
#ifdef __UTIL_WINDOWS
if (path[0] == '/') {
// Remove drive letter, e.g. /c/Projects/ph/ -> /Projects/ph/
const char *root = strchr(path + 1, '/');
@@ -86,7 +121,7 @@ bool AllocFullPath(const char *path, char **pFullPath) {
if (resultSize == 0 || resultSize > size) FATAL("Failed to get full path for '%s'\n", path);
*pFullPath = fullPath;
return true;
#elif __linux__
#elif defined(__UTIL_LINUX)
char *fullPath = realpath(path, NULL);
if (fullPath == NULL) FATAL("Failed to get full path for '%s'\n", path);
*pFullPath = fullPath;