From f763eb6bf0182c0d44718c00b85578693b6b56e4 Mon Sep 17 00:00:00 2001 From: water111 <48171810+water111@users.noreply.github.com> Date: Thu, 30 Jun 2022 21:11:58 -0400 Subject: [PATCH] [jak2] support for multiple out/ directories (#1585) * [jak2] support for multiple out/ directories * windows --- common/goos/ReplUtils.cpp | 38 ++++++++----------- common/util/DgoWriter.cpp | 11 +++--- common/util/DgoWriter.h | 3 +- common/util/FileUtil.cpp | 6 ++- common/util/FileUtil.h | 1 + common/versions.h | 4 +- decompiler/config/jak1_pal.jsonc | 6 +-- decompiler/config/jak2_ntsc_v1.jsonc | 6 +-- decompiler/extractor/main.cpp | 4 +- decompiler/main.cpp | 4 +- game/graphics/display.cpp | 9 ++++- game/graphics/display.h | 6 ++- game/graphics/gfx.cpp | 7 ++-- game/graphics/gfx.h | 11 ++++-- game/graphics/pipelines/opengl.cpp | 13 ++++--- game/overlord/fake_iso.cpp | 7 +++- game/runtime.cpp | 3 +- goal_src/goal-lib.gc | 8 ++-- goal_src/jak1/game.gp | 12 +++--- goalc/build_level/build_level.cpp | 16 ++++---- goalc/build_level/build_level.h | 5 ++- goalc/compiler/Compiler.cpp | 3 +- goalc/compiler/CompilerSettings.cpp | 2 - goalc/compiler/CompilerSettings.h | 9 +---- .../compiler/compilation/CompilerControl.cpp | 13 ++++--- goalc/data_compiler/dir_tpages.cpp | 10 ++--- goalc/data_compiler/dir_tpages.h | 2 +- goalc/data_compiler/game_count.cpp | 10 ++--- goalc/data_compiler/game_count.h | 2 +- goalc/data_compiler/game_text_common.cpp | 24 +++++++----- goalc/data_compiler/game_text_common.h | 8 +++- goalc/make/MakeSystem.cpp | 19 +++++++++- goalc/make/MakeSystem.h | 9 +++++ goalc/make/Tool.h | 1 + goalc/make/Tools.cpp | 24 ++++++------ out/hash.md5 | 9 ----- out/{ => jak1/fr3}/.gitignore | 2 +- out/jak1/iso/.gitignore | 3 ++ out/jak1/obj/.gitignore | 3 ++ out/jak2/fr3/.gitignore | 3 ++ out/jak2/iso/.gitignore | 3 ++ out/jak2/obj/.gitignore | 3 ++ test/goalc/test_with_game.cpp | 6 +-- 43 files changed, 207 insertions(+), 141 deletions(-) delete mode 100644 out/hash.md5 rename out/{ => jak1/fr3}/.gitignore (58%) create mode 100644 out/jak1/iso/.gitignore create mode 100644 out/jak1/obj/.gitignore create mode 100644 out/jak2/fr3/.gitignore create mode 100644 out/jak2/iso/.gitignore create mode 100644 out/jak2/obj/.gitignore diff --git a/common/goos/ReplUtils.cpp b/common/goos/ReplUtils.cpp index bf9e010bc4..f6b8b6d6e4 100644 --- a/common/goos/ReplUtils.cpp +++ b/common/goos/ReplUtils.cpp @@ -34,7 +34,10 @@ void ReplWrapper::print_welcome_message() { fmt::print(" for help with common commands and REPL usage.\n"); fmt::print("Run "); fmt::print(fmt::emphasis::bold | fg(fmt::color::cyan), "(lt)"); - fmt::print(" to connect to the local target.\n\n"); + fmt::print(" to connect to the local target.\n"); + fmt::print("Run "); + fmt::print(fmt::emphasis::bold | fg(fmt::color::cyan), "(mi)"); + fmt::print(" to rebuild the entire game.\n\n"); } void ReplWrapper::print_to_repl(const std::string_view& str) { @@ -55,7 +58,8 @@ void ReplWrapper::add_to_history(const std::string& line) { void ReplWrapper::save_history() { std::filesystem::path path = file_util::get_user_config_dir(); - if (file_util::create_dir_if_needed(path)) { + file_util::create_dir_if_needed(path); + if (exists(path)) { repl.history_save((path / ".opengoal.repl.history").string()); } else { fmt::print("Couldn't save REPL history file to '{}'", path.string()); @@ -95,7 +99,7 @@ void ReplWrapper::print_help_message() { fmt::print(fmt::emphasis::bold | fg(fmt::color::cyan), "(:clear)\n"); fmt::print(" - Clear the current screen\n"); fmt::print(fmt::emphasis::bold | fg(fmt::color::cyan), "(e)\n"); - fmt::print(" - Exit the compiler once the current REPL command is finished\n"); + fmt::print(" - Exit the compiler\n"); fmt::print(fmt::emphasis::bold | fg(fmt::color::cyan), "(lt [ip-address] [port-number])\n"); fmt::print( " - Connect the listener to a running target. The IP address defaults to `127.0.0.1` and the " @@ -110,34 +114,24 @@ void ReplWrapper::print_help_message() { fmt::print(" - If the target is connected, make it exit\n"); fmt::print(fmt::emphasis::bold, "\nCompiling & Building:\n"); + fmt::print(fmt::emphasis::bold | fg(fmt::color::lime_green), "(mi)\n"); + fmt::print(" - Build entire game\n"); + fmt::print(fmt::emphasis::bold | fg(fmt::color::lime_green), "(mng)\n"); + fmt::print(" - Build game engine\n"); fmt::print(fmt::emphasis::bold | fg(fmt::color::lime_green), "(m \"filename\")\n"); fmt::print(" - Compile an OpenGOAL source file\n"); fmt::print(fmt::emphasis::bold | fg(fmt::color::lime_green), "(ml \"filename\")\n"); - fmt::print(" - Compile and Load an OpenGOAL source file\n"); - fmt::print(fmt::emphasis::bold | fg(fmt::color::lime_green), "(build-game)\n"); - fmt::print(" - Loads and builds all game files and rebuilds DGOs\n"); + fmt::print(" - Compile and Load (or reload) an OpenGOAL source file\n"); fmt::print(fmt::emphasis::bold | fg(fmt::color::lime_green), "(build-kernel)\n"); - fmt::print(" - Similar to (build-game) but only the kernel files\n"); - fmt::print(fmt::emphasis::bold | fg(fmt::color::lime_green), "(blg)\n"); - fmt::print(" - Performs a (build-game) and then loads all CGOs\n"); - fmt::print(fmt::emphasis::bold | fg(fmt::color::lime_green), - "(build-dgos \"path/to/dgos/description/file\")\n"); + fmt::print(" - Build the GOAL kernel\n"); + fmt::print(fmt::emphasis::bold | fg(fmt::color::lime_green), "(make \"file-name\")\n"); fmt::print( - " - Builds all the DGO files described in the DGO description file. See " - "`goal_src/builds/dgos.txt` for an example.\n"); - fmt::print(fmt::emphasis::bold | fg(fmt::color::lime_green), - "(asm-data-file tool-name \"file-name\")\n"); - fmt::print( - " - Build a data file. The `tool-name` refers to which data building tool should be used.\n"); - fmt::print(fmt::emphasis::bold | fg(fmt::color::lime_green), "(build-data)\n"); - fmt::print(" - Macro for rebuilding all data files\n"); + " - Build a file and any out-of-date dependencies. This file must be a target in the make " + "system.\n"); fmt::print(fmt::emphasis::bold, "\nOther:\n"); fmt::print(fmt::emphasis::bold | fg(fmt::color::magenta), "(gs)\n"); fmt::print(" - Enter a GOOS REPL\n"); - fmt::print(fmt::emphasis::bold | fg(fmt::color::magenta), - "(set-config! config-name config-value)\n"); - fmt::print(" - Used to set compiler configuration\n"); } void ReplWrapper::init_default_settings() { diff --git a/common/util/DgoWriter.cpp b/common/util/DgoWriter.cpp index d0b0b07bcb..03e7c02b46 100644 --- a/common/util/DgoWriter.cpp +++ b/common/util/DgoWriter.cpp @@ -8,16 +8,15 @@ #include "BinaryWriter.h" #include "FileUtil.h" -void build_dgo(const DgoDescription& description) { +void build_dgo(const DgoDescription& description, const std::string& output_prefix) { BinaryWriter writer; // dgo header writer.add(description.entries.size()); writer.add_cstr_len(description.dgo_name.c_str(), 60); for (auto& obj : description.entries) { - // todo: hardcoded out - auto obj_data = - file_util::read_binary_file(file_util::get_file_path({"out", "obj", obj.file_name})); + auto obj_data = file_util::read_binary_file(file_util::get_jak_project_dir() / "out" / + output_prefix / "obj" / obj.file_name); // size writer.add(obj_data.size()); // name @@ -30,6 +29,6 @@ void build_dgo(const DgoDescription& description) { } } - file_util::create_dir_if_needed(file_util::get_file_path({"out", "iso"})); - writer.write_to_file(file_util::get_file_path({"out", "iso", description.dgo_name})); + writer.write_to_file(file_util::get_jak_project_dir() / "out" / output_prefix / "iso" / + description.dgo_name); } diff --git a/common/util/DgoWriter.h b/common/util/DgoWriter.h index d192abe1c6..1c4c753d0c 100644 --- a/common/util/DgoWriter.h +++ b/common/util/DgoWriter.h @@ -5,6 +5,7 @@ * Create a DGO from existing files. */ +#include #include #include @@ -17,4 +18,4 @@ struct DgoDescription { std::vector entries; }; -void build_dgo(const DgoDescription& description); +void build_dgo(const DgoDescription& description, const std::string& output_prefix); diff --git a/common/util/FileUtil.cpp b/common/util/FileUtil.cpp index 79b23f8f13..4a08586527 100644 --- a/common/util/FileUtil.cpp +++ b/common/util/FileUtil.cpp @@ -192,7 +192,11 @@ bool create_dir_if_needed(const std::filesystem::path& path) { } bool create_dir_if_needed_for_file(const std::string& path) { - return std::filesystem::create_directories(std::filesystem::path(path).parent_path()); + return create_dir_if_needed_for_file(std::filesystem::path(path)); +} + +bool create_dir_if_needed_for_file(const std::filesystem::path& path) { + return std::filesystem::create_directories(path.parent_path()); } void write_binary_file(const std::filesystem::path& name, const void* data, size_t size) { diff --git a/common/util/FileUtil.h b/common/util/FileUtil.h index fb527dbd72..765c7762b1 100644 --- a/common/util/FileUtil.h +++ b/common/util/FileUtil.h @@ -23,6 +23,7 @@ std::filesystem::path get_jak_project_dir(); bool create_dir_if_needed(const std::filesystem::path& path); bool create_dir_if_needed_for_file(const std::string& path); +bool create_dir_if_needed_for_file(const std::filesystem::path& path); bool setup_project_path(std::optional project_path_override); std::string get_file_path(const std::vector& path); void write_binary_file(const std::string& name, const void* data, size_t size); diff --git a/common/versions.h b/common/versions.h index c2878f7afa..4f27f72a5a 100644 --- a/common/versions.h +++ b/common/versions.h @@ -46,4 +46,6 @@ struct PerGameVersion { constexpr PerGameVersion(T jak1, T jak2) : data{jak1, jak2} {} constexpr T operator[](GameVersion v) const { return data[(int)v - 1]; } T data[2]; -}; \ No newline at end of file +}; + +constexpr PerGameVersion game_version_names = {"jak1", "jak2"}; \ No newline at end of file diff --git a/decompiler/config/jak1_pal.jsonc b/decompiler/config/jak1_pal.jsonc index 685b8e8e9d..041641914f 100644 --- a/decompiler/config/jak1_pal.jsonc +++ b/decompiler/config/jak1_pal.jsonc @@ -105,10 +105,10 @@ //////////////////////////// // PATCHING OPTIONS //////////////////////////// - + // these are options related to xdelta3 patches on specific objects - // this allows us to get a more consistent input - + // this allows us to get a more consistent input + // set to true to write new patch files "write_patches": false, // set to true to apply patch files diff --git a/decompiler/config/jak2_ntsc_v1.jsonc b/decompiler/config/jak2_ntsc_v1.jsonc index 48c43cbe4b..9b11d97d07 100644 --- a/decompiler/config/jak2_ntsc_v1.jsonc +++ b/decompiler/config/jak2_ntsc_v1.jsonc @@ -109,10 +109,10 @@ //////////////////////////// // PATCHING OPTIONS //////////////////////////// - + // these are options related to xdelta3 patches on specific objects - // this allows us to get a more consistent input - + // this allows us to get a more consistent input + // set to true to write new patch files "write_patches": false, // set to true to apply patch files diff --git a/decompiler/extractor/main.cpp b/decompiler/extractor/main.cpp index 8c49746862..9c5804ba4f 100644 --- a/decompiler/extractor/main.cpp +++ b/decompiler/extractor/main.cpp @@ -436,8 +436,8 @@ void decompile(std::filesystem::path jak1_input_files) { // levels { - // TODO separate out dirs - auto level_out_path = file_util::get_jak_project_dir() / "out" / "fr3"; + auto level_out_path = + file_util::get_jak_project_dir() / "out" / game_version_names[config.game_version] / "fr3"; file_util::create_dir_if_needed(level_out_path); extract_all_levels(db, tex_db, config.levels_to_extract, "GAME.CGO", config.hacks, config.rip_levels, config.extract_collision, level_out_path); diff --git a/decompiler/main.cpp b/decompiler/main.cpp index 5140bb6e0d..e790f2f60f 100644 --- a/decompiler/main.cpp +++ b/decompiler/main.cpp @@ -232,8 +232,8 @@ int main(int argc, char** argv) { } if (config.levels_extract) { - // TODO separate out dirs - auto level_out_path = file_util::get_jak_project_dir() / "out" / "fr3"; + auto level_out_path = + file_util::get_jak_project_dir() / "out" / game_version_names[config.game_version] / "fr3"; file_util::create_dir_if_needed(level_out_path); extract_all_levels(db, tex_db, config.levels_to_extract, "GAME.CGO", config.hacks, config.rip_levels, config.extract_collision, level_out_path); diff --git a/game/graphics/display.cpp b/game/graphics/display.cpp index d492025084..8c1a5c780f 100644 --- a/game/graphics/display.cpp +++ b/game/graphics/display.cpp @@ -82,13 +82,18 @@ std::shared_ptr GetMainDisplay() { return g_displays.front()->is_active() ? g_displays.front() : NULL; } -int InitMainDisplay(int width, int height, const char* title, GfxSettings& settings) { +int InitMainDisplay(int width, + int height, + const char* title, + GfxSettings& settings, + GameVersion version) { if (GetMainDisplay() != NULL) { lg::warn("InitMainDisplay called when main display already exists."); return 1; } - auto display = Gfx::GetCurrentRenderer()->make_display(width, height, title, settings, true); + auto display = + Gfx::GetCurrentRenderer()->make_display(width, height, title, settings, version, true); if (display == NULL) { lg::error("Failed to make main display."); return 1; diff --git a/game/graphics/display.h b/game/graphics/display.h index 26508c14d6..04c5edd741 100644 --- a/game/graphics/display.h +++ b/game/graphics/display.h @@ -87,7 +87,11 @@ namespace Display { // views. extern std::vector> g_displays; -int InitMainDisplay(int width, int height, const char* title, GfxSettings& settings); +int InitMainDisplay(int width, + int height, + const char* title, + GfxSettings& settings, + GameVersion version); void KillDisplay(std::shared_ptr display); void KillMainDisplay(); diff --git a/game/graphics/gfx.cpp b/game/graphics/gfx.cpp index b1cecce2c4..c4eefc1dc1 100644 --- a/game/graphics/gfx.cpp +++ b/game/graphics/gfx.cpp @@ -106,7 +106,7 @@ const GfxRendererModule* GetCurrentRenderer() { return g_global_settings.renderer; } -u32 Init() { +u32 Init(GameVersion version) { lg::info("GFX Init"); // initialize settings InitSettings(g_settings); @@ -124,8 +124,9 @@ u32 Init() { if (g_main_thread_id != std::this_thread::get_id()) { lg::error("Ran Gfx::Init outside main thread. Init display elsewhere?"); } else { - Display::InitMainDisplay( - 640, 480, fmt::format("OpenGOAL - Work in Progress - {}", GIT_VERSION).c_str(), g_settings); + Display::InitMainDisplay(640, 480, + fmt::format("OpenGOAL - Work in Progress - {}", GIT_VERSION).c_str(), + g_settings, version); } return 0; diff --git a/game/graphics/gfx.h b/game/graphics/gfx.h index e4bbeb11c6..d7ee6e5c53 100644 --- a/game/graphics/gfx.h +++ b/game/graphics/gfx.h @@ -10,6 +10,7 @@ #include #include "common/common_types.h" +#include "common/versions.h" #include "game/kernel/common/kboot.h" #include "game/system/newpad.h" @@ -25,8 +26,12 @@ enum GfxDisplayMode { Windowed = 0, Fullscreen = 1, Borderless = 2 }; // module for the different rendering pipelines struct GfxRendererModule { std::function init; - std::function(int width, int height, const char* title, GfxSettings& settings, bool is_main)> + std::function(int width, + int height, + const char* title, + GfxSettings& settings, + GameVersion version, + bool is_main)> make_display; std::function exit; std::function vsync; @@ -108,7 +113,7 @@ extern GfxSettings g_settings; const GfxRendererModule* GetCurrentRenderer(); -u32 Init(); +u32 Init(GameVersion version); void Loop(std::function f); u32 Exit(); diff --git a/game/graphics/pipelines/opengl.cpp b/game/graphics/pipelines/opengl.cpp index cf692fadfe..273b6c646d 100644 --- a/game/graphics/pipelines/opengl.cpp +++ b/game/graphics/pipelines/opengl.cpp @@ -64,13 +64,15 @@ struct GraphicsData { float pmode_alp = 0.f; std::string imgui_log_filename, imgui_filename; + GameVersion version; - GraphicsData() + GraphicsData(GameVersion version) : dma_copier(EE_MAIN_MEM_SIZE), texture_pool(std::make_shared()), - // TODO out dir - loader(std::make_shared(file_util::get_jak_project_dir() / "out" / "fr3")), - ogl_renderer(texture_pool, loader) {} + loader(std::make_shared(file_util::get_jak_project_dir() / "out" / + game_version_names[version] / "fr3")), + ogl_renderer(texture_pool, loader), + version(version) {} }; std::unique_ptr g_gfx_data; @@ -154,6 +156,7 @@ static std::shared_ptr gl_make_display(int width, int height, const char* title, GfxSettings& settings, + GameVersion game_version, bool is_main) { GLFWwindow* window = glfwCreateWindow(width, height, title, NULL, NULL); @@ -169,7 +172,7 @@ static std::shared_ptr gl_make_display(int width, lg::error("GL init fail"); return NULL; } - g_gfx_data = std::make_unique(); + g_gfx_data = std::make_unique(game_version); gl_inited = true; } diff --git a/game/overlord/fake_iso.cpp b/game/overlord/fake_iso.cpp index 0f1aef2d64..94ef862be0 100644 --- a/game/overlord/fake_iso.cpp +++ b/game/overlord/fake_iso.cpp @@ -24,6 +24,7 @@ #include "game/overlord/sbank.h" #include "game/overlord/soundcommon.h" #include "game/overlord/srpc.h" +#include "game/runtime.h" #include "game/sce/iop.h" #include "game/sound/sndshim.h" @@ -89,14 +90,16 @@ void fake_iso_init_globals() { int FS_Init(u8* buffer) { (void)buffer; - for (const auto& f : std::filesystem::directory_iterator(file_util::get_file_path({"out/iso"}))) { + for (const auto& f : std::filesystem::directory_iterator( + file_util::get_jak_project_dir() / "out" / game_version_names[g_game_version] / "iso")) { if (f.is_regular_file()) { ASSERT(fake_iso_entry_count < MAX_ISO_FILES); FakeIsoEntry* e = &fake_iso_entries[fake_iso_entry_count]; std::string file_name = f.path().filename().string(); ASSERT(file_name.length() < 16); // should be 8.3. strcpy(e->iso_name, file_name.c_str()); - strcpy(e->file_path, fmt::format("out/iso/{}", file_name).c_str()); + strcpy(e->file_path, + fmt::format("out/{}/iso/{}", game_version_names[g_game_version], file_name).c_str()); fake_iso_entry_count++; } } diff --git a/game/runtime.cpp b/game/runtime.cpp index 80895546a0..c77ceaf34f 100644 --- a/game/runtime.cpp +++ b/game/runtime.cpp @@ -305,6 +305,7 @@ RuntimeExitStatus exec_runtime(int argc, char** argv) { g_main_thread_id = std::this_thread::get_id(); // parse opengoal arguments + g_game_version = GameVersion::Jak1; bool enable_display = true; for (int i = 1; i < argc; i++) { if (std::string("-nodisplay") == argv[i]) { // disable video display @@ -321,7 +322,7 @@ RuntimeExitStatus exec_runtime(int argc, char** argv) { // initialize graphics first - the EE code will upload textures during boot and we // want the graphics system to catch them. if (enable_display) { - Gfx::Init(); + Gfx::Init(g_game_version); } // step 1: sce library prep diff --git a/goal_src/goal-lib.gc b/goal_src/goal-lib.gc index c9cde4a2a2..b0f1dcacc9 100644 --- a/goal_src/goal-lib.gc +++ b/goal_src/goal-lib.gc @@ -878,7 +878,7 @@ (defmacro makeo (object-name &rest flags) "Make the given object. Can use a string, or not." `(make ,(string-append - "out/obj/" + "$OUT/" (if (string? object-name) object-name (symbol->string object-name)) ".o" ) @@ -886,11 +886,11 @@ ) (defmacro make-cgo (file) - `(make ,(string-append "out/iso/" file ".CGO")) + `(make ,(string-append "$OUT/iso/" file ".CGO")) ) (defmacro make-dgo (file) - `(make ,(string-append "out/iso/" file ".DGO")) + `(make ,(string-append "$OUT/iso/" file ".DGO")) ) (defmacro make-group (name &key (verbose #f) &key (force #f)) @@ -1053,5 +1053,5 @@ (defmacro __get_jak1_full_game () *jak1-full-game*) (defconstant *jak1-full-game* (__get_jak1_full_game)) -;; load the default project +;; todo: loading jak1 by default (load-project "goal_src/jak1/game.gp") diff --git a/goal_src/jak1/game.gp b/goal_src/jak1/game.gp index f0da9283c7..f16f6601b0 100644 --- a/goal_src/jak1/game.gp +++ b/goal_src/jak1/game.gp @@ -62,9 +62,11 @@ ;; Output ;;;;;;;;;;;;;;;;;;;;;;; -;; NOTE: this isn't perfect yet, some tools still are hardcoded to look in out/ for stuff. -(map-path! "$OUT" "out/") +;; NOTE: the game itself will load from out/jak1/iso and out/jak1/fr3. +(map-path! "$OUT" "out/jak1/") +;; tell the compiler to put its outputs in out/jak1/ +(set-output-prefix "jak1/") ;; use defmacro to define goos macros. (define defmacro defsmacro) @@ -142,7 +144,7 @@ ) (defun custom-level-cgo (output-name desc-file-name) - "Add a CGO with the given output name (in out/iso) and input name (in custom_levels/)" + "Add a CGO with the given output name (in $OUT/iso) and input name (in custom_levels/)" (let ((out-name (string-append "$OUT/iso/" output-name))) (defstep :in (string-append "custom_levels/" desc-file-name) :tool 'dgo @@ -153,7 +155,7 @@ ) (defun cgo (output-name desc-file-name) - "Add a CGO with the given output name (in out/iso) and input name (in goal_src/jak1/dgos)" + "Add a CGO with the given output name (in $OUT/iso) and input name (in goal_src/jak1/dgos)" (let ((out-name (string-append "$OUT/iso/" output-name))) (defstep :in (string-append "goal_src/jak1/dgos/" desc-file-name) :tool 'dgo @@ -1420,7 +1422,7 @@ (goal-src-sequence "levels/citadel/" - :deps ("$OUT/obj/battlecontroller.o" "out/obj/snow-bunny.o") + :deps ("$OUT/obj/battlecontroller.o" "$OUT/obj/snow-bunny.o") "citadel-part.gc" "citadel-obs.gc" diff --git a/goalc/build_level/build_level.cpp b/goalc/build_level/build_level.cpp index 3f6e04a9d1..0a1ee3eaee 100644 --- a/goalc/build_level/build_level.cpp +++ b/goalc/build_level/build_level.cpp @@ -16,7 +16,7 @@ void save_pc_data(const std::string& nickname, tfrag3::Level& data, - const std::filesystem::path& output_dir) { + const std::filesystem::path& fr3_output_dir) { Serializer ser; data.serialize(ser); auto compressed = @@ -25,7 +25,7 @@ void save_pc_data(const std::string& nickname, print_memory_usage(data, ser.get_save_result().second); fmt::print("compressed: {} -> {} ({:.2f}%)\n", ser.get_save_result().second, compressed.size(), 100.f * compressed.size() / ser.get_save_result().second); - file_util::write_binary_file(output_dir / fmt::format("{}.fr3", nickname), compressed.data(), + file_util::write_binary_file(fr3_output_dir / fmt::format("{}.fr3", nickname), compressed.data(), compressed.size()); } @@ -35,7 +35,9 @@ std::vector get_build_level_deps(const std::string& input_file) { return {level_json.at("gltf_file").get()}; } -bool run_build_level(const std::string& input_file, const std::string& output_file) { +bool run_build_level(const std::string& input_file, + const std::string& bsp_output_file, + const std::string& output_prefix) { auto level_json = parse_commented_json( file_util::read_text_file(file_util::get_file_path({input_file})), input_file); LevelFile file; // GOAL level file @@ -102,14 +104,14 @@ bool run_build_level(const std::string& input_file, const std::string& output_fi // Save the GOAL level auto result = file.save_object_file(); fmt::print("Level bsp file size {} bytes\n", result.size()); - auto save_path = file_util::get_file_path({output_file}); + auto save_path = file_util::get_jak_project_dir() / bsp_output_file; file_util::create_dir_if_needed_for_file(save_path); - fmt::print("Saving to {}\n", save_path); + fmt::print("Saving to {}\n", save_path.string()); file_util::write_binary_file(save_path, result.data(), result.size()); // Save the PC level - // TODO out dir - save_pc_data(file.nickname, pc_level, file_util::get_jak_project_dir() / "out" / "fr3"); + save_pc_data(file.nickname, pc_level, + file_util::get_jak_project_dir() / "out" / output_prefix / "fr3"); return true; } diff --git a/goalc/build_level/build_level.h b/goalc/build_level/build_level.h index e37d1ef15c..24931528b1 100644 --- a/goalc/build_level/build_level.h +++ b/goalc/build_level/build_level.h @@ -1,7 +1,10 @@ #pragma once +#include #include #include -bool run_build_level(const std::string& input_file, const std::string& output_file); +bool run_build_level(const std::string& input_file, + const std::string& bsp_output_file, + const std::string& output_prefix); std::vector get_build_level_deps(const std::string& input_file); \ No newline at end of file diff --git a/goalc/compiler/Compiler.cpp b/goalc/compiler/Compiler.cpp index 2b6409ba00..a56e20b2c3 100644 --- a/goalc/compiler/Compiler.cpp +++ b/goalc/compiler/Compiler.cpp @@ -422,7 +422,8 @@ void Compiler::asm_file(const CompilationOptions& options) { // save file if (options.write) { - auto path = file_util::get_file_path({"out", "obj", obj_file_name + ".o"}); + auto path = file_util::get_jak_project_dir() / "out" / m_make.compiler_output_prefix() / + "obj" / (obj_file_name + ".o"); file_util::create_dir_if_needed_for_file(path); file_util::write_binary_file(path, (void*)data.data(), data.size()); } diff --git a/goalc/compiler/CompilerSettings.cpp b/goalc/compiler/CompilerSettings.cpp index edf55be4ce..8ccedb8568 100644 --- a/goalc/compiler/CompilerSettings.cpp +++ b/goalc/compiler/CompilerSettings.cpp @@ -9,8 +9,6 @@ CompilerSettings::CompilerSettings() { m_settings["disable-math-const-prop"].kind = SettingKind::BOOL; m_settings["disable-math-const-prop"].boolp = &disable_math_const_prop; - - link(print_timing, "print-timing"); } void CompilerSettings::set(const std::string& name, const goos::Object& value) { diff --git a/goalc/compiler/CompilerSettings.h b/goalc/compiler/CompilerSettings.h index 61d788d3a5..cd62ef7360 100644 --- a/goalc/compiler/CompilerSettings.h +++ b/goalc/compiler/CompilerSettings.h @@ -1,8 +1,5 @@ #pragma once -#ifndef JAK_COMPILERSETTINGS_H -#define JAK_COMPILERSETTINGS_H - #include #include @@ -15,13 +12,13 @@ class CompilerSettings { bool debug_print_regalloc = false; bool disable_math_const_prop = false; bool emit_move_after_return = true; - bool print_timing = false; void set(const std::string& name, const goos::Object& value); private: void link(bool& val, const std::string& name); - enum class SettingKind { BOOL, INVALID }; + + enum class SettingKind { BOOL, STRING, INVALID }; struct SettingsEntry { SettingKind kind = SettingKind::INVALID; @@ -31,5 +28,3 @@ class CompilerSettings { std::unordered_map m_settings; }; - -#endif // JAK_COMPILERSETTINGS_H diff --git a/goalc/compiler/compilation/CompilerControl.cpp b/goalc/compiler/compilation/CompilerControl.cpp index 566d454c22..8fab874a71 100644 --- a/goalc/compiler/compilation/CompilerControl.cpp +++ b/goalc/compiler/compilation/CompilerControl.cpp @@ -67,9 +67,9 @@ Val* Compiler::compile_asm_data_file(const goos::Object& form, const goos::Objec va_check(form, args, {goos::ObjectType::SYMBOL, goos::ObjectType::STRING}, {}); auto kind = symbol_string(args.unnamed.at(0)); if (kind == "game-count") { - compile_game_count(as_string(args.unnamed.at(1))); + compile_game_count(as_string(args.unnamed.at(1)), m_make.compiler_output_prefix()); } else if (kind == "dir-tpages") { - compile_dir_tpages(as_string(args.unnamed.at(1))); + compile_dir_tpages(as_string(args.unnamed.at(1)), m_make.compiler_output_prefix()); } else { throw_compiler_error(form, "The option {} was not recognized for asm-data-file.", kind); } @@ -102,10 +102,10 @@ Val* Compiler::compile_asm_text_file(const goos::Object& form, const goos::Objec // compile files. if (kind == "subtitle") { GameSubtitleDB db; - compile_game_subtitle(inputs, db); + compile_game_subtitle(inputs, db, m_make.compiler_output_prefix()); } else if (kind == "text") { GameTextDB db; - compile_game_text(inputs, db); + compile_game_text(inputs, db, m_make.compiler_output_prefix()); } else { throw_compiler_error(form, "The option {} was not recognized for asm-text-file.", kind); } @@ -306,13 +306,14 @@ Val* Compiler::compile_build_dgo(const goos::Object& form, const goos::Object& r desc.entries.push_back(o); } else { // allow data objects to be missing. - if (std::filesystem::exists(file_util::get_file_path({"out", "obj", o.file_name}))) { + if (std::filesystem::exists(file_util::get_file_path( + {"out", m_make.compiler_output_prefix(), "obj", o.file_name}))) { desc.entries.push_back(o); } } }); - build_dgo(desc); + build_dgo(desc, m_make.compiler_output_prefix()); }); return get_none(); diff --git a/goalc/data_compiler/dir_tpages.cpp b/goalc/data_compiler/dir_tpages.cpp index fd898f51bc..3f06213595 100644 --- a/goalc/data_compiler/dir_tpages.cpp +++ b/goalc/data_compiler/dir_tpages.cpp @@ -6,11 +6,11 @@ #include "common/goos/Reader.h" #include "common/util/FileUtil.h" -void compile_dir_tpages(const std::string& filename) { +void compile_dir_tpages(const std::string& input_file, const std::string& output_prefix) { std::vector lengths; goos::Reader reader; - auto code = reader.read_from_file({filename}); + auto code = reader.read_from_file({input_file}); std::string err; goos::for_each_in_list(code.as_pair()->cdr, [&](const goos::Object& obj) { @@ -30,7 +30,7 @@ void compile_dir_tpages(const std::string& filename) { } auto data = gen.generate_v4(); - file_util::create_dir_if_needed(file_util::get_file_path({"out", "obj"})); - file_util::write_binary_file(file_util::get_file_path({"out", "obj", "dir-tpages.go"}), - data.data(), data.size()); + file_util::write_binary_file( + file_util::get_jak_project_dir() / "out" / output_prefix / "obj" / "dir-tpages.go", + data.data(), data.size()); } diff --git a/goalc/data_compiler/dir_tpages.h b/goalc/data_compiler/dir_tpages.h index faf2919171..4dbfdb59ad 100644 --- a/goalc/data_compiler/dir_tpages.h +++ b/goalc/data_compiler/dir_tpages.h @@ -2,4 +2,4 @@ #include -void compile_dir_tpages(const std::string& filename); \ No newline at end of file +void compile_dir_tpages(const std::string& input_file, const std::string& output_prefix); \ No newline at end of file diff --git a/goalc/data_compiler/game_count.cpp b/goalc/data_compiler/game_count.cpp index 3eeb68ba53..6ae2572eb4 100644 --- a/goalc/data_compiler/game_count.cpp +++ b/goalc/data_compiler/game_count.cpp @@ -8,7 +8,7 @@ #include "common/goos/Reader.h" #include "common/util/FileUtil.h" -void compile_game_count(const std::string& filename) { +void compile_game_count(const std::string& input_filename, const std::string& output_prefix) { struct Count { int buzzer; int money; @@ -18,7 +18,7 @@ void compile_game_count(const std::string& filename) { int unknowns[2] = {0, 0}; goos::Reader reader; - auto code = reader.read_from_file({filename}); + auto code = reader.read_from_file({input_filename}); int len = goos::list_length(code) - 1; int i = 0; std::string err; @@ -74,7 +74,7 @@ void compile_game_count(const std::string& filename) { gen.add_word(unknowns[1]); auto result = gen.generate_v4(); - file_util::create_dir_if_needed(file_util::get_file_path({"out", "obj"})); - file_util::write_binary_file(file_util::get_file_path({"out", "obj", "game-cnt.go"}), - result.data(), result.size()); + file_util::write_binary_file( + file_util::get_jak_project_dir() / "out" / output_prefix / "obj" / "game-cnt.go", + result.data(), result.size()); } diff --git a/goalc/data_compiler/game_count.h b/goalc/data_compiler/game_count.h index df6e39b372..c91a5c1a8b 100644 --- a/goalc/data_compiler/game_count.h +++ b/goalc/data_compiler/game_count.h @@ -1,4 +1,4 @@ #pragma once #include -void compile_game_count(const std::string& filename); \ No newline at end of file +void compile_game_count(const std::string& input_filename, const std::string& output_prefix); \ No newline at end of file diff --git a/goalc/data_compiler/game_text_common.cpp b/goalc/data_compiler/game_text_common.cpp index 8e6bbb55c2..72fc7f9cce 100644 --- a/goalc/data_compiler/game_text_common.cpp +++ b/goalc/data_compiler/game_text_common.cpp @@ -60,7 +60,7 @@ std::string uppercase(const std::string& in) { * Write game text data to a file. Uses the V2 object format which is identical between GOAL and * OpenGOAL, so this should produce exactly identical files to what is found in the game. */ -void compile_text(GameTextDB& db) { +void compile_text(GameTextDB& db, const std::string& output_prefix) { for (const auto& [group_name, banks] : db.groups()) { for (const auto& [lang, bank] : banks) { DataObjectGenerator gen; @@ -81,10 +81,10 @@ void compile_text(GameTextDB& db) { auto data = gen.generate_v2(); - file_util::create_dir_if_needed(file_util::get_file_path({"out", "iso"})); + file_util::create_dir_if_needed(file_util::get_file_path({"out", output_prefix, "iso"})); file_util::write_binary_file( file_util::get_file_path( - {"out", "iso", fmt::format("{}{}.TXT", lang, uppercase(group_name))}), + {"out", output_prefix, "iso", fmt::format("{}{}.TXT", lang, uppercase(group_name))}), data.data(), data.size()); } } @@ -94,7 +94,7 @@ void compile_text(GameTextDB& db) { * Write game subtitle data to a file. Uses the V2 object format which is identical between GOAL and * OpenGOAL. */ -void compile_subtitle(GameSubtitleDB& db) { +void compile_subtitle(GameSubtitleDB& db, const std::string& output_prefix) { for (const auto& [lang, bank] : db.banks()) { DataObjectGenerator gen; gen.add_type_tag("subtitle-text-info"); // type @@ -136,10 +136,10 @@ void compile_subtitle(GameSubtitleDB& db) { auto data = gen.generate_v2(); - file_util::create_dir_if_needed(file_util::get_file_path({"out", "iso"})); + file_util::create_dir_if_needed(file_util::get_file_path({"out", output_prefix, "iso"})); file_util::write_binary_file( file_util::get_file_path( - {"out", "iso", fmt::format("{}{}.TXT", lang, uppercase("subtit"))}), + {"out", output_prefix, "iso", fmt::format("{}{}.TXT", lang, uppercase("subtit"))}), data.data(), data.size()); } } @@ -148,22 +148,26 @@ void compile_subtitle(GameSubtitleDB& db) { /*! * Read a game text description file and generate GOAL objects. */ -void compile_game_text(const std::vector& filenames, GameTextDB& db) { +void compile_game_text(const std::vector& filenames, + GameTextDB& db, + const std::string& output_prefix) { goos::Reader reader; for (auto& filename : filenames) { fmt::print("[Build Game Text] {}\n", filename.c_str()); auto code = reader.read_from_file({filename}); parse_text(code, db); } - compile_text(db); + compile_text(db, output_prefix); } -void compile_game_subtitle(const std::vector& filenames, GameSubtitleDB& db) { +void compile_game_subtitle(const std::vector& filenames, + GameSubtitleDB& db, + const std::string& output_prefix) { goos::Reader reader; for (auto& filename : filenames) { fmt::print("[Build Game Subtitle] {}\n", filename.c_str()); auto code = reader.read_from_file({filename}); parse_subtitle(code, db, filename); } - compile_subtitle(db); + compile_subtitle(db, output_prefix); } diff --git a/goalc/data_compiler/game_text_common.h b/goalc/data_compiler/game_text_common.h index 5e7f355112..9a38dc1295 100644 --- a/goalc/data_compiler/game_text_common.h +++ b/goalc/data_compiler/game_text_common.h @@ -9,5 +9,9 @@ #include "common/util/Assert.h" #include "common/util/FontUtils.h" -void compile_game_text(const std::vector& filenames, GameTextDB& db); -void compile_game_subtitle(const std::vector& filenames, GameSubtitleDB& db); +void compile_game_text(const std::vector& filenames, + GameTextDB& db, + const std::string& output_prefix); +void compile_game_subtitle(const std::vector& filenames, + GameSubtitleDB& db, + const std::string& output_prefix); diff --git a/goalc/make/MakeSystem.cpp b/goalc/make/MakeSystem.cpp index 416ef8c875..2b9894f77a 100644 --- a/goalc/make/MakeSystem.cpp +++ b/goalc/make/MakeSystem.cpp @@ -59,6 +59,12 @@ MakeSystem::MakeSystem(const std::string& username) : m_goos(username) { return handle_map_path(obj, args, env); }); + m_goos.register_form("set-output-prefix", + [=](const goos::Object& obj, goos::Arguments& args, + const std::shared_ptr& env) { + return handle_set_output_prefix(obj, args, env); + }); + m_goos.set_global_variable_to_symbol("ASSETS", "#t"); set_constant("*iso-data*", file_util::get_file_path({"iso_data"})); @@ -202,6 +208,16 @@ goos::Object MakeSystem::handle_map_path(const goos::Object& form, return goos::Object::make_empty_list(); } +goos::Object MakeSystem::handle_set_output_prefix( + const goos::Object& form, + goos::Arguments& args, + const std::shared_ptr& env) { + m_goos.eval_args(&args, env); + va_check(form, args, {goos::ObjectType::STRING}, {}); + m_path_map.output_prefix = args.unnamed.at(0).as_string()->data; + return goos::Object::make_empty_list(); +} + void MakeSystem::get_dependencies(const std::string& master_target, const std::string& output, std::vector* result, @@ -321,7 +337,8 @@ void print_input(const std::vector& in, char end) { } } // namespace -bool MakeSystem::make(const std::string& target, bool force, bool verbose) { +bool MakeSystem::make(const std::string& target_in, bool force, bool verbose) { + std::string target = m_path_map.apply_remaps(target_in); auto deps = get_dependencies(target); // fmt::print("All deps:\n"); // for (auto& dep : deps) { diff --git a/goalc/make/MakeSystem.h b/goalc/make/MakeSystem.h index 63a0db6297..c8c0c5740e 100644 --- a/goalc/make/MakeSystem.h +++ b/goalc/make/MakeSystem.h @@ -34,6 +34,10 @@ class MakeSystem { goos::Arguments& args, const std::shared_ptr& env); + goos::Object handle_set_output_prefix(const goos::Object& obj, + goos::Arguments& args, + const std::shared_ptr& env); + std::vector get_dependencies(const std::string& target) const; std::vector filter_dependencies(const std::vector& all_deps); @@ -50,6 +54,11 @@ class MakeSystem { void clear_project(); + /*! + * Get the prefix that the project has requested for all compiler outputs + */ + const std::string& compiler_output_prefix() const { return m_path_map.output_prefix; } + private: void va_check(const goos::Object& form, const goos::Arguments& args, diff --git a/goalc/make/Tool.h b/goalc/make/Tool.h index d594d3db74..377a284943 100644 --- a/goalc/make/Tool.h +++ b/goalc/make/Tool.h @@ -7,6 +7,7 @@ #include "common/goos/Object.h" struct PathMap { + std::string output_prefix; std::unordered_map path_remap; std::string apply_remaps(const std::string& input) const; }; diff --git a/goalc/make/Tools.cpp b/goalc/make/Tools.cpp index a267d6c2ef..0f90f26ad4 100644 --- a/goalc/make/Tools.cpp +++ b/goalc/make/Tools.cpp @@ -76,33 +76,33 @@ DgoDescription parse_desc_file(const std::string& filename, goos::Reader& reader DgoTool::DgoTool() : Tool("dgo") {} -bool DgoTool::run(const ToolInput& task, const PathMap& /*path_map*/) { +bool DgoTool::run(const ToolInput& task, const PathMap& path_map) { if (task.input.size() != 1) { throw std::runtime_error(fmt::format("Invalid amount of inputs to {} tool", name())); } auto desc = parse_desc_file(task.input.at(0), m_reader); - build_dgo(desc); + build_dgo(desc, path_map.output_prefix); return true; } std::vector DgoTool::get_additional_dependencies(const ToolInput& task, - const PathMap& /*path_map*/) { + const PathMap& path_map) { std::vector result; auto desc = parse_desc_file(task.input.at(0), m_reader); for (auto& x : desc.entries) { // todo out - result.push_back(fmt::format("out/obj/{}", x.file_name)); + result.push_back(fmt::format("out/{}obj/{}", path_map.output_prefix, x.file_name)); } return result; } TpageDirTool::TpageDirTool() : Tool("tpage-dir") {} -bool TpageDirTool::run(const ToolInput& task, const PathMap& /*path_map*/) { +bool TpageDirTool::run(const ToolInput& task, const PathMap& path_map) { if (task.input.size() != 1) { throw std::runtime_error(fmt::format("Invalid amount of inputs to {} tool", name())); } - compile_dir_tpages(task.input.at(0)); + compile_dir_tpages(task.input.at(0), path_map.output_prefix); return true; } @@ -122,11 +122,11 @@ bool CopyTool::run(const ToolInput& task, const PathMap& /*path_map*/) { GameCntTool::GameCntTool() : Tool("game-cnt") {} -bool GameCntTool::run(const ToolInput& task, const PathMap& /*path_map*/) { +bool GameCntTool::run(const ToolInput& task, const PathMap& path_map) { if (task.input.size() != 1) { throw std::runtime_error(fmt::format("Invalid amount of inputs to {} tool", name())); } - compile_game_count(task.input.at(0)); + compile_game_count(task.input.at(0), path_map.output_prefix); return true; } @@ -152,7 +152,7 @@ bool TextTool::run(const ToolInput& task, const PathMap& path_map) { for (auto& in : inputs) { in = path_map.apply_remaps(in); } - compile_game_text(inputs, db); + compile_game_text(inputs, db, path_map.output_prefix); return true; } @@ -186,7 +186,7 @@ bool SubtitleTool::run(const ToolInput& task, const PathMap& path_map) { for (auto& in : inputs) { in = path_map.apply_remaps(in); } - compile_game_subtitle(inputs, db); + compile_game_subtitle(inputs, db, path_map.output_prefix); return true; } @@ -200,9 +200,9 @@ bool BuildLevelTool::needs_run(const ToolInput& task, const PathMap& path_map) { return Tool::needs_run({task.input, deps, task.output, task.arg}, path_map); } -bool BuildLevelTool::run(const ToolInput& task, const PathMap& /*path_map*/) { +bool BuildLevelTool::run(const ToolInput& task, const PathMap& path_map) { if (task.input.size() != 1) { throw std::runtime_error(fmt::format("Invalid amount of inputs to {} tool", name())); } - return run_build_level(task.input.at(0), task.output.at(0)); + return run_build_level(task.input.at(0), task.output.at(0), path_map.output_prefix); } diff --git a/out/hash.md5 b/out/hash.md5 deleted file mode 100644 index 88c760d42b..0000000000 --- a/out/hash.md5 +++ /dev/null @@ -1,9 +0,0 @@ -b06369c2dd9197cb17aae6286246caf9 iso/0COMMON.TXT -da0d6012181f13803e8b3267a4099b97 iso/1COMMON.TXT -4a9a27beb4ce7e75fa4c70811d2c0013 iso/2COMMON.TXT -abcc25e5d7469dd6a572dc53dbb9671c iso/3COMMON.TXT -82eabdb7159f2059fbdbd18bb6fc06aa iso/4COMMON.TXT -5d62de2c78b4cf102b9a78f3aa96c8c9 iso/5COMMON.TXT -9495f80955e6782513fe12f6539fc8e7 iso/6COMMON.TXT -9765bdc3add08cb06fd3e87ebd5713aa obj/game-cnt.go -5033811c685e1bde4411d396b1d4ffba obj/dir-tpages.go diff --git a/out/.gitignore b/out/jak1/fr3/.gitignore similarity index 58% rename from out/.gitignore rename to out/jak1/fr3/.gitignore index 30bd40c3f4..268b9c8dd5 100644 --- a/out/.gitignore +++ b/out/jak1/fr3/.gitignore @@ -1,3 +1,3 @@ * !.gitignore -!hash.md5 \ No newline at end of file +!hash.md5 diff --git a/out/jak1/iso/.gitignore b/out/jak1/iso/.gitignore new file mode 100644 index 0000000000..268b9c8dd5 --- /dev/null +++ b/out/jak1/iso/.gitignore @@ -0,0 +1,3 @@ +* +!.gitignore +!hash.md5 diff --git a/out/jak1/obj/.gitignore b/out/jak1/obj/.gitignore new file mode 100644 index 0000000000..268b9c8dd5 --- /dev/null +++ b/out/jak1/obj/.gitignore @@ -0,0 +1,3 @@ +* +!.gitignore +!hash.md5 diff --git a/out/jak2/fr3/.gitignore b/out/jak2/fr3/.gitignore new file mode 100644 index 0000000000..268b9c8dd5 --- /dev/null +++ b/out/jak2/fr3/.gitignore @@ -0,0 +1,3 @@ +* +!.gitignore +!hash.md5 diff --git a/out/jak2/iso/.gitignore b/out/jak2/iso/.gitignore new file mode 100644 index 0000000000..268b9c8dd5 --- /dev/null +++ b/out/jak2/iso/.gitignore @@ -0,0 +1,3 @@ +* +!.gitignore +!hash.md5 diff --git a/out/jak2/obj/.gitignore b/out/jak2/obj/.gitignore new file mode 100644 index 0000000000..268b9c8dd5 --- /dev/null +++ b/out/jak2/obj/.gitignore @@ -0,0 +1,3 @@ +* +!.gitignore +!hash.md5 diff --git a/test/goalc/test_with_game.cpp b/test/goalc/test_with_game.cpp index 848d555b7f..c2f817445e 100644 --- a/test/goalc/test_with_game.cpp +++ b/test/goalc/test_with_game.cpp @@ -131,7 +131,7 @@ std::vector get_test_pass_string(const std::string& name, int count } // namespace TEST_F(WithGameTests, MakeSystem) { - shared_compiler->compiler.run_front_end_on_string("(make \"out/iso/ENGINE.CGO\")"); + shared_compiler->compiler.run_front_end_on_string("(make \"out/jak1/iso/ENGINE.CGO\")"); } TEST_F(WithGameTests, ReturnConstant) { @@ -380,8 +380,8 @@ TEST_F(WithGameTests, GameCount) { shared_compiler->runner.run_static_test(env, testCategory, "test-game-count.gc", get_test_pass_string("game-count", 4)); // don't leave behind a weird version of the game-count file. - std::filesystem::remove(file_util::get_file_path({"out", "iso", "ENGINE.CGO"})); - std::filesystem::remove(file_util::get_file_path({"out", "obj", "game-cnt.go"})); + std::filesystem::remove(file_util::get_file_path({"out", "jak1", "iso", "ENGINE.CGO"})); + std::filesystem::remove(file_util::get_file_path({"out", "jak1", "obj", "game-cnt.go"})); } TEST_F(WithGameTests, BitFieldAccess) {