diff --git a/Makefile b/Makefile index 3193e4b7..99d987a7 100644 --- a/Makefile +++ b/Makefile @@ -7,6 +7,12 @@ else $(error Unknown region '$(REGION)') endif +ifeq ($(OS),Windows_NT) + WINE := +else + WINE := wine +endif + ROOT := $(shell pwd) BUILD_DIR := $(ROOT)/build TARGET_DIR := $(BUILD_DIR)/$(REGION_NAME) @@ -30,9 +36,9 @@ BASE_ROM := baserom_$(REGION_NAME).nds CHECKSUM := ph_$(REGION_NAME).sha1 MW_VER := 2.0/sp1p5 -MW_ASM := $(TOOLS_DIR)/mwccarm/$(MW_VER)/mwasmarm -MW_CC := $(TOOLS_DIR)/mwccarm/$(MW_VER)/mwccarm -MW_LD := $(TOOLS_DIR)/mwccarm/$(MW_VER)/mwldarm +MW_ASM := $(TOOLS_DIR)/mwccarm/$(MW_VER)/mwasmarm.exe +MW_CC := $(TOOLS_DIR)/mwccarm/$(MW_VER)/mwccarm.exe +MW_LD := $(TOOLS_DIR)/mwccarm/$(MW_VER)/mwldarm.exe MW_LICENSE := $(TOOLS_DIR)/mwccarm/license.dat ASM_FLAGS := -proc arm5te -d $(REGION) -i asm -msgstyle gcc @@ -79,15 +85,15 @@ lcf: setup $(TOOLS_DIR)/lcf.py $(ASM_OBJS): $(TARGET_DIR)/%.o: % mkdir -p $(dir $@) - LM_LICENSE_FILE=$(MW_LICENSE) $(MW_ASM) $(ASM_FLAGS) $< -o $@ + LM_LICENSE_FILE=$(MW_LICENSE) $(WINE) $(MW_ASM) $(ASM_FLAGS) $< -o $@ $(CXX_OBJS): $(TARGET_DIR)/%.o: % mkdir -p $(dir $@) - LM_LICENSE_FILE=$(MW_LICENSE) $(MW_CC) $(CC_FLAGS) $< -o $@ + LM_LICENSE_FILE=$(MW_LICENSE) $(WINE) $(MW_CC) $(CC_FLAGS) $< -o $@ .PHONY: link link: lcf $(ASM_OBJS) $(CXX_OBJS) - cd $(TARGET_DIR) && LM_LICENSE_FILE=$(MW_LICENSE) $(MW_LD) $(LD_FLAGS) $(LCF_FILE) @$(OBJS_FILE) + cd $(TARGET_DIR) && LM_LICENSE_FILE=$(MW_LICENSE) $(WINE) $(MW_LD) $(LD_FLAGS) $(LCF_FILE) @$(OBJS_FILE) .PHONY: compress compress: $(OV_LZS) diff --git a/tools/rom/Makefile b/tools/rom/Makefile index 4ba8e715..3cd63d49 100644 --- a/tools/rom/Makefile +++ b/tools/rom/Makefile @@ -1,5 +1,5 @@ CC := gcc -CFLAGS := -g +CFLAGS := -g -Wall ifneq ($(DEBUG),1) CFLAGS += -O2 -DNDEBUG @@ -11,6 +11,7 @@ ifeq ($(OS),Windows_NT) else EXTRACTFILE := extractrom BUILDFILE := buildrom + CFLAGS += -fshort-wchar endif .PHONY: all clean diff --git a/tools/rom/build.c b/tools/rom/build.c index 762fbeef..cfd3a0e5 100644 --- a/tools/rom/build.c +++ b/tools/rom/build.c @@ -1,4 +1,5 @@ #include +#include #include #include @@ -7,7 +8,7 @@ #include "util.h" #include "files.h" -#define VERSION "1.0" +#define VERSION "1.0.1" #define BUFFER_SIZE 1024 * 1024 uint8_t *readBuffer = NULL; @@ -213,7 +214,7 @@ bool Align(size_t alignment, FILE *fpRom, size_t *pAddress) { 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); + if (fputc(0xff, fpRom) == -1) FATAL("Failed to pad output ROM at address 0x%lx\n", address); address += 1; } *pAddress = address; @@ -236,7 +237,7 @@ bool WriteArm9OverlayTable( fseek(fp, 0, SEEK_END); size_t tableSize = ftell(fp); if (tableSize % sizeof(OverlayEntry) != 0) { - FATAL("ARM9 overlay table has an invalid size (entries must be %d bytes long)\n", sizeof(OverlayEntry)); + FATAL("ARM9 overlay table has an invalid size (entries must be %ld bytes long)\n", sizeof(OverlayEntry)); } size_t numOverlays = tableSize / sizeof(OverlayEntry); fseek(fp, 0, SEEK_SET); @@ -251,7 +252,7 @@ bool WriteArm9OverlayTable( fseek(fp, 0, SEEK_END); size_t dataSize = ftell(fp); 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)); + FATAL("ARM9 overlay data file has an invalid size (expected %ld overlays with %ld bytes each)\n", numOverlays, sizeof(OverlayData)); } fseek(fp, 0, SEEK_SET); @@ -287,7 +288,7 @@ bool WriteArm9OverlayFiles( if (chdir(OVERLAYS_SUBDIR) != 0) FATAL("Failed to enter overlays directory '" OVERLAYS_SUBDIR "'\n"); for (size_t ovNum = 0; ovNum < numOverlays; ++ovNum) { - sprintf(fileName, "ov%02d.lz", ovNum); + sprintf(fileName, "ov%02ld.lz", ovNum); if (!Align(512, fpRom, &address)) return false; size_t startOffset = address; uint32_t fileSize = 0; @@ -295,7 +296,7 @@ bool WriteArm9OverlayFiles( table[ovNum].compressedSize = fileSize; table[ovNum].isCompressed = true; 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); + if (fileId >= MAX_OVERLAYS) FATAL("Overlay %ld's file ID (%d) exceeds the maximum %d\n", ovNum, fileId, MAX_OVERLAYS); fatEntries[fileId].startOffset = startOffset; fatEntries[fileId].endOffset = address; } @@ -379,7 +380,7 @@ bool GrowFntSubtable(FntContext *pContext, size_t growSize) { } uint8_t *newTable = realloc(ctx.subtable, ctx.subtableMax); - if (newTable == NULL) FATAL("Failed to reallocate FNT subtable to %d bytes\n", ctx.subtableMax); + if (newTable == NULL) FATAL("Failed to reallocate FNT subtable to %ld bytes\n", ctx.subtableMax); ctx.subtable = newTable; memcpy(pContext, &ctx, sizeof(ctx)); @@ -477,7 +478,6 @@ bool WriteFnt(FILE *fpRom, size_t *pAddress, FileTree *pRoot, size_t firstFileId 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; ctx.table[0].parentId = ctx.tableSize; @@ -500,7 +500,6 @@ bool WriteFnt(FILE *fpRom, size_t *pAddress, FileTree *pRoot, size_t firstFileId bool WriteFat(FILE *fpRom, size_t *pAddress, size_t numFiles) { size_t address = *pAddress; - size_t fatStart = address; FatEntry blank; blank.startOffset = 0; @@ -659,6 +658,7 @@ bool RewriteFat(FILE *fpRom, size_t fatStart, const FatEntry *entries, size_t nu 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); + return true; } typedef struct { diff --git a/tools/rom/extract.c b/tools/rom/extract.c index 4c54cf6b..5ce4a293 100644 --- a/tools/rom/extract.c +++ b/tools/rom/extract.c @@ -8,7 +8,7 @@ #include "ph.h" #include "util.h" -#define VERSION "1.0" +#define VERSION "1.0.1" #define INDENT 4 // Command line flags for debugging purposes @@ -20,7 +20,7 @@ void Indent(size_t depth) { memset(spaces, ' ', INDENT); spaces[INDENT] = '\0'; for (size_t i = 0; i < depth; ++i) { - printf(spaces); + puts(spaces); } } @@ -30,7 +30,7 @@ bool MakeDir(const char *dir) { 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"); + if (!S_ISDIR(dirStat.st_mode)) FATAL("Could not make directory '%s' due to a file with the same name\n", dir); return true; } @@ -119,7 +119,7 @@ bool GrowFilePathList(ExtractContext *pContext, size_t minEntries) { } char **newFilePathList = realloc(ctx.filePathList, ctx.maxFilePaths * sizeof(*ctx.filePathList)); - if (newFilePathList == NULL) FATAL("Failed to reallocate file path list to %d entries\n", ctx.maxFilePaths); + if (newFilePathList == NULL) FATAL("Failed to reallocate file path list to %ld entries\n", ctx.maxFilePaths); ctx.filePathList = newFilePathList; // Fill new entries with 0 @@ -245,7 +245,6 @@ bool PrintFileAllocOrder(ExtractContext *ctx, const uint8_t *fatAddr) { for (size_t i = 0; i < numFiles; ++i) { uint32_t fileId = fatInfo[i].fileId; if (ctx->filePathList[fileId] == NULL) continue; - size_t len = strlen(ctx->filePathList[fileId]); printf("%s\n", ctx->filePathList[fileId]); } @@ -275,6 +274,7 @@ bool ExtractAssets(const uint8_t *rom, const uint8_t *fatStart, const uint8_t *f } free(ctx.filePathList); } + return true; } bool ExtractOverlayData(const uint8_t *rom, const Header *header) { diff --git a/tools/rom/files.h b/tools/rom/files.h index abd685d9..6284ed6e 100644 --- a/tools/rom/files.h +++ b/tools/rom/files.h @@ -1,6 +1,8 @@ #ifndef __FILES_H #define __FILES_H +#include + #include "util.h" #include "rom.h" @@ -30,14 +32,17 @@ bool IterFiles(bool (*callback)(const char *name, bool isDir, void*), void *user FindClose(hFind); #elif __linux__ DIR *dir = opendir("."); - struct dirent entry; + struct dirent *entry; while ((entry = readdir(dir)) != NULL) { const char *name = entry->d_name; + if (strcmp(name, ".") == 0) continue; + if (strcmp(name, "..") == 0) continue; bool isDir = entry->d_type == DT_DIR; if (!callback(name, isDir, userData)) return false; } closedir(dir); #endif + return true; } bool _GrowFileTreeChildren(FileTree *pTree, size_t minChildren) { @@ -176,9 +181,6 @@ int CompareFileTreeAscii(const void *a, const void *b) { size_t minSize = (lenA < lenB) ? lenA : lenB; // ASCII order - if (strncmp(treeA->entry->name, "Color0.NCLR", 11) == 0 || strncmp(treeB->entry->name, "Color0.NCLR", 11) == 0) { - printf(""); - } int cmp = strncmp(treeA->entry->name, treeB->entry->name, minSize); if (cmp != 0) return cmp; diff --git a/tools/rom/rom.h b/tools/rom/rom.h index 2a91e2bb..45c0999b 100644 --- a/tools/rom/rom.h +++ b/tools/rom/rom.h @@ -2,6 +2,7 @@ #define __ROM_H #include +#include #include typedef struct { diff --git a/tools/rom/util.h b/tools/rom/util.h index 29c2e157..a1dbf3b7 100644 --- a/tools/rom/util.h +++ b/tools/rom/util.h @@ -4,6 +4,7 @@ #include #include #include +#include #define FATAL(...) do { fprintf(stderr, __VA_ARGS__); return false; } while (0) @@ -20,9 +21,11 @@ # include # define mkdir(path, mode) mkdir(path) #elif __linux__ +# include # include # include # include +# include #else # error "Target platform not supported" #endif @@ -34,10 +37,12 @@ bool WcharToUtf8(wchar_t *in, size_t inSize, char *out, size_t outSize, size_t * *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"); + 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; - if (iconv(convDesc, &in, &inSize, &out, &remainingBytes) == -1) FATAL("Failed to convert to UTF-8\n"); + if (iconv(convDesc, (char**) &in, &inSize, &out, &remainingBytes) == -1) { + FATAL("Failed to convert to UTF-8: %s (%d)\n", strerror(errno), errno); + } if (inSize > 0) FATAL("Some characters were not converted to UTF-8\n"); *pResultSize = outSize - remainingBytes; return true; @@ -50,11 +55,20 @@ bool Utf8ToWchar(char *in, size_t inSize, wchar_t *out, size_t outSize) { if (resultSize == 0) FATAL("Failed to convert from UTF-8: %d\n", GetLastError()); return true; #elif __linux__ - iconv_t convDesc = iconv_open("UTF-8", "UTF-16"); - if (convDesc == -1) FATAL("Failed to get conversion description from UTF-8\n"); + 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; - if (iconv(convDesc, &in, &inSize, &out, &remainingBytes) == -1) FATAL("Failed to convert from UTF-8\n"); + wchar_t *result = out; + if (iconv(convDesc, &in, &inSize, (char**) &out, &remainingBytes) == -1) { + FATAL("Failed to convert from UTF-8: %s (%d)\n", strerror(errno), errno); + } if (inSize > 0) FATAL("Some characters were not converted from UTF-8\n"); + // Remove 0xFEFF header + if (*result == 0xfeff) { + size_t numChars = (outSize - remainingBytes) / sizeof(wchar_t) - 1; + memmove(result, result + 1, numChars * sizeof(wchar_t)); + result[numChars] = '\0'; + } return true; #endif }