diff options
author | Akira Akashi <rubenru09@aol.com> | 2021-05-31 23:58:57 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-05-31 23:58:57 +0100 |
commit | 40bf7584958428b8645256d5093143b7f0c6ebdd (patch) | |
tree | 5afeb1fde81971ba32843e7119c8d9c3c9f8eb56 | |
parent | 901807cd6f693ffa9941ddd167ef0ad9a5cf3d51 (diff) | |
parent | 6cffcf0ee5f4e04ce4e79f30645938e0b58f4650 (diff) |
Merge pull request #394 from PikalaxALT/make_naix
Output NARC contents as C enums in .naix files
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | Makefile | 5 | ||||
-rw-r--r-- | arm9/CMakeLists.txt | 2 | ||||
-rw-r--r-- | arm9/Makefile | 2 | ||||
-rw-r--r-- | arm9/modules/16/asm/module_16.s | 12 | ||||
-rw-r--r-- | arm9/src/main.c | 1 | ||||
-rw-r--r-- | filesystem.mk | 10 | ||||
-rw-r--r-- | tools/knarc/Narc.cpp | 46 | ||||
-rw-r--r-- | tools/knarc/Source.cpp | 5 | ||||
-rw-r--r-- | tools/o2narc/o2narc.cpp | 64 |
10 files changed, 127 insertions, 21 deletions
@@ -49,3 +49,4 @@ symbols.csv *.arc files/**/*.c *.o +*.naix @@ -162,6 +162,7 @@ clean: mostlyclean clean-fs clean-tools clean-fs: $(RM) $(filter %.narc %.arc,$(HOSTFS_FILES)) + $(RM) $(patsubst %.narc,%.naix,$(patsubst %.arc,%.naix,$(filter %.narc %.arc,$(HOSTFS_FILES)))) $(RM) $(NCGR_CLEAN_LIST) $(NCLR_CLEAN_LIST) $(NCER_CLEAN_LIST) $(NSCR_CLEAN_LIST) find . \( -iname '*.1bpp' -o -iname '*.4bpp' -o -iname '*.8bpp' -o -iname '*.gbapal' -o -iname '*.lz' \) -exec $(RM) {} + $(RM) files/msgdata/msg/narc_*.bin @@ -204,7 +205,7 @@ $(BUILD_DIR)/%.o: %.c $$(dep) $(BUILD_DIR)/%.o: %.s $$(dep) $(AS) $(ASFLAGS) $< -o $@ -arm9: +arm9: filesystem $(MAKE) -C arm9 $(MAKE_VARS) arm7: @@ -214,7 +215,7 @@ include filesystem.mk # TODO: Rules for Pearl # FIXME: Computed secure area CRC in header is incorrect due to first 8 bytes of header not actually being "encryObj" -$(ROM): rom.rsf arm9 arm7 filesystem $(BNR) tools/bin/rom_header.template.sbin +$(ROM): rom.rsf arm9 arm7 $(BNR) tools/bin/rom_header.template.sbin $(MAKEROM) -DBUILD_DIR="$(BUILD_DIR)" -DBNR="$(BNR)" -DTITLE_NAME="$(TITLE_NAME)" -DNITROFS_FILES="$(NITROFS_FILES)" $< $@ ifeq ($(SHIFTED),0) $(FIXROM) $@ --secure-crc $(SECURE_CRC) --game-code $(GAME_CODE) diff --git a/arm9/CMakeLists.txt b/arm9/CMakeLists.txt index fce2106f..0de93feb 100644 --- a/arm9/CMakeLists.txt +++ b/arm9/CMakeLists.txt @@ -15,5 +15,5 @@ file(GLOB_RECURSE SOURCES "*.c" "*.cpp") file(GLOB MODULE_INC modules/*/include) add_executable(DP_Arm9 ${SOURCES}) -target_include_directories(DP_Arm9 PRIVATE ../include ../include-mw lib/include ${MODULE_INC}) +target_include_directories(DP_Arm9 PRIVATE ../include ../include-mw lib/include ${MODULE_INC} ../files) target_compile_definitions(DP_Arm9 PUBLIC __CLION_IDE__) diff --git a/arm9/Makefile b/arm9/Makefile index 6f05d1c5..2ad29363 100644 --- a/arm9/Makefile +++ b/arm9/Makefile @@ -54,7 +54,7 @@ SRC_DIRS := src lib lib/src $(sort $(wildcard modules/*/src)) ASM_DIRS := asm data files $(sort $(wildcard modules/*/asm)) LIBASM_DIRS := lib/syscall INCLUDE_RECURSIVE_DIRS := ../include-mw lib/include -INCLUDE_DIRS := ../include $(sort $(wildcard modules/*/include)) +INCLUDE_DIRS := ../include $(sort $(wildcard modules/*/include)) ../files C_FILES := $(foreach dir,$(SRC_DIRS),$(sort $(wildcard $(dir)/*.c))) CXX_FILES := $(foreach dir,$(SRC_DIRS),$(sort $(wildcard $(dir)/*.cpp))) diff --git a/arm9/modules/16/asm/module_16.s b/arm9/modules/16/asm/module_16.s index 82ff69c0..e9eedca1 100644 --- a/arm9/modules/16/asm/module_16.s +++ b/arm9/modules/16/asm/module_16.s @@ -9944,9 +9944,9 @@ _021DBD82: add r0, sp, #8 str r0, [sp, #4] .ifdef DIAMOND - mov r0, #0x8b + mov r0, #0x8b ; NARC_APPLICATION_ZUKANLIST_ZKN_DATA_ZUKAN_ENC_DIAMOND .else - mov r0, #0x8c + mov r0, #0x8c ; NARC_APPLICATION_ZUKANLIST_ZKN_DATA_ZUKAN_ENC_PEARL .endif add r1, r5, r1 bl GfGfxLoader_LoadFromNarc_GetSizeOut @@ -9999,9 +9999,9 @@ MOD16_021DBDE4: ; 0x021DBDE4 add r0, sp, #8 str r0, [sp, #4] .ifdef DIAMOND - mov r0, #0x8b + mov r0, #0x8b ; NARC_APPLICATION_ZUKANLIST_ZKN_DATA_ZUKAN_ENC_DIAMOND .else - mov r0, #0x8c + mov r0, #0x8c ; NARC_APPLICATION_ZUKANLIST_ZKN_DATA_ZUKAN_ENC_PEARL .endif add r2, r1, #0 bl GfGfxLoader_LoadFromNarc_GetSizeOut @@ -10027,9 +10027,9 @@ MOD16_021DBE0C: ; 0x021DBE0C add r0, sp, #8 str r0, [sp, #4] .ifdef DIAMOND - mov r0, #0x8b + mov r0, #0x8b ; NARC_APPLICATION_ZUKANLIST_ZKN_DATA_ZUKAN_ENC_DIAMOND .else - mov r0, #0x8c + mov r0, #0x8c ; NARC_APPLICATION_ZUKANLIST_ZKN_DATA_ZUKAN_ENC_PEARL .endif mov r1, #2 bl GfGfxLoader_LoadFromNarc_GetSizeOut diff --git a/arm9/src/main.c b/arm9/src/main.c index 7a8a14d8..749bec41 100644 --- a/arm9/src/main.c +++ b/arm9/src/main.c @@ -16,7 +16,6 @@ #include "unk_0202F150.h" #include "module_52.h" - FS_EXTERN_OVERLAY(MODULE_52); FS_EXTERN_OVERLAY(MODULE_63); diff --git a/filesystem.mk b/filesystem.mk index 2b74f25f..387231bf 100644 --- a/filesystem.mk +++ b/filesystem.mk @@ -275,10 +275,13 @@ endif HOSTFS_FILES := $(NITROFS_FILES:%=files/%) %.narc: - $(KNARC) -d $(basename $@)/ -p $@ + $(KNARC) -d $(basename $@)/ -p $@ -i %.arc: - $(KNARC) -d $(basename $@)/ -p $@ + $(KNARC) -d $(basename $@)/ -p $@ -i + +%.naix: %.narc +files/wazaeffect/we.naix: %.naix: %.arc O2NARC_TARGETS := \ files/poketool/personal/personal.narc \ @@ -295,8 +298,9 @@ O2NARC_TARGETS := \ ALL_O2NARC_TARGETS := $(O2NARC_TARGETS) \ files/poketool/trainer/trpoke.narc +O2NARCFLAGS := -i files/poketool/personal/pms.narc: O2NARCFLAGS = -f -files/itemtool/itemdata/item_data.narc: O2NARCFLAGS = -p 0xFF +files/itemtool/itemdata/item_data.narc: O2NARCFLAGS += -p 0xFF ifeq (,$(NODEP)) $(ALL_O2NARC_TARGETS): dep = $(shell $(SCANINC) -I include -I include-mw -I arm9/lib/include $(patsubst %.narc,%.json.txt,$@)) diff --git a/tools/knarc/Narc.cpp b/tools/knarc/Narc.cpp index 7e698571..cce7cdea 100644 --- a/tools/knarc/Narc.cpp +++ b/tools/knarc/Narc.cpp @@ -29,6 +29,7 @@ using namespace std; extern bool debug; extern bool pack_no_fnt; +extern bool output_header; void Narc::AlignDword(ofstream& ofs, uint8_t paddingChar) { @@ -145,6 +146,39 @@ bool Narc::Pack(const fs::path& fileName, const fs::path& directory) if (!ofs.good()) { return Cleanup(ofs, NarcError::InvalidOutputFile); } + ofstream ofhs; + string stem; + string stem_upper; + // Pikalax 29 May 2021 + // Output an includable header that enumerates the NARC contents + if (output_header) + { + fs::path naixfname = fileName; + naixfname.replace_extension(".naix"); + + ofhs.open(naixfname); + if (!ofhs.good()) + { + ofhs.close(); + return Cleanup(ofs, NarcError::InvalidOutputFile); + } + + stem = fileName.stem().string(); + stem_upper = stem; + for (char &c : stem_upper) + { c = toupper(c); } + + ofhs << "/*\n" + " * THIS FILE WAS AUTOMATICALLY\n" + " * GENERATED BY tools/knarc\n" + " * DO NOT MODIFY!!!\n" + " */\n" + "\n" + "#ifndef NARC_" << stem_upper << "_NAIX_\n" + "#define NARC_" << stem_upper << "_NAIX_\n" + "\n" + "enum {\n"; + } vector<FileAllocationTableEntry> fatEntries; uint16_t directoryCounter = 1; @@ -153,6 +187,7 @@ bool Narc::Pack(const fs::path& fileName, const fs::path& directory) ignore_patterns.push_back(".*keep"); WildcardVector keep_patterns(directory / ".knarckeep"); + int memberNo = 0; for (const auto& de : OrderedDirectoryIterator(directory, true)) { if (is_directory(de)) @@ -164,6 +199,12 @@ bool Narc::Pack(const fs::path& fileName, const fs::path& directory) if (debug) { cerr << "DEBUG: adding file " << de.path() << endl; } + if (output_header) + { + string de_stem = de.path().filename().string(); + std::replace(de_stem.begin(), de_stem.end(), '.', '_'); + ofhs << "\tNARC_" << stem << "_" << de_stem << " = " << (memberNo++) << ",\n"; + } fatEntries.push_back(FileAllocationTableEntry { .Start = 0x0, @@ -183,6 +224,11 @@ bool Narc::Pack(const fs::path& fileName, const fs::path& directory) fatEntries.back().End = fatEntries.back().Start + static_cast<uint32_t>(file_size(de)); } } + if (output_header) + { + ofhs << "};\n\n#endif //NARC_" << stem_upper << "_NAIX_\n"; + ofhs.close(); + } FileAllocationTable fat { diff --git a/tools/knarc/Source.cpp b/tools/knarc/Source.cpp index d9a5cf83..587c8527 100644 --- a/tools/knarc/Source.cpp +++ b/tools/knarc/Source.cpp @@ -8,6 +8,7 @@ using namespace std; bool debug = false; bool pack_no_fnt = true; +bool output_header = false; void PrintError(NarcError error) { @@ -40,6 +41,7 @@ static inline void usage() { cout << "\t-n\tBuild the filename table (default: discards filenames)" << endl; cout << "\t-D/--debug\tPrint additional debug messages" << endl; cout << "\t-h/--help\tPrint this message and exit" << endl; + cout << "\t-i\tOutput a .naix header" << endl; } int main(int argc, char* argv[]) @@ -104,6 +106,9 @@ int main(int argc, char* argv[]) else if (!strcmp(argv[i], "-n")) { pack_no_fnt = false; } + else if (!strcmp(argv[i], "-i")) { + output_header = true; + } else { usage(); cerr << "ERROR: Unrecognized argument: " << argv[i] << endl; diff --git a/tools/o2narc/o2narc.cpp b/tools/o2narc/o2narc.cpp index 1381788a..60e4e242 100644 --- a/tools/o2narc/o2narc.cpp +++ b/tools/o2narc/o2narc.cpp @@ -3,6 +3,7 @@ #include <getopt.h> #include <cstring> #include <vector> +#include <iomanip> #include "elf.h" #include "Narc.h" @@ -49,6 +50,7 @@ class Elf { public: ShdrTab shdr; Symtab symtab; + Elf(string const& filename) : Elf(filename.c_str()) {} Elf(const char * filename) { // Read the ELF header phdr = nullptr; @@ -155,25 +157,29 @@ static inline void usage() { cout << "\toutfile\tOutput NARC file" << endl; cout << "Options:" << endl; cout << "\t-f|--flatten\tDon't generate NARC headers" << endl; + cout << "\t-i|--output-header\tCreate a .naix file" << endl; } int main(int argc, char ** argv) { // CLI arguments - int flatten = 0; + int flatten = 0, output_header = 0; char padding = '\xFF'; static option options [] { { "flatten", no_argument, &flatten, 1 }, { "padding", required_argument, nullptr, 'p' }, + { "output_header", no_argument, &output_header, 1 }, {nullptr, 0, nullptr, 0} }; int opt_index; int c; - while ((c = getopt_long(argc, argv, "fp:", options, &opt_index)) != -1) + while ((c = getopt_long(argc, argv, "fp:i", options, &opt_index)) != -1) { if (c == 'f') { flatten = 1; } else if (c == 'p') { padding = strtol(optarg, NULL, 0); + } else if (c == 'i') { + output_header = 1; } } argv += optind; @@ -188,8 +194,13 @@ int main(int argc, char ** argv) { cerr << "Excess arguments: first unrecognized '" << argv[2] << "'" << endl; return 1; } - char * infname = argv[0]; - char * outfname = argv[1]; + if (output_header && flatten) { + usage(); + cerr << "Incompatible flags: -i, -f" << endl; + return 1; + } + const char * infname = argv[0]; + const char * outfname = argv[1]; // Read the ELF file Elf elf(infname); @@ -201,15 +212,45 @@ int main(int argc, char ** argv) { exit(1); } - fstream ofile; - ofile.open(outfname, ios_base::out | ios_base::binary); + ofstream ofile; + ofile.open(outfname, ios_base::binary); if (!ofile.good()) { cerr << "ERROR: Unable to open '" << outfname << "' for writing" << endl; exit(1); } - if (!flatten) // then build the NARC chunks { + string stem, stem_upper; + ofstream ofheader; + if (output_header) + { + string outhname = outfname; + outhname.replace(outhname.find(".narc"), 5, ".naix"); + ofheader.open(outhname); + if (!ofheader.good()) + { + ofile.close(); + cerr << "ERROR: Unable to open '" << outhname << "' for writing" << endl; + exit(1); + } + stem = outfname; + stem = stem.substr(0, stem.rfind(".")); + stem = stem.substr(stem.rfind("/") + 1); + stem_upper = stem; + for (char &_c : stem_upper) + { _c = toupper(_c); } + + ofheader << "/*\n" + " * THIS FILE WAS AUTOMATICALLY\n" + " * GENERATED BY tools/o2narc\n" + " * DO NOT MODIFY!!!\n" + " */\n" + "\n" + "#ifndef NARC_" << stem_upper << "_NAIX_\n" + "#define NARC_" << stem_upper << "_NAIX_\n" + "\n" + "enum {\n"; + } // .data contains the size table Elf32_Shdr & data_sec = elf.shdr[".data"]; uint32_t * _data = (uint32_t *)elf.read(data_sec); @@ -275,6 +316,15 @@ int main(int argc, char ** argv) { { _rodata[fat_entries[i].Start + j] = padding; } + if (output_header) + { + ofheader << "\tNARC_" << stem << "_narc_" << setw(4) << setfill('0') << i << " = " << i << ",\n"; + } + } + if (output_header) + { + ofheader << "};\n\n#endif //NARC_" << stem_upper << "_NAIX_\n"; + ofheader.close(); } // These NARCs have empty FNTs FileNameTable fnt{ |