diff --git a/README.md b/README.md index 2b6fd104f5..32b8c3ba0e 100644 --- a/README.md +++ b/README.md @@ -299,11 +299,11 @@ Run the following to build the game: g > (mi) ``` -> IMPORTANT NOTE! If you're not using the black label version, you may hit issues trying to run `(mi)` in this step. An example error might include something like: +> IMPORTANT NOTE! If you're not using the non-default version of the game, you may hit issues trying to run `(mi)` in this step. An example error might include something like: > > `Input file iso_data/jak1/MUS/TWEAKVAL.MUS does not exist.` > -> This is because other version paths are not currently accounted for in the build. A quick workaround is to rename both your `decompiler_out` and `iso_data` folders to use the black label naming, for example changing `decompiler_out/jak1_pal` to `decompiler_out/jak1` and `iso_data/jak1_pal` to `iso_data/jak1`, then running `(mi)` again. +> This is because the decompiler inputs/outputs using the `gameName` JSON field in the decompiler config. For example if you are using Jak 1 PAL, it will assume `iso_data/jak1_pal` and `decompiler_out/jak1_pal`. Therefore, you can inform the REPL/compiler of this via the `gameVersionFolder` config field described [here](./goal_src/user/README.md) #### Run the Game diff --git a/common/repl/config.cpp b/common/repl/config.cpp index ea106405e6..32c805a2f5 100644 --- a/common/repl/config.cpp +++ b/common/repl/config.cpp @@ -7,6 +7,7 @@ namespace REPL { void to_json(json& j, const Config& obj) { j = json{ + {"gameVersionFolder", obj.game_version_folder}, {"numConnectToTargetAttempts", obj.target_connect_attempts}, {"asmFileSearchDirs", obj.asm_file_search_dirs}, {"keybinds", obj.keybinds}, @@ -14,6 +15,9 @@ void to_json(json& j, const Config& obj) { } void from_json(const json& j, Config& obj) { + if (j.contains("gameVersionFolder")) { + j.at("gameVersionFolder").get_to(obj.game_version_folder); + } if (j.contains("numConnectToTargetAttempts")) { j.at("numConnectToTargetAttempts").get_to(obj.target_connect_attempts); } diff --git a/common/repl/config.h b/common/repl/config.h index c051ea5153..0da9563f52 100644 --- a/common/repl/config.h +++ b/common/repl/config.h @@ -31,6 +31,7 @@ struct Config { Config(GameVersion _game_version) : game_version(_game_version){}; // this is the default REPL configuration + std::string game_version_folder; int target_connect_attempts = 30; std::vector asm_file_search_dirs = {}; bool append_keybinds = true; diff --git a/goal_src/jak1/game.gp b/goal_src/jak1/game.gp index d548cf1b1b..23d060c2ed 100644 --- a/goal_src/jak1/game.gp +++ b/goal_src/jak1/game.gp @@ -39,13 +39,17 @@ (cond ;; extractor can override everything by providing *use-iso-data-path* (*use-iso-data-path* - (map-path! "$ISO" (string-append *iso-data* "/"))) + (map-path! "$ISO" (string-append *iso-data* "/"))) ;; user-specific places to put $ISO + ;; TODO - remove? ((user? dass) - (map-path! "$ISO" "iso_data/jak1_us2/")) - ;; for normal people, just use jak1. + (map-path! "$ISO" "iso_data/jak1_us2/")) + ;; if the user's repl-config has a game version folder, use that + ((> (string-length (get-game-version-folder)) 0) + (map-path! "$ISO" (string-append "iso_data/" (get-game-version-folder) "/"))) + ;; otherwise, default to jak1 (#t - (map-path! "$ISO" "iso_data/jak1/"))) + (map-path! "$ISO" "iso_data/jak1/"))) ;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Inputs from decompiler @@ -53,10 +57,15 @@ (cond ;; user-specific places to put $ISO + ;; TODO - remove? ((user? dass) - (map-path! "$DECOMP" "decompiler_out/jak1_us2/")) + (map-path! "$DECOMP" "decompiler_out/jak1_us2/")) + ;; if the user's repl-config has a game version folder, use that + ((> (string-length (get-game-version-folder)) 0) + (map-path! "$DECOMP" (string-append "decompiler_out/" (get-game-version-folder) "/"))) + ;; otherwise, default to jak1 (#t - (map-path! "$DECOMP" "decompiler_out/jak1/"))) + (map-path! "$DECOMP" "decompiler_out/jak1/"))) ;;;;;;;;;;;;;;;;;;;;;;; ;; Output diff --git a/goal_src/jak2/game.gp b/goal_src/jak2/game.gp index d8b9cff3ee..58011f2f0f 100644 --- a/goal_src/jak2/game.gp +++ b/goal_src/jak2/game.gp @@ -13,15 +13,25 @@ (cond ;; extractor can override everything by providing *use-iso-data-path* (*use-iso-data-path* - (map-path! "$ISO" (string-append *iso-data* "/"))) + (map-path! "$ISO" (string-append *iso-data* "/"))) + ;; if the user's repl-config has a game version folder, use that + ((> (string-length (get-game-version-folder)) 0) + (map-path! "$ISO" (string-append "iso_data/" (get-game-version-folder) "/"))) + ;; otherwise, default to jak2 (#t - (map-path! "$ISO" "iso_data/jak2/"))) + (map-path! "$ISO" "iso_data/jak2/"))) ;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Inputs from decompiler ;;;;;;;;;;;;;;;;;;;;;;;;;; -(map-path! "$DECOMP" "decompiler_out/jak2/") +(cond + ;; if the user's repl-config has a game version folder, use that + ((> (string-length (get-game-version-folder)) 0) + (map-path! "$DECOMP" (string-append "decompiler_out/" (get-game-version-folder) "/"))) + ;; otherwise, default to jak2 + (#t + (map-path! "$DECOMP" "decompiler_out/jak2/"))) ;;;;;;;;;;;;;;;;;;;;;;; ;; Output diff --git a/goal_src/user/readme.md b/goal_src/user/README.md similarity index 90% rename from goal_src/user/readme.md rename to goal_src/user/README.md index d4f5d66f53..c602277794 100644 --- a/goal_src/user/readme.md +++ b/goal_src/user/README.md @@ -20,11 +20,13 @@ Additionally, you can provide a `repl-config.json` to set various REPL settings, { "numConnectToTargetAttempts": 1, "jak1": { + "gameVersionFolder": "jak1_pal", // corresponds with your "gameName" in the decomp config, "jak1" by default "asmFileSearchDirs": [ "goal_src/jak1" ] }, "jak2": { + "gameVersionFolder": "jak2_pal", // corresponds with your "gameName" in the decomp config, "jak2" by default "asmFileSearchDirs": [ "goal_src/jak2" ] diff --git a/goalc/compiler/Compiler.cpp b/goalc/compiler/Compiler.cpp index 207d7946b2..c7d1b6b4cc 100644 --- a/goalc/compiler/Compiler.cpp +++ b/goalc/compiler/Compiler.cpp @@ -19,13 +19,14 @@ using namespace goos; Compiler::Compiler(GameVersion version, + const std::optional repl_config, const std::string& user_profile, std::unique_ptr repl) : m_version(version), m_goos(user_profile), m_debugger(&m_listener, &m_goos.reader, version), m_repl(std::move(repl)), - m_make(user_profile) { + m_make(repl_config, user_profile) { m_listener.add_debugger(&m_debugger); m_listener.set_default_port(version); m_ts.add_builtin_types(m_version); diff --git a/goalc/compiler/Compiler.h b/goalc/compiler/Compiler.h index a7a53e1945..104e0231f9 100644 --- a/goalc/compiler/Compiler.h +++ b/goalc/compiler/Compiler.h @@ -40,6 +40,7 @@ struct CompilationOptions { class Compiler { public: Compiler(GameVersion version, + const std::optional repl_config = {}, const std::string& user_profile = "#f", std::unique_ptr repl = nullptr); ~Compiler(); diff --git a/goalc/main.cpp b/goalc/main.cpp index ac5695d11e..52466ce0c0 100644 --- a/goalc/main.cpp +++ b/goalc/main.cpp @@ -115,7 +115,7 @@ int main(int argc, char** argv) { // the compiler may throw an exception if it fails to load its standard library. try { compiler = std::make_unique( - game_version, username, + game_version, std::make_optional(repl_config), username, std::make_unique(username, repl_config, startup_file)); // Start nREPL Server if it spun up successfully if (repl_server_ok) { @@ -143,7 +143,7 @@ int main(int argc, char** argv) { compiler->save_repl_history(); } compiler = std::make_unique( - game_version, username, + game_version, std::make_optional(repl_config), username, std::make_unique(username, repl_config, startup_file)); status = ReplStatus::OK; } diff --git a/goalc/make/MakeSystem.cpp b/goalc/make/MakeSystem.cpp index dba65adea4..5bb825494c 100644 --- a/goalc/make/MakeSystem.cpp +++ b/goalc/make/MakeSystem.cpp @@ -38,7 +38,8 @@ std::string MakeStep::print() const { return result; } -MakeSystem::MakeSystem(const std::string& username) : m_goos(username) { +MakeSystem::MakeSystem(const std::optional repl_config, const std::string& username) + : m_goos(username), m_repl_config(repl_config) { m_goos.register_form("defstep", [=](const goos::Object& obj, goos::Arguments& args, const std::shared_ptr& env) { return handle_defstep(obj, args, env); @@ -81,6 +82,12 @@ MakeSystem::MakeSystem(const std::string& username) : m_goos(username) { return handle_get_gsrc_folder(obj, args, env); }); + m_goos.register_form("get-game-version-folder", + [=](const goos::Object& obj, goos::Arguments& args, + const std::shared_ptr& env) { + return handle_get_game_version_folder(obj, args, env); + }); + m_goos.set_global_variable_to_symbol("ASSETS", "#t"); set_constant("*iso-data*", file_util::get_file_path({"iso_data"})); @@ -296,6 +303,19 @@ goos::Object MakeSystem::handle_get_gsrc_folder( return goos::StringObject::make_new(out); } +goos::Object MakeSystem::handle_get_game_version_folder( + const goos::Object& form, + goos::Arguments& args, + const std::shared_ptr& env) { + m_goos.eval_args(&args, env); + va_check(form, args, {}, {}); + if (m_repl_config) { + return goos::StringObject::make_new(m_repl_config->game_version_folder); + } else { + return goos::StringObject::make_new(""); + } +} + void MakeSystem::get_dependencies(const std::string& master_target, const std::string& output, std::vector* result, diff --git a/goalc/make/MakeSystem.h b/goalc/make/MakeSystem.h index 1b36d413ed..b7c75b8252 100644 --- a/goalc/make/MakeSystem.h +++ b/goalc/make/MakeSystem.h @@ -15,7 +15,7 @@ struct MakeStep { class MakeSystem { public: - MakeSystem(const std::string& username = "#f"); + MakeSystem(const std::optional repl_config, const std::string& username = "#f"); void load_project_file(const std::string& file_path); goos::Object handle_defstep(const goos::Object& obj, @@ -50,6 +50,10 @@ class MakeSystem { goos::Arguments& args, const std::shared_ptr& env); + goos::Object handle_get_game_version_folder(const goos::Object& obj, + goos::Arguments&, + const std::shared_ptr& env); + std::vector get_dependencies(const std::string& target) const; std::vector filter_dependencies(const std::vector& all_deps); @@ -85,6 +89,8 @@ class MakeSystem { goos::Interpreter m_goos; + std::optional m_repl_config; + std::unordered_map> m_output_to_step; std::unordered_map> m_tools; PathMap m_path_map; diff --git a/goalc/simple_main.cpp b/goalc/simple_main.cpp index b582fba8ff..ee48b73bd4 100644 --- a/goalc/simple_main.cpp +++ b/goalc/simple_main.cpp @@ -27,15 +27,15 @@ int main(int argc, char** argv) { std::unique_ptr compiler; ReplStatus status = ReplStatus::OK; try { - compiler = - std::make_unique(game_version, "", std::make_unique(game_version)); + compiler = std::make_unique(game_version, std::nullopt, "", + std::make_unique(game_version)); while (status != ReplStatus::WANT_EXIT) { if (status == ReplStatus::WANT_RELOAD) { lg::info("Reloading compiler..."); if (compiler) { compiler->save_repl_history(); } - compiler = std::make_unique(game_version, "", + compiler = std::make_unique(game_version, std::nullopt, "", std::make_unique(game_version)); status = ReplStatus::OK; }