diff --git a/.github/workflows/build-matrix.yaml b/.github/workflows/build-matrix.yaml new file mode 100644 index 0000000000..59601c577f --- /dev/null +++ b/.github/workflows/build-matrix.yaml @@ -0,0 +1,62 @@ +name: Build + +on: + push: + branches: + - master + pull_request: + branches: + - master + merge_group: {} + +jobs: + # Windows + build_windows_clang: + name: "🖥️ Windows" + uses: ./.github/workflows/windows-build-clang.yaml + with: + cmakePreset: "Release-windows-clang" + cachePrefix: "" + secrets: inherit + + build_windows_msvc: + name: "🖥️ Windows" + uses: ./.github/workflows/windows-build-msvc.yaml + with: + cmakePreset: "Release-windows-msvc" + cachePrefix: "" + secrets: inherit + + # Linux + build_linux_clang: + name: "🐧 Linux" + uses: ./.github/workflows/linux-build-clang.yaml + with: + cmakePreset: "Release-linux-clang-asan" + cachePrefix: "" + secrets: inherit + + build_linux_gcc: + name: "🐧 Linux" + uses: ./.github/workflows/linux-build-gcc.yaml + with: + cmakePreset: "Release-linux-gcc" + cachePrefix: "" + secrets: inherit + + # MacOS + build_macos_intel: + name: "🍎 MacOS" + uses: ./.github/workflows/macos-build.yaml + with: + cmakePreset: "Release-macos-clang" + cachePrefix: "" + + # Q4 2023 there will hopefully be native arm64 runners + # https://github.com/github/roadmap/issues/528 + # build_macos_arm: + # name: "🍎 MacOS" + # uses: ./.github/workflows/macos-build-arm.yaml + # with: + # cmakePreset: "Release-macos-clang" + # cachePrefix: "" diff --git a/.github/workflows/macos-build.yaml b/.github/workflows/macos-build.yaml index f51a244cb9..6f9811b427 100644 --- a/.github/workflows/macos-build.yaml +++ b/.github/workflows/macos-build.yaml @@ -9,18 +9,6 @@ on: cachePrefix: required: true type: string -<<<<<<< HEAD - -jobs: - build: -<<<<<<<< HEAD:.github/workflows/macos-build.yaml - name: Intel - runs-on: macos-12 -======== - name: ARM - runs-on: macos-latest ->>>>>>>> vanilla/master:.github/workflows/macos-build-arm.yaml -======= uploadArtifacts: required: false type: boolean @@ -30,7 +18,6 @@ jobs: build: name: Intel runs-on: macos-12 ->>>>>>> vanilla/master timeout-minutes: 120 env: # overrides: https://github.com/mbitsnbites/buildcache/blob/master/doc/configuration.md @@ -44,16 +31,8 @@ jobs: - name: Checkout Repository uses: actions/checkout@v3 -<<<<<<< HEAD - - name: Set up ARM64 environment - run: sudo softwareupdate --install-rosetta --agree-to-license - - - name: Install Package Dependencies - run: arch -arm64 brew install cmake ninja -======= - name: Install Package Dependencies run: brew install cmake nasm ninja ->>>>>>> vanilla/master - name: Setup Buildcache uses: mikehardy/buildcache-action@v2.1.0 @@ -76,10 +55,6 @@ jobs: - name: Run Tests run: ./test.sh -<<<<<<< HEAD - - name: Upload artifact - uses: actions/upload-artifact@v3 -======= - name: Prepare artifacts if: ${{ inputs.uploadArtifacts }} run: | @@ -91,7 +66,6 @@ jobs: - name: Upload artifact uses: actions/upload-artifact@v3 if: ${{ inputs.uploadArtifacts }} ->>>>>>> vanilla/master with: name: opengoal-macos-${{ inputs.cachePrefix }} if-no-files-found: error @@ -99,4 +73,4 @@ jobs: ./build/goalc/goalc ./build/decompiler/extractor ./build/game/gk - ./build/lsp/lsp + ./build/lsp/lsp \ No newline at end of file diff --git a/.github/workflows/release-pipeline.yaml b/.github/workflows/release-pipeline.yaml new file mode 100644 index 0000000000..c4080bc98a --- /dev/null +++ b/.github/workflows/release-pipeline.yaml @@ -0,0 +1,104 @@ +name: 🏭 Release Pipeline + +on: + push: + tags: + - v* + +jobs: + # Windows + build_windows_clang: + name: "🖥️ Windows" + uses: ./.github/workflows/windows-build-clang.yaml + with: + cmakePreset: "Release-windows-clang-static" + cachePrefix: "static" + uploadArtifacts: true + secrets: inherit + + # Linux + build_linux_clang: + name: "🐧 Linux" + uses: ./.github/workflows/linux-build-clang.yaml + with: + cmakePreset: "Release-linux-clang-static" + cachePrefix: "static" + uploadArtifacts: true + secrets: inherit + + # macOS + build_macos_intel: + name: "🍎 MacOS" + uses: ./.github/workflows/macos-build.yaml + with: + cmakePreset: "Release-macos-clang-static" + cachePrefix: "static" + uploadArtifacts: true + secrets: inherit + + # Upload the Artifacts + upload_artifacts: + if: github.repository == 'open-goal/jak-project' + needs: + - build_windows_clang + - build_linux_clang + - build_macos_intel + name: "Upload Artifacts" + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Prepare Artifact Folder + run: mkdir -p ./ci-artifacts/final + + - uses: actions/download-artifact@v3 + name: Download all Artifacts + with: + path: ./ci-artifacts/ + + - name: Display structure of downloaded files + run: ls -Rl ./ci-artifacts/ + + - name: Prepare Linux Release Assets + run: | + mkdir -p ./ci-artifacts/linux + ./.github/scripts/releases/extract_build_unix.sh ./ci-artifacts/linux ./ci-artifacts/opengoal-linux-static ./ + pushd ci-artifacts/linux + TAG_VAL=$(echo ${{ github.REF }} | awk -F'refs/tags/' '{print $2}') + tar czf ../final/opengoal-linux-${TAG_VAL}.tar.gz . + popd + chmod +x ./ci-artifacts/opengoal-linux-static/lsp/lsp + cp ./ci-artifacts/opengoal-linux-static/lsp/lsp ./ci-artifacts/final/opengoal-lsp-linux-${TAG_VAL}.bin + + - name: Prepare Windows Build Assets + run: | + mkdir -p ./ci-artifacts/windows + ./.github/scripts/releases/extract_build_windows.sh ./ci-artifacts/windows ./ci-artifacts/opengoal-windows-static ./ + TAG_VAL=$(echo ${{ github.REF }} | awk -F'refs/tags/' '{print $2}') + 7z a -tzip ./ci-artifacts/final/opengoal-windows-${TAG_VAL}.zip ./ci-artifacts/windows/* + cp ./ci-artifacts/opengoal-windows-static/lsp.exe ./ci-artifacts/final/opengoal-lsp-windows-${TAG_VAL}.exe + + - name: Prepare macOS Build Assets + run: | + mkdir -p ./ci-artifacts/macos + ./.github/scripts/releases/extract_build_unix.sh ./ci-artifacts/macos ./ci-artifacts/opengoal-macos-static ./ + pushd ci-artifacts/macos + TAG_VAL=$(echo ${{ github.REF }} | awk -F'refs/tags/' '{print $2}') + tar czf ../final/opengoal-macos-intel-${TAG_VAL}.tar.gz . + popd + chmod +x ./ci-artifacts/opengoal-macos-static/lsp/lsp + cp ./ci-artifacts/opengoal-macos-static/lsp/lsp ./ci-artifacts/final/opengoal-lsp-macos-intel-${TAG_VAL}.bin + + - name: Upload Assets + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + TAG_VAL=$(echo ${{ github.REF }} | awk -F'refs/tags/' '{print $2}') + gh release upload "${TAG_VAL}" ${{ github.WORKSPACE }}/ci-artifacts/final/* --repo open-goal/jak-project --clobber + + - name: Publish Release + env: + GITHUB_TOKEN: ${{ secrets.BOT_PAT }} + run: | + TAG_VAL=$(echo ${{ github.REF }} | awk -F'refs/tags/' '{print $2}') + gh release edit ${TAG_VAL} --draft=false --repo open-goal/jak-project diff --git a/common/log/log.cpp b/common/log/log.cpp index 48b62aff82..9b98cda2e5 100644 --- a/common/log/log.cpp +++ b/common/log/log.cpp @@ -128,6 +128,7 @@ void set_file(const std::string& filename, } else { file_path = file_util::get_file_path({"log", filename}); } + file_util::create_dir_if_needed_for_file(file_path); std::string complete_filename = file_path; if (should_rotate) { complete_filename += "." + str_util::current_local_timestamp_no_colons() + ".log"; diff --git a/common/util/FileUtil.h b/common/util/FileUtil.h index 540793ca5a..2e5588a8b6 100644 --- a/common/util/FileUtil.h +++ b/common/util/FileUtil.h @@ -63,9 +63,11 @@ bool dgo_header_is_compressed(const std::vector& data); std::vector decompress_dgo(const std::vector& data_in); FILE* open_file(const fs::path& path, const std::string& mode); std::vector find_files_in_dir(const fs::path& dir, const std::regex& pattern); +std::vector find_files_in_dir(const fs::path& dir, const std::regex& pattern); std::vector find_files_recursively(const fs::path& base_dir, const std::regex& pattern); std::vector find_directories_in_dir(const fs::path& base_dir); std::vector sort_filepaths(const std::vector& paths, const bool aescending); +std::vector sort_filepaths(const std::vector& paths, const bool aescending); /// Will overwrite the destination if it exists void copy_file(const fs::path& src, const fs::path& dst); std::string make_screenshot_filepath(const GameVersion game_version, const std::string& name = ""); diff --git a/decompiler/ObjectFile/ObjectFileDB.cpp b/decompiler/ObjectFile/ObjectFileDB.cpp index 66deffca63..2febc5271e 100644 --- a/decompiler/ObjectFile/ObjectFileDB.cpp +++ b/decompiler/ObjectFile/ObjectFileDB.cpp @@ -741,7 +741,8 @@ std::string ObjectFileDB::process_tpages(TextureDB& tex_db, std::string result; for_each_obj([&](ObjectFileData& data) { if (data.name_in_dgo.substr(0, tpage_string.length()) == tpage_string) { - auto statistics = process_tpage(data, tex_db, output_path, cfg.animated_textures); + auto statistics = + process_tpage(data, tex_db, output_path, cfg.animated_textures, cfg.save_texture_pngs); total += statistics.total_textures; success += statistics.successful_textures; total_px += statistics.num_px; diff --git a/decompiler/config.cpp b/decompiler/config.cpp index 8145f69bbe..d789625187 100644 --- a/decompiler/config.cpp +++ b/decompiler/config.cpp @@ -272,6 +272,18 @@ Config make_config_via_json(nlohmann::json& json) { config.levels_to_extract = inputs_json.at("levels_to_extract").get>(); config.levels_extract = json.at("levels_extract").get(); + if (json.contains("save_texture_pngs")) { + config.save_texture_pngs = json.at("save_texture_pngs").get(); + } + + if (inputs_json.contains("animated_textures")) { + config.animated_textures = + inputs_json.at("animated_textures").get>(); + } + + if (inputs_json.contains("common_tpages")) { + config.common_tpages = inputs_json.at("common_tpages").get>(); + } if (inputs_json.contains("animated_textures")) { config.animated_textures = diff --git a/decompiler/config.h b/decompiler/config.h index 50531367a7..f9689bc31d 100644 --- a/decompiler/config.h +++ b/decompiler/config.h @@ -165,6 +165,7 @@ struct Config { std::vector levels_to_extract; bool levels_extract; + bool save_texture_pngs = false; DecompileHacks hacks; diff --git a/decompiler/config/jak1/jak1_config.jsonc b/decompiler/config/jak1/jak1_config.jsonc index cf6750aace..6a3a5aafef 100644 --- a/decompiler/config/jak1/jak1_config.jsonc +++ b/decompiler/config/jak1/jak1_config.jsonc @@ -104,6 +104,8 @@ // should we extract collision meshes? // these can be displayed in game, but makes the .fr3 files slightly larger "extract_collision": true, + // save game textures as .png files. + "save_texture_pngs": true, //////////////////////////// // PATCHING OPTIONS diff --git a/decompiler/config/jak2/jak2_config.jsonc b/decompiler/config/jak2/jak2_config.jsonc index 87f76cc7e5..ee33e295bb 100644 --- a/decompiler/config/jak2/jak2_config.jsonc +++ b/decompiler/config/jak2/jak2_config.jsonc @@ -115,6 +115,8 @@ // these can be displayed in game, but makes the .fr3 files slightly larger "extract_collision": true, + "save_texture_pngs": false, + //////////////////////////// // PATCHING OPTIONS //////////////////////////// diff --git a/decompiler/data/tpage.cpp b/decompiler/data/tpage.cpp index 005e14a578..a1579f602e 100644 --- a/decompiler/data/tpage.cpp +++ b/decompiler/data/tpage.cpp @@ -433,7 +433,8 @@ TexturePage read_texture_page(ObjectFileData& data, TPageResultStats process_tpage(ObjectFileData& data, TextureDB& texture_db, const fs::path& output_path, - const std::unordered_set& animated_textures) { + const std::unordered_set& animated_textures, + bool save_pngs) { TPageResultStats stats; auto& words = data.linked_data.words_by_seg.at(0); const auto& level_names = data.dgo_names; @@ -596,8 +597,10 @@ TPageResultStats process_tpage(ObjectFileData& data, } // write texture to a PNG. - file_util::write_rgba_png(texture_dump_dir / fmt::format("{}.png", tex.name), out.data(), - tex.w, tex.h); + if (save_pngs) { + file_util::write_rgba_png(texture_dump_dir / fmt::format("{}.png", tex.name), out.data(), + tex.w, tex.h); + } texture_db.add_texture(texture_page.id, tex_id, out, tex.w, tex.h, tex.name, texture_page.name, level_names, tex.num_mips, tex.dest[0]); stats.successful_textures++; @@ -639,8 +642,10 @@ TPageResultStats process_tpage(ObjectFileData& data, } // write texture to a PNG. - file_util::write_rgba_png(texture_dump_dir / fmt::format("{}.png", tex.name), out.data(), - tex.w, tex.h); + if (save_pngs) { + file_util::write_rgba_png(texture_dump_dir / fmt::format("{}.png", tex.name), out.data(), + tex.w, tex.h); + } texture_db.add_texture(texture_page.id, tex_id, out, tex.w, tex.h, tex.name, texture_page.name, level_names, tex.num_mips, tex.dest[0]); stats.successful_textures++; @@ -664,8 +669,10 @@ TPageResultStats process_tpage(ObjectFileData& data, } // write texture to a PNG. - file_util::write_rgba_png(texture_dump_dir / fmt::format("{}.png", tex.name), out.data(), - tex.w, tex.h); + if (save_pngs) { + file_util::write_rgba_png(texture_dump_dir / fmt::format("{}.png", tex.name), out.data(), + tex.w, tex.h); + } texture_db.add_texture(texture_page.id, tex_id, out, tex.w, tex.h, tex.name, texture_page.name, level_names, tex.num_mips, tex.dest[0]); stats.successful_textures++; @@ -705,8 +712,10 @@ TPageResultStats process_tpage(ObjectFileData& data, } // write texture to a PNG. - file_util::write_rgba_png(texture_dump_dir / fmt::format("{}.png", tex.name), out.data(), - tex.w, tex.h); + if (save_pngs) { + file_util::write_rgba_png(texture_dump_dir / fmt::format("{}.png", tex.name), out.data(), + tex.w, tex.h); + } texture_db.add_texture(texture_page.id, tex_id, out, tex.w, tex.h, tex.name, texture_page.name, level_names, tex.num_mips, tex.dest[0]); stats.successful_textures++; @@ -746,8 +755,10 @@ TPageResultStats process_tpage(ObjectFileData& data, } // write texture to a PNG. - file_util::write_rgba_png(texture_dump_dir / fmt::format("{}.png", tex.name), out.data(), - tex.w, tex.h); + if (save_pngs) { + file_util::write_rgba_png(texture_dump_dir / fmt::format("{}.png", tex.name), out.data(), + tex.w, tex.h); + } texture_db.add_texture(texture_page.id, tex_id, out, tex.w, tex.h, tex.name, texture_page.name, level_names, tex.num_mips, tex.dest[0]); stats.successful_textures++; @@ -771,8 +782,10 @@ TPageResultStats process_tpage(ObjectFileData& data, } // write texture to a PNG. - file_util::write_rgba_png(texture_dump_dir / fmt::format("{}.png", tex.name), out.data(), - tex.w, tex.h); + if (save_pngs) { + file_util::write_rgba_png(texture_dump_dir / fmt::format("{}.png", tex.name), out.data(), + tex.w, tex.h); + } texture_db.add_texture(texture_page.id, tex_id, out, tex.w, tex.h, tex.name, texture_page.name, level_names, tex.num_mips, tex.dest[0]); stats.successful_textures++; diff --git a/decompiler/data/tpage.h b/decompiler/data/tpage.h index d9592f71a8..f892fdbf9a 100644 --- a/decompiler/data/tpage.h +++ b/decompiler/data/tpage.h @@ -1,6 +1,8 @@ #pragma once #include #include +#include +#include #include "decompiler/data/TextureDB.h" @@ -16,5 +18,6 @@ struct TPageResultStats { TPageResultStats process_tpage(ObjectFileData& data, TextureDB& texture_db, const fs::path& output_path, - const std::unordered_set& animated_textures); + const std::unordered_set& animated_textures, + bool save_pngs); } // namespace decompiler diff --git a/decompiler/level_extractor/extract_shrub.cpp b/decompiler/level_extractor/extract_shrub.cpp index fdb3f95ec3..eb86c33714 100644 --- a/decompiler/level_extractor/extract_shrub.cpp +++ b/decompiler/level_extractor/extract_shrub.cpp @@ -155,11 +155,13 @@ DrawSettings adgif_to_draw_mode(const AdGifData& ad, current_mode.set_depth_write_enable(true); // todo, is this actual true current_mode.set_alpha_blend(DrawMode::AlphaBlend::SRC_SRC_SRC_SRC); current_mode.enable_fog(); + current_mode.set_ab(false); if (alpha_tpage_flag) { current_mode.set_alpha_test(DrawMode::AlphaTest::NEVER); current_mode.set_aref(0); current_mode.set_alpha_fail(GsTest::AlphaFail::FB_ONLY); + current_mode.set_ab(true); } // ADGIF 0 diff --git a/decompiler/level_extractor/extract_tie.cpp b/decompiler/level_extractor/extract_tie.cpp index e247cc5850..c6db02d090 100644 --- a/decompiler/level_extractor/extract_tie.cpp +++ b/decompiler/level_extractor/extract_tie.cpp @@ -2442,7 +2442,7 @@ void handle_draw_for_strip(tfrag3::TieTree& tree, std::vector& category_draws, const std::vector>>& packed_vert_indices, DrawMode mode, - u32 idx_in_lev_data, + s32 idx_in_lev_data, const TieStrip& strip, const TieInstanceInfo& inst, const TieInstanceFragInfo& ifrag, diff --git a/game/graphics/opengl_renderer/sprite/GlowRenderer.cpp b/game/graphics/opengl_renderer/sprite/GlowRenderer.cpp index b5941beb05..8bb0675d72 100644 --- a/game/graphics/opengl_renderer/sprite/GlowRenderer.cpp +++ b/game/graphics/opengl_renderer/sprite/GlowRenderer.cpp @@ -241,7 +241,9 @@ void copy_to_vertex(GlowRenderer::Vertex* vtx, const Vector4f& xyzw) { vtx->x = xyzw.x(); vtx->y = xyzw.y(); vtx->z = xyzw.z(); - vtx->w = xyzw.w(); + // ignore the w computed by the game, and just use 1. The game's VU program ignores this value, + // and we need to set w = 1 to get the correct opengl clipping behavior + vtx->w = 1; } } // namespace diff --git a/goal_src/jak1/engine/gfx/texture/texture.gc b/goal_src/jak1/engine/gfx/texture/texture.gc index b7be88434b..47f6960cc6 100644 --- a/goal_src/jak1/engine/gfx/texture/texture.gc +++ b/goal_src/jak1/engine/gfx/texture/texture.gc @@ -2492,7 +2492,12 @@ ) ) -(when (not *debug-segment*) +;; modified for PC port: never bother with the debug-mode texture login. +;; it will never work on PC, and it causes problems with custom levels, due to the way that it allocates the link +;; array for texture-pages that don't exist, which are never then set to false, causing them to be referenced +;; after the level is unloaded. This probably works fine if you are playing one level at a time, or if the backup +;; texture page loading actually works. +(when (or (not *debug-segment*) PC_PORT) ;; when not debugging, use the "fast" logins. There's no way we can load a texture over the network anyway. (set! adgif-shader-login adgif-shader-login-fast) (set! adgif-shader-login-no-remap adgif-shader-login-no-remap-fast) diff --git a/goal_src/jak2/engine/ui/text-id-h.gc b/goal_src/jak2/engine/ui/text-id-h.gc index dfe67337cb..3dad46c74b 100644 --- a/goal_src/jak2/engine/ui/text-id-h.gc +++ b/goal_src/jak2/engine/ui/text-id-h.gc @@ -585,7 +585,6 @@ (discord-rpc-dark-gun-training #x1105) (discord-rpc-onin-game #x1106) (discord-rpc-whack #x1107) - (progress-display-mode #x1200) (progress-windowed #x1201) (progress-fullscreen #x1202) diff --git a/goalc/build_level/build_level.cpp b/goalc/build_level/build_level.cpp index 431ad65fed..dcf3c09f99 100644 --- a/goalc/build_level/build_level.cpp +++ b/goalc/build_level/build_level.cpp @@ -3,6 +3,7 @@ #include "common/util/FileUtil.h" #include "common/util/compress.h" #include "common/util/json_util.h" +#include "common/util/string_util.h" #include "goalc/build_level/Entity.h" #include "goalc/build_level/FileInfo.h" @@ -25,8 +26,8 @@ void save_pc_data(const std::string& nickname, print_memory_usage(data, ser.get_save_result().second); lg::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(fr3_output_dir / fmt::format("{}.fr3", nickname), compressed.data(), - compressed.size()); + file_util::write_binary_file(fr3_output_dir / fmt::format("{}.fr3", str_util::to_upper(nickname)), + compressed.data(), compressed.size()); } std::vector get_build_level_deps(const std::string& input_file) { diff --git a/out/build/Release/bin/decompiler.exe b/out/build/Release/bin/decompiler.exe index f5c92b9106..3bdf31eaba 100644 Binary files a/out/build/Release/bin/decompiler.exe and b/out/build/Release/bin/decompiler.exe differ diff --git a/out/build/Release/bin/extractor.exe b/out/build/Release/bin/extractor.exe index d89ed4b9ee..51131f9e20 100644 Binary files a/out/build/Release/bin/extractor.exe and b/out/build/Release/bin/extractor.exe differ diff --git a/out/build/Release/bin/gk.exe b/out/build/Release/bin/gk.exe index ad68a2f344..467b1ea257 100644 Binary files a/out/build/Release/bin/gk.exe and b/out/build/Release/bin/gk.exe differ diff --git a/out/build/Release/bin/goalc.exe b/out/build/Release/bin/goalc.exe index f31b13b8f8..6082d3e585 100644 Binary files a/out/build/Release/bin/goalc.exe and b/out/build/Release/bin/goalc.exe differ