mirror of
https://github.com/zeldaret/ph
synced 2026-07-11 14:38:44 -04:00
Add MSYS support in rom tools
This commit is contained in:
+20
-56
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user