diff --git a/Makefile b/Makefile index 754ecebe36..25c7a7248b 100644 --- a/Makefile +++ b/Makefile @@ -71,6 +71,7 @@ ROM_NAME := $(FILE_NAME).gba OBJ_DIR_NAME := $(BUILD_DIR)/emerald MODERN_ROM_NAME := $(FILE_NAME)_modern.gba MODERN_OBJ_DIR_NAME := $(BUILD_DIR)/modern +ASSETS_DIR_NAME := $(BUILD_DIR)/assets ELF_NAME := $(ROM_NAME:.gba=.elf) MAP_NAME := $(ROM_NAME:.gba=.map) @@ -234,6 +235,7 @@ clean: tidy clean-tools clean-generated clean-assets @$(MAKE) clean -C libagbsyscall clean-assets: + rm -rf $(ASSETS_DIR_NAME) rm -f $(MID_SUBDIR)/*.s rm -f $(DATA_ASM_SUBDIR)/layouts/layouts.inc $(DATA_ASM_SUBDIR)/layouts/layouts_table.inc rm -f $(DATA_ASM_SUBDIR)/maps/connections.inc $(DATA_ASM_SUBDIR)/maps/events.inc $(DATA_ASM_SUBDIR)/maps/groups.inc $(DATA_ASM_SUBDIR)/maps/headers.inc @@ -306,16 +308,16 @@ endif $(C_BUILDDIR)/%.o: $(C_SUBDIR)/%.c ifneq ($(KEEP_TEMPS),1) @echo "$(CC1) -o $@ $<" - @$(CPP) $(CPPFLAGS) $< | $(PREPROC) -i $< charmap.txt | $(CC1) $(CFLAGS) -o - - | cat - <(echo -e ".text\n\t.align\t2, 0") | $(AS) $(ASFLAGS) -o $@ - + @$(CPP) $(CPPFLAGS) $< | $(PREPROC) -i -g $(ASSETS_DIR_NAME) $< charmap.txt | $(CC1) $(CFLAGS) -o - - | cat - <(echo -e ".text\n\t.align\t2, 0") | $(AS) $(ASFLAGS) -o $@ - else @$(CPP) $(CPPFLAGS) $< -o $(C_BUILDDIR)/$*.i - @$(PREPROC) $(C_BUILDDIR)/$*.i charmap.txt | $(CC1) $(CFLAGS) -o $(C_BUILDDIR)/$*.s + @$(PREPROC) -g $(ASSETS_DIR_NAME) $(C_BUILDDIR)/$*.i charmap.txt | $(CC1) $(CFLAGS) -o $(C_BUILDDIR)/$*.s @echo -e ".text\n\t.align\t2, 0\n" >> $(C_BUILDDIR)/$*.s $(AS) $(ASFLAGS) -o $@ $(C_BUILDDIR)/$*.s endif $(C_BUILDDIR)/%.d: $(C_SUBDIR)/%.c - $(SCANINC) -M $@ $(INCLUDE_SCANINC_ARGS) -I tools/agbcc/include $< + $(SCANINC) -M $@ -g $(ASSETS_DIR_NAME) $(INCLUDE_SCANINC_ARGS) -I tools/agbcc/include $< ifneq ($(NODEP),1) -include $(addprefix $(OBJ_DIR)/,$(C_SRCS:.c=.d)) @@ -325,7 +327,7 @@ $(ASM_BUILDDIR)/%.o: $(ASM_SUBDIR)/%.s $(AS) $(ASFLAGS) -o $@ $< $(ASM_BUILDDIR)/%.d: $(ASM_SUBDIR)/%.s - $(SCANINC) -M $@ $(INCLUDE_SCANINC_ARGS) -I "" $< + $(SCANINC) -M $@ -g $(ASSETS_DIR_NAME) $(INCLUDE_SCANINC_ARGS) -I "" $< ifneq ($(NODEP),1) -include $(addprefix $(OBJ_DIR)/,$(ASM_SRCS:.s=.d)) @@ -335,7 +337,7 @@ $(C_BUILDDIR)/%.o: $(C_SUBDIR)/%.s $(PREPROC) $< charmap.txt | $(CPP) $(INCLUDE_SCANINC_ARGS) - | $(PREPROC) -ie $< charmap.txt | $(AS) $(ASFLAGS) -o $@ $(C_BUILDDIR)/%.d: $(C_SUBDIR)/%.s - $(SCANINC) -M $@ $(INCLUDE_SCANINC_ARGS) -I "" $< + $(SCANINC) -M $@ -g $(ASSETS_DIR_NAME) $(INCLUDE_SCANINC_ARGS) -I "" $< ifneq ($(NODEP),1) -include $(addprefix $(OBJ_DIR)/,$(C_ASM_SRCS:.s=.d)) @@ -345,7 +347,7 @@ $(DATA_ASM_BUILDDIR)/%.o: $(DATA_ASM_SUBDIR)/%.s $(PREPROC) $< charmap.txt | $(CPP) $(INCLUDE_SCANINC_ARGS) - | $(PREPROC) -ie $< charmap.txt | $(AS) $(ASFLAGS) -o $@ $(DATA_ASM_BUILDDIR)/%.d: $(DATA_ASM_SUBDIR)/%.s - $(SCANINC) -M $@ $(INCLUDE_SCANINC_ARGS) -I "" $< + $(SCANINC) -M $@ -g $(ASSETS_DIR_NAME) $(INCLUDE_SCANINC_ARGS) -I "" $< ifneq ($(NODEP),1) -include $(addprefix $(OBJ_DIR)/,$(REGULAR_DATA_ASM_SRCS:.s=.d)) diff --git a/tools/preproc/c_file.cpp b/tools/preproc/c_file.cpp index d034b3f1f1..8de8ed7a92 100644 --- a/tools/preproc/c_file.cpp +++ b/tools/preproc/c_file.cpp @@ -18,6 +18,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. +#include #include #include #include @@ -32,7 +33,7 @@ #include "string_parser.h" #include "io.h" -CFile::CFile(const char * filenameCStr, bool isStdin) +CFile::CFile(const char * filenameCStr, bool isStdin, const char * graphicsRootCStr) { if (isStdin) m_filename = std::string{"/"}.append(filenameCStr); @@ -44,6 +45,9 @@ CFile::CFile(const char * filenameCStr, bool isStdin) m_pos = 0; m_lineNum = 1; m_isStdin = isStdin; + m_graphicsRoot = graphicsRootCStr; + if (m_graphicsRoot.empty()) m_graphicsRoot = "./"; + if (m_graphicsRoot[m_graphicsRoot.length() - 1] != '/') m_graphicsRoot.push_back('/'); } CFile::CFile(CFile&& other) : m_filename(std::move(other.m_filename)) @@ -94,6 +98,7 @@ void CFile::Preproc() { TryConvertString(); TryConvertIncbin(); + TryConvertIncgfx(); if (m_pos >= m_size) break; @@ -237,6 +242,37 @@ bool CFile::CheckIdentifier(const std::string& ident) return (i == ident.length()); } +std::string CFile::ReadString() +{ + if (m_buffer[m_pos] != '"') + RaiseError("expected '\"'"); + m_pos++; + + long startPos = m_pos; + + while (m_buffer[m_pos] != '"') + { + if (m_buffer[m_pos] == 0) + { + if (m_pos >= m_size) + RaiseError("unexpected EOF in string"); + else + RaiseError("unexpected null character in string"); + } + + if (m_buffer[m_pos] == '\r' || m_buffer[m_pos] == '\n') + RaiseError("unexpected end of line character in string"); + + if (m_buffer[m_pos] == '\\') + RaiseError("unexpected escape in string"); + + m_pos++; + } + m_pos++; + + return std::string(&m_buffer[startPos], m_pos - 1 - startPos); +} + std::unique_ptr CFile::ReadWholeFile(const std::string& path, int& size) { FILE* fp = std::fopen(path.c_str(), "rb"); @@ -319,36 +355,7 @@ void CFile::TryConvertIncbin() while (true) { SkipWhitespace(); - - if (m_buffer[m_pos] != '"') - RaiseError("expected double quote"); - - m_pos++; - - int startPos = m_pos; - - while (m_buffer[m_pos] != '"') - { - if (m_buffer[m_pos] == 0) - { - if (m_pos >= m_size) - RaiseError("unexpected EOF in path string"); - else - RaiseError("unexpected null character in path string"); - } - - if (m_buffer[m_pos] == '\r' || m_buffer[m_pos] == '\n') - RaiseError("unexpected end of line character in path string"); - - if (m_buffer[m_pos] == '\\') - RaiseError("unexpected escape in path string"); - - m_pos++; - } - - std::string path(&m_buffer[startPos], m_pos - startPos); - - m_pos++; + auto path = ReadString(); int fileSize; std::unique_ptr buffer = ReadWholeFile(path, fileSize); @@ -382,6 +389,108 @@ void CFile::TryConvertIncbin() std::printf("}"); } +void CFile::TryConvertIncgfx() +{ + if (!CheckIdentifier("INCGFX_")) + return; + + std::string idents[3] = { "INCGFX_U8", "INCGFX_U16", "INCGFX_U32" }; + int incgfxType = -1; + + for (int i = 0; i < 3; i++) + { + if (CheckIdentifier(idents[i])) + { + incgfxType = i; + break; + } + } + + if (incgfxType == -1) + return; + + int size = 1 << incgfxType; + + long oldPos = m_pos; + long oldLineNum = m_lineNum; + + m_pos += idents[incgfxType].length(); + + SkipWhitespace(); + if (m_buffer[m_pos] != '(') + { + m_pos = oldPos; + m_lineNum = oldLineNum; + return; + } + m_pos++; + + SkipWhitespace(); + auto source = ReadString(); + + SkipWhitespace(); + if (m_buffer[m_pos] != ',') + RaiseError("expected ','"); + m_pos++; + + SkipWhitespace(); + auto extensions = ReadString(); + + SkipWhitespace(); + std::string arguments; + if (m_buffer[m_pos] == ',') + { + m_pos++; + SkipWhitespace(); + arguments = ReadString(); + + SkipWhitespace(); + if (m_buffer[m_pos] != ')') + RaiseError("expected ')'"); + m_pos++; + } + else if (m_buffer[m_pos] == ')') + { + m_pos++; + } + else + { + RaiseError("exected ')' or ','"); + } + + // WARNING: This must stay in-sync with 'tools/scaninc/source_file.cpp'. + std::string arguments_as_path; + for (auto c : arguments) + { + if (std::isalnum(c)) + arguments_as_path += c; + else + arguments_as_path += '_'; + } + + // WARNING: This must stay in-sync with 'tools/scaninc/scaninc.cpp'. + auto converted = m_graphicsRoot + source + arguments_as_path + extensions; + + int fileSize; + std::unique_ptr buffer = ReadWholeFile(converted, fileSize); + + if ((fileSize % size) != 0) + RaiseError("Size %d doesn't evenly divide file size %d.\n", size, fileSize); + + std::printf("{"); + + int count = fileSize / size; + int offset = 0; + for (int i = 0; i < count; i++) + { + int data = ExtractData(buffer, offset, size); + offset += size; + std::printf("%uu,", data); + } + + std::printf("}"); +} + // Reports a diagnostic message. void CFile::ReportDiagnostic(const char* type, const char* format, std::va_list args) { diff --git a/tools/preproc/c_file.h b/tools/preproc/c_file.h index c40c33c962..0dbc4aef1b 100644 --- a/tools/preproc/c_file.h +++ b/tools/preproc/c_file.h @@ -30,7 +30,7 @@ class CFile { public: - CFile(const char * filenameCStr, bool isStdin); + CFile(const char * filenameCStr, bool isStdin, const char * graphicsRootCStr); CFile(CFile&& other); CFile(const CFile&) = delete; ~CFile(); @@ -43,6 +43,7 @@ private: long m_lineNum; std::string m_filename; bool m_isStdin; + std::string m_graphicsRoot; bool ConsumeHorizontalWhitespace(); bool ConsumeNewline(); @@ -50,7 +51,9 @@ private: void TryConvertString(); std::unique_ptr ReadWholeFile(const std::string& path, int& size); bool CheckIdentifier(const std::string& ident); + std::string ReadString(); void TryConvertIncbin(); + void TryConvertIncgfx(); void ReportDiagnostic(const char* type, const char* format, std::va_list args); void RaiseError(const char* format, ...); void RaiseWarning(const char* format, ...); diff --git a/tools/preproc/preproc.cpp b/tools/preproc/preproc.cpp index ac9496d701..112d884044 100644 --- a/tools/preproc/preproc.cpp +++ b/tools/preproc/preproc.cpp @@ -118,9 +118,9 @@ void PreprocAsmFile(std::string filename, bool isStdin, bool doEnum) } } -void PreprocCFile(const char * filename, bool isStdin) +void PreprocCFile(const char * filename, bool isStdin, const char * graphicsRoot) { - CFile cFile(filename, isStdin); + CFile cFile(filename, isStdin, graphicsRoot); cFile.Preproc(); } @@ -147,7 +147,7 @@ const char* GetFileExtension(const char* filename) static void UsageAndExit(const char *program) { - std::fprintf(stderr, "Usage: %s [-i] [-e] SRC_FILE CHARMAP_FILE\nwhere -i denotes if input is from stdin\n -e enables enum handling\n", program); + std::fprintf(stderr, "Usage: %s [-i] [-e] [-g PATH] SRC_FILE CHARMAP_FILE\nwhere -i denotes if input is from stdin\n -e enables enum handling\n-g specifies the root for INCGFX\n", program); std::exit(EXIT_FAILURE); } @@ -158,9 +158,10 @@ int main(int argc, char **argv) const char *charmap = NULL; bool isStdin = false; bool doEnum = false; + const char *graphicsRoot = ""; - /* preproc [-i] [-e] SRC_FILE CHARMAP_FILE */ - while ((opt = getopt(argc, argv, "ie")) != -1) + /* preproc [-i] [-e] [-g PATH] SRC_FILE CHARMAP_FILE */ + while ((opt = getopt(argc, argv, "ieg:")) != -1) { switch (opt) { @@ -170,6 +171,9 @@ int main(int argc, char **argv) case 'e': doEnum = true; break; + case 'g': + graphicsRoot = optarg; + break; default: UsageAndExit(argv[0]); break; @@ -202,7 +206,7 @@ int main(int argc, char **argv) { if (doEnum) FATAL_ERROR("-e is invalid for C sources\n"); - PreprocCFile(source, isStdin); + PreprocCFile(source, isStdin, graphicsRoot); } else { diff --git a/tools/scaninc/c_file.cpp b/tools/scaninc/c_file.cpp index f76976696d..e6ce65d056 100644 --- a/tools/scaninc/c_file.cpp +++ b/tools/scaninc/c_file.cpp @@ -18,6 +18,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. +#include #include "c_file.h" CFile::CFile(std::string path) @@ -86,6 +87,7 @@ void CFile::FindIncbins() SkipWhitespace(); CheckInclude(); CheckIncbin(); + CheckIncgfx(); if (m_pos >= m_size) break; @@ -215,7 +217,7 @@ void CFile::CheckIncbin() && m_buffer[m_pos+5] == 'N' && m_buffer[m_pos+6] == '_')) { - return; + return; } std::string idents[3] = { "INCBIN_U8", "INCBIN_U16", "INCBIN_U32" }; @@ -272,6 +274,86 @@ void CFile::CheckIncbin() } +void CFile::CheckIncgfx() +{ + // Optimization: assume most lines are not incgfxs + if (!(m_buffer[m_pos+0] == 'I' + && m_buffer[m_pos+1] == 'N' + && m_buffer[m_pos+2] == 'C' + && m_buffer[m_pos+3] == 'G' + && m_buffer[m_pos+4] == 'F' + && m_buffer[m_pos+5] == 'X' + && m_buffer[m_pos+6] == '_')) + { + return; + } + + std::string idents[3] = { "INCGFX_U8", "INCGFX_U16", "INCGFX_U32" }; + int incgfxType = -1; + + for (int i = 0; i < 3; i++) + { + if (CheckIdentifier(idents[i])) + { + incgfxType = i; + break; + } + } + + if (incgfxType == -1) + return; + + long oldPos = m_pos; + long oldLineNum = m_lineNum; + + m_pos += idents[incgfxType].length(); + + SkipWhitespace(); + if (m_buffer[m_pos] != '(') + { + m_pos = oldPos; + m_lineNum = oldLineNum; + return; + } + m_pos++; + + SkipWhitespace(); + std::string path = ReadPath(); + + SkipWhitespace(); + if (m_buffer[m_pos] != ',') + FATAL_INPUT_ERROR("expected ','"); + m_pos++; + + SkipWhitespace(); + std::string extensions = ReadString(); + + SkipWhitespace(); + std::string arguments; + if (m_buffer[m_pos] == ',') + { + m_pos++; + SkipWhitespace(); + arguments = ReadString(); + + SkipWhitespace(); + if (m_buffer[m_pos] != ')') + FATAL_INPUT_ERROR("expected ')'"); + m_pos++; + } + else if (m_buffer[m_pos] == ')') + { + m_pos++; + } + else + { + FATAL_INPUT_ERROR("expected ')' or ','"); + } + + Incgfx incgfx = { path, extensions, arguments }; + m_incgfxs.emplace(incgfx); +} + std::string CFile::ReadPath() { if (m_buffer[m_pos] != '"') @@ -285,7 +367,7 @@ std::string CFile::ReadPath() m_pos++; - int startPos = m_pos; + long startPos = m_pos; while (m_buffer[m_pos] != '"') { @@ -310,3 +392,34 @@ std::string CFile::ReadPath() return std::string(m_buffer + startPos, m_pos - 1 - startPos); } + +std::string CFile::ReadString() +{ + if (m_buffer[m_pos] != '"') + FATAL_INPUT_ERROR("expected '\"', got: '%c'", m_buffer[m_pos]); + m_pos++; + + long startPos = m_pos; + + while (m_buffer[m_pos] != '"') + { + if (m_buffer[m_pos] == 0) + { + if (m_pos >= m_size) + FATAL_INPUT_ERROR("expected EOF in string"); + else + FATAL_INPUT_ERROR("unexpected null character in string"); + } + + if (m_buffer[m_pos] == '\r' || m_buffer[m_pos] == '\n') + FATAL_INPUT_ERROR("unexpected end of line character in string"); + + if (m_buffer[m_pos] == '\\') + FATAL_INPUT_ERROR("unexpected escape in string"); + + m_pos++; + } + m_pos++; + + return std::string(m_buffer + startPos, m_pos - 1 - startPos); +} diff --git a/tools/scaninc/c_file.h b/tools/scaninc/c_file.h index 618901b855..fc1565b73a 100644 --- a/tools/scaninc/c_file.h +++ b/tools/scaninc/c_file.h @@ -21,9 +21,10 @@ #ifndef C_FILE_H #define C_FILE_H -#include -#include #include +#include +#include +#include #include "scaninc.h" class CFile @@ -33,6 +34,7 @@ public: ~CFile(); void FindIncbins(); const std::set& GetIncbins() { return m_incbins; } + const std::set& GetIncgfxs() { return m_incgfxs; } const std::set& GetIncludes() { return m_includes; } private: @@ -42,6 +44,7 @@ private: int m_lineNum; std::string m_path; std::set m_incbins; + std::set m_incgfxs; std::set m_includes; bool ConsumeHorizontalWhitespace(); @@ -51,7 +54,9 @@ private: bool CheckIdentifier(const std::string& ident); void CheckInclude(); void CheckIncbin(); + void CheckIncgfx(); std::string ReadPath(); + std::string ReadString(); }; #endif // C_FILE_H diff --git a/tools/scaninc/scaninc.cpp b/tools/scaninc/scaninc.cpp index d470a3f163..56434e5a41 100644 --- a/tools/scaninc/scaninc.cpp +++ b/tools/scaninc/scaninc.cpp @@ -18,9 +18,11 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. +#include #include #include #include +#include #include #include #include @@ -41,18 +43,20 @@ bool CanOpenFile(std::string path) return true; } -const char *const USAGE = "Usage: scaninc [-I INCLUDE_PATH] [-M DEPENDENCY_OUT_PATH] FILE_PATH\n"; +const char *const USAGE = "Usage: scaninc [-I INCLUDE_PATH] [-M DEPENDENCY_OUT_PATH] [-g PATH] FILE_PATH\n"; int main(int argc, char **argv) { std::queue filesToProcess; std::set dependencies; std::set dependencies_includes; + std::map> dependencies_gfx_rules; std::vector includeDirs; bool makeformat = false; std::string make_outfile; + std::string gfx_root; argc--; argv++; @@ -82,6 +86,12 @@ int main(int argc, char **argv) argv++; make_outfile = std::string(argv[0]); } + else if (arg.substr(0, 2) == "-g") + { + argc--; + argv++; + gfx_root = std::string(argv[0]); + } else { FATAL_ERROR(USAGE); @@ -94,6 +104,11 @@ int main(int argc, char **argv) FATAL_ERROR(USAGE); } + size_t ext_pos = make_outfile.find_last_of("."); + auto object_file = make_outfile.substr(0, ext_pos + 1) + "o"; + if (gfx_root.empty()) gfx_root = "./"; + if (gfx_root[gfx_root.length() - 1] != '/') gfx_root.push_back('/'); + std::string initialPath(argv[0]); filesToProcess.push(initialPath); @@ -109,6 +124,34 @@ int main(int argc, char **argv) { dependencies.insert(incbin); } + for (auto incgfx : file.GetIncgfxs()) + { + // WARNING: This must stay in-sync with 'tools/preproc/c_file.cpp'. + std::string arguments_as_path; + for (auto c : incgfx.arguments) + { + if (std::isalnum(c)) + arguments_as_path += c; + else + arguments_as_path += '_'; + } + + // WARNING: This must stay in-sync with 'tools/preproc/c_file.cpp'. + auto target = gfx_root + incgfx.source + arguments_as_path + incgfx.extensions; + size_t target_slash_pos = target.find_last_of('/'); + auto mk_target_basedir = target_slash_pos == std::string::npos + ? "" + : "\t@mkdir -p '" + target.substr(0, target_slash_pos) + "'\n"; + auto rule = mk_target_basedir + "\t$(GFX) $< $@ " + incgfx.arguments + "\n"; + + dependencies.insert(target); + + // If "foo.4bpp.lz" we want a rule for "foo.4bpp", the ".lz" + // doesn't require any arguments. + size_t dot_pos = incgfx.extensions.find_first_of('.', 1); + auto firstTarget = gfx_root + incgfx.source + arguments_as_path + incgfx.extensions.substr(0, dot_pos); + dependencies_gfx_rules[firstTarget] = std::make_pair(incgfx.source, rule); + } for (auto include : file.GetIncludes()) { bool exists = false; @@ -141,7 +184,7 @@ int main(int argc, char **argv) includeDirs.pop_back(); } - if(!makeformat) + if (!makeformat) { for (const std::string &path : dependencies) { @@ -155,8 +198,6 @@ int main(int argc, char **argv) std::ofstream output(make_outfile); // Print a make rule for the object file - size_t ext_pos = make_outfile.find_last_of("."); - auto object_file = make_outfile.substr(0, ext_pos + 1) + "o"; output << object_file.c_str() << ":"; for (const std::string &path : dependencies) { @@ -180,6 +221,27 @@ int main(int argc, char **argv) output << path << ":\n"; } + // Graphics rules + // GNU make will issue a warning if there is more than one + // recipe for a target. This would occur whenever a target is + // 'INCGFX'ed multiple times, which is something that happens a + // few times in vanilla. As a workaround, we maintain a variable + // with all the 'INCGFX' targets and only emit the recipe if + // the target is not in that variable. This is safe, because + // targets with the same name necessarily have the same recipe. + output + << "ifndef _INCGFX\n" + << "_INCGFX :=\n" + << "endif\n"; + for (auto gfx_rule : dependencies_gfx_rules) + { + output + << "ifeq (,$(findstring " << gfx_rule.first << ",$(_INCGFX)))\n" + << "_INCGFX += " << gfx_rule.first << "\n" + << gfx_rule.first << ": " << gfx_rule.second.first << "\n" << gfx_rule.second.second + << "endif\n"; + } + output.flush(); output.close(); } diff --git a/tools/scaninc/scaninc.h b/tools/scaninc/scaninc.h index 30cc9611c1..902d8bea16 100644 --- a/tools/scaninc/scaninc.h +++ b/tools/scaninc/scaninc.h @@ -56,4 +56,18 @@ do { \ #define SCANINC_MAX_PATH 255 +struct Incgfx +{ + std::string source; + std::string extensions; + std::string arguments; + + bool operator<(const struct Incgfx &rhs) const + { + return source < rhs.source + || extensions < rhs.extensions + || arguments < rhs.arguments; + } +}; + #endif // SCANINC_H diff --git a/tools/scaninc/source_file.cpp b/tools/scaninc/source_file.cpp index 9d188eb738..e90959f7b3 100644 --- a/tools/scaninc/source_file.cpp +++ b/tools/scaninc/source_file.cpp @@ -72,6 +72,7 @@ SourceFile::SourceFile(std::string path) { AsmFile file(path); std::set incbins; + std::set incgfxs; std::set includes; IncDirectiveType incDirectiveType; @@ -85,7 +86,7 @@ SourceFile::SourceFile(std::string path) incbins.insert(outputPath); } - new (&m_source_file.asm_wrapper) SourceFile::InnerUnion::AsmWrapper{incbins, includes}; + new (&m_source_file.asm_wrapper) SourceFile::InnerUnion::AsmWrapper{incbins, incgfxs, includes}; } } @@ -103,6 +104,7 @@ SourceFile::~SourceFile() else { m_source_file.asm_wrapper.asm_incbins.~set(); + m_source_file.asm_wrapper.asm_incgfxs.~set(); m_source_file.asm_wrapper.asm_includes.~set(); } } @@ -115,6 +117,14 @@ const std::set& SourceFile::GetIncbins() return m_source_file.asm_wrapper.asm_incbins; } +const std::set& SourceFile::GetIncgfxs() +{ + if (m_file_type == SourceFileType::Cpp || m_file_type == SourceFileType::Header) + return m_source_file.c_file.GetIncgfxs(); + else + return m_source_file.asm_wrapper.asm_incgfxs; +} + const std::set& SourceFile::GetIncludes() { if (m_file_type == SourceFileType::Cpp || m_file_type == SourceFileType::Header) diff --git a/tools/scaninc/source_file.h b/tools/scaninc/source_file.h index 854b3f116b..91cdd67bdd 100644 --- a/tools/scaninc/source_file.h +++ b/tools/scaninc/source_file.h @@ -46,8 +46,8 @@ public: SourceFile(SourceFile&&) = delete; SourceFile& operator =(SourceFile const&) = delete; SourceFile& operator =(SourceFile&&) = delete; - bool HasIncbins(); const std::set& GetIncbins(); + const std::set& GetIncgfxs(); const std::set& GetIncludes(); std::string& GetSrcDir(); SourceFileType FileType(); @@ -57,6 +57,7 @@ private: CFile c_file; struct AsmWrapper { std::set asm_incbins; + std::set asm_incgfxs; std::set asm_includes; } asm_wrapper;