From d1e03e14db04396a82ed7585bb951cb276acfa1d Mon Sep 17 00:00:00 2001 From: Matt Dallmeyer Date: Tue, 31 Mar 2026 21:53:48 -0700 Subject: [PATCH] config cleanup (#4146) - jak 3 extractor config - validation that extractor expected game matches the provided ISO (no more drag and drop extractor for jak 2/3) - jak 3 bug report template --- .github/ISSUE_TEMPLATE/jak3-bug-report.yml | 75 ++++++++++++++++++++++ decompiler/config/jak3/jak3_config.jsonc | 15 +++-- decompiler/extractor/extractor_util.cpp | 40 ++++++++++++ decompiler/extractor/main.cpp | 15 ++++- 4 files changed, 136 insertions(+), 9 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/jak3-bug-report.yml diff --git a/.github/ISSUE_TEMPLATE/jak3-bug-report.yml b/.github/ISSUE_TEMPLATE/jak3-bug-report.yml new file mode 100644 index 0000000000..36ac5550af --- /dev/null +++ b/.github/ISSUE_TEMPLATE/jak3-bug-report.yml @@ -0,0 +1,75 @@ +name: "\U0001F41B Jak 3 Bug Report" +description: Create a bug report for Jak 3. +labels: ["jak3"] +type: 'bug' +body: + - type: checkboxes + attributes: + label: Acknowledgements + description: Take a couple minutes to help our maintainers work faster. + options: + - label: I have [searched](https://github.com/open-goal/jak-project/issues?q=is%3Aissue+is%3Aopen+label%3Abug+label%3Ajak3+sort%3Aupdated-desc+) for duplicate or closed bug reports + required: true + - label: I understand that I am supposed to provide my own legitimately obtained copy of the game + required: true + + - type: textarea + attributes: + label: Describe the Bug + description: A clear and concise description of what the bug is. You may post screenshots or videos of the bug here. + validations: + required: true + + - type: textarea + attributes: + label: How To Reproduce + description: Steps to reproduce the behavior. You can also post a video of it here. + validations: + required: true + + - type: dropdown + attributes: + label: Does this problem occur on original hardware or PCSX2? + description: Some things that may seem like bugs are actually exactly how the original game behaved. + options: + - Yes, it's unique to OpenGOAL + - Didn't check + - Not needed, bug is obvious + validations: + required: true + + - type: textarea + attributes: + label: Expected Behavior + description: A clear and concise description of the expected behavior. + placeholder: When I do X, Y should happen. + validations: + required: true + + - type: textarea + attributes: + label: Environment Information + description: "You can upload the [Support Package](https://github.com/open-goal/launcher#asking-for-help) provided by the Launcher here, or you can provide the following information: CPU, GPU, OS Version, OpenGOAL Version (found in the window's title bar)" + validations: + required: true + + - type: dropdown + attributes: + label: Game Version + options: + - NTSC 1.0 (black label) + - NTSC Greatest Hits version (red label) + - PAL + - KO + validations: + required: true + + - type: dropdown + attributes: + label: Have you set the game to something other than `60fps`? + options: + - "No" + - "Yes" + validations: + required: true + diff --git a/decompiler/config/jak3/jak3_config.jsonc b/decompiler/config/jak3/jak3_config.jsonc index cba298bfd7..d84fb0280e 100644 --- a/decompiler/config/jak3/jak3_config.jsonc +++ b/decompiler/config/jak3/jak3_config.jsonc @@ -19,7 +19,7 @@ "disassemble_code": false, // Run the decompiler - "decompile_code": true, + "decompile_code": false, "find_functions": true, @@ -39,7 +39,7 @@ // unpack game text to assets folder "process_game_text": true, // unpack game count to assets folder - "process_game_count": false, + "process_game_count": true, // write goal imports for art groups "process_art_groups": false, // write goal imports for the part group table @@ -54,7 +54,7 @@ "dump_part_group_table": false, // set to false to skip adding .STR files to the decompiler database - "read_spools": true, + "read_spools": false, // write out spool subtitle text, implies read_spools "process_subtitle_text": false, // write out spool subtitle images, implies read_spools @@ -121,7 +121,7 @@ //////////////////////////// // turn this on to extract level background graphics data as .fr3 files in out//fr3 - "levels_extract": false, + "levels_extract": true, // turn this on if you want extracted levels to be saved out as .glb files in decompiler_out//levels "rip_levels": false, // should we also extract collision meshes to the .fr3 files? @@ -154,8 +154,11 @@ "pal": { "game_name": "jak3_pal", "expected_elf_name": "SCES_524.60", - "is_pal": true, - "object_patches": {} + "is_pal": true + }, + "ko": { + "game_name": "jak3_ko", + "expected_elf_name": "SCKA_200.40" } } } diff --git a/decompiler/extractor/extractor_util.cpp b/decompiler/extractor/extractor_util.cpp index ea53058fcd..997395090b 100644 --- a/decompiler/extractor/extractor_util.cpp +++ b/decompiler/extractor/extractor_util.cpp @@ -121,6 +121,46 @@ extractor_iso_database() { "ko", // decompiler config "jak2", {}}}}}, + // Jak 3 NTSC-U + {"SCUS-97330", // serial from ELF name + {{4975852519304227343, // hash of ELF + {"Jak 3", // canonical name + GAME_TERRITORY_SCEA, + 749, // number of files + {61426067393410901}, // iso hash + "ntsc_v1", // decompiler config + "jak3", + {}}}}}, + // // Jak 3 NTSC-U (Greatest Hits) + {"SCUS-97516", // serial from ELF name + {{4975852519304227343, // hash of ELF + {"Jak 3", // canonical name + GAME_TERRITORY_SCEA, + 749, // number of files + {61426067393410901}, // iso hash + "ntsc_v1", // decompiler config + "jak3", + {}}}}}, + // Jak 3 NTSC-K + {"SCKA-20040", // serial from ELF name + {{10389946801578948532, // hash of ELF + {"ěž­ 3", // canonical name + GAME_TERRITORY_SCEI, + 749, // number of files + {15744436203314864205}, // iso hash + "ko", // decompiler config + "jak3", + {}}}}}, + // Jak 3 PAL + {"SCES-52460", // serial from ELF name + {{1406394940700478958, // hash of ELF + {"Jak 3", // canonical name + GAME_TERRITORY_SCEE, + 746, // number of files + {9845530557249070761}, // iso hash + "pal", // decompiler config + "jak3", + {}}}}}, }; return database; } diff --git a/decompiler/extractor/main.cpp b/decompiler/extractor/main.cpp index 3f015ea647..70d9e26bef 100644 --- a/decompiler/extractor/main.cpp +++ b/decompiler/extractor/main.cpp @@ -14,7 +14,8 @@ // used for - decompiler_out/ and iso_data/ const std::unordered_map data_subfolders = {{"jak1", "jak1"}, - {"jak2", "jak2"}}; + {"jak2", "jak2"}, + {"jak3", "jak3"}}; IsoFile extract_files(fs::path input_file_path, fs::path extracted_iso_path) { lg::info( @@ -32,6 +33,7 @@ IsoFile extract_files(fs::path input_file_path, fs::path extracted_iso_path) { } std::tuple, ExtractorErrorCode> validate( + const std::string& game_name, const fs::path& extracted_iso_path, const uint64_t expected_hash, const int expected_num_files) { @@ -78,6 +80,13 @@ std::tuple, ExtractorErrorCode> validate( lg::info("\tSerial - {}", dbEntry->first); lg::info("\tUses Decompiler Config Version - {}", version_info.decomp_config_version); + // Make sure the game provided matches the expected game (game arg must be provided for jak 2/3) + if (version_info.game_name != game_name) { + lg::error("Serial '{}' is for {}, expecting an ISO for {}", serial.value(), + version_info.game_name, game_name); + return {std::nullopt, ExtractorErrorCode::VALIDATION_SERIAL_MISSING_FROM_DB}; + } + // - Number of Files if (version_info.num_files != expected_num_files) { lg::error("Extracted an unexpected number of files. Expected '{}', Actual '{}'", @@ -290,7 +299,7 @@ int main(int argc, char** argv) { const auto [hash, file_count] = calculate_extraction_hash(iso_file); // Validate the result to determine the release const auto [version_info, validate_code] = - validate(temp_iso_extract_location, hash, file_count); + validate(game_name, temp_iso_extract_location, hash, file_count); if (validate_code == ExtractorErrorCode::VALIDATION_BAD_EXTRACTION || (flag_fail_on_validation && validate_code != ExtractorErrorCode::SUCCESS)) { return static_cast(validate_code); @@ -334,7 +343,7 @@ int main(int argc, char** argv) { // Get hash and file count const auto [hash, file_count] = calculate_extraction_hash(iso_data_path); // Validate - auto [version_info, validate_code] = validate(iso_data_path, hash, file_count); + auto [version_info, validate_code] = validate(game_name, iso_data_path, hash, file_count); if (validate_code == ExtractorErrorCode::VALIDATION_BAD_EXTRACTION || (flag_fail_on_validation && validate_code != ExtractorErrorCode::SUCCESS)) { return static_cast(validate_code);