mirror of
https://github.com/open-goal/jak-project.git
synced 2026-11-07 17:38:24 -10:00
Compare commits
89
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8feb46dc45 | ||
|
|
620168c45a | ||
|
|
4c2e1a8a90 | ||
|
|
ef719d2ab7 | ||
|
|
7848ba05b8 | ||
|
|
f6c55eba9f | ||
|
|
6a06291e6e | ||
|
|
9b393e2ddb | ||
|
|
3f7aca3c72 | ||
|
|
c263bc2114 | ||
|
|
2ff49b9905 | ||
|
|
8f445bda3e | ||
|
|
24ad5515f8 | ||
|
|
7543acfb8a | ||
|
|
5e3cb8faa6 | ||
|
|
321a113dd7 | ||
|
|
63676c70a5 | ||
|
|
2c6d41c87a | ||
|
|
2a41bc615e | ||
|
|
7553877e57 | ||
|
|
af5cb9b1cb | ||
|
|
b55a918902 | ||
|
|
f8058f2138 | ||
|
|
e3efede029 | ||
|
|
4604636593 | ||
|
|
8930141b72 | ||
|
|
1e530714b7 | ||
|
|
cbb8add81c | ||
|
|
10d7dabfd7 | ||
|
|
ba9085fee0 | ||
|
|
5e8ea23c30 | ||
|
|
2f0a90b693 | ||
|
|
348bf83b89 | ||
|
|
dff9ac163a | ||
|
|
1962fbfb51 | ||
|
|
5bc61c5854 | ||
|
|
510b23163f | ||
|
|
cb51bd3f5b | ||
|
|
e76a4399e5 | ||
|
|
e144406c16 | ||
|
|
d82b6209b6 | ||
|
|
eac11b5b93 | ||
|
|
a6680cc26d | ||
|
|
7dbacc72d3 | ||
|
|
b50652ce54 | ||
|
|
c623190bff | ||
|
|
a7a7110550 | ||
|
|
10008caad1 | ||
|
|
452f1329dd | ||
|
|
b8c77c65f5 | ||
|
|
eb544bcfc0 | ||
|
|
cb4f7772bb | ||
|
|
03cae68c7d | ||
|
|
6b7dd7ae22 | ||
|
|
07c224b966 | ||
|
|
66c455225d | ||
|
|
5b8bb8fe23 | ||
|
|
614c5a663c | ||
|
|
fedfb6fd09 | ||
|
|
7de5eb9fc0 | ||
|
|
f60a155c0f | ||
|
|
4e33746634 | ||
|
|
58467c50fc | ||
|
|
b6f25bf6d6 | ||
|
|
8d9966fd2c | ||
|
|
fe29eae395 | ||
|
|
431508aab1 | ||
|
|
69d879f901 | ||
|
|
d82bb3fde8 | ||
|
|
a39af394fb | ||
|
|
7053090541 | ||
|
|
bc66d416b4 | ||
|
|
d46e9fb8bb | ||
|
|
ebd02b28a4 | ||
|
|
4fd0a57046 | ||
|
|
7b7885e7a8 | ||
|
|
8c71827974 | ||
|
|
6c63a396c0 | ||
|
|
8a6348594a | ||
|
|
4c10b42841 | ||
|
|
9426683ae5 | ||
|
|
f2e7606f1b | ||
|
|
b0cd59e6ba | ||
|
|
9d2a23effe | ||
|
|
1ba3fa7cda | ||
|
|
a7d1336899 | ||
|
|
879f8cb5a2 | ||
|
|
8b7e0bde53 | ||
|
|
a13b0dce45 |
No files matched your search
@@ -1,6 +1,7 @@
|
||||
name: "\U0001F41B Jak 1 Bug Report"
|
||||
description: Create a bug report for Jak 1.
|
||||
labels: ["bug", "jak1"]
|
||||
labels: ["jak1"]
|
||||
type: 'bug'
|
||||
body:
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
name: "\U0001F41B Jak 2 Bug Report"
|
||||
description: Create a bug report for Jak 2.
|
||||
labels: ["bug", "jak2"]
|
||||
labels: ["jak2"]
|
||||
type: 'bug'
|
||||
body:
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
{
|
||||
"3990": {
|
||||
"msg": "Provided invalid or missing arguments"
|
||||
},
|
||||
"3991": {
|
||||
"msg": "Input path(s) do not exist"
|
||||
},
|
||||
"4000": {
|
||||
"msg": "Validation Failed: Cannot locate ELF"
|
||||
},
|
||||
|
||||
@@ -49,14 +49,12 @@ jobs:
|
||||
name: "🍎 MacOS"
|
||||
uses: ./.github/workflows/macos-build.yaml
|
||||
with:
|
||||
cmakePreset: "Release-macos-clang"
|
||||
cmakePreset: "Release-macos-x86_64-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: ""
|
||||
build_macos_arm:
|
||||
name: "🍎 MacOS"
|
||||
uses: ./.github/workflows/macos-build-arm.yaml
|
||||
with:
|
||||
cmakePreset: "Release-macos-x86_64-clang"
|
||||
cachePrefix: ""
|
||||
@@ -0,0 +1,98 @@
|
||||
name: Compilation Check
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Compare
|
||||
runs-on: ubuntu-20.04
|
||||
timeout-minutes: 60
|
||||
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: master
|
||||
|
||||
- name: Install Package Dependencies
|
||||
run: |
|
||||
sudo apt update
|
||||
sudo apt install build-essential cmake \
|
||||
clang gcc g++ lcov make nasm libxrandr-dev \
|
||||
libxinerama-dev libxcursor-dev libpulse-dev \
|
||||
libxi-dev zip ninja-build libgl1-mesa-dev libssl-dev
|
||||
|
||||
- name: Setup sccache
|
||||
uses: hendrikmuhs/[email protected]
|
||||
with:
|
||||
variant: sccache
|
||||
key: linux-ubuntu-20.04--Release-linux-clang-static-${{ github.sha }}
|
||||
restore-keys: linux-ubuntu-20.04--Release-linux-clang-static
|
||||
max-size: 1000M
|
||||
|
||||
- name: CMake Generation (master)
|
||||
env:
|
||||
CC: clang
|
||||
CXX: clang++
|
||||
run: |
|
||||
cmake -B build --preset=Release-linux-clang-static \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=sccache \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=sccache
|
||||
|
||||
- name: Build goalc (master)
|
||||
run: |
|
||||
cmake --build build --parallel $((`nproc`)) --target goalc
|
||||
mv ./build ./build.master
|
||||
|
||||
- name: Checkout PR
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
clean: "false"
|
||||
|
||||
- name: CMake Generation (PR)
|
||||
env:
|
||||
CC: clang
|
||||
CXX: clang++
|
||||
run: |
|
||||
cmake -B build --preset=Release-linux-clang-static \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=sccache \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=sccache
|
||||
|
||||
- name: Build goalc (PR)
|
||||
run: cmake --build build --parallel $((`nproc`)) --target goalc
|
||||
|
||||
- name: Compile and preserve (master)
|
||||
run: |
|
||||
./build.master/goalc/goalc --game jak1 --cmd "(make-group \"all-code\")"
|
||||
./build.master/goalc/goalc --game jak2 --cmd "(make-group \"all-code\")"
|
||||
./build.master/goalc/goalc --game jak3 --cmd "(make-group \"all-code\")"
|
||||
mv ./out/jak1/obj ./out/jak1/obj.master
|
||||
mv ./out/jak2/obj ./out/jak2/obj.master
|
||||
mv ./out/jak3/obj ./out/jak3/obj.master
|
||||
|
||||
- name: Compile and preserve (PR)
|
||||
run: |
|
||||
./build/goalc/goalc --game jak1 --cmd "(make-group \"all-code\")"
|
||||
./build/goalc/goalc --game jak2 --cmd "(make-group \"all-code\")"
|
||||
./build/goalc/goalc --game jak3 --cmd "(make-group \"all-code\")"
|
||||
mv ./out/jak1/obj ./out/jak1/obj.pr
|
||||
mv ./out/jak2/obj ./out/jak2/obj.pr
|
||||
mv ./out/jak3/obj ./out/jak3/obj.pr
|
||||
|
||||
- name: Compare Results and Produce Report
|
||||
run: |
|
||||
ls -l ./out/jak1
|
||||
ls -l ./out/jak2
|
||||
ls -l ./out/jak3
|
||||
set +e
|
||||
python ./scripts/gsrc/compare-compilation-outputs.py --base "./out/jak1/obj.master,./out/jak2/obj.master,./out/jak3/obj.master" --compare "./out/jak1/obj.pr,./out/jak2/obj.pr,./out/jak3/obj.pr" --markdown
|
||||
SCRIPT_EXIT_CODE=$?
|
||||
cat ./comp-diff-report.md >> $GITHUB_STEP_SUMMARY
|
||||
if [ "$SCRIPT_EXIT_CODE" -ne 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
name: 🏭 Draft Release
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
bump:
|
||||
description: 'Semver Bump Type'
|
||||
required: true
|
||||
default: 'patch'
|
||||
type: choice
|
||||
options:
|
||||
- patch
|
||||
- minor
|
||||
- major
|
||||
|
||||
jobs:
|
||||
cut-release:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
# Docs - https://github.com/mathieudutour/github-tag-action
|
||||
# Workflows cannot trigger other workflows implicitly
|
||||
# - https://github.community/t/github-actions-workflow-not-triggering-with-tag-push/17053/7
|
||||
- name: Bump Version and Push Tag
|
||||
if: github.repository == 'open-goal/jak-project'
|
||||
id: tag_version
|
||||
uses: mathieudutour/[email protected]
|
||||
with:
|
||||
github_token: ${{ secrets.BOT_PAT }}
|
||||
tag_prefix: v
|
||||
default_bump: ${{ github.event.inputs.bump }}
|
||||
|
||||
- name: Create Release
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.BOT_PAT }}
|
||||
run: gh release create ${{ steps.tag_version.outputs.new_tag }} --generate-notes --draft --repo open-goal/jak-project
|
||||
@@ -21,9 +21,19 @@ jobs:
|
||||
timeout-minutes: 60
|
||||
|
||||
steps:
|
||||
# minimal checkout if we're NOT uploading artifacts
|
||||
- name: Checkout Repository
|
||||
if: ${{ ! inputs.uploadArtifacts }}
|
||||
uses: actions/checkout@v4
|
||||
|
||||
# full checkout with tags if we ARE uploading artifacts
|
||||
- name: Checkout Repository with Tags
|
||||
if: ${{ inputs.uploadArtifacts }}
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
fetch-tags: true
|
||||
|
||||
- name: Install Package Dependencies
|
||||
run: |
|
||||
sudo apt update
|
||||
@@ -33,7 +43,7 @@ jobs:
|
||||
libxi-dev zip ninja-build libgl1-mesa-dev libssl-dev
|
||||
|
||||
- name: Setup sccache
|
||||
uses: hendrikmuhs/[email protected]3
|
||||
uses: hendrikmuhs/[email protected]4
|
||||
with:
|
||||
variant: sccache
|
||||
key: linux-ubuntu-20.04-${{ inputs.cachePrefix }}-${{ inputs.cmakePreset }}-${{ github.sha }}
|
||||
|
||||
@@ -34,7 +34,7 @@ jobs:
|
||||
sudo update-alternatives --set g++ /usr/bin/g++-10
|
||||
|
||||
- name: Setup sccache
|
||||
uses: hendrikmuhs/[email protected]3
|
||||
uses: hendrikmuhs/[email protected]4
|
||||
with:
|
||||
variant: sccache
|
||||
key: linux-ubuntu-20.04-${{ inputs.cachePrefix }}-${{ inputs.cmakePreset }}-${{ github.sha }}
|
||||
|
||||
@@ -13,25 +13,22 @@ on:
|
||||
jobs:
|
||||
build:
|
||||
name: ARM
|
||||
runs-on: macos-12
|
||||
runs-on: macos-15
|
||||
timeout-minutes: 120
|
||||
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up ARM64 environment
|
||||
run: sudo softwareupdate --install-rosetta --agree-to-license
|
||||
|
||||
- name: Install Package Dependencies
|
||||
run: arch -arm64 brew install cmake ninja
|
||||
run: brew install cmake ninja nasm
|
||||
|
||||
- name: Setup sccache
|
||||
uses: hendrikmuhs/[email protected]3
|
||||
uses: hendrikmuhs/[email protected]4
|
||||
with:
|
||||
variant: sccache
|
||||
key: macos-12-${{ inputs.cachePrefix }}-${{ inputs.cmakePreset }}-${{ github.sha }}
|
||||
restore-keys: macos-12-${{ inputs.cachePrefix }}-${{ inputs.cmakePreset }}
|
||||
key: macos-15-${{ inputs.cachePrefix }}-${{ inputs.cmakePreset }}-${{ github.sha }}
|
||||
restore-keys: macos-15-${{ inputs.cachePrefix }}-${{ inputs.cmakePreset }}
|
||||
max-size: 1000M
|
||||
|
||||
- name: CMake Generation
|
||||
@@ -52,7 +49,7 @@ jobs:
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: opengoal-macos-${{ inputs.cachePrefix }}
|
||||
name: opengoal-macos-arm-${{ inputs.cachePrefix }}
|
||||
if-no-files-found: error
|
||||
path: |
|
||||
./build/goalc/goalc
|
||||
|
||||
@@ -17,22 +17,32 @@ on:
|
||||
jobs:
|
||||
build:
|
||||
name: Intel
|
||||
runs-on: macos-12
|
||||
runs-on: macos-13
|
||||
timeout-minutes: 120
|
||||
|
||||
steps:
|
||||
# minimal checkout if we're NOT uploading artifacts
|
||||
- name: Checkout Repository
|
||||
if: ${{ ! inputs.uploadArtifacts }}
|
||||
uses: actions/checkout@v4
|
||||
|
||||
# full checkout with tags if we ARE uploading artifacts
|
||||
- name: Checkout Repository with Tags
|
||||
if: ${{ inputs.uploadArtifacts }}
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
fetch-tags: true
|
||||
|
||||
- name: Install Package Dependencies
|
||||
run: brew install cmake nasm ninja
|
||||
|
||||
- name: Setup sccache
|
||||
uses: hendrikmuhs/[email protected]3
|
||||
uses: hendrikmuhs/[email protected]4
|
||||
with:
|
||||
variant: sccache
|
||||
key: macos-12-${{ inputs.cachePrefix }}-${{ inputs.cmakePreset }}-${{ github.sha }}
|
||||
restore-keys: macos-12-${{ inputs.cachePrefix }}-${{ inputs.cmakePreset }}
|
||||
key: macos-13-${{ inputs.cachePrefix }}-${{ inputs.cmakePreset }}-${{ github.sha }}
|
||||
restore-keys: macos-13-${{ inputs.cachePrefix }}-${{ inputs.cmakePreset }}
|
||||
max-size: 1000M
|
||||
|
||||
- name: CMake Generation
|
||||
|
||||
@@ -1,13 +1,52 @@
|
||||
name: 🏭 Release Pipeline
|
||||
name: 🏭 Draft Release
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- v*
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
bump:
|
||||
description: 'Semver Bump Type'
|
||||
required: true
|
||||
default: 'patch'
|
||||
type: choice
|
||||
options:
|
||||
- patch
|
||||
- minor
|
||||
- major
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
cut_release:
|
||||
name: Cut Release
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
new_tag: ${{ steps.set_tag.outputs.new_tag }}
|
||||
steps:
|
||||
# Docs - https://github.com/mathieudutour/github-tag-action
|
||||
- name: Bump Version and Push Tag
|
||||
if: github.repository == 'open-goal/jak-project'
|
||||
id: tag_version
|
||||
uses: mathieudutour/[email protected]
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
tag_prefix: v
|
||||
default_bump: ${{ github.event.inputs.bump }}
|
||||
|
||||
- name: Create Release
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: gh release create ${{ steps.tag_version.outputs.new_tag }} --generate-notes --draft --repo ${{ github.repository }}
|
||||
|
||||
- name: Output new tag
|
||||
id: set_tag
|
||||
run: |
|
||||
echo "new_tag=${{ steps.tag_version.outputs.new_tag }}" >> $GITHUB_OUTPUT
|
||||
|
||||
# Windows
|
||||
build_windows_clang:
|
||||
needs:
|
||||
- cut_release
|
||||
name: "🖥️ Windows"
|
||||
uses: ./.github/workflows/windows-build-clang.yaml
|
||||
with:
|
||||
@@ -18,6 +57,8 @@ jobs:
|
||||
|
||||
# Linux
|
||||
build_linux_clang:
|
||||
needs:
|
||||
- cut_release
|
||||
name: "🐧 Linux"
|
||||
uses: ./.github/workflows/linux-build-clang.yaml
|
||||
with:
|
||||
@@ -28,25 +69,42 @@ jobs:
|
||||
|
||||
# macOS
|
||||
build_macos_intel:
|
||||
needs:
|
||||
- cut_release
|
||||
name: "🍎 MacOS"
|
||||
uses: ./.github/workflows/macos-build.yaml
|
||||
with:
|
||||
cmakePreset: "Release-macos-clang-static"
|
||||
cmakePreset: "Release-macos-x86_64-clang-static"
|
||||
cachePrefix: "static"
|
||||
uploadArtifacts: true
|
||||
secrets: inherit
|
||||
|
||||
build_macos_arm:
|
||||
needs:
|
||||
- cut_release
|
||||
name: "🍎 MacOS"
|
||||
uses: ./.github/workflows/macos-build.yaml
|
||||
with:
|
||||
cmakePreset: "Release-macos-x86_64-clang-static"
|
||||
cachePrefix: "static-arm"
|
||||
uploadArtifacts: true
|
||||
secrets: inherit
|
||||
|
||||
# Upload the Artifacts
|
||||
upload_artifacts:
|
||||
if: github.repository == 'open-goal/jak-project'
|
||||
needs:
|
||||
- cut_release
|
||||
- build_windows_clang
|
||||
- build_linux_clang
|
||||
- build_macos_intel
|
||||
- build_macos_arm
|
||||
name: "Upload Artifacts"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ needs.cut_release.outputs.new_tag }}
|
||||
|
||||
- name: Prepare Artifact Folder
|
||||
run: mkdir -p ./ci-artifacts/final
|
||||
@@ -64,7 +122,7 @@ jobs:
|
||||
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}')
|
||||
TAG_VAL=${{ needs.cut_release.outputs.new_tag }}
|
||||
tar czf ../final/opengoal-linux-${TAG_VAL}.tar.gz .
|
||||
popd
|
||||
chmod +x ./ci-artifacts/opengoal-linux-static/lsp/lsp
|
||||
@@ -74,31 +132,42 @@ jobs:
|
||||
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}')
|
||||
TAG_VAL=${{ needs.cut_release.outputs.new_tag }}
|
||||
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
|
||||
- name: Prepare Intel 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}')
|
||||
TAG_VAL=${{ needs.cut_release.outputs.new_tag }}
|
||||
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: Prepare ARM macOS Build Assets
|
||||
run: |
|
||||
mkdir -p ./ci-artifacts/macos-arm
|
||||
./.github/scripts/releases/extract_build_unix.sh ./ci-artifacts/macos-arm ./ci-artifacts/opengoal-macos-static-arm ./
|
||||
pushd ci-artifacts/macos-arm
|
||||
TAG_VAL=${{ needs.cut_release.outputs.new_tag }}
|
||||
tar czf ../final/opengoal-macos-arm-${TAG_VAL}.tar.gz .
|
||||
popd
|
||||
chmod +x ./ci-artifacts/opengoal-macos-static-arm/lsp/lsp
|
||||
cp ./ci-artifacts/opengoal-macos-static-arm/lsp/lsp ./ci-artifacts/final/opengoal-lsp-macos-arm-${TAG_VAL}.bin
|
||||
|
||||
- name: Upload Assets
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
TAG_VAL=$(echo ${{ github.REF }} | awk -F'refs/tags/' '{print $2}')
|
||||
TAG_VAL=${{ needs.cut_release.outputs.new_tag }}
|
||||
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 }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
TAG_VAL=$(echo ${{ github.REF }} | awk -F'refs/tags/' '{print $2}')
|
||||
TAG_VAL=${{ needs.cut_release.outputs.new_tag }}
|
||||
gh release edit ${TAG_VAL} --draft=false --repo open-goal/jak-project
|
||||
@@ -19,7 +19,7 @@ jobs:
|
||||
wget -O ./game/assets/sdl_controller_db.txt https://raw.githubusercontent.com/gabomdq/SDL_GameControllerDB/master/gamecontrollerdb.txt
|
||||
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v6
|
||||
uses: peter-evans/create-pull-request@v7
|
||||
with:
|
||||
token: ${{ secrets.BOT_PAT }}
|
||||
author: 'OpenGOALBot <[email protected]>'
|
||||
|
||||
@@ -22,9 +22,19 @@ jobs:
|
||||
timeout-minutes: 60
|
||||
|
||||
steps:
|
||||
# minimal checkout if we're NOT uploading artifacts
|
||||
- name: Checkout Repository
|
||||
if: ${{ ! inputs.uploadArtifacts }}
|
||||
uses: actions/checkout@v4
|
||||
|
||||
# full checkout with tags if we ARE uploading artifacts
|
||||
- name: Checkout Repository with Tags
|
||||
if: ${{ inputs.uploadArtifacts }}
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
fetch-tags: true
|
||||
|
||||
- name: Install NASM
|
||||
# TODO - Simplify this with just the first command once choco 2.0 rolls out everywhere
|
||||
run: |
|
||||
@@ -36,7 +46,7 @@ jobs:
|
||||
}
|
||||
|
||||
- name: Setup sccache
|
||||
uses: hendrikmuhs/[email protected]3
|
||||
uses: hendrikmuhs/[email protected]4
|
||||
with:
|
||||
variant: sccache
|
||||
key: windows-2022-${{ inputs.cachePrefix }}-${{ inputs.cmakePreset }}-${{ github.sha }}
|
||||
|
||||
@@ -31,7 +31,7 @@ jobs:
|
||||
}
|
||||
|
||||
- name: Setup sccache
|
||||
uses: hendrikmuhs/[email protected]3
|
||||
uses: hendrikmuhs/[email protected]4
|
||||
with:
|
||||
variant: sccache
|
||||
key: windows-2022-${{ inputs.cachePrefix }}-${{ inputs.cmakePreset }}-${{ github.sha }}
|
||||
|
||||
+5
-2
@@ -1,6 +1,7 @@
|
||||
# logs
|
||||
/log
|
||||
prof.json
|
||||
/gpu-test.json
|
||||
|
||||
# for CMake
|
||||
/Testing
|
||||
@@ -9,7 +10,8 @@ prof.json
|
||||
cmake-build-debug/*
|
||||
cmake-build-debug--o0/*
|
||||
.idea/*
|
||||
build/*
|
||||
build/
|
||||
build.master/
|
||||
/decompiler_out*
|
||||
logs/*
|
||||
profile_data/*
|
||||
@@ -32,6 +34,7 @@ linux-default/
|
||||
*.bin
|
||||
*.log
|
||||
*.p2s
|
||||
out/
|
||||
savestate-out/
|
||||
savestate_out/
|
||||
failures/
|
||||
@@ -39,6 +42,7 @@ ee-results*.json
|
||||
search-results.json
|
||||
.env
|
||||
/search-results.json
|
||||
comp-diff-report.md
|
||||
|
||||
# graphics debug
|
||||
debug_out/
|
||||
@@ -67,7 +71,6 @@ custom_assets/jak3/merc_replacements/*
|
||||
svnrev.h
|
||||
common/versions/revision.h
|
||||
ci-artifacts/
|
||||
out/build/
|
||||
__pycache__/
|
||||
|
||||
# sqlite stuff
|
||||
|
||||
@@ -138,6 +138,19 @@
|
||||
"-debug"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "default",
|
||||
"project": "CMakeLists.txt",
|
||||
"projectTarget": "gk.exe (bin\\gk.exe)",
|
||||
"name": "Game - GPU Test",
|
||||
"args": [
|
||||
"-v",
|
||||
"--gpu-test",
|
||||
"opengl",
|
||||
"--gpu-test-out-path",
|
||||
"./gpu-test.json"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "default",
|
||||
"project": "CMakeLists.txt",
|
||||
|
||||
+10
-1
@@ -2,6 +2,7 @@
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
project(jak)
|
||||
include(CTest)
|
||||
|
||||
@@ -43,6 +44,10 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
-Wall \
|
||||
-Wno-c++11-narrowing \
|
||||
-Wno-c++98-compat \
|
||||
-Wno-deprecated-this-capture \
|
||||
-Wno-missing-field-initializers \
|
||||
-Wno-sign-compare \
|
||||
-Wno-ignored-qualifiers \
|
||||
-O3 \
|
||||
-D_CRT_SECURE_NO_WARNINGS")
|
||||
|
||||
@@ -52,7 +57,7 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
# Note: this is only _reserved_ memory, not necessarily _committed_ memory
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${LDFLAGS} -Xlinker /STACK:16000000")
|
||||
else()
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ggdb -g -Wextra")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ggdb -g")
|
||||
endif()
|
||||
|
||||
# additional c++ and linker flags for release mode for our projects
|
||||
@@ -283,6 +288,10 @@ include(test/CMakeLists.txt)
|
||||
build_third_party_lib(lzokay lzokay)
|
||||
|
||||
build_third_party_lib(stb_image stb_image)
|
||||
# build draco library for tinygltf compression support
|
||||
include_directories(third-party/draco/src)
|
||||
add_subdirectory(third-party/draco)
|
||||
add_compile_definitions(TINYGLTF_ENABLE_DRACO)
|
||||
build_third_party_lib(tiny_gltf tiny_gltf)
|
||||
build_third_party_lib(xdelta3 xdelta3)
|
||||
|
||||
|
||||
+40
-8
@@ -78,6 +78,22 @@
|
||||
"CMAKE_INSTALL_PREFIX": "${sourceDir}/build/install/${presetName}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "base-macos-arm64",
|
||||
"hidden": true,
|
||||
"cacheVariables": {
|
||||
"CMAKE_APPLE_SILICON_PROCESSOR": "arm64",
|
||||
"CMAKE_OSX_ARCHITECTURES": "arm64"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "base-macos-x86_64",
|
||||
"hidden": true,
|
||||
"cacheVariables": {
|
||||
"CMAKE_APPLE_SILICON_PROCESSOR": "x86_64",
|
||||
"CMAKE_OSX_ARCHITECTURES": "x86_64"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "base-clang",
|
||||
"hidden": true,
|
||||
@@ -159,16 +175,32 @@
|
||||
"inherits": ["base-linux-release", "base-clang"]
|
||||
},
|
||||
{
|
||||
"name": "Release-macos-clang",
|
||||
"displayName": "MacOS Release (clang)",
|
||||
"description": "Build with Clang as Release without Debug Symbols",
|
||||
"inherits": ["base-macos-release", "base-clang"]
|
||||
"name": "Release-macos-arm64-clang",
|
||||
"displayName": "MacOS ARM64 Release (clang)",
|
||||
"description": "Build for ARM64 with Clang as Release without Debug Symbols",
|
||||
"inherits": ["base-macos-release", "base-macos-arm64", "base-clang"]
|
||||
},
|
||||
{
|
||||
"name": "Release-macos-clang-static",
|
||||
"displayName": "MacOS Static Release (clang)",
|
||||
"description": "Build with Clang as Release without Debug Symbols but statically linked",
|
||||
"inherits": ["base-macos-release", "base-clang"],
|
||||
"name": "Release-macos-x86_64-clang",
|
||||
"displayName": "MacOS x86_64 Release (clang)",
|
||||
"description": "Build for x86_64 with Clang as Release without Debug Symbols",
|
||||
"inherits": ["base-macos-release", "base-macos-x86_64", "base-clang"]
|
||||
},
|
||||
{
|
||||
"name": "Release-macos-arm64-clang-static",
|
||||
"displayName": "MacOS ARM64 Static Release (clang)",
|
||||
"description": "Build for ARM64 with Clang as Release without Debug Symbols but statically linked",
|
||||
"inherits": ["base-macos-release", "base-macos-arm64", "base-clang"],
|
||||
"cacheVariables": {
|
||||
"STATICALLY_LINK": "true",
|
||||
"ZYDIS_BUILD_SHARED_LIB": "OFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Release-macos-x86_64-clang-static",
|
||||
"displayName": "MacOS x86_64 Static Release (clang)",
|
||||
"description": "Build for x86_64 with Clang as Release without Debug Symbols but statically linked, requires MacOS Sequoia",
|
||||
"inherits": ["base-macos-release", "base-macos-x86_64", "base-clang"],
|
||||
"cacheVariables": {
|
||||
"STATICALLY_LINK": "true",
|
||||
"ZYDIS_BUILD_SHARED_LIB": "OFF"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
ISC License
|
||||
|
||||
Copyright (c) 2020-2022 OpenGOAL Team
|
||||
Copyright (c) 2020-2025 OpenGOAL Team
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
|
||||
@@ -72,7 +72,7 @@ Our objectives are:
|
||||
|
||||
We support both Linux and Windows on x86-64.
|
||||
|
||||
> We do not support, or plan to support the ARM architecture. This means that this will not run on devices such as an M1 Mac or a mobile device.
|
||||
> We do not support, or plan to support the ARM architecture. This means that this will not run on devices such as a mobile device.
|
||||
|
||||
### Current Status
|
||||
|
||||
@@ -127,7 +127,7 @@ Unfortunately you'll still need task runner on your local machine to run the gam
|
||||
Install packages and init repository:
|
||||
|
||||
```sh
|
||||
sudo apt install gcc make cmake build-essential g++ nasm clang-format libxrandr-dev libxinerama-dev libxcursor-dev libpulse-dev libxi-dev python libgl1-mesa-dev libssl-dev
|
||||
sudo apt install gcc make cmake ninja-build build-essential g++ nasm clang-format libxrandr-dev libxinerama-dev libxcursor-dev libpulse-dev libxi-dev python libgl1-mesa-dev libssl-dev
|
||||
sudo sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b /usr/local/bin
|
||||
```
|
||||
|
||||
@@ -235,7 +235,7 @@ Then build the entire project as `Windows Release (clang)`. You can also press C
|
||||
|
||||
### MacOS
|
||||
|
||||
> NOTE: At this time you can only run the game on macOS if you have an Intel processor.
|
||||
> NOTE: Running the game requires an Apple Silicon Mac running macOS Sequoia, or an Intel Mac.
|
||||
|
||||
Ensure that you have Xcode command line tools installed (this installs things like Apple Clang). If you don't, you can run the following command:
|
||||
|
||||
@@ -243,23 +243,25 @@ Ensure that you have Xcode command line tools installed (this installs things li
|
||||
xcode-select --install
|
||||
```
|
||||
|
||||
#### Intel Based
|
||||
On Apple Silicon, Rosetta 2 also must be installed:
|
||||
|
||||
```bash
|
||||
softwareupdate --install-rosetta
|
||||
```
|
||||
|
||||
#### Building for x86_64
|
||||
|
||||
```bash
|
||||
brew install go-task/tap/go-task
|
||||
brew install cmake nasm ninja go-task clang-format
|
||||
cmake -B build --preset=Release-macos-clang
|
||||
cmake -B build --preset=Release-macos-x86_64-clang
|
||||
cmake --build build --parallel $((`sysctl -n hw.logicalcpu`))
|
||||
```
|
||||
|
||||
#### Apple Silicon
|
||||
|
||||
**Not Supported at This Time**
|
||||
#### Building for ARM64 (experimental, unsupported)
|
||||
|
||||
```bash
|
||||
brew install go-task/tap/go-task
|
||||
brew install cmake ninja go-task clang-format
|
||||
cmake -B build --preset=Release-macos-clang
|
||||
cmake -B build --preset=Release-macos-arm64-clang
|
||||
cmake --build build --parallel $((`sysctl -n hw.logicalcpu`))
|
||||
```
|
||||
|
||||
|
||||
+44
-29
@@ -10,33 +10,33 @@ dotenv:
|
||||
tasks:
|
||||
# SETTINGS / CONFIGURATION
|
||||
settings:
|
||||
- 'python ./scripts/tasks/update-env.py --info'
|
||||
- '{{.PYTHON}} ./scripts/tasks/update-env.py --info'
|
||||
set-game-jak1:
|
||||
- 'python ./scripts/tasks/update-env.py --game jak1'
|
||||
- '{{.PYTHON}} ./scripts/tasks/update-env.py --game jak1'
|
||||
set-game-jak2:
|
||||
- 'python ./scripts/tasks/update-env.py --game jak2'
|
||||
- '{{.PYTHON}} ./scripts/tasks/update-env.py --game jak2'
|
||||
set-game-jak3:
|
||||
- 'python ./scripts/tasks/update-env.py --game jak3'
|
||||
- '{{.PYTHON}} ./scripts/tasks/update-env.py --game jak3'
|
||||
set-decomp-ntscv1:
|
||||
desc: "aka black label"
|
||||
cmds:
|
||||
- 'python ./scripts/tasks/update-env.py --decomp_config ntscv1'
|
||||
- '{{.PYTHON}} ./scripts/tasks/update-env.py --decomp_config ntscv1'
|
||||
set-decomp-ntscv2:
|
||||
desc: "aka red label"
|
||||
cmds:
|
||||
- 'python ./scripts/tasks/update-env.py --decomp_config ntscv2'
|
||||
- '{{.PYTHON}} ./scripts/tasks/update-env.py --decomp_config ntscv2'
|
||||
set-decomp-pal:
|
||||
desc: "PAL region version"
|
||||
cmds:
|
||||
- 'python ./scripts/tasks/update-env.py --decomp_config pal'
|
||||
- '{{.PYTHON}} ./scripts/tasks/update-env.py --decomp_config pal'
|
||||
set-decomp-ntscjp:
|
||||
desc: "NTSC-J region version"
|
||||
cmds:
|
||||
- 'python ./scripts/tasks/update-env.py --decomp_config ntscjp'
|
||||
- '{{.PYTHON}} ./scripts/tasks/update-env.py --decomp_config ntscjp'
|
||||
set-decomp-ntscko:
|
||||
desc: "NTSC-K region version"
|
||||
cmds:
|
||||
- 'python ./scripts/tasks/update-env.py --decomp_config ntscko'
|
||||
- '{{.PYTHON}} ./scripts/tasks/update-env.py --decomp_config ntscko'
|
||||
# GENERAL
|
||||
extract:
|
||||
desc: "Extracts the game's assets from './iso_data' with the set decompiler config"
|
||||
@@ -67,6 +67,14 @@ tasks:
|
||||
cmds:
|
||||
- "{{.GK_BIN_RELEASE_DIR}}/gk -v --game {{.GAME}} -- -fakeiso -debug"
|
||||
# DEVELOPMENT
|
||||
gen-cmake:
|
||||
desc: "Generate the CMake"
|
||||
cmds:
|
||||
- "cmake -B build --preset={{.CMAKE_PRESET}}"
|
||||
build:
|
||||
desc: "Build the project using the generated CMake"
|
||||
cmds:
|
||||
- "cmake --build build --parallel {{.CMAKE_NUM_THREADS}}"
|
||||
repl:
|
||||
desc: "Start the REPL"
|
||||
preconditions:
|
||||
@@ -83,9 +91,9 @@ tasks:
|
||||
format:
|
||||
desc: "Format code"
|
||||
cmds:
|
||||
- cmd: python ./scripts/cpp/format-includes.py
|
||||
- cmd: python ./scripts/ci/lint-trailing-whitespace.py --fix
|
||||
- cmd: python ./third-party/run-clang-format/run-clang-format.py -r common decompiler game goalc test tools lsp -i
|
||||
- cmd: '{{.PYTHON}} ./scripts/cpp/format-includes.py'
|
||||
- cmd: '{{.PYTHON}} ./scripts/ci/lint-trailing-whitespace.py --fix'
|
||||
- cmd: '{{.PYTHON}} ./third-party/run-clang-format/run-clang-format.py -r common decompiler game goalc test tools lsp -i'
|
||||
- task: format-json
|
||||
format-gsrc:
|
||||
desc: "Run formatter on gsrc file"
|
||||
@@ -103,28 +111,28 @@ tasks:
|
||||
- "{{.DECOMP_BIN_RELEASE_DIR}}/decompiler \"./decompiler/config/{{.DECOMP_CONFIG}}\" \"./iso_data\" \"./decompiler_out\" --version \"{{.DECOMP_CONFIG_VERSION}}\" --config-override '{\"decompile_code\": true, \"levels_extract\": false, \"allowed_objects\": [\"{{.FILE}}\"]}'"
|
||||
decomp-clean:
|
||||
cmds:
|
||||
- python ./scripts/tasks/clean-decomp.py --game "{{.GAME}}"
|
||||
- '{{.PYTHON}} ./scripts/tasks/clean-decomp.py --game "{{.GAME}}"'
|
||||
lint-gsrc-file:
|
||||
cmds:
|
||||
- python ./scripts/gsrc/lint-gsrc-file.py --game {{.GAME}} --file "{{.FILE}}"
|
||||
- '{{.PYTHON}} ./scripts/gsrc/lint-gsrc-file.py --game {{.GAME}} --file "{{.FILE}}"'
|
||||
update-gsrc:
|
||||
cmds:
|
||||
- python ./scripts/gsrc/update-gsrc-via-refs.py --game "{{.GAME}}" --decompiler "{{.DECOMP_BIN_RELEASE_DIR}}/decompiler" --decompiler_config {{.DECOMP_CONFIG}} --version {{.DECOMP_CONFIG_VERSION}}
|
||||
- '{{.PYTHON}} ./scripts/gsrc/update-gsrc-via-refs.py --game "{{.GAME}}" --decompiler "{{.DECOMP_BIN_RELEASE_DIR}}/decompiler" --decompiler_config {{.DECOMP_CONFIG}} --version {{.DECOMP_CONFIG_VERSION}}'
|
||||
update-gsrc-glob:
|
||||
cmds:
|
||||
- python ./scripts/gsrc/update-gsrc-via-refs.py --game "{{.GAME}}" --file_pattern "{{.GLOB}}" --decompiler "{{.DECOMP_BIN_RELEASE_DIR}}/decompiler" --decompiler_config {{.DECOMP_CONFIG}} --version {{.DECOMP_CONFIG_VERSION}}
|
||||
- '{{.PYTHON}} ./scripts/gsrc/update-gsrc-via-refs.py --game "{{.GAME}}" --file_pattern "{{.GLOB}}" --decompiler "{{.DECOMP_BIN_RELEASE_DIR}}/decompiler" --decompiler_config {{.DECOMP_CONFIG}} --version {{.DECOMP_CONFIG_VERSION}}'
|
||||
update-gsrc-file:
|
||||
cmds:
|
||||
- task: decomp-file
|
||||
- python ./scripts/gsrc/update-from-decomp.py --game "{{.GAME}}" --file "{{.FILE}}"
|
||||
- '{{.PYTHON}} ./scripts/gsrc/update-from-decomp.py --game "{{.GAME}}" --file "{{.FILE}}"'
|
||||
- task: lint-gsrc-file
|
||||
copy-common-naming:
|
||||
cmds:
|
||||
- python ./scripts/gsrc/copy-common-naming.py --file "{{.FILE}}" --decompiler "{{.DECOMP_BIN_RELEASE_DIR}}/decompiler"
|
||||
- '{{.PYTHON}} ./scripts/gsrc/copy-common-naming.py --file "{{.FILE}}" --decompiler "{{.DECOMP_BIN_RELEASE_DIR}}/decompiler"'
|
||||
- task: format-json
|
||||
copy-common-naming-from-refs:
|
||||
cmds:
|
||||
- python ./scripts/gsrc/copy-common-naming.py --update-names-from-refs --decompiler "{{.DECOMP_BIN_RELEASE_DIR}}/decompiler"
|
||||
- '{{.PYTHON}} ./scripts/gsrc/copy-common-naming.py --update-names-from-refs --decompiler "{{.DECOMP_BIN_RELEASE_DIR}}/decompiler"'
|
||||
- task: format-json
|
||||
# ASSET RIPPING
|
||||
rip-textures:
|
||||
@@ -139,10 +147,10 @@ tasks:
|
||||
# TOOLS
|
||||
analyze-ee-memory:
|
||||
cmds:
|
||||
- python ./scripts/tasks/extract-zip.py --file "{{.FILE}}" --out ./savestate_out/
|
||||
- '{{.PYTHON}} ./scripts/tasks/extract-zip.py --file "{{.FILE}}" --out ./savestate_out/'
|
||||
- '{{.MEMDUMP_BIN_RELEASE_DIR}}/memory_dump_tool ./savestate_out/eeMemory.bin --output-path ./ --game {{.GAME}} > ee-analysis.log'
|
||||
watch-pcsx2:
|
||||
# python -m pip install -U "watchdog[watchmedo]"
|
||||
# {{.PYTHON}} -m pip install -U "watchdog[watchmedo]"
|
||||
cmds:
|
||||
- watchmedo shell-command --drop --patterns="*.p2s" --recursive --command='task analyze-ee-memory FILE="${watch_src_path}"' "{{.SAVESTATE_DIR}}"
|
||||
vars:
|
||||
@@ -155,15 +163,22 @@ tasks:
|
||||
desc: Updates locally built tree-sitter rules
|
||||
cmds:
|
||||
- cd ../tree-sitter-opengoal && yarn gen
|
||||
- python ./scripts/tasks/cp.py --src "../tree-sitter-opengoal/src/*" --dest "./third-party/tree-sitter/tree-sitter-opengoal"
|
||||
- python ./scripts/tasks/cp.py --src "../tree-sitter-opengoal/grammar.js" --dest "./third-party/tree-sitter/tree-sitter-opengoal"
|
||||
- '{{.PYTHON}} ./scripts/tasks/cp.py --src "../tree-sitter-opengoal/src/*" --dest "./third-party/tree-sitter/tree-sitter-opengoal"'
|
||||
- '{{.PYTHON}} ./scripts/tasks/cp.py --src "../tree-sitter-opengoal/grammar.js" --dest "./third-party/tree-sitter/tree-sitter-opengoal"'
|
||||
fix-translations:
|
||||
desc: Finds and tries to fix invalid translation Characters
|
||||
cmds:
|
||||
- python ./scripts/ci/lint-characters.py --fix
|
||||
- '{{.PYTHON}} ./scripts/ci/lint-characters.py --fix'
|
||||
lint:
|
||||
cmds:
|
||||
- python ./scripts/ci/lint-trailing-whitespace.py
|
||||
- '{{.PYTHON}} ./scripts/ci/lint-trailing-whitespace.py'
|
||||
run-gpu-test:
|
||||
desc: "Runs the game's built in GPU test"
|
||||
preconditions:
|
||||
- sh: test -f {{.GK_BIN_RELEASE_DIR}}/gk{{.EXE_FILE_EXTENSION}}
|
||||
msg: "Couldn't locate runtime executable in '{{.GK_BIN_RELEASE_DIR}}/gk'"
|
||||
cmds:
|
||||
- "{{.GK_BIN_RELEASE_DIR}}/gk -v --gpu-test opengl --gpu-test-out-path ./gpu-test.json"
|
||||
# TESTS
|
||||
offline-tests: # ran by jenkins
|
||||
cmds:
|
||||
@@ -177,17 +192,17 @@ tasks:
|
||||
# TODO - amalgamate offline-tests and this task, run twice if the previous step fails
|
||||
update-ref-tests:
|
||||
cmds:
|
||||
- cmd: python ./scripts/tasks/delete-file-or-folder.py --path failures
|
||||
- cmd: '{{.PYTHON}} ./scripts/tasks/delete-file-or-folder.py --path failures'
|
||||
- cmd: '{{.OFFLINETEST_BIN_RELEASE_DIR}}/offline-test --iso_data_path "./iso_data/{{.GAME}}" --game {{.GAME}} --pretty-print --num_threads 32 --dump_current_output --fail-on-cmp'
|
||||
ignore_error: true
|
||||
- python ./scripts/update_decomp_reference.py ./failures ./test/decompiler/reference/ --game {{.GAME}}
|
||||
- '{{.PYTHON}} ./scripts/update_decomp_reference.py ./failures ./test/decompiler/reference/ --game {{.GAME}}'
|
||||
- task: offline-tests-fast
|
||||
update-ref-file:
|
||||
cmds:
|
||||
- cmd: python ./scripts/tasks/delete-file-or-folder.py --path failures
|
||||
- cmd: '{{.PYTHON}} ./scripts/tasks/delete-file-or-folder.py --path failures'
|
||||
- cmd: '{{.OFFLINETEST_BIN_RELEASE_DIR}}/offline-test --iso_data_path "./iso_data/{{.GAME}}" --file {{.FILE}} --game {{.GAME}} --dump_current_output --fail-on-cmp'
|
||||
ignore_error: true
|
||||
- python ./scripts/update_decomp_reference.py ./failures ./test/decompiler/reference/ --game {{.GAME}}
|
||||
- '{{.PYTHON}} ./scripts/update_decomp_reference.py ./failures ./test/decompiler/reference/ --game {{.GAME}}'
|
||||
- task: offline-test-file
|
||||
type-test:
|
||||
cmds:
|
||||
|
||||
@@ -15,6 +15,13 @@ function(write_revision_h)
|
||||
OUTPUT_VARIABLE GIT_TAG
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
ERROR_QUIET)
|
||||
# To support being on a commit with mutiple tags
|
||||
if(${GIT_TAG} MATCHES "\n")
|
||||
string(REPLACE "\n" ";" GIT_TAG_LIST "${GIT_TAG}")
|
||||
list(LENGTH GIT_TAG_LIST GIT_TAG_LIST_LENGTH)
|
||||
math(EXPR GIT_TAG_LAST_INDEX "${GIT_TAG_LIST_LENGTH} - 1")
|
||||
list(GET GIT_TAG_LIST ${GIT_TAG_LAST_INDEX} GIT_TAG)
|
||||
endif()
|
||||
endif()
|
||||
file(WRITE ${CMAKE_CURRENT_SOURCE_DIR}/versions/revision.h "#define BUILT_TAG \"${GIT_TAG}\"\n#define BUILT_SHA \"${GIT_SHORT_SHA}\"\n")
|
||||
endfunction()
|
||||
@@ -88,6 +95,7 @@ add_library(common
|
||||
util/Timer.cpp
|
||||
util/unicode_util.cpp
|
||||
util/gltf_util.cpp
|
||||
util/image_resize.cpp
|
||||
versions/versions.cpp
|
||||
)
|
||||
|
||||
|
||||
@@ -304,13 +304,15 @@ void TieTree::unpack() {
|
||||
|
||||
for (auto& draw : static_draws) {
|
||||
draw.unpacked.idx_of_first_idx_in_full_buffer = unpacked.indices.size();
|
||||
ASSERT(draw.plain_indices.empty());
|
||||
// indices can come from either runs or already in plain indices.
|
||||
for (auto& run : draw.runs) {
|
||||
for (u32 ri = 0; ri < run.length; ri++) {
|
||||
unpacked.indices.push_back(run.vertex0 + ri);
|
||||
}
|
||||
unpacked.indices.push_back(UINT32_MAX);
|
||||
}
|
||||
unpacked.indices.insert(unpacked.indices.end(), draw.plain_indices.begin(),
|
||||
draw.plain_indices.end());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -406,6 +408,8 @@ void TieTree::serialize(Serializer& ser) {
|
||||
colors.serialize(ser);
|
||||
bvh.serialize(ser);
|
||||
|
||||
ser.from_ptr(&use_strips);
|
||||
|
||||
ser.from_ptr(&has_per_proto_visibility_toggle);
|
||||
ser.from_string_vector(&proto_names);
|
||||
}
|
||||
@@ -850,4 +854,11 @@ std::size_t PreloadedVertex::hash::operator()(const PreloadedVertex& v) const {
|
||||
std::hash<float>()(v.s) ^ std::hash<float>()(v.t) ^ std::hash<u16>()(v.color_index);
|
||||
}
|
||||
|
||||
std::size_t PackedTieVertices::Vertex::hash::operator()(const Vertex& v) const {
|
||||
return std::hash<float>()(v.x) ^ std::hash<float>()(v.y) ^ std::hash<float>()(v.z) ^
|
||||
std::hash<float>()(v.r) ^ std::hash<float>()(v.g) ^ std::hash<float>()(v.b) ^
|
||||
std::hash<float>()(v.a) ^ std::hash<float>()(v.s) ^ std::hash<float>()(v.t) ^
|
||||
std::hash<float>()(v.nx) ^ std::hash<float>()(v.ny) ^ std::hash<float>()(v.nz);
|
||||
}
|
||||
|
||||
} // namespace tfrag3
|
||||
@@ -18,7 +18,7 @@ namespace tfrag3 {
|
||||
// - if changing any large things (vertices, vis, bvh, colors, textures) update get_memory_usage
|
||||
// - if adding a new category to the memory usage, update extract_level to print it.
|
||||
|
||||
constexpr int TFRAG3_VERSION = 41;
|
||||
constexpr int TFRAG3_VERSION = 43;
|
||||
|
||||
enum MemoryUsageCategory {
|
||||
TEXTURE,
|
||||
@@ -116,6 +116,16 @@ struct PackedTieVertices {
|
||||
float s, t;
|
||||
s8 nx, ny, nz;
|
||||
u8 r, g, b, a;
|
||||
|
||||
struct hash {
|
||||
std::size_t operator()(const Vertex& x) const;
|
||||
};
|
||||
|
||||
bool operator==(const Vertex& other) const {
|
||||
return x == other.x && y == other.y && z == other.z && s == other.s && t == other.t &&
|
||||
nx == other.nx && ny == other.ny && nz == other.nz && r == other.r && g == other.g &&
|
||||
b == other.b && a == other.a;
|
||||
}
|
||||
};
|
||||
|
||||
struct MatrixGroup {
|
||||
@@ -231,7 +241,7 @@ struct ShrubDraw {
|
||||
|
||||
struct InstancedStripDraw {
|
||||
DrawMode mode; // the OpenGL draw settings.
|
||||
u32 tree_tex_id = 0; // the texture that should be bound for the draw
|
||||
s32 tree_tex_id = 0; // the texture that should be bound for the draw
|
||||
|
||||
// the list of vertices in the draw. This includes the restart code of UINT32_MAX that OpenGL
|
||||
// will use to start a new strip.
|
||||
@@ -420,6 +430,8 @@ struct TieTree {
|
||||
bool has_per_proto_visibility_toggle = false;
|
||||
std::vector<std::string> proto_names;
|
||||
|
||||
bool use_strips = true;
|
||||
|
||||
struct {
|
||||
std::vector<PreloadedVertex> vertices; // mesh vertices
|
||||
std::vector<u32> indices;
|
||||
|
||||
+1
-1
@@ -37,7 +37,7 @@ struct DmaTag {
|
||||
DmaTag(u64 value) {
|
||||
spr = (value >> 63);
|
||||
addr = (value >> 32) & 0x7fffffff;
|
||||
qwc = value & 0xfff;
|
||||
qwc = value & 0xffff;
|
||||
kind = Kind((value >> 28) & 0b111);
|
||||
}
|
||||
|
||||
|
||||
@@ -143,7 +143,7 @@ void FormatterTree::construct_formatter_tree_recursive(const std::string& source
|
||||
}
|
||||
for (size_t i = 0; i < ts_node_child_count(curr_node); i++) {
|
||||
const auto child_node = ts_node_child(curr_node, i);
|
||||
auto debug_child = ts_node_string(child_node);
|
||||
[[maybe_unused]] auto debug_child = ts_node_string(child_node);
|
||||
const auto contents = get_source_code(source, child_node);
|
||||
bool skip_node = false;
|
||||
for (const auto& skippable_content : skippable_nodes) {
|
||||
|
||||
@@ -168,6 +168,39 @@ static FormFormattingConfig new_deftype_rule(
|
||||
return cfg;
|
||||
}
|
||||
|
||||
static FormFormattingConfig new_defproc_rule(
|
||||
int start_index,
|
||||
int num_columns_to_compute_widths,
|
||||
const std::vector<int>& inlining_preventation_indices) {
|
||||
FormFormattingConfig cfg;
|
||||
cfg.has_constant_pairs = true;
|
||||
cfg.config_set = true;
|
||||
cfg.hang_forms = false;
|
||||
cfg.inline_until_index = [start_index](std::vector<std::string> curr_lines) {
|
||||
// if (curr_lines.size() >= 4 && curr_lines.at(3) == "()") {
|
||||
// return 4;
|
||||
// }
|
||||
return start_index;
|
||||
};
|
||||
for (const auto& index : inlining_preventation_indices) {
|
||||
auto temp_config = std::make_shared<FormFormattingConfig>();
|
||||
temp_config->config_set = true;
|
||||
temp_config->prevent_inlining = true;
|
||||
temp_config->hang_forms = false;
|
||||
temp_config->indentation_width = 1;
|
||||
auto temp_list_config = std::make_shared<FormFormattingConfig>();
|
||||
temp_list_config->force_inline = false;
|
||||
temp_list_config->hang_forms = false;
|
||||
temp_config->default_index_config = temp_list_config;
|
||||
if (index == 3) {
|
||||
temp_config->determine_column_widths_for_list_elements = true;
|
||||
temp_config->num_columns_to_compute_widths = num_columns_to_compute_widths;
|
||||
}
|
||||
cfg.index_configs.emplace(index, temp_config);
|
||||
}
|
||||
return cfg;
|
||||
}
|
||||
|
||||
static FormFormattingConfig new_binding_rule(int form_head_width) {
|
||||
FormFormattingConfig cfg;
|
||||
cfg.config_set = true;
|
||||
@@ -253,6 +286,9 @@ const std::unordered_map<std::string, FormFormattingConfig> opengoal_form_config
|
||||
{"defmethod", new_defmethod_rule(3)},
|
||||
{"lambda", new_lambda_rule(2)},
|
||||
{"deftype", new_deftype_rule(3, 1, {3, 4, 5, 6})},
|
||||
{"defproc", new_defproc_rule(3, 1, {3, 4, 5, 6})},
|
||||
{"suspend-for", new_flow_rule(2)},
|
||||
{"spawn-proc", new_flow_rule(2)},
|
||||
{"defun", new_flow_rule(3)},
|
||||
{"defun-recursive", new_flow_rule(4)},
|
||||
{"defun-debug-recursive", new_flow_rule(4)},
|
||||
@@ -281,12 +317,14 @@ const std::unordered_map<std::string, FormFormattingConfig> opengoal_form_config
|
||||
{"protect", new_binding_rule(4)},
|
||||
{"let*", new_binding_rule(5)},
|
||||
{"rlet", new_binding_rule(5)},
|
||||
{"mlet", new_binding_rule(5)},
|
||||
{"when", new_flow_rule(2)},
|
||||
{"unless", new_flow_rule(2)},
|
||||
{"with-profiler", new_flow_rule(2)},
|
||||
{"with-pc", new_flow_rule(0)},
|
||||
{"#unless", new_flow_rule(2)},
|
||||
{"#when", new_flow_rule(2)},
|
||||
{"#when-game", new_flow_rule(2)},
|
||||
{"countdown", new_flow_rule(2)},
|
||||
{"until", new_flow_rule(2)},
|
||||
{"loop", new_flow_rule(0)},
|
||||
|
||||
@@ -295,7 +295,7 @@ void break_list(Node* node) {
|
||||
}
|
||||
} else if (name == "until" || name == "while" || name == "dotimes" || name == "countdown" ||
|
||||
name == "when" || name == "behavior" || name == "lambda" || name == "defpart" ||
|
||||
name == "define") {
|
||||
name == "define" || name == "suspend-for") {
|
||||
node->top_line_count = 2;
|
||||
} else if (name == "let" || name == "let*" || name == "rlet" ||
|
||||
name == "with-dma-buffer-add-bucket") {
|
||||
@@ -341,9 +341,9 @@ void break_list(Node* node) {
|
||||
|
||||
void insert_required_breaks(const std::vector<Node*>& bfs_order) {
|
||||
const std::unordered_set<std::string> always_break = {
|
||||
"when", "defun-debug", "countdown", "case", "defun", "defmethod", "let",
|
||||
"until", "while", "if", "dotimes", "cond", "else", "defbehavior",
|
||||
"with-pp", "rlet", "defstate", "behavior", "defpart", "loop", "let*"};
|
||||
"when", "defun-debug", "countdown", "case", "defun", "defmethod", "let", "until",
|
||||
"while", "if", "dotimes", "cond", "else", "defbehavior", "with-pp", "rlet",
|
||||
"defstate", "behavior", "defpart", "loop", "let*", "suspend-for"};
|
||||
for (auto node : bfs_order) {
|
||||
if (!node->break_list && node->kind == Node::Kind::LIST &&
|
||||
node->child_nodes.at(0).kind == Node::Kind::ATOM) {
|
||||
|
||||
@@ -369,6 +369,17 @@ struct Matrix {
|
||||
return result;
|
||||
}
|
||||
|
||||
Matrix<T, Rows, Cols> transposed() const {
|
||||
static_assert(Rows == Cols);
|
||||
Matrix<T, Rows, Cols> ret;
|
||||
for (int i = 0; i < Rows; i++) {
|
||||
for (int j = 0; j < Cols; j++) {
|
||||
ret(i, j) = operator()(j, i);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <int OtherCols>
|
||||
Matrix<T, Rows, OtherCols> operator*(const Matrix<T, Cols, OtherCols>& y) const {
|
||||
Matrix<T, Rows, OtherCols> result;
|
||||
|
||||
@@ -49,6 +49,7 @@ struct Config {
|
||||
{KeyBind::Modifier::CTRL, "N", "Full build of the game", "(mi)"}};
|
||||
bool per_game_history = true;
|
||||
bool permissive_redefinitions = false;
|
||||
std::string iso_path;
|
||||
|
||||
int get_nrepl_port() {
|
||||
if (temp_nrepl_port != -1) {
|
||||
|
||||
@@ -43,6 +43,15 @@ void Wrapper::print_welcome_message(const std::vector<std::string>& loaded_proje
|
||||
fmt::format(" Project Path: {}\n",
|
||||
fmt::format(fg(fmt::color::gray), file_util::get_jak_project_dir().string()));
|
||||
message += fmt::format(fmt::emphasis::bold | fg(fmt::color::orange), " - :===: -");
|
||||
std::string effective_iso_path;
|
||||
if (repl_config.iso_path.empty()) {
|
||||
effective_iso_path = file_util::get_file_path({"iso_data"});
|
||||
} else {
|
||||
effective_iso_path = repl_config.iso_path;
|
||||
}
|
||||
message +=
|
||||
fmt::format(" ISO Data Path: {}\n", fmt::format(fg(fmt::color::gray), effective_iso_path));
|
||||
message += fmt::format(fmt::emphasis::bold | fg(fmt::color::orange), " --. .--: :--. .--");
|
||||
message += " nREPL:";
|
||||
if (!nrepl_alive) {
|
||||
message += fmt::format(fg(fmt::color::red), "DISABLED\n");
|
||||
@@ -50,22 +59,21 @@ void Wrapper::print_welcome_message(const std::vector<std::string>& loaded_proje
|
||||
message += fmt::format(fg(fmt::color::light_green), " Listening on {}\n",
|
||||
repl_config.get_nrepl_port());
|
||||
}
|
||||
message += fmt::format(fmt::emphasis::bold | fg(fmt::color::orange), " --. .--: :--. .--");
|
||||
message += fmt::format(fmt::emphasis::bold | fg(fmt::color::orange), " .=======. =======.");
|
||||
message += " Source File Search Dirs: ";
|
||||
const auto search_dir_string =
|
||||
fmt::format("{}", fmt::join(repl_config.asm_file_search_dirs, ","));
|
||||
message += fmt::format("[{}]\n", fmt::format(fg(fmt::color::gray), search_dir_string));
|
||||
message += fmt::format(fmt::emphasis::bold | fg(fmt::color::orange), " .=======. =======.");
|
||||
message += fmt::format(" {} or {} for basic help and usage\n",
|
||||
message += fmt::format(fmt::emphasis::bold | fg(fmt::color::orange), " .-=====-. .-=====-");
|
||||
message += fmt::format(" {} or {} for basic help and usage\n",
|
||||
fmt::format(fg(fmt::color::cyan), "(repl-help)"),
|
||||
fmt::format(fg(fmt::color::cyan), "(repl-keybinds)"));
|
||||
message += fmt::format(fmt::emphasis::bold | fg(fmt::color::orange), " .-=====-. .-=====-");
|
||||
message +=
|
||||
fmt::format(" {} to connect to the game\n", fmt::format(fg(fmt::color::cyan), "(lt)"));
|
||||
message += fmt::format(fmt::emphasis::bold | fg(fmt::color::orange), " .-===========-.");
|
||||
message += fmt::format(" {} to recompile the active project.\n",
|
||||
message +=
|
||||
fmt::format(" {} to connect to the game\n", fmt::format(fg(fmt::color::cyan), "(lt)"));
|
||||
message += fmt::format(fmt::emphasis::bold | fg(fmt::color::orange), " .-===-.");
|
||||
message += fmt::format(" {} to recompile the active project.\n",
|
||||
fmt::format(fg(fmt::color::cyan), "(mi)"));
|
||||
message += fmt::format(fmt::emphasis::bold | fg(fmt::color::orange), " .-===-.\n");
|
||||
message += fmt::format(fmt::emphasis::bold | fg(fmt::color::orange), " .\n");
|
||||
fmt::print("{}", message);
|
||||
}
|
||||
|
||||
@@ -61,7 +61,10 @@ const std::unordered_map<GameVersion, std::vector<std::string>> locale_lookup =
|
||||
{GameVersion::Jak1,
|
||||
{"en-US", "fr-FR", "de-DE", "es-ES", "it-IT", "jp-JP", "en-GB", "pt-PT", "fi-FI", "sv-SE",
|
||||
"da-DK", "no-NO", "nl-NL", "pt-BR", "hu-HU", "ca-ES", "is-IS"}},
|
||||
{GameVersion::Jak2, {"en-US", "fr-FR", "de-DE", "es-ES", "it-IT", "jp-JP", "ko-KR", "en-GB"}}};
|
||||
{GameVersion::Jak2, {"en-US", "fr-FR", "de-DE", "es-ES", "it-IT", "jp-JP", "ko-KR", "en-GB"}},
|
||||
{GameVersion::Jak3,
|
||||
{"en-US", "fr-FR", "de-DE", "es-ES", "it-IT", "cm-CM", "jp-JP", "ko-KR", "ru-RU", "pt-PT",
|
||||
"nl-NL", "en-GB"}}};
|
||||
|
||||
std::string lookup_locale_code(const GameVersion game_version, const int language_id) {
|
||||
if (locale_lookup.find(game_version) == locale_lookup.end() ||
|
||||
@@ -73,7 +76,8 @@ std::string lookup_locale_code(const GameVersion game_version, const int languag
|
||||
|
||||
const std::unordered_map<GameVersion, std::vector<int>> language_ids_with_audio = {
|
||||
{GameVersion::Jak1, {0, 1, 2, 3, 4, 5, 6}},
|
||||
{GameVersion::Jak2, {0, 1, 2, 3, 4, 5, 6, 7}}};
|
||||
{GameVersion::Jak2, {0, 1, 2, 3, 4, 5, 6, 7}},
|
||||
{GameVersion::Jak3, {0, 1, 2, 3, 4, 5, 11}}};
|
||||
|
||||
bool dump_language_with_duplicates_from_base(const GameVersion game_version,
|
||||
const int language_id) {
|
||||
|
||||
@@ -93,6 +93,55 @@ const std::unordered_map<std::string, u16> jak2_speaker_name_to_enum_val = {
|
||||
{"metalkor-before-consite", 35},
|
||||
{"metalkor-intro", 36}};
|
||||
|
||||
// matches enum in `subtitle3-h.gc` with "none" (first) and "max" (last and removed)
|
||||
const std::unordered_map<std::string, u16> jak3_speaker_name_to_enum_val = {
|
||||
{"none", 0},
|
||||
{"jak", 1},
|
||||
{"darkjak", 2},
|
||||
{"daxter", 3},
|
||||
{"pecker", 4},
|
||||
{"ashelin", 5},
|
||||
{"veger", 6},
|
||||
{"samos", 7},
|
||||
{"damas", 8},
|
||||
{"kleiver", 9},
|
||||
{"seem", 10},
|
||||
{"errol", 11},
|
||||
{"errol-hologram", 12},
|
||||
{"sig", 13},
|
||||
{"torn", 14},
|
||||
{"tess", 15},
|
||||
{"guard", 16},
|
||||
{"guard-a", 17},
|
||||
{"guard-b", 18},
|
||||
{"keira", 19},
|
||||
{"vin", 20},
|
||||
{"onin", 21},
|
||||
{"jinx", 22},
|
||||
{"wastelander-male", 23},
|
||||
{"wastelander-female", 24},
|
||||
{"citizen-male", 25},
|
||||
{"citizen-female", 26},
|
||||
{"marauder", 27},
|
||||
{"oracle", 28},
|
||||
{"precursor", 29},
|
||||
{"ottsel-leader", 30},
|
||||
{"ottsel-surfer", 31},
|
||||
{"ottsel-dummy", 32},
|
||||
{"ottsel-veger", 33},
|
||||
{"ottsel-tess", 34},
|
||||
{"computer", 35},
|
||||
{"krew", 36},
|
||||
{"baron", 37},
|
||||
{"scherr", 38},
|
||||
{"arey", 39},
|
||||
{"baldwin", 40},
|
||||
{"schimpf", 41},
|
||||
{"martinsen", 42},
|
||||
{"phillips", 43},
|
||||
{"yates", 44},
|
||||
};
|
||||
|
||||
GameSubtitlePackage read_json_files_v2(const GameSubtitleDefinitionFile& file_info) {
|
||||
GameSubtitlePackage package;
|
||||
SubtitleFile lang_lines;
|
||||
@@ -256,11 +305,21 @@ void GameSubtitleBank::add_scenes_from_files(const GameSubtitlePackage& package)
|
||||
}
|
||||
}
|
||||
|
||||
// TODO - for jak 3+, this needs some game version context info (could infer from text version)
|
||||
std::vector<std::string> GameSubtitleBank::speaker_names_ordered_by_enum_value() {
|
||||
// Create a temporary vector of pairs (key, value)
|
||||
std::vector<std::pair<std::string, u16>> temp_vec(jak2_speaker_name_to_enum_val.begin(),
|
||||
jak2_speaker_name_to_enum_val.end());
|
||||
std::vector<std::pair<std::string, u16>> temp_vec;
|
||||
switch (m_text_version) {
|
||||
case GameTextVersion::JAK2:
|
||||
temp_vec = {jak2_speaker_name_to_enum_val.begin(), jak2_speaker_name_to_enum_val.end()};
|
||||
break;
|
||||
case GameTextVersion::JAK3:
|
||||
temp_vec = {jak3_speaker_name_to_enum_val.begin(), jak3_speaker_name_to_enum_val.end()};
|
||||
break;
|
||||
default:
|
||||
throw std::runtime_error(fmt::format("GameSubtitleBank: invalid game text version {} ({})",
|
||||
(int)m_text_version,
|
||||
get_text_version_name(m_text_version)));
|
||||
}
|
||||
// Sort the temporary vector based on the enum value in ascending order
|
||||
std::sort(temp_vec.begin(), temp_vec.end(),
|
||||
[](const auto& a, const auto& b) { return a.second < b.second; });
|
||||
@@ -279,13 +338,25 @@ std::vector<std::string> GameSubtitleBank::speaker_names_ordered_by_enum_value()
|
||||
}
|
||||
|
||||
u16 GameSubtitleBank::speaker_enum_value_from_name(const std::string& speaker_id) {
|
||||
if (jak2_speaker_name_to_enum_val.find(speaker_id) == jak2_speaker_name_to_enum_val.end()) {
|
||||
std::unordered_map<std::string, u16> enum_map;
|
||||
switch (m_text_version) {
|
||||
case GameTextVersion::JAK2:
|
||||
enum_map = jak2_speaker_name_to_enum_val;
|
||||
break;
|
||||
case GameTextVersion::JAK3:
|
||||
enum_map = jak3_speaker_name_to_enum_val;
|
||||
break;
|
||||
default:
|
||||
throw std::runtime_error(fmt::format("GameSubtitleBank: invalid game text version {}",
|
||||
get_text_version_name(m_text_version)));
|
||||
}
|
||||
if (enum_map.find(speaker_id) == enum_map.end()) {
|
||||
throw std::runtime_error(
|
||||
fmt::format("'{}' speaker could not be found in the enum value mapping, update it or fix "
|
||||
"the invalid speaker!",
|
||||
speaker_id));
|
||||
}
|
||||
return u16(jak2_speaker_name_to_enum_val.at(speaker_id));
|
||||
return u16(enum_map.at(speaker_id));
|
||||
}
|
||||
|
||||
SubtitleMetadataFile dump_bank_meta_v2(const GameVersion game_version,
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
#include "BinaryWriter.h"
|
||||
#include "FileUtil.h"
|
||||
|
||||
#include "common/log/log.h"
|
||||
|
||||
void build_dgo(const DgoDescription& description, const std::string& output_prefix) {
|
||||
BinaryWriter writer;
|
||||
// dgo header
|
||||
@@ -15,8 +17,14 @@ void build_dgo(const DgoDescription& description, const std::string& output_pref
|
||||
writer.add_cstr_len(description.dgo_name.c_str(), 60);
|
||||
|
||||
for (auto& obj : description.entries) {
|
||||
auto obj_data = file_util::read_binary_file(file_util::get_jak_project_dir() / "out" /
|
||||
output_prefix / "obj" / obj.file_name);
|
||||
// Ensure the directory exists
|
||||
const auto file_path =
|
||||
file_util::get_jak_project_dir() / "out" / output_prefix / "obj" / obj.file_name;
|
||||
if (!file_util::file_exists(file_path.string())) {
|
||||
lg::warn("tried to build a DGO with a file that doesn't exist: {}", file_path.string());
|
||||
continue;
|
||||
}
|
||||
auto obj_data = file_util::read_binary_file(file_path);
|
||||
// size
|
||||
writer.add<uint32_t>(obj_data.size());
|
||||
// name
|
||||
@@ -29,6 +37,9 @@ void build_dgo(const DgoDescription& description, const std::string& output_pref
|
||||
}
|
||||
}
|
||||
|
||||
writer.write_to_file(file_util::get_jak_project_dir() / "out" / output_prefix / "iso" /
|
||||
description.dgo_name);
|
||||
// Ensure the output directory exists
|
||||
const auto dgo_path =
|
||||
file_util::get_jak_project_dir() / "out" / output_prefix / "iso" / description.dgo_name;
|
||||
file_util::create_dir_if_needed_for_file(dgo_path);
|
||||
writer.write_to_file(dgo_path);
|
||||
}
|
||||
@@ -1156,6 +1156,25 @@ static std::vector<ReplaceInfo> s_replace_info_jak2 = {
|
||||
"<FLAG_KOREA>"},
|
||||
{"~Y~1L<FLAG_PART_FILL>~]~-1H~Y~1L<FLAG_PART_FILL>~Z~-11H~3L<FLAG_PART_JAPAN_SUN>~Z~+26H",
|
||||
"<FLAG_JAPAN>"},
|
||||
{"~Y~1L<FLAG_PART_FILL>~Z~7L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~7L<FLAG_PART_VERT_STRIPE_RIGHT>~]"
|
||||
"~-1H~Y~1L<FLAG_PART_FILL>~Z~7L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~+26H",
|
||||
"<FLAG_FINLAND>"},
|
||||
{"~Y~7L<FLAG_PART_FILL>~Z~5L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~5L<FLAG_PART_VERT_STRIPE_RIGHT>~]"
|
||||
"~-1H~Y~7L<FLAG_PART_FILL>~Z~5L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~+26H",
|
||||
"<FLAG_SWEDEN>"},
|
||||
{"~Y~3L<FLAG_PART_FILL>~Z~1L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~1L<FLAG_PART_VERT_STRIPE_RIGHT>~]"
|
||||
"~-1H~Y~3L<FLAG_PART_FILL>~Z~1L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~+26H",
|
||||
"<FLAG_DENMARK>"},
|
||||
{"~Y~1L<FLAG_PART_FILL>~Z~3L<FLAG_PART_TOP_BOTTOM_STRIPE>~]~-1H~Y~1L<FLAG_PART_FILL>~Z~3L<FLAG_"
|
||||
"PART_TOP_BOTTOM_STRIPE>~Z~-19H~1L<FLAG_PART_VERT_STRIPE_MIDDLE>~Z~-23H~7L<FLAG_PART_VERT_"
|
||||
"STRIPE_RIGHT>~Z~-23H~7L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~7L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~"
|
||||
"+26H",
|
||||
"<FLAG_NORWAY>"},
|
||||
{"~Y~1L<FLAG_PART_FILL>~Z~7L<FLAG_PART_TOP_BOTTOM_STRIPE>~]~-1H~Y~1L<FLAG_PART_FILL>~Z~7L<FLAG_"
|
||||
"PART_TOP_BOTTOM_STRIPE>~Z~-19H~1L<FLAG_PART_VERT_STRIPE_MIDDLE>~Z~-23H~3L<FLAG_PART_VERT_"
|
||||
"STRIPE_RIGHT>~Z~-23H~3L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~3L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~"
|
||||
"+26H",
|
||||
"<FLAG_ICELAND>"},
|
||||
|
||||
// weird stuff
|
||||
// - descenders
|
||||
|
||||
+313
-21
@@ -1,5 +1,7 @@
|
||||
#include "gltf_util.h"
|
||||
|
||||
#include "image_resize.h"
|
||||
|
||||
#include "common/log/log.h"
|
||||
|
||||
namespace gltf_util {
|
||||
@@ -44,6 +46,20 @@ std::vector<math::Vector<u8, 4>> extract_color_from_vec4_float(const u8* data,
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<math::Vector<u8, 4>> extract_color_from_vec3_float(const u8* data,
|
||||
u32 count,
|
||||
u32 stride) {
|
||||
std::vector<math::Vector<u8, 4>> result;
|
||||
result.reserve(count);
|
||||
for (u32 i = 0; i < count; i++) {
|
||||
math::Vector<float, 3> temp;
|
||||
memcpy(&temp, data, sizeof(math::Vector<float, 3>));
|
||||
data += stride;
|
||||
result.emplace_back(temp.x() * 255, temp.y() * 255, temp.z() * 255, 255);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Convert a GLTF color buffer (u16 format) to u8 colors.
|
||||
*/
|
||||
@@ -61,6 +77,16 @@ std::vector<math::Vector<u8, 4>> extract_color_from_vec4_u16(const u8* data,
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<math::Vector<u8, 4>> extract_color_from_vec4_u8(const u8* data, u32 count, u32 stride) {
|
||||
std::vector<math::Vector<u8, 4>> result;
|
||||
result.reserve(count);
|
||||
for (u32 i = 0; i < count; i++) {
|
||||
result.push_back(math::Vector<u8, 4>(data[0], data[1], data[2], data[3]));
|
||||
data += stride;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Convert a GLTF index buffer
|
||||
*/
|
||||
@@ -92,6 +118,74 @@ std::vector<u32> gltf_index_buffer(const tinygltf::Model& model,
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<math::Matrix4f> extract_mat4(const tinygltf::Model& model, int accessor_idx) {
|
||||
const auto& accessor = model.accessors[accessor_idx];
|
||||
const auto& buffer_view = model.bufferViews[accessor.bufferView];
|
||||
const auto& buffer = model.buffers[buffer_view.buffer];
|
||||
const u8* data_ptr = buffer.data.data() + buffer_view.byteOffset + accessor.byteOffset;
|
||||
const auto stride = accessor.ByteStride(buffer_view);
|
||||
const auto count = accessor.count;
|
||||
|
||||
// ASSERT(buffer_view.target == TINYGLTF_TARGET_ARRAY_BUFFER); // ??
|
||||
ASSERT(accessor.componentType == TINYGLTF_COMPONENT_TYPE_FLOAT);
|
||||
ASSERT(accessor.type == TINYGLTF_TYPE_MAT4);
|
||||
|
||||
std::vector<math::Matrix4f> result(accessor.count);
|
||||
for (size_t x = 0; x < count; x++) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (int j = 0; j < 4; j++) {
|
||||
memcpy(&result[x](j, i), data_ptr + sizeof(float) * (i * 4 + j), sizeof(float));
|
||||
}
|
||||
}
|
||||
data_ptr += stride;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
JointsAndWeights convert_per_vertex_data(const math::Vector4f& weights,
|
||||
const math::Vector<u8, 4>& joints) {
|
||||
int discard_idx = -1;
|
||||
float discard_weight = 100;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (weights[i] < discard_weight) {
|
||||
discard_idx = i;
|
||||
discard_weight = weights[i];
|
||||
}
|
||||
}
|
||||
|
||||
JointsAndWeights ret;
|
||||
int dst = 0;
|
||||
float sum = 0;
|
||||
for (int src = 0; src < 4; src++) {
|
||||
if (src == discard_idx) {
|
||||
continue;
|
||||
}
|
||||
// this +1 is to account for align not existing in the gltf.
|
||||
ret.joints[dst] = joints[src] + 2;
|
||||
ret.weights[dst] = weights[src];
|
||||
sum += ret.weights[dst];
|
||||
dst++;
|
||||
}
|
||||
|
||||
ret.weights /= sum;
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::vector<JointsAndWeights> extract_and_flatten_joints_and_weights(
|
||||
const tinygltf::Model& model,
|
||||
const tinygltf::Primitive& prim) {
|
||||
auto weights =
|
||||
extract_vec<float, 4>(model, prim.attributes.at("WEIGHTS_0"), TINYGLTF_COMPONENT_TYPE_FLOAT);
|
||||
auto joints = extract_vec<u8, 4>(model, prim.attributes.at("JOINTS_0"),
|
||||
TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE);
|
||||
std::vector<JointsAndWeights> ret;
|
||||
ASSERT(weights.size() == joints.size());
|
||||
for (size_t i = 0; i < weights.size(); i++) {
|
||||
ret.push_back(convert_per_vertex_data(weights[i], joints[i]));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Extract positions, colors, and normals from a mesh.
|
||||
*/
|
||||
@@ -148,19 +242,37 @@ ExtractedVertices gltf_vertices(const tinygltf::Model& model,
|
||||
buffer.data.data() + buffer_view.byteOffset + attrib_accessor.byteOffset;
|
||||
const auto byte_stride = attrib_accessor.ByteStride(buffer_view);
|
||||
const auto count = attrib_accessor.count;
|
||||
|
||||
ASSERT_MSG(attrib_accessor.type == TINYGLTF_TYPE_VEC4, "COLOR_0 wasn't vec4");
|
||||
std::vector<math::Vector<u8, 4>> colors;
|
||||
switch (attrib_accessor.componentType) {
|
||||
case TINYGLTF_COMPONENT_TYPE_FLOAT:
|
||||
colors = extract_color_from_vec4_float(data_ptr, count, byte_stride);
|
||||
|
||||
switch (attrib_accessor.type) {
|
||||
case TINYGLTF_TYPE_VEC4:
|
||||
switch (attrib_accessor.componentType) {
|
||||
case TINYGLTF_COMPONENT_TYPE_FLOAT:
|
||||
colors = extract_color_from_vec4_float(data_ptr, count, byte_stride);
|
||||
break;
|
||||
case TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT:
|
||||
colors = extract_color_from_vec4_u16(data_ptr, count, byte_stride);
|
||||
break;
|
||||
case TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE:
|
||||
colors = extract_color_from_vec4_u8(data_ptr, count, byte_stride);
|
||||
break;
|
||||
default:
|
||||
lg::die("Unknown type for COLOR_0: {}", attrib_accessor.componentType);
|
||||
}
|
||||
break;
|
||||
case TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT:
|
||||
colors = extract_color_from_vec4_u16(data_ptr, count, byte_stride);
|
||||
case TINYGLTF_TYPE_VEC3:
|
||||
switch (attrib_accessor.componentType) {
|
||||
case TINYGLTF_COMPONENT_TYPE_FLOAT:
|
||||
colors = extract_color_from_vec3_float(data_ptr, count, byte_stride);
|
||||
break;
|
||||
default:
|
||||
lg::die("unkonwn component type for vec3 color {}", attrib_accessor.componentType);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
lg::die("Unknown component type for COLOR_0: {}", attrib_accessor.componentType);
|
||||
lg::die("unknown attribute type for color {}", attrib_accessor.type);
|
||||
}
|
||||
|
||||
vtx_colors.insert(vtx_colors.end(), colors.begin(), colors.end());
|
||||
}
|
||||
}
|
||||
@@ -213,7 +325,8 @@ ExtractedVertices gltf_vertices(const tinygltf::Model& model,
|
||||
normals = extract_vec3f(data_ptr, count, byte_stride);
|
||||
for (auto& nrm : normals) {
|
||||
math::Vector4f nrm4(nrm.x(), nrm.y(), nrm.z(), 0.f);
|
||||
nrm = (w_T_local * nrm4).xyz();
|
||||
// we found that normals aren't normalized if an object is scaled in blender.
|
||||
nrm = (w_T_local * nrm4).xyz().normalized();
|
||||
}
|
||||
ASSERT(normals.size() == result.size());
|
||||
} else {
|
||||
@@ -277,7 +390,7 @@ int texture_pool_debug_checker(TexturePool* pool) {
|
||||
}
|
||||
}
|
||||
|
||||
int texture_pool_add_texture(TexturePool* pool, const tinygltf::Image& tex) {
|
||||
int texture_pool_add_texture(TexturePool* pool, const tinygltf::Image& tex, int alpha_shift) {
|
||||
const auto& existing = pool->textures_by_name.find(tex.name);
|
||||
if (existing != pool->textures_by_name.end()) {
|
||||
lg::info("Reusing image: {}", tex.name);
|
||||
@@ -302,6 +415,72 @@ int texture_pool_add_texture(TexturePool* pool, const tinygltf::Image& tex) {
|
||||
tt.data.resize(tt.w * tt.h);
|
||||
ASSERT(tex.image.size() >= tt.data.size());
|
||||
memcpy(tt.data.data(), tex.image.data(), tt.data.size() * 4);
|
||||
|
||||
// adjust alpha colors for PS2/PC difference
|
||||
for (auto& color : tt.data) {
|
||||
u32 alpha = color >> 24;
|
||||
alpha >>= alpha_shift;
|
||||
color &= 0xff'ff'ff;
|
||||
color |= (alpha << 24);
|
||||
}
|
||||
return idx;
|
||||
}
|
||||
|
||||
int texture_pool_add_envmap_control_texture(TexturePool* pool,
|
||||
const tinygltf::Model& model,
|
||||
int rgb_image_id,
|
||||
int mr_image_id,
|
||||
bool wrap_w,
|
||||
bool wrap_h) {
|
||||
const auto& existing = pool->envmap_textures_by_gltf_id.find({rgb_image_id, mr_image_id});
|
||||
if (existing != pool->envmap_textures_by_gltf_id.end()) {
|
||||
lg::info("Reusing envmap textures");
|
||||
return existing->second;
|
||||
}
|
||||
const auto& rgb_tex = model.images.at(rgb_image_id);
|
||||
const auto& mr_tex = model.images.at(mr_image_id);
|
||||
lg::info("new envmap texture {} {}", rgb_tex.name, mr_tex.name);
|
||||
ASSERT(rgb_tex.bits == 8);
|
||||
ASSERT(rgb_tex.component == 4);
|
||||
ASSERT(rgb_tex.pixel_type == TINYGLTF_TEXTURE_TYPE_UNSIGNED_BYTE);
|
||||
|
||||
ASSERT(mr_tex.bits == 8);
|
||||
ASSERT(mr_tex.pixel_type == TINYGLTF_TEXTURE_TYPE_UNSIGNED_BYTE);
|
||||
ASSERT(mr_tex.component == 4);
|
||||
|
||||
std::vector<u8> resized_mr_tex;
|
||||
const u8* mr_src;
|
||||
if (rgb_tex.width == mr_tex.width && rgb_tex.height == mr_tex.height) {
|
||||
mr_src = mr_tex.image.data();
|
||||
} else {
|
||||
resized_mr_tex.resize(rgb_tex.width * rgb_tex.height * 4);
|
||||
resize_rgba_image(resized_mr_tex.data(), rgb_tex.width, rgb_tex.height, mr_tex.image.data(),
|
||||
mr_tex.width, mr_tex.height, wrap_w, wrap_h);
|
||||
mr_src = resized_mr_tex.data();
|
||||
}
|
||||
|
||||
size_t idx = pool->textures_by_idx.size();
|
||||
pool->envmap_textures_by_gltf_id[{rgb_image_id, mr_image_id}] = idx;
|
||||
auto& tt = pool->textures_by_idx.emplace_back();
|
||||
tt.w = rgb_tex.width;
|
||||
tt.h = rgb_tex.height;
|
||||
tt.debug_name = rgb_tex.name;
|
||||
tt.debug_tpage_name = "custom-level";
|
||||
tt.load_to_pool = false;
|
||||
tt.combo_id = 0; // doesn't matter, not a pool tex
|
||||
tt.data.resize(tt.w * tt.h);
|
||||
ASSERT(rgb_tex.image.size() >= tt.data.size());
|
||||
memcpy(tt.data.data(), rgb_tex.image.data(), tt.data.size() * 4);
|
||||
|
||||
// adjust alpha from metallic channel
|
||||
for (size_t i = 0; i < tt.data.size(); i++) {
|
||||
u32 rgb = tt.data[i];
|
||||
u32 metal = mr_src[4 * i + 2] / 4;
|
||||
rgb &= 0xff'ff'ff;
|
||||
rgb |= (metal << 24);
|
||||
tt.data[i] = rgb;
|
||||
}
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
@@ -348,6 +527,15 @@ math::Vector4f vector4f_from_gltf(const std::vector<double>& in) {
|
||||
return math::Vector4f{in[0], in[1], in[2], in[3]};
|
||||
}
|
||||
|
||||
math::Matrix4f matrix_from_trs(const math::Vector3f& trans,
|
||||
const math::Vector4f& quat,
|
||||
const math::Vector3f& scale) {
|
||||
math::Matrix4f t = affine_translation(trans);
|
||||
math::Matrix4f r = affine_rot_qxyzw(quat);
|
||||
math::Matrix4f s = affine_scale(scale);
|
||||
return t * r * s;
|
||||
}
|
||||
|
||||
math::Matrix4f matrix_from_node(const tinygltf::Node& node) {
|
||||
if (!node.matrix.empty()) {
|
||||
math::Matrix4f result;
|
||||
@@ -430,22 +618,38 @@ void dedup_vertices(const std::vector<tfrag3::PreloadedVertex>& vertices_in,
|
||||
}
|
||||
}
|
||||
|
||||
DrawMode draw_mode_from_sampler(const tinygltf::Sampler& sampler) {
|
||||
DrawMode mode = make_default_draw_mode();
|
||||
void setup_alpha_from_material(const tinygltf::Material& material, DrawMode* mode) {
|
||||
if (material.alphaMode == "OPAQUE") {
|
||||
mode->disable_ab();
|
||||
} else if (material.alphaMode == "MASK") {
|
||||
mode->enable_at();
|
||||
mode->set_alpha_test(DrawMode::AlphaTest::GEQUAL);
|
||||
mode->set_alpha_fail(GsTest::AlphaFail::KEEP);
|
||||
mode->set_aref(material.alphaCutoff * 127);
|
||||
} else if (material.alphaMode == "BLEND") {
|
||||
mode->enable_ab();
|
||||
mode->set_alpha_blend(DrawMode::AlphaBlend::SRC_DST_SRC_DST);
|
||||
mode->set_depth_write_enable(false);
|
||||
} else {
|
||||
lg::die("Unknown GLTF alphaMode {}", material.alphaMode);
|
||||
}
|
||||
}
|
||||
|
||||
void setup_draw_mode_from_sampler(const tinygltf::Sampler& sampler, DrawMode* mode) {
|
||||
if (sampler.magFilter == TINYGLTF_TEXTURE_FILTER_NEAREST) {
|
||||
ASSERT(sampler.minFilter == TINYGLTF_TEXTURE_FILTER_NEAREST);
|
||||
mode.set_filt_enable(false);
|
||||
ASSERT(sampler.minFilter == TINYGLTF_TEXTURE_FILTER_NEAREST_MIPMAP_NEAREST);
|
||||
mode->set_filt_enable(false);
|
||||
} else {
|
||||
ASSERT(sampler.minFilter != TINYGLTF_TEXTURE_FILTER_NEAREST);
|
||||
mode.set_filt_enable(true);
|
||||
mode->set_filt_enable(true);
|
||||
}
|
||||
|
||||
switch (sampler.wrapS) {
|
||||
case TINYGLTF_TEXTURE_WRAP_CLAMP_TO_EDGE:
|
||||
mode.set_clamp_s_enable(true);
|
||||
mode->set_clamp_s_enable(true);
|
||||
break;
|
||||
case TINYGLTF_TEXTURE_WRAP_REPEAT:
|
||||
mode.set_clamp_s_enable(false);
|
||||
mode->set_clamp_s_enable(false);
|
||||
break;
|
||||
default:
|
||||
ASSERT(false);
|
||||
@@ -453,15 +657,103 @@ DrawMode draw_mode_from_sampler(const tinygltf::Sampler& sampler) {
|
||||
|
||||
switch (sampler.wrapT) {
|
||||
case TINYGLTF_TEXTURE_WRAP_CLAMP_TO_EDGE:
|
||||
mode.set_clamp_t_enable(true);
|
||||
mode->set_clamp_t_enable(true);
|
||||
break;
|
||||
case TINYGLTF_TEXTURE_WRAP_REPEAT:
|
||||
mode.set_clamp_t_enable(false);
|
||||
mode->set_clamp_t_enable(false);
|
||||
break;
|
||||
default:
|
||||
ASSERT(false);
|
||||
}
|
||||
|
||||
return mode;
|
||||
}
|
||||
|
||||
EnvmapSettings envmap_settings_from_gltf(const tinygltf::Material& mat) {
|
||||
EnvmapSettings settings;
|
||||
|
||||
ASSERT(mat.extensions.contains("KHR_materials_specular"));
|
||||
const auto& specular_extension = mat.extensions.at("KHR_materials_specular");
|
||||
ASSERT(specular_extension.Has("specularColorTexture"));
|
||||
|
||||
auto& texture = specular_extension.Get("specularColorTexture");
|
||||
ASSERT(texture.Has("index"));
|
||||
settings.texture_idx = texture.Get("index").Get<int>();
|
||||
return settings;
|
||||
}
|
||||
|
||||
bool material_has_envmap(const tinygltf::Material& mat) {
|
||||
return mat.extensions.contains("KHR_materials_specular");
|
||||
}
|
||||
|
||||
bool envmap_is_valid(const tinygltf::Material& mat) {
|
||||
if (material_has_envmap(mat) && mat.pbrMetallicRoughness.metallicRoughnessTexture.index < 0) {
|
||||
lg::warn(fmt::format(
|
||||
"Material \"{}\" has specular property set, but is missing a metallic roughness texture, "
|
||||
"ignoring envmap!",
|
||||
mat.name));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
std::optional<int> find_single_skin(const tinygltf::Model& model,
|
||||
const std::vector<NodeWithTransform>& all_nodes) {
|
||||
std::optional<int> skin_index;
|
||||
for (const auto& n : all_nodes) {
|
||||
const auto& node = model.nodes.at(n.node_idx);
|
||||
if (node.skin >= 0) {
|
||||
if (skin_index && *skin_index != node.skin) {
|
||||
lg::die("GLTF contains multiple skins, but only one skin per actor is supported.");
|
||||
}
|
||||
skin_index = node.skin;
|
||||
}
|
||||
}
|
||||
return skin_index;
|
||||
}
|
||||
|
||||
int get_joint_count(const tinygltf::Model& model, int skin_idx) {
|
||||
const auto& skin = model.skins.at(skin_idx);
|
||||
return skin.joints.size();
|
||||
}
|
||||
|
||||
std::vector<float> extract_floats(const tinygltf::Model& model, int accessor_idx) {
|
||||
const auto& accessor = model.accessors[accessor_idx];
|
||||
const auto& buffer_view = model.bufferViews[accessor.bufferView];
|
||||
const auto& buffer = model.buffers[buffer_view.buffer];
|
||||
const u8* data_ptr = buffer.data.data() + buffer_view.byteOffset + accessor.byteOffset;
|
||||
const auto stride = accessor.ByteStride(buffer_view);
|
||||
const auto count = accessor.count;
|
||||
|
||||
// ASSERT(buffer_view.target == TINYGLTF_TARGET_ARRAY_BUFFER); // ??
|
||||
if (accessor.componentType != TINYGLTF_COMPONENT_TYPE_FLOAT) {
|
||||
lg::die("mismatched format, wanted {} but got {}", TINYGLTF_COMPONENT_TYPE_FLOAT,
|
||||
accessor.componentType);
|
||||
}
|
||||
ASSERT(accessor.type == TINYGLTF_TYPE_SCALAR);
|
||||
|
||||
std::vector<float> result(accessor.count);
|
||||
for (size_t x = 0; x < count; x++) {
|
||||
memcpy(&result[x], data_ptr, sizeof(float));
|
||||
data_ptr += stride;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::size_t TieFullVertex::hash::operator()(const TieFullVertex& x) const {
|
||||
return tfrag3::PackedTieVertices::Vertex::hash()(x.vertex) ^ std::hash<u16>()(x.color_index);
|
||||
}
|
||||
|
||||
tfrag3::PackedTimeOfDay pack_time_of_day(const std::vector<math::Vector<u8, 4>>& color_palette) {
|
||||
tfrag3::PackedTimeOfDay colors;
|
||||
colors.color_count = (color_palette.size() + 3) & (~3);
|
||||
colors.data.resize(colors.color_count * 8 * 4);
|
||||
for (u32 color_index = 0; color_index < color_palette.size(); color_index++) {
|
||||
for (u32 palette = 0; palette < 8; palette++) {
|
||||
for (u32 channel = 0; channel < 4; channel++) {
|
||||
colors.read(color_index, palette, channel) = color_palette[color_index][channel];
|
||||
}
|
||||
}
|
||||
}
|
||||
return colors;
|
||||
}
|
||||
|
||||
} // namespace gltf_util
|
||||
+117
-5
@@ -1,11 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include "common/common_types.h"
|
||||
#include "common/custom_data/Tfrag3Data.h"
|
||||
#include "common/log/log.h"
|
||||
#include "common/math/Vector.h"
|
||||
|
||||
#include "third-party/tiny_gltf/tiny_gltf.h"
|
||||
@@ -28,10 +30,19 @@ std::vector<u32> index_list_to_u32(const u8* data, u32 num_verts, u32 offset, u3
|
||||
return result;
|
||||
}
|
||||
|
||||
struct JointsAndWeights {
|
||||
math::Vector<u8, 3> joints = math::Vector<u8, 3>::zero();
|
||||
math::Vector<float, 3> weights = math::Vector<float, 3>::zero();
|
||||
};
|
||||
|
||||
std::vector<math::Vector3f> extract_vec3f(const u8* data, u32 count, u32 stride);
|
||||
std::vector<math::Vector2f> extract_vec2f(const u8* data, u32 count, u32 stride);
|
||||
std::vector<math::Vector<u8, 4>> extract_color_from_vec4_u16(const u8* data, u32 count, u32 stride);
|
||||
std::vector<u32> gltf_index_buffer(const tinygltf::Model& model, int indices_idx, u32 index_offset);
|
||||
std::vector<math::Matrix4f> extract_mat4(const tinygltf::Model& model, int accessor_idx);
|
||||
std::vector<JointsAndWeights> extract_and_flatten_joints_and_weights(
|
||||
const tinygltf::Model& model,
|
||||
const tinygltf::Primitive& prim);
|
||||
|
||||
struct ExtractedVertices {
|
||||
std::vector<tfrag3::PreloadedVertex> vtx;
|
||||
@@ -50,9 +61,16 @@ DrawMode make_default_draw_mode();
|
||||
struct TexturePool {
|
||||
std::unordered_map<std::string, int> textures_by_name;
|
||||
std::vector<tfrag3::Texture> textures_by_idx;
|
||||
std::map<std::pair<int, int>, int> envmap_textures_by_gltf_id;
|
||||
};
|
||||
|
||||
int texture_pool_add_texture(TexturePool* pool, const tinygltf::Image& tex);
|
||||
int texture_pool_add_texture(TexturePool* pool, const tinygltf::Image& tex, int alpha_shift = 1);
|
||||
int texture_pool_add_envmap_control_texture(TexturePool* pool,
|
||||
const tinygltf::Model& model,
|
||||
int rgb_image_id,
|
||||
int mr_image_id,
|
||||
bool wrap_w,
|
||||
bool wrap_h);
|
||||
int texture_pool_debug_checker(TexturePool* pool);
|
||||
|
||||
struct NodeWithTransform {
|
||||
@@ -60,12 +78,106 @@ struct NodeWithTransform {
|
||||
math::Matrix4f w_T_node;
|
||||
};
|
||||
|
||||
void dedup_vertices(const std::vector<tfrag3::PreloadedVertex>& vertices_in,
|
||||
std::vector<tfrag3::PreloadedVertex>& vertices_out,
|
||||
std::vector<u32>& old_to_new_out);
|
||||
struct TieFullVertex {
|
||||
tfrag3::PackedTieVertices::Vertex vertex;
|
||||
u16 color_index = 0;
|
||||
struct hash {
|
||||
std::size_t operator()(const TieFullVertex& x) const;
|
||||
};
|
||||
|
||||
bool operator==(const TieFullVertex& other) const {
|
||||
return vertex == other.vertex && color_index == other.color_index;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
void dedup_vertices(const std::vector<T>& vertices_in,
|
||||
std::vector<T>& vertices_out,
|
||||
std::vector<u32>& old_to_new_out) {
|
||||
ASSERT(vertices_out.empty());
|
||||
ASSERT(old_to_new_out.empty());
|
||||
old_to_new_out.resize(vertices_in.size(), -1);
|
||||
|
||||
std::unordered_map<T, u32, typename T::hash> vtx_to_new;
|
||||
|
||||
for (size_t in_idx = 0; in_idx < vertices_in.size(); in_idx++) {
|
||||
auto& vtx = vertices_in[in_idx];
|
||||
const auto& lookup = vtx_to_new.find(vtx);
|
||||
if (lookup == vtx_to_new.end()) {
|
||||
// first time seeing this one
|
||||
size_t new_idx = vertices_out.size();
|
||||
vertices_out.push_back(vtx);
|
||||
old_to_new_out[in_idx] = new_idx;
|
||||
vtx_to_new[vtx] = new_idx;
|
||||
} else {
|
||||
old_to_new_out[in_idx] = lookup->second;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<NodeWithTransform> flatten_nodes_from_all_scenes(const tinygltf::Model& model);
|
||||
|
||||
DrawMode draw_mode_from_sampler(const tinygltf::Sampler& sampler);
|
||||
void setup_alpha_from_material(const tinygltf::Material& material, DrawMode* mode);
|
||||
void setup_draw_mode_from_sampler(const tinygltf::Sampler& sampler, DrawMode* mode);
|
||||
|
||||
struct EnvmapSettings {
|
||||
int texture_idx = -1;
|
||||
};
|
||||
|
||||
EnvmapSettings envmap_settings_from_gltf(const tinygltf::Material& mat);
|
||||
bool material_has_envmap(const tinygltf::Material& mat);
|
||||
bool envmap_is_valid(const tinygltf::Material& mat);
|
||||
|
||||
/*!
|
||||
* Find the index of the skin for this model. Returns nullopt if there is no skin, the index of the
|
||||
* skin if there is a single skin used, or fatal error if there are multiple skins.
|
||||
*/
|
||||
std::optional<int> find_single_skin(const tinygltf::Model& model,
|
||||
const std::vector<NodeWithTransform>& all_nodes);
|
||||
int get_joint_count(const tinygltf::Model& model, int skin_idx);
|
||||
|
||||
template <typename T, int n>
|
||||
std::vector<math::Vector<T, n>> extract_vec(const tinygltf::Model& model,
|
||||
int accessor_idx,
|
||||
int format) {
|
||||
const auto& accessor = model.accessors[accessor_idx];
|
||||
const auto& buffer_view = model.bufferViews[accessor.bufferView];
|
||||
const auto& buffer = model.buffers[buffer_view.buffer];
|
||||
const u8* data_ptr = buffer.data.data() + buffer_view.byteOffset + accessor.byteOffset;
|
||||
const auto stride = accessor.ByteStride(buffer_view);
|
||||
const auto count = accessor.count;
|
||||
|
||||
// ASSERT(buffer_view.target == TINYGLTF_TARGET_ARRAY_BUFFER); // ??
|
||||
if (accessor.componentType != format) {
|
||||
lg::die("mismatched format, wanted {} but got {}", format, accessor.componentType);
|
||||
}
|
||||
ASSERT(accessor.componentType == format);
|
||||
switch (n) {
|
||||
case 3:
|
||||
ASSERT(accessor.type == TINYGLTF_TYPE_VEC3);
|
||||
break;
|
||||
case 4:
|
||||
ASSERT(accessor.type == TINYGLTF_TYPE_VEC4);
|
||||
break;
|
||||
default:
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
|
||||
std::vector<math::Vector<T, n>> result(accessor.count);
|
||||
for (size_t x = 0; x < count; x++) {
|
||||
for (int i = 0; i < n; i++) {
|
||||
memcpy(&result[x][i], data_ptr + sizeof(T) * i, sizeof(T));
|
||||
}
|
||||
data_ptr += stride;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<float> extract_floats(const tinygltf::Model& model, int accessor_idx);
|
||||
math::Matrix4f matrix_from_trs(const math::Vector3f& trans,
|
||||
const math::Vector4f& quat,
|
||||
const math::Vector3f& scale);
|
||||
|
||||
tfrag3::PackedTimeOfDay pack_time_of_day(const std::vector<math::Vector<u8, 4>>& color_palette);
|
||||
|
||||
} // namespace gltf_util
|
||||
@@ -0,0 +1,101 @@
|
||||
#include "image_resize.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include "common/math/Vector.h"
|
||||
|
||||
namespace {
|
||||
struct BilinearSample {
|
||||
int i0, i1;
|
||||
double w0, w1;
|
||||
};
|
||||
|
||||
BilinearSample bilinear(int src_i, double sample, bool wrap) {
|
||||
BilinearSample result;
|
||||
|
||||
const double px_size = 1. / double(src_i);
|
||||
const double px_center_f = (sample - 0.5 * px_size) / px_size;
|
||||
const int px_floor = std::floor(px_center_f);
|
||||
const double frac = px_center_f - double(px_floor);
|
||||
|
||||
if (px_center_f < 0) { // off the bottom
|
||||
if (wrap) {
|
||||
// wrap around!
|
||||
result.i0 = 0;
|
||||
result.i1 = src_i - 1;
|
||||
result.w1 = -px_center_f;
|
||||
result.w0 = 1. - result.w1;
|
||||
} else {
|
||||
// clamp to edge
|
||||
result.i0 = 0;
|
||||
result.i1 = 0;
|
||||
result.w0 = 1;
|
||||
result.w1 = 0;
|
||||
}
|
||||
} else if (px_floor >= (src_i - 1)) { // off the top
|
||||
if (wrap) {
|
||||
result.i0 = src_i - 1;
|
||||
result.i1 = 0;
|
||||
result.w0 = 1. - frac;
|
||||
result.w1 = frac;
|
||||
} else {
|
||||
// clamp
|
||||
result.i0 = src_i - 1;
|
||||
result.i1 = src_i - 1;
|
||||
result.w0 = 1;
|
||||
result.w1 = 0;
|
||||
}
|
||||
} else {
|
||||
result.i0 = px_floor;
|
||||
result.i1 = px_floor + 1;
|
||||
result.w0 = 1. - frac;
|
||||
result.w1 = frac;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
math::Vector4<u8> sample1(const u8* src, int w, int h, int x, int y) {
|
||||
(void)h;
|
||||
int offset = 4 * (y * w + x);
|
||||
return math::Vector4<u8>(src[offset], src[offset + 1], src[offset + 2], src[offset + 3]);
|
||||
}
|
||||
|
||||
math::Vector4<u8> sample_bilinear(const u8* src,
|
||||
int w,
|
||||
int h,
|
||||
const BilinearSample& x,
|
||||
const BilinearSample& y) {
|
||||
auto p00 = sample1(src, w, h, x.i0, y.i0).cast<double>();
|
||||
auto p01 = sample1(src, w, h, x.i0, y.i1).cast<double>();
|
||||
auto p10 = sample1(src, w, h, x.i1, y.i0).cast<double>();
|
||||
auto p11 = sample1(src, w, h, x.i1, y.i1).cast<double>();
|
||||
auto p_interp = (p00 * x.w0 * y.w0 + p01 * x.w0 * y.w1 + p10 * x.w1 * y.w0 + p11 * x.w1 * y.w1);
|
||||
return p_interp.cast<u8>();
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void resize_rgba_image(u8* dst,
|
||||
int dst_w,
|
||||
int dst_h,
|
||||
const u8* src,
|
||||
int src_w,
|
||||
int src_h,
|
||||
bool wrap_w,
|
||||
bool wrap_h) {
|
||||
const double dst_px_h = 1. / dst_h;
|
||||
const double dst_px_w = 1. / dst_w;
|
||||
for (int h = 0; h < dst_h; h++) {
|
||||
const float h_pos = (double(h) + 0.5) * dst_px_h;
|
||||
const auto h_sample = bilinear(src_h, h_pos, wrap_h);
|
||||
for (int w = 0; w < dst_w; w++) {
|
||||
const float w_pos = (double(w) + 0.5) * dst_px_w;
|
||||
const auto w_sample = bilinear(src_w, w_pos, wrap_w);
|
||||
auto result = sample_bilinear(src, src_w, src_h, w_sample, h_sample);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
*dst = result[i];
|
||||
dst++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include "common/common_types.h"
|
||||
|
||||
void resize_rgba_image(u8* dst,
|
||||
int dst_w,
|
||||
int dst_h,
|
||||
const u8* src,
|
||||
int src_w,
|
||||
int src_h,
|
||||
bool wrap_w,
|
||||
bool wrap_h);
|
||||
@@ -3,6 +3,13 @@
|
||||
#include "common/common_types.h"
|
||||
#include "common/log/log.h"
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <stdio.h>
|
||||
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
// clang-format off
|
||||
#define NOMINMAX
|
||||
@@ -104,3 +111,23 @@ void setup_cpu_info() {
|
||||
CpuInfo& get_cpu_info() {
|
||||
return gCpuInfo;
|
||||
}
|
||||
|
||||
std::optional<double> get_macos_version() {
|
||||
#ifndef __APPLE__
|
||||
return {};
|
||||
#else
|
||||
char buffer[128];
|
||||
size_t bufferlen = 128;
|
||||
auto ok = sysctlbyname("kern.osproductversion", &buffer, &bufferlen, NULL, 0);
|
||||
if (ok != 0) {
|
||||
lg::warn("Unable to check for `kern.osproductversion` to determine macOS version");
|
||||
return {};
|
||||
}
|
||||
try {
|
||||
return std::stod(buffer);
|
||||
} catch (std::exception& e) {
|
||||
lg::error("Error occured when attempting to convert sysctl value {} to number", buffer);
|
||||
return {};
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
size_t get_peak_rss();
|
||||
@@ -16,3 +17,5 @@ struct CpuInfo {
|
||||
};
|
||||
|
||||
CpuInfo& get_cpu_info();
|
||||
|
||||
std::optional<double> get_macos_version();
|
||||
@@ -90,6 +90,7 @@ def draw_func_ob(self, context):
|
||||
layout = self.layout
|
||||
ob = context.object
|
||||
layout.prop(ob, "set_invisible")
|
||||
layout.prop(ob, "enable_custom_weights")
|
||||
layout.prop(ob, "set_collision")
|
||||
if (ob.set_collision):
|
||||
layout.prop(ob, "ignore")
|
||||
@@ -116,6 +117,7 @@ def register():
|
||||
|
||||
bpy.types.Object.set_invisible = bpy.props.BoolProperty(name="Invisible")
|
||||
bpy.types.Object.set_collision = bpy.props.BoolProperty(name="Apply Collision Properties")
|
||||
bpy.types.Object.enable_custom_weights = bpy.props.BoolProperty(name="Use Custom Bone Weights")
|
||||
bpy.types.Object.ignore = bpy.props.BoolProperty(name="ignore")
|
||||
bpy.types.Object.noedge = bpy.props.BoolProperty(name="No-Edge")
|
||||
bpy.types.Object.noentity = bpy.props.BoolProperty(name="No-Entity")
|
||||
|
||||
@@ -67,21 +67,60 @@
|
||||
"custom_models": ["test-actor"],
|
||||
|
||||
// Any textures you want to include in your custom level. This is mainly useful for things such as the zoomer HUD,
|
||||
// which is not in the common level files and has no art group associated with it.
|
||||
// sky textures and cases where you want to use objects drawn with the generic renderer,
|
||||
// which also requires you to set a texture remap table and a list of tpages.
|
||||
// To get a list of all the textures, you can extract all of the game's textures
|
||||
// by setting "save_texture_pngs" to true in the decompiler config.
|
||||
// The format is ["tpage-name", "texture-name1", "texture-name2", ...].
|
||||
// If you want all textures from a tpage, you can just do ["tpage-name"].
|
||||
"textures": [
|
||||
// all textures required for the zoomer HUD
|
||||
// "zoomerhud",
|
||||
// "zoomerhud-dial",
|
||||
// "zoomerhud-main-02",
|
||||
// "zoomerhud-main-03",
|
||||
// "zoomerhud-pieslice",
|
||||
// "zoomerhud-heatbg-01",
|
||||
// "zoomerhud-main-03arrow",
|
||||
// "zoomerhud-main-03knob"
|
||||
// Zoomer HUD textures
|
||||
// ["zoomerhud"],
|
||||
// Sandover sky textures
|
||||
["village1-vis-alpha"]
|
||||
],
|
||||
|
||||
// Which vanilla level's texture remap table to use.
|
||||
// This is needed if you want to have proper textures for objects that are drawn using generic, such as
|
||||
// dark eco pools or dying enemies. If you choose to use this,
|
||||
// the order of art groups and tpages in your level's .gd MUST match the vanilla level's for the textures to work.
|
||||
"tex_remap": "village1",
|
||||
|
||||
// Which sky to use for your custom level. This needs to be the name of a vanilla level with sky textures.
|
||||
// Your level's mood update needs to be set up to copy the sky texture (update-mood-default already handles this as an example).
|
||||
// You also need to add a specific tpage to your level .gd depending on the level you chose:
|
||||
// training: tpage-1308.go
|
||||
// village1: tpage-401.go
|
||||
// beach: tpage-215.go
|
||||
// jungle: tpage-388.go
|
||||
// misty: tpage-520.go
|
||||
// firecanyon: tpage-1123.go
|
||||
// village2: tpage-921.go
|
||||
// rolling: tpage-925.go
|
||||
// sunkenb: tpage-162.go
|
||||
// swamp: tpage-630.go
|
||||
// ogre: tpage-1117.go
|
||||
// village3: tpage-1194.go
|
||||
// snow: tpage-712.go
|
||||
// finalboss: tpage-1418.go
|
||||
// The tpage you choose also has to be in the alpha (4th) slot in the "tpages" list below.
|
||||
"sky": "village1",
|
||||
|
||||
// Any texture pages that are added to the level's "texture-ids" array.
|
||||
// These will be logged in and linked as part of level loading.
|
||||
// There are five tpage categories, in this order:
|
||||
// - tfrag
|
||||
// - pris
|
||||
// - shrub
|
||||
// - alpha
|
||||
// - water
|
||||
// This is also (with the exception of levels that use the zoomer) the order that the tpages are listed in in the vanilla .gd files.
|
||||
// You need to also add these to your level .gd as well.
|
||||
// Sky textures use the alpha slot.
|
||||
// If this is empty and "tex_remap" and "sky" are the same level, this will be auto-filled with the tpages from the
|
||||
// corresponding level (check its .gd file for the art group/tpage order to copy over).
|
||||
"tpages": [],
|
||||
|
||||
// Ambients you want to use in your custom level. Ambients can be used for various things like changing the music variation (flava),
|
||||
// adding ambient sounds, level name hints, etc.
|
||||
"ambients": [
|
||||
@@ -97,10 +136,10 @@
|
||||
}
|
||||
],
|
||||
|
||||
"actors" : [
|
||||
"actors": [
|
||||
{
|
||||
"trans": [-21.6238, 20.0496, 17.1191], // translation
|
||||
"etype": "fuel-cell", // actor type
|
||||
"etype": "fuel-cell", // actor type
|
||||
"game_task": "(game-task none)", // associated game task (for powercells, etc)
|
||||
"quat": [0, 0, 0, 1], // quaternion
|
||||
"bsphere": [-21.6238, 19.3496, 17.1191, 10], // bounding sphere
|
||||
@@ -111,11 +150,11 @@
|
||||
},
|
||||
|
||||
{
|
||||
"trans": [-15.2818, 15.2461, 17.1360], // translation
|
||||
"etype": "crate", // actor type
|
||||
"trans": [-15.2818, 15.2461, 17.136], // translation
|
||||
"etype": "crate", // actor type
|
||||
"game_task": "(game-task none)", // associated game task (for powercells, etc)
|
||||
"quat": [0, 0, 0, 1], // quaternion
|
||||
"bsphere": [-15.2818, 15.2461, 17.1360, 10], // bounding sphere
|
||||
"bsphere": [-15.2818, 15.2461, 17.136, 10], // bounding sphere
|
||||
"lump": {
|
||||
"name": "test-crate",
|
||||
"crate-type": "'steel",
|
||||
@@ -124,18 +163,18 @@
|
||||
},
|
||||
|
||||
{
|
||||
"trans": [-5.4630, 17.4553, 1.6169], // translation
|
||||
"etype": "eco-yellow", // actor type
|
||||
"trans": [-5.463, 17.4553, 1.6169], // translation
|
||||
"etype": "eco-yellow", // actor type
|
||||
"game_task": "(game-task none)", // associated game task (for powercells, etc)
|
||||
"quat": [0, 0, 0, 1], // quaternion
|
||||
"bsphere": [-5.4630, 17.4553, 1.6169, 10], // bounding sphere
|
||||
"bsphere": [-5.463, 17.4553, 1.6169, 10], // bounding sphere
|
||||
"lump": {
|
||||
"name": "test-eco"
|
||||
}
|
||||
},
|
||||
{
|
||||
"trans": [-5.41, 3.5, 28.42], // translation
|
||||
"etype": "test-actor", // actor type
|
||||
"etype": "test-actor", // actor type
|
||||
"game_task": 0, // associated game task (for powercells, etc)
|
||||
"quat": [0, 0, 0, 1], // quaternion
|
||||
"bsphere": [-7.41, 3.5, 28.42, 10], // bounding sphere
|
||||
@@ -154,4 +193,4 @@
|
||||
// }
|
||||
// }
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -3,9 +3,14 @@
|
||||
|
||||
;; the actual file name still needs to be 8.3
|
||||
("TSZ.DGO"
|
||||
("static-screen.o"
|
||||
"test-zone-obs.o"
|
||||
("test-zone-obs.o"
|
||||
"tpage-398.go"
|
||||
"tpage-400.go"
|
||||
"tpage-399.go"
|
||||
"tpage-401.go"
|
||||
"tpage-1470.go"
|
||||
"plat-ag.go"
|
||||
"test-actor-ag.go"
|
||||
"test-zone.go"
|
||||
))
|
||||
)
|
||||
)
|
||||
@@ -49,27 +49,29 @@
|
||||
// adds a 'type' tag (using the "symbol" and "string" lump types works the same way):
|
||||
// "spawn-types": ["type", "spyder", "juicer"]
|
||||
|
||||
// The base actor id for your custom level. If you have multiple levels, this should be unique!
|
||||
"base_id": 100,
|
||||
// The base actor id for your custom level. If you have multiple levels, this should be unique!
|
||||
"base_id": 100,
|
||||
|
||||
// All art groups you want to use in your custom level. Will add their models and corresponding textures to the FR3 file.
|
||||
// Removed so that the release builds don't have to double-decompile the game
|
||||
// "art_groups": ["prsn-torture-ag"],
|
||||
|
||||
// Any textures you want to include in your custom level.
|
||||
// This is mainly useful for textures which are not in the common level files and have no art group associated with them.
|
||||
// To get a list of all the textures, you can extract all of the game's textures
|
||||
// by setting "save_texture_pngs" to true in the decompiler config.
|
||||
"textures": [],
|
||||
// Any textures you want to include in your custom level.
|
||||
// This is mainly useful for textures which are not in the common level files and have no art group associated with them.
|
||||
// To get a list of all the textures, you can extract all of the game's textures
|
||||
// by setting "save_texture_pngs" to true in the decompiler config.
|
||||
// The format is ["tpage-name", "texture-name1", "texture-name2", ...].
|
||||
// If you want all textures from a tpage, you can just do ["tpage-name"].
|
||||
"textures": [],
|
||||
|
||||
"actors" : [
|
||||
"actors": [
|
||||
{
|
||||
"trans": [-15.2818, 15.2461, 17.1360], // translation
|
||||
"etype": "crate", // actor type
|
||||
"trans": [-15.2818, 15.2461, 17.136], // translation
|
||||
"etype": "crate", // actor type
|
||||
"game_task": 0, // associated game task (for powercells, etc)
|
||||
"kill_mask": 0,
|
||||
"quat": [0, 0, 0, 1], // quaternion
|
||||
"bsphere": [-15.2818, 15.2461, 17.1360, 10], // bounding sphere
|
||||
"bsphere": [-15.2818, 15.2461, 17.136, 10], // bounding sphere
|
||||
"lump": {
|
||||
"name": "test-crate",
|
||||
"eco-info": ["eco-info", "(pickup-type health)", 2]
|
||||
@@ -77,12 +79,12 @@
|
||||
},
|
||||
|
||||
{
|
||||
"trans": [-5.4630, 17.4553, 1.6169], // translation
|
||||
"etype": "eco-yellow", // actor type
|
||||
"trans": [-5.463, 17.4553, 1.6169], // translation
|
||||
"etype": "eco-yellow", // actor type
|
||||
"game_task": "(game-task none)", // associated game task (for powercells, etc)
|
||||
"kill_mask": 0,
|
||||
"quat": [0, 0, 0, 1], // quaternion
|
||||
"bsphere": [-5.4630, 17.4553, 1.6169, 10], // bounding sphere
|
||||
"bsphere": [-5.463, 17.4553, 1.6169, 10], // bounding sphere
|
||||
"lump": {
|
||||
"name": "test-eco"
|
||||
}
|
||||
@@ -90,7 +92,7 @@
|
||||
|
||||
{
|
||||
"trans": [-7.41, 13.5, 28.42], // translation
|
||||
"etype": "prsn-torture", // actor type
|
||||
"etype": "prsn-torture", // actor type
|
||||
"game_task": "(game-task none)", // associated game task (for powercells, etc)
|
||||
"quat": [0, 0, 0, 1], // quaternion
|
||||
"bsphere": [-7.41, 13.5, 28.42, 10], // bounding sphere
|
||||
@@ -99,4 +101,4 @@
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -49,26 +49,28 @@
|
||||
// adds a 'type' tag (using the "symbol" and "string" lump types works the same way):
|
||||
// "spawn-types": ["type", "spyder", "juicer"]
|
||||
|
||||
// The base actor id for your custom level. If you have multiple levels, this should be unique!
|
||||
"base_id": 100,
|
||||
// The base actor id for your custom level. If you have multiple levels, this should be unique!
|
||||
"base_id": 100,
|
||||
|
||||
// All art groups you want to use in your custom level. Will add their models and corresponding textures to the FR3 file.
|
||||
// "art_groups": [],
|
||||
|
||||
// Any textures you want to include in your custom level.
|
||||
// This is mainly useful for textures which are not in the common level files and have no art group associated with them.
|
||||
// To get a list of all the textures, you can extract all of the game's textures
|
||||
// by setting "save_texture_pngs" to true in the decompiler config.
|
||||
// "textures": [],
|
||||
// Any textures you want to include in your custom level.
|
||||
// This is mainly useful for textures which are not in the common level files and have no art group associated with them.
|
||||
// To get a list of all the textures, you can extract all of the game's textures
|
||||
// by setting "save_texture_pngs" to true in the decompiler config.
|
||||
// The format is ["tpage-name", "texture-name1", "texture-name2", ...].
|
||||
// If you want all textures from a tpage, you can just do ["tpage-name"].
|
||||
"textures": [],
|
||||
|
||||
"actors" : [
|
||||
"actors": [
|
||||
{
|
||||
"trans": [-15.2818, 15.2461, 17.1360], // translation
|
||||
"etype": "crate", // actor type
|
||||
"trans": [-15.2818, 15.2461, 17.136], // translation
|
||||
"etype": "crate", // actor type
|
||||
"game_task": "(game-task none)", // associated game task (for powercells, etc)
|
||||
"kill_mask": 0,
|
||||
"quat": [0, 0, 0, 1], // quaternion
|
||||
"bsphere": [-15.2818, 15.2461, 17.1360, 10], // bounding sphere
|
||||
"bsphere": [-15.2818, 15.2461, 17.136, 10], // bounding sphere
|
||||
"lump": {
|
||||
"name": "test-crate",
|
||||
"eco-info": ["eco-info", "(pickup-type gem)", 1]
|
||||
@@ -76,15 +78,15 @@
|
||||
},
|
||||
|
||||
{
|
||||
"trans": [-5.4630, 17.4553, 1.6169], // translation
|
||||
"etype": "eco-yellow", // actor type
|
||||
"trans": [-5.463, 17.4553, 1.6169], // translation
|
||||
"etype": "eco-yellow", // actor type
|
||||
"game_task": "(game-task none)", // associated game task (for powercells, etc)
|
||||
"kill_mask": 0,
|
||||
"quat": [0, 0, 0, 1], // quaternion
|
||||
"bsphere": [-5.4630, 17.4553, 1.6169, 10], // bounding sphere
|
||||
"bsphere": [-5.463, 17.4553, 1.6169, 10], // bounding sphere
|
||||
"lump": {
|
||||
"name": "test-eco"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -3175,7 +3175,7 @@ goos::Object DefskelgroupElement::ClothParams::to_list(const std::string& ag_nam
|
||||
pretty_print::to_symbol(std::to_string(timestep_freq))}));
|
||||
}
|
||||
if (secret != 0) {
|
||||
auto bits = decompile_bitfield_enum_from_int(TypeSpec("game-secrets"), env.dts->ts, flags);
|
||||
auto bits = decompile_bitfield_enum_from_int(TypeSpec("game-secrets"), env.dts->ts, secret);
|
||||
result.push_back(pretty_print::build_list(
|
||||
{pretty_print::to_symbol("secret-disable"),
|
||||
pretty_print::to_symbol(fmt::format("(game-secrets {})", fmt::join(bits, " ")))}));
|
||||
|
||||
@@ -211,6 +211,13 @@ Matcher Matcher::while_loop(const Matcher& condition, const Matcher& body) {
|
||||
return m;
|
||||
}
|
||||
|
||||
Matcher Matcher::until_loop(const Matcher& condition, const Matcher& body) {
|
||||
Matcher m;
|
||||
m.m_kind = Kind::UNTIL_LOOP;
|
||||
m.m_sub_matchers = {condition, body};
|
||||
return m;
|
||||
}
|
||||
|
||||
Matcher Matcher::any_constant_token(int match_id) {
|
||||
Matcher m;
|
||||
m.m_kind = Kind::ANY_CONSTANT_TOKEN;
|
||||
@@ -671,6 +678,22 @@ bool Matcher::do_match(Form* input, MatchResult::Maps* maps_out, const Env* cons
|
||||
return true;
|
||||
} break;
|
||||
|
||||
case Kind::UNTIL_LOOP: {
|
||||
auto as_until = dynamic_cast<UntilElement*>(input->try_as_single_active_element());
|
||||
if (!as_until) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_sub_matchers.at(0).do_match(as_until->condition, maps_out, env)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_sub_matchers.at(1).do_match(as_until->body, maps_out, env)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} break;
|
||||
|
||||
case Kind::BEGIN: {
|
||||
if ((int)m_sub_matchers.size() != input->size()) {
|
||||
return false;
|
||||
|
||||
@@ -69,6 +69,7 @@ class Matcher {
|
||||
const Matcher& false_case);
|
||||
static Matcher if_no_else(const Matcher& condition, const Matcher& true_case);
|
||||
static Matcher while_loop(const Matcher& condition, const Matcher& body);
|
||||
static Matcher until_loop(const Matcher& condition, const Matcher& body);
|
||||
static Matcher any_constant_token(int match_id = -1);
|
||||
static Matcher constant_token(const std::string& name);
|
||||
static Matcher or_expression(const std::vector<Matcher>& elts);
|
||||
@@ -100,6 +101,7 @@ class Matcher {
|
||||
IF_WITH_ELSE,
|
||||
IF_NO_ELSE,
|
||||
WHILE_LOOP,
|
||||
UNTIL_LOOP,
|
||||
ANY_CONSTANT_TOKEN,
|
||||
CONSTANT_TOKEN,
|
||||
SC_OR,
|
||||
|
||||
@@ -231,10 +231,11 @@ ObjectFileDB::ObjectFileDB(const std::vector<fs::path>& _dgos,
|
||||
StrFileReader reader(obj, version());
|
||||
// name from the file name
|
||||
std::string base_name = obj_filename_to_name(obj.string());
|
||||
ASSERT(reader.chunk_count() == 1);
|
||||
auto name = reader.get_texture_name();
|
||||
add_obj_from_dgo(name, name, reader.get_chunk(0).data(), reader.get_chunk(0).size(),
|
||||
"TEXSPOOL", config, name);
|
||||
for (int i = 0; i < reader.chunk_count(); i++) {
|
||||
auto name = reader.get_chunk_texture_name(i);
|
||||
add_obj_from_dgo(name, name, reader.get_chunk(i).data(), reader.get_chunk(i).size(),
|
||||
"TEXSPOOL", config, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -79,12 +79,14 @@ struct LetRewriteStats {
|
||||
int with_dma_buf_add_bucket = 0;
|
||||
int dma_buffer_add_gs_set = 0;
|
||||
int launch_particles = 0;
|
||||
int call_parent_state_handler = 0;
|
||||
int suspend_for = 0;
|
||||
|
||||
int total() const {
|
||||
return dotimes + countdown + abs + abs2 + unused + ja + case_no_else + case_with_else +
|
||||
set_vector + set_vector2 + send_event + font_context_meth + proc_new + attack_info +
|
||||
vector_dot + rand_float_gen + set_let + with_dma_buf_add_bucket + dma_buffer_add_gs_set +
|
||||
launch_particles;
|
||||
launch_particles + call_parent_state_handler + suspend_for;
|
||||
}
|
||||
|
||||
std::string print() const {
|
||||
@@ -111,6 +113,8 @@ struct LetRewriteStats {
|
||||
out += fmt::format(" with_dma_buf_add_bucket: {}\n", with_dma_buf_add_bucket);
|
||||
out += fmt::format(" dma_buffer_add_gs_set: {}\n", dma_buffer_add_gs_set);
|
||||
out += fmt::format(" launch_particles: {}\n", launch_particles);
|
||||
out += fmt::format(" call_parent_state_handler: {}\n", call_parent_state_handler);
|
||||
out += fmt::format(" suspend_for: {}\n", suspend_for);
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -135,6 +139,8 @@ struct LetRewriteStats {
|
||||
result.set_let = rand_float_gen + other.set_let;
|
||||
result.with_dma_buf_add_bucket = rand_float_gen + other.with_dma_buf_add_bucket;
|
||||
result.launch_particles = launch_particles + other.launch_particles;
|
||||
result.call_parent_state_handler = call_parent_state_handler + other.call_parent_state_handler;
|
||||
result.suspend_for = suspend_for + other.suspend_for;
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -158,6 +164,8 @@ struct LetRewriteStats {
|
||||
set_let += other.set_let;
|
||||
with_dma_buf_add_bucket += other.with_dma_buf_add_bucket;
|
||||
launch_particles += other.launch_particles;
|
||||
call_parent_state_handler += other.call_parent_state_handler;
|
||||
suspend_for += other.suspend_for;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1673,6 +1673,99 @@ FormElement* rewrite_part_tracker_new(const std::string& type,
|
||||
->try_as_single_element();
|
||||
}
|
||||
|
||||
FormElement* rewrite_call_parent_state_handler(LetElement* in, const Env& env, FormPool& pool) {
|
||||
// (let ((t9-3 (-> (find-parent-state) code)))
|
||||
// (if t9-3
|
||||
// ((the-as (function none) t9-3))
|
||||
// )
|
||||
// )
|
||||
auto mr =
|
||||
Matcher::let(false,
|
||||
{LetEntryMatcher::any(Matcher::deref(Matcher::func("find-parent-state", {}),
|
||||
false, {DerefTokenMatcher::any_string(1)}),
|
||||
0)},
|
||||
{Matcher::if_no_else(Matcher::any(), Matcher::any(2))});
|
||||
auto let_mr = match(mr, in);
|
||||
if (!let_mr.matched) {
|
||||
return nullptr;
|
||||
}
|
||||
auto handler = let_mr.maps.strings.at(1);
|
||||
auto valid_handlers = {"enter", "trans", "code", "post"};
|
||||
if (std::find(valid_handlers.begin(), valid_handlers.end(), handler) != valid_handlers.end()) {
|
||||
std::vector<Form*> macro_args;
|
||||
macro_args.push_back(pool.form<ConstantTokenElement>(handler));
|
||||
// there are no examples of this being used with args, so that is not handled for now...
|
||||
// auto func = let_mr.maps.forms.at(2);
|
||||
return pool
|
||||
.form<GenericElement>(GenericOperator::make_function(
|
||||
pool.form<ConstantTokenElement>("call-parent-state-handler")),
|
||||
macro_args)
|
||||
->try_as_single_element();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
FormElement* rewrite_suspend_for(LetElement* in, const Env& env, FormPool& pool) {
|
||||
// (let ((gp-1 (current-time)))
|
||||
// (until (time-elapsed? gp-1 (seconds 0.5))
|
||||
// (suspend)
|
||||
// )
|
||||
// )
|
||||
// ->
|
||||
// (suspend-for (seconds 0.5))
|
||||
auto until = dynamic_cast<UntilElement*>(in->body()->at(0));
|
||||
if (!until) {
|
||||
return nullptr;
|
||||
}
|
||||
auto mr = Matcher::let(
|
||||
false, {LetEntryMatcher::any(Matcher::func("current-time", {}), 0)},
|
||||
{Matcher::until_loop(Matcher::func("time-elapsed?", {Matcher::any_reg(1), Matcher::any(2)}),
|
||||
Matcher::any(3))});
|
||||
auto let_mr = match(mr, in);
|
||||
if (!let_mr.matched) {
|
||||
return nullptr;
|
||||
}
|
||||
auto var = let_mr.maps.regs.at(1);
|
||||
auto time = let_mr.maps.forms.at(2);
|
||||
auto body = let_mr.maps.forms.at(3);
|
||||
std::vector<Form*> macro_args;
|
||||
std::vector<FormElement*> macro_elts;
|
||||
macro_args.push_back(time);
|
||||
for (auto& elt : body->elts()) {
|
||||
auto op = dynamic_cast<AtomicOpElement*>(elt);
|
||||
auto suspend = op && op->op() && dynamic_cast<SpecialOp*>(op->op()) &&
|
||||
dynamic_cast<SpecialOp*>(op->op())->kind() == SpecialOp::Kind::SUSPEND;
|
||||
if (!suspend || elt != body->elts().back()) {
|
||||
elt->apply_form([&](Form* form) {
|
||||
for (auto& e : form->elts()) {
|
||||
auto as_expr = dynamic_cast<SimpleExpressionElement*>(e);
|
||||
if (as_expr) {
|
||||
RegAccessSet regs;
|
||||
as_expr->collect_vars(regs, false);
|
||||
for (auto reg : regs) {
|
||||
if (reg.to_string(env, RegisterAccess::Print::AS_VARIABLE) ==
|
||||
var.value().to_string(env, RegisterAccess::Print::AS_VARIABLE)) {
|
||||
e = pool.alloc_element<ConstantTokenElement>("time");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
macro_elts.push_back(elt);
|
||||
}
|
||||
}
|
||||
if (!macro_elts.empty()) {
|
||||
for (auto elt : macro_elts) {
|
||||
macro_args.push_back(pool.alloc_single_form(nullptr, elt));
|
||||
}
|
||||
}
|
||||
return pool
|
||||
.form<GenericElement>(
|
||||
GenericOperator::make_function(pool.form<ConstantTokenElement>("suspend-for")),
|
||||
macro_args)
|
||||
->try_as_single_element();
|
||||
}
|
||||
|
||||
FormElement* rewrite_proc_new(LetElement* in, const Env& env, FormPool& pool) {
|
||||
// this function checks for the process-spawn macros.
|
||||
// it uses recursive form scanning to wrap the macro inside a potential "shell"
|
||||
@@ -2185,6 +2278,12 @@ FormElement* rewrite_let(LetElement* in, const Env& env, FormPool& pool, LetRewr
|
||||
return as_set_vector3;
|
||||
}
|
||||
|
||||
auto suspend_for = rewrite_suspend_for(in, env, pool);
|
||||
if (suspend_for) {
|
||||
stats.suspend_for++;
|
||||
return suspend_for;
|
||||
}
|
||||
|
||||
auto as_abs_2 = fix_up_abs_2(in, env, pool);
|
||||
if (as_abs_2) {
|
||||
stats.abs2++;
|
||||
@@ -2215,6 +2314,12 @@ FormElement* rewrite_let(LetElement* in, const Env& env, FormPool& pool, LetRewr
|
||||
return as_attack_info;
|
||||
}
|
||||
|
||||
auto as_call_parent_state = rewrite_call_parent_state_handler(in, env, pool);
|
||||
if (as_call_parent_state) {
|
||||
stats.call_parent_state_handler++;
|
||||
return as_call_parent_state;
|
||||
}
|
||||
|
||||
// nothing matched.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -287,25 +287,41 @@
|
||||
)
|
||||
|
||||
(defenum pad-buttons
|
||||
:bitfield #t
|
||||
:type uint32
|
||||
(select 0)
|
||||
(l3 1)
|
||||
(r3 2)
|
||||
(start 3)
|
||||
(up 4)
|
||||
(right 5)
|
||||
(down 6)
|
||||
(left 7)
|
||||
(l2 8)
|
||||
(r2 9)
|
||||
(l1 10)
|
||||
(r1 11)
|
||||
(triangle 12)
|
||||
(circle 13)
|
||||
(x 14)
|
||||
(square 15)
|
||||
)
|
||||
:bitfield #t
|
||||
:type uint32
|
||||
(select 0)
|
||||
(l3 1)
|
||||
(r3 2)
|
||||
(start 3)
|
||||
(up 4)
|
||||
(right 5)
|
||||
(down 6)
|
||||
(left 7)
|
||||
(l2 8)
|
||||
(r2 9)
|
||||
(l1 10)
|
||||
(r1 11)
|
||||
(triangle 12)
|
||||
(circle 13)
|
||||
(x 14)
|
||||
(square 15)
|
||||
)
|
||||
|
||||
(defenum abutton-idx
|
||||
:type uint8
|
||||
(right 0)
|
||||
(left 1)
|
||||
(up 2)
|
||||
(down 3)
|
||||
(triangle 4)
|
||||
(circle 5)
|
||||
(x 6)
|
||||
(square 7)
|
||||
(l1 8)
|
||||
(r1 9)
|
||||
(l2 10)
|
||||
(r2 11)
|
||||
)
|
||||
|
||||
(defenum gs-psm
|
||||
:bitfield #f
|
||||
@@ -19612,6 +19628,57 @@
|
||||
(wt31)
|
||||
)
|
||||
|
||||
(defenum water-look
|
||||
(water-anim-sunken-big-room 0)
|
||||
(water-anim-sunken-first-room-from-entrance 1)
|
||||
(water-anim-sunken-qbert-room 2)
|
||||
(water-anim-sunken-first-right-branch 3)
|
||||
(water-anim-sunken-circular-with-bullys 4)
|
||||
(water-anim-sunken-hall-with-one-whirlpool 5)
|
||||
(water-anim-sunken-hall-with-three-whirlpools 6)
|
||||
(water-anim-sunken-start-of-helix-slide 7)
|
||||
(water-anim-sunken-room-above-exit-chamber 8)
|
||||
(water-anim-sunken-hall-before-big-room 9)
|
||||
(water-anim-sunken-dark-eco-qbert 10)
|
||||
(water-anim-sunken-short-piece 11)
|
||||
(water-anim-sunken-big-room-upper-water 12)
|
||||
(water-anim-sunken-dark-eco-platform-room 13)
|
||||
(water-anim-maincave-water-with-crystal 14)
|
||||
(water-anim-maincave-center-pool 15)
|
||||
(water-anim-maincave-lower-right-pool 16)
|
||||
(water-anim-maincave-mid-right-pool 17)
|
||||
(water-anim-maincave-lower-left-pool 18)
|
||||
(water-anim-maincave-mid-left-pool 19)
|
||||
(water-anim-robocave-main-pool 20)
|
||||
(water-anim-misty-mud-by-arena 21)
|
||||
(water-anim-misty-mud-above-skeleton 22)
|
||||
(water-anim-misty-mud-behind-skeleton 23)
|
||||
(water-anim-misty-mud-above-skull-back 24)
|
||||
(water-anim-misty-mud-above-skull-front 25)
|
||||
(water-anim-misty-mud-other-near-skull 26)
|
||||
(water-anim-misty-mud-near-skull 27)
|
||||
(water-anim-misty-mud-under-spine 28)
|
||||
(water-anim-misty-mud-by-dock 29)
|
||||
(water-anim-misty-mud-island-near-dock 30)
|
||||
(water-anim-misty-mud-lonely-island 31)
|
||||
(water-anim-misty-dark-eco-pool 32)
|
||||
(water-anim-ogre-lava 33)
|
||||
(water-anim-jungle-river 34)
|
||||
(water-anim-village3-lava 35)
|
||||
(water-anim-training-lake 36)
|
||||
(water-anim-darkcave-water-with-crystal 37)
|
||||
(water-anim-rolling-water-back 38)
|
||||
(water-anim-rolling-water-front 39)
|
||||
(water-anim-sunken-dark-eco-helix-room 40)
|
||||
(water-anim-finalboss-dark-eco-pool 41)
|
||||
(water-anim-lavatube-energy-lava 42)
|
||||
(water-anim-village1-rice-paddy 43)
|
||||
(water-anim-village1-fountain 44)
|
||||
(water-anim-village1-rice-paddy-mid 45)
|
||||
(water-anim-village1-rice-paddy-top 46)
|
||||
(water-anim-village2-bucket 47)
|
||||
)
|
||||
|
||||
(deftype water-control (basic)
|
||||
((flags water-flags :offset-assert 4)
|
||||
(process process-drawable :offset-assert 8)
|
||||
|
||||
@@ -1 +1 @@
|
||||
[]
|
||||
[[2147418112,{"idx":0,"name":"placeholder-white","tpage_name":"placeholder"}],[105447426,{"idx":2,"name":"demo5cj","tpage_name":"demo5j"}],[105447425,{"idx":1,"name":"demo5bj","tpage_name":"demo5j"}],[105447424,{"idx":0,"name":"demo5aj","tpage_name":"demo5j"}],[105316354,{"idx":2,"name":"demo4cs","tpage_name":"demo4s"}],[105316353,{"idx":1,"name":"demo4bs","tpage_name":"demo4s"}],[105316352,{"idx":0,"name":"demo4as","tpage_name":"demo4s"}],[105250818,{"idx":2,"name":"demo4ci","tpage_name":"demo4i"}],[105250817,{"idx":1,"name":"demo4bi","tpage_name":"demo4i"}],[105250816,{"idx":0,"name":"demo4ai","tpage_name":"demo4i"}],[105119746,{"idx":2,"name":"demo4cf","tpage_name":"demo4f"}],[105119745,{"idx":1,"name":"demo4bf","tpage_name":"demo4f"}],[105119744,{"idx":0,"name":"demo4af","tpage_name":"demo4f"}],[104988674,{"idx":2,"name":"demo2cs","tpage_name":"demo2s"}],[104988673,{"idx":1,"name":"demo2bs","tpage_name":"demo2s"}],[104988672,{"idx":0,"name":"demo2as","tpage_name":"demo2s"}],[104923138,{"idx":2,"name":"demo2ci","tpage_name":"demo2i"}],[104923137,{"idx":1,"name":"demo2bi","tpage_name":"demo2i"}],[104923136,{"idx":0,"name":"demo2ai","tpage_name":"demo2i"}],[100401161,{"idx":9,"name":"sk-eye-lid","tpage_name":"sidekick-lod0"}],[100401160,{"idx":8,"name":"e-white-alpha","tpage_name":"sidekick-lod0"}],[100401159,{"idx":7,"name":"sk-armfur","tpage_name":"sidekick-lod0"}],[98238464,{"idx":0,"name":"logo-flare","tpage_name":"title-vis-water"}],[97386498,{"idx":2,"name":"demo3c","tpage_name":"demo3"}],[97386497,{"idx":1,"name":"demo3b","tpage_name":"demo3"}],[97320962,{"idx":2,"name":"demo2c","tpage_name":"demo2"}],[97320961,{"idx":1,"name":"demo2b","tpage_name":"demo2"}],[97320960,{"idx":0,"name":"demo2a","tpage_name":"demo2"}],[96927748,{"idx":4,"name":"vil1-sky-03","tpage_name":"demo-vis-alpha"}],[96927747,{"idx":3,"name":"vil1-sky-02","tpage_name":"demo-vis-alpha"}],[96927746,{"idx":2,"name":"vil1-sky-01","tpage_name":"demo-vis-alpha"}],[96927745,{"idx":1,"name":"vil1-sky-00","tpage_name":"demo-vis-alpha"}],[96927744,{"idx":0,"name":"vil1-clouds","tpage_name":"demo-vis-alpha"}],[96731136,{"idx":0,"name":"cv-water","tpage_name":"village2-vis-water"}],[95485988,{"idx":36,"name":"vest-01","tpage_name":"intro-vis-pris"}],[95485987,{"idx":35,"name":"hair-01","tpage_name":"intro-vis-pris"}],[95485986,{"idx":34,"name":"farmer-teeth","tpage_name":"intro-vis-pris"}],[95485985,{"idx":33,"name":"esskin","tpage_name":"intro-vis-pris"}],[95485984,{"idx":32,"name":"espants-02","tpage_name":"intro-vis-pris"}],[95485983,{"idx":31,"name":"espants-01","tpage_name":"intro-vis-pris"}],[95485981,{"idx":29,"name":"eseyebrow","tpage_name":"intro-vis-pris"}],[95485980,{"idx":28,"name":"eseye","tpage_name":"intro-vis-pris"}],[95485979,{"idx":27,"name":"evilbro-eyelid","tpage_name":"intro-vis-pris"}],[95485978,{"idx":26,"name":"esbelly-01","tpage_name":"intro-vis-pris"}],[95485977,{"idx":25,"name":"es-precursor-metal-01","tpage_name":"intro-vis-pris"}],[95485976,{"idx":24,"name":"es-green-metal","tpage_name":"intro-vis-pris"}],[95485975,{"idx":23,"name":"ogre-envmap","tpage_name":"intro-vis-pris"}],[95485974,{"idx":22,"name":"evilbro-wrap","tpage_name":"intro-vis-pris"}],[95485973,{"idx":21,"name":"evilbro-teeth","tpage_name":"intro-vis-pris"}],[95485972,{"idx":20,"name":"evilbro-strap","tpage_name":"intro-vis-pris"}],[95485971,{"idx":19,"name":"evilbro-rings","tpage_name":"intro-vis-pris"}],[95485970,{"idx":18,"name":"evilbro-redcape","tpage_name":"intro-vis-pris"}],[95485969,{"idx":17,"name":"evilbro-pipes","tpage_name":"intro-vis-pris"}],[95485968,{"idx":16,"name":"evilbro-pants","tpage_name":"intro-vis-pris"}],[95485967,{"idx":15,"name":"evilbro-mechglove-02","tpage_name":"intro-vis-pris"}],[95485966,{"idx":14,"name":"evilbro-mechglove-01","tpage_name":"intro-vis-pris"}],[95485965,{"idx":13,"name":"evilbro-mecharm-03","tpage_name":"intro-vis-pris"}],[95485964,{"idx":12,"name":"evilbro-mecharm-02","tpage_name":"intro-vis-pris"}],[95485962,{"idx":10,"name":"evilbro-hair-01","tpage_name":"intro-vis-pris"}],[95485961,{"idx":9,"name":"evilbro-flesh","tpage_name":"intro-vis-pris"}],[95485959,{"idx":7,"name":"evilbro-envmap","tpage_name":"intro-vis-pris"}],[95485958,{"idx":6,"name":"evilbro-chin","tpage_name":"intro-vis-pris"}],[95485957,{"idx":5,"name":"evilbro-brownleather","tpage_name":"intro-vis-pris"}],[95485956,{"idx":4,"name":"evilbro-blueleather-02","tpage_name":"intro-vis-pris"}],[95485955,{"idx":3,"name":"evilbro-blueleather-01","tpage_name":"intro-vis-pris"}],[95485954,{"idx":2,"name":"evilbro-belt","tpage_name":"intro-vis-pris"}],[95485953,{"idx":1,"name":"evilbro-beard","tpage_name":"intro-vis-pris"}],[95485952,{"idx":0,"name":"evilbro-balls","tpage_name":"intro-vis-pris"}],[95354886,{"idx":6,"name":"mis-rockwall-trim","tpage_name":"intro-vis-tfrag"}],[95354885,{"idx":5,"name":"mis-ground","tpage_name":"intro-vis-tfrag"}],[95354884,{"idx":4,"name":"mis-tree","tpage_name":"intro-vis-tfrag"}],[95354883,{"idx":3,"name":"mis-boLine truncated
|
||||
@@ -52,14 +52,28 @@
|
||||
|
||||
(defenum language-enum
|
||||
:type int64
|
||||
(english)
|
||||
(french)
|
||||
(german)
|
||||
(spanish)
|
||||
(italian)
|
||||
(japanese)
|
||||
(korean)
|
||||
(uk-english)
|
||||
(english 0)
|
||||
(french 1)
|
||||
(german 2)
|
||||
(spanish 3)
|
||||
(italian 4)
|
||||
(japanese 5)
|
||||
(korean 6)
|
||||
(uk-english 7)
|
||||
;; custom
|
||||
(portuguese 8)
|
||||
(finnish 9)
|
||||
(swedish 10)
|
||||
(danish 11)
|
||||
(norwegian 12)
|
||||
(dutch 13)
|
||||
(br-portuguese 14)
|
||||
(hungarian 15)
|
||||
(catalan 16)
|
||||
(icelandic 17)
|
||||
(russian 18)
|
||||
(polish 19)
|
||||
(lithuanian 20)
|
||||
)
|
||||
|
||||
(defenum runtime-exit-status
|
||||
@@ -4188,6 +4202,22 @@ and the state of the VU memory buffers at the end of the bucket."
|
||||
(confirm 24)
|
||||
)
|
||||
|
||||
(defenum abutton-idx
|
||||
:type uint8
|
||||
(right 0)
|
||||
(left 1)
|
||||
(up 2)
|
||||
(down 3)
|
||||
(triangle 4)
|
||||
(circle 5)
|
||||
(x 6)
|
||||
(square 7)
|
||||
(l1 8)
|
||||
(r1 9)
|
||||
(l2 10)
|
||||
(r2 11)
|
||||
)
|
||||
|
||||
(defenum mouse-buttons
|
||||
:bitfield #t
|
||||
:type uint32
|
||||
@@ -8787,6 +8817,8 @@ Unlike [[engine]], users can use [[engine-pers]] as a parent class."
|
||||
(progress-graphics-ps2-lod-dist #x1337)
|
||||
(progress-graphics-msaa-off #x1338)
|
||||
(progress-graphics-display #x1339)
|
||||
(language-name-finnish #x133a)
|
||||
(progress-hint-subtitles #x133b)
|
||||
)
|
||||
;; ---text-id-h:text-id
|
||||
|
||||
@@ -9433,18 +9465,6 @@ Unlike [[engine]], users can use [[engine-pers]] as a parent class."
|
||||
;; settings-h ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(defenum language-enum
|
||||
:type int64
|
||||
(english)
|
||||
(french)
|
||||
(german)
|
||||
(spanish)
|
||||
(italian)
|
||||
(japanese)
|
||||
(korean)
|
||||
(uk-english)
|
||||
)
|
||||
|
||||
(defenum game-feature
|
||||
:type uint64
|
||||
:bitfield #t
|
||||
|
||||
@@ -1 +1 @@
|
||||
[]
|
||||
[[232521729,{"idx":1,"name":"dig-shrub-pebbles","tpage_name":"dig3b-vis-shrub"}],[232521728,{"idx":0,"name":"dig-rock-shrubs","tpage_name":"dig3b-vis-shrub"}],[230227972,{"idx":4,"name":"firework-mini-glow-orange","tpage_name":"outrocst-sprite"}],[230227971,{"idx":3,"name":"firework-dust-grey","tpage_name":"outrocst-sprite"}],[230227970,{"idx":2,"name":"firework-mini-glow-grey","tpage_name":"outrocst-sprite"}],[230227969,{"idx":1,"name":"firework-mini-glow","tpage_name":"outrocst-sprite"}],[230227968,{"idx":0,"name":"firework-dust","tpage_name":"outrocst-sprite"}],[229244928,{"idx":0,"name":"cpad-grass-fringe","tpage_name":"caspad-vis-alpha"}],[227999746,{"idx":2,"name":"sew-mar-ruby-env","tpage_name":"sewer-warp"}],[226623489,{"idx":1,"name":"explosion","tpage_name":"casboss-sprite"}],[226623488,{"idx":0,"name":"cboss-green-lightning-01","tpage_name":"casboss-sprite"}],[226164805,{"idx":69,"name":"stdmc-yellow-light-02","tpage_name":"stadiumb-vis-tfrag"}],[226164804,{"idx":68,"name":"stdmc-yellow-light-01","tpage_name":"stadiumb-vis-tfrag"}],[226164803,{"idx":67,"name":"stdmb-redlight-02","tpage_name":"stadiumb-vis-tfrag"}],[226164801,{"idx":65,"name":"race-hatch-side-01","tpage_name":"stadiumb-vis-tfrag"}],[226164800,{"idx":64,"name":"stdmb-pipe-04a","tpage_name":"stadiumb-vis-tfrag"}],[226164799,{"idx":63,"name":"stdmb-blastdoors-ramp","tpage_name":"stadiumb-vis-tfrag"}],[226164798,{"idx":62,"name":"stdmb-green-grill-light-02","tpage_name":"stadiumb-vis-tfrag"}],[226164797,{"idx":61,"name":"stdmb-floor-01","tpage_name":"stadiumb-vis-tfrag"}],[226164796,{"idx":60,"name":"stdmb-startline","tpage_name":"stadiumb-vis-tfrag"}],[226164795,{"idx":59,"name":"stdmb-green-grill-light-01-hitweak","tpage_name":"stadiumb-vis-tfrag"}],[226164794,{"idx":58,"name":"stdmb-pillar-01-hitweak","tpage_name":"stadiumb-vis-tfrag"}],[226164793,{"idx":57,"name":"stdmb-trim-02","tpage_name":"stadiumb-vis-tfrag"}],[226164792,{"idx":56,"name":"stdmb-arena-floor","tpage_name":"stadiumb-vis-tfrag"}],[226164791,{"idx":55,"name":"stdmb-forcefield-light-02","tpage_name":"stadiumb-vis-tfrag"}],[226164790,{"idx":54,"name":"stdmb-panel-10","tpage_name":"stadiumb-vis-tfrag"}],[226164789,{"idx":53,"name":"stdmb-honeycomb-glow-01","tpage_name":"stadiumb-vis-tfrag"}],[226164788,{"idx":52,"name":"stdmb-road-side-02","tpage_name":"stadiumb-vis-tfrag"}],[226164787,{"idx":51,"name":"stdmb-redstripe","tpage_name":"stadiumb-vis-tfrag"}],[226164786,{"idx":50,"name":"stdmb-shaft-rim-01","tpage_name":"stadiumb-vis-tfrag"}],[226164785,{"idx":49,"name":"stdmb-wall-01","tpage_name":"stadiumb-vis-tfrag"}],[226164784,{"idx":48,"name":"stdmb-track-01","tpage_name":"stadiumb-vis-tfrag"}],[226164783,{"idx":47,"name":"stdmb-track-02","tpage_name":"stadiumb-vis-tfrag"}],[226164782,{"idx":46,"name":"stdmb-roof-01","tpage_name":"stadiumb-vis-tfrag"}],[226164781,{"idx":45,"name":"stdmb-slope-metal","tpage_name":"stadiumb-vis-tfrag"}],[226164780,{"idx":44,"name":"stdmb-tech-walls","tpage_name":"stadiumb-vis-tfrag"}],[226164779,{"idx":43,"name":"stdmb-sign-glow-blue","tpage_name":"stadiumb-vis-tfrag"}],[226164778,{"idx":42,"name":"stdmb-rail-02","tpage_name":"stadiumb-vis-tfrag"}],[226164777,{"idx":41,"name":"stdmb-pipe-04","tpage_name":"stadiumb-vis-tfrag"}],[226164776,{"idx":40,"name":"stdmb-pipe-ring-02","tpage_name":"stadiumb-vis-tfrag"}],[226164775,{"idx":39,"name":"stdmb-pipe-ring-03","tpage_name":"stadiumb-vis-tfrag"}],[226164774,{"idx":38,"name":"stdmb-floor-plate-01","tpage_name":"stadiumb-vis-tfrag"}],[226164773,{"idx":37,"name":"stdmb-arrow-gradient","tpage_name":"stadiumb-vis-tfrag"}],[226164772,{"idx":36,"name":"stdmb-pipe-01","tpage_name":"stadiumb-vis-tfrag"}],[226164771,{"idx":35,"name":"stdmb-track-side-01","tpage_name":"stadiumb-vis-tfrag"}],[226164770,{"idx":34,"name":"stdmb-panel-05","tpage_name":"stadiumb-vis-tfrag"}],[226164769,{"idx":33,"name":"stdmb-panel-11","tpage_name":"stadiumb-vis-tfrag"}],[226164768,{"idx":32,"name":"stdmb-panel-09","tpage_name":"stadiumb-vis-tfrag"}],[226164767,{"idx":31,"name":"stdmb-wall-03","tpage_name":"stadiumb-vis-tfrag"}],[226164766,{"idx":30,"name":"stdmb-stone-trim-01","tpage_name":"stadiumb-vis-tfrag"}],[226164765,{"idx":29,"name":"stdmb-panel-08","tpage_name":"stadiumb-vis-tfrag"}],[226164764,{"idx":28,"name":"stdmb-yellowstripe","tpage_name":"stadiumb-vis-tfrag"}],[226164763,{"idx":27,"name":"stdmb-wall-detail-04","tpage_name":"stadiumb-vis-tfrag"}],[226164762,{"idx":26,"name":"stdmb-pipe-02","tpage_name":"stadiumb-vis-tfrag"}],[226164761,{"idx":25,"name":"stdmb-wall-detail-02","tpage_name":"stadiumb-vis-tfrag"}],[226164760,{"idx":24,"name":"stdmb-pipe-ring-01","tpage_name":"stadiumb-vis-tfrag"}],[226164759,{"idx":23,"name":"stdmb-wall-detail-05","tpage_name":"stadiumb-vis-tfrag"}],[226164758,{"idx":22,"name":"stdmb-panel-06","tpage_name":"stadiumb-vis-tfrag"}],[226164757,{"idx":21,"name":"stdmb-pillar-blue-light-01","tpage_name":"stadiumb-vis-tfrag"}],[226164756,{"idx":20,"name":"stdmb-pillar-01","tpage_naLine truncated
|
||||
@@ -4603,6 +4603,24 @@
|
||||
)
|
||||
;; ---pad:pad-buttons
|
||||
|
||||
;; +++pad:abutton-idx
|
||||
(defenum abutton-idx
|
||||
:type uint8
|
||||
(right 0)
|
||||
(left 1)
|
||||
(up 2)
|
||||
(down 3)
|
||||
(triangle 4)
|
||||
(circle 5)
|
||||
(x 6)
|
||||
(square 7)
|
||||
(l1 8)
|
||||
(r1 9)
|
||||
(l2 10)
|
||||
(r2 11)
|
||||
)
|
||||
;; ---pad:abutton-idx
|
||||
|
||||
;; +++pad:mouse-buttons
|
||||
(defenum mouse-buttons
|
||||
:bitfield #t
|
||||
@@ -7523,27 +7541,27 @@
|
||||
;; +++level-h:bigmap-id
|
||||
(defenum bigmap-id
|
||||
:type uint32
|
||||
(bigmap-id-0 0)
|
||||
(bigmap-id-1 1)
|
||||
(city 0)
|
||||
(comb 1)
|
||||
(desert 2)
|
||||
(factory 3)
|
||||
(forest 4)
|
||||
(mhcity 5)
|
||||
(mine 6)
|
||||
(nest 7)
|
||||
(bigmap-id-8 8)
|
||||
(no-map 9)
|
||||
(precursor 10)
|
||||
(bigmap-id-11 11)
|
||||
(nest2 8)
|
||||
(none 9)
|
||||
(precursor1 10)
|
||||
(precursor2 11)
|
||||
(rubble 12)
|
||||
(sewer0 13)
|
||||
(sewer1 14)
|
||||
(sewer2 15)
|
||||
(sewer-hum-kg 13)
|
||||
(sewer-kg-met 14)
|
||||
(sewer-met-hum 15)
|
||||
(stadium 16)
|
||||
(temple 17)
|
||||
(bigmap-id-18 18)
|
||||
(bigmap-id-19 19)
|
||||
(bigmap-id-20 20)
|
||||
(temple1 17)
|
||||
(temple2 18)
|
||||
(temple3 19)
|
||||
(temple4 20)
|
||||
(tower 21)
|
||||
(volcano 22)
|
||||
(wascity 23)
|
||||
@@ -8288,7 +8306,7 @@
|
||||
(define-extern *font-default-matrix* matrix)
|
||||
(define-extern *font-work* font-work)
|
||||
(define-extern font-set-tex0 (function (pointer gs-tex0) texture int int int none))
|
||||
(define-extern set-font-color (function font-color int rgba rgba rgba int))
|
||||
(define-extern set-font-color (function font-color rgba rgba rgba rgba int))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; decomp-h ;;
|
||||
@@ -10724,16 +10742,55 @@
|
||||
:flag-assert #x900000180
|
||||
)
|
||||
|
||||
;; +++bigmap-h:bigmap-flag
|
||||
(defenum bigmap-flag
|
||||
:type uint32
|
||||
:bitfield #t
|
||||
(bf00 0)
|
||||
(bf01 1)
|
||||
(bf02 2)
|
||||
(bf03 3)
|
||||
(bf04 4)
|
||||
(bf05 5)
|
||||
(bf06 6)
|
||||
(bf07 7)
|
||||
(bf08 8)
|
||||
(bf09 9)
|
||||
(bf10 10)
|
||||
(bf11 11)
|
||||
(bf12 12)
|
||||
(bf13 13)
|
||||
(bf14 14)
|
||||
(bf15 15)
|
||||
(bf16 16)
|
||||
(bf17 17)
|
||||
(ctywide 18)
|
||||
(waswide 19)
|
||||
(wasall 20)
|
||||
(desert 21)
|
||||
(bf22 22)
|
||||
(bf23 23)
|
||||
(bf24 24)
|
||||
(bf25 25)
|
||||
(bf26 26)
|
||||
(bf27 27)
|
||||
(bf28 28)
|
||||
(bf29 29)
|
||||
(bf30 30)
|
||||
(bf31 31)
|
||||
)
|
||||
;; ---bigmap-h:bigmap-flag
|
||||
|
||||
(deftype bigmap (basic)
|
||||
((drawing-flag symbol :offset-assert 4) ;; guessed by decompiler
|
||||
(loading-flag symbol :offset-assert 8) ;; guessed by decompiler
|
||||
(bigmap-index uint32 :offset-assert 12)
|
||||
(bigmap-index bigmap-id :offset-assert 12)
|
||||
(bigmap-image external-art-buffer :offset-assert 16) ;; guessed by decompiler
|
||||
(tpage external-art-buffer :offset-assert 20) ;; guessed by decompiler
|
||||
(tpage2 basic :offset-assert 24)
|
||||
(tpage2 external-art-buffer :offset-assert 24)
|
||||
(progress-minimap texture-page :offset-assert 28) ;; guessed by decompiler
|
||||
(progress-minimap2 texture-page :offset-assert 32)
|
||||
(load-index uint32 :offset-assert 36)
|
||||
(load-index bigmap-id :offset-assert 36)
|
||||
(x0 int32 :offset-assert 40)
|
||||
(y0 int32 :offset-assert 44)
|
||||
(x1 int32 :offset-assert 48)
|
||||
@@ -10748,29 +10805,29 @@
|
||||
(scroll vector :inline :offset-assert 176)
|
||||
(pos vector4w :inline :offset-assert 192)
|
||||
(color vector4w :inline :offset-assert 208)
|
||||
(corner vector 4 :inline :offset-assert 224) ;; guessed by decompiler
|
||||
(corner vector 4 :inline :offset-assert 224) ;; guessed by decompiler
|
||||
(auto-save-icon-flag symbol :offset-assert 288) ;; guessed by decompiler
|
||||
(global-flags uint32 :offset-assert 292)
|
||||
(global-flags bigmap-flag :offset-assert 292)
|
||||
)
|
||||
:method-count-assert 23
|
||||
:size-assert #x128
|
||||
:flag-assert #x1700000128
|
||||
(:methods
|
||||
(new (symbol type) _type_) ;; 0 ;; (new (symbol type) _type_)
|
||||
(bigmap-method-9 () none) ;; 9 ;; (initialize (_type_) none)
|
||||
(new (symbol type) _type_) ;; 0
|
||||
(initialize (_type_) none) ;; 9
|
||||
(update (_type_) none) ;; 10
|
||||
(bigmap-method-11 (_type_) symbol) ;; 11
|
||||
(bigmap-method-12 () none) ;; 12 ;; (handle-cpad-inputs (_type_) int)
|
||||
(bigmap-method-13 () none) ;; 13 ;; (compress-all (_type_) int)
|
||||
(loaded? (_type_) symbol) ;; 11
|
||||
(draw! (_type_ int int int int) none) ;; 12 ;; (handle-cpad-inputs (_type_) int)
|
||||
(handle-cpad-input (_type_) none) ;; 13 ;; (compress-all (_type_) int)
|
||||
(enable-drawing (_type_) none) ;; 14
|
||||
(disable-drawing (_type_) int) ;; 15
|
||||
(bigmap-method-16 (_type_) none) ;; 16 ;; (dump-to-file (_type_) file-stream)
|
||||
(bigmap-method-17 () none) ;; 17 ;; (set-pos! (_type_ vector) int)
|
||||
(bigmap-method-18 () none) ;; 18 ;; (decompress-current-masks! (_type_) int)
|
||||
(bigmap-method-19 () none) ;; 19 ;; (compress-current-masks! (_type_) int)
|
||||
(bigmap-method-20 () none) ;; 20 ;; (set-enable-from-position! (_type_) int)
|
||||
(bigmap-method-21 () none) ;; 21 ;; (maybe-fill-for-position (_type_ int int) int)
|
||||
(bigmap-method-22 () none) ;; 22 ;; (texture-upload-dma (_type_ dma-buffer (pointer uint32) int int int gs-psm) none)
|
||||
(set-map-indices! (_type_) none) ;; 16 ;; (dump-to-file (_type_) file-stream)
|
||||
(set-pos! (_type_ vector) none) ;; 17
|
||||
(bigmap-method-18 (_type_ (pointer int32)) none) ;; 18 ;; (decompress-current-masks! (_type_) int)
|
||||
(texture-upload-dma (_type_ dma-buffer (pointer uint32) int int int gs-psm) none) ;; 19 ;; (compress-current-masks! (_type_) int)
|
||||
(bigmap-method-20 (_type_ dma-buffer) symbol) ;; 20 ;; (set-enable-from-position! (_type_) int)
|
||||
(sprite-dma (_type_ dma-buffer int int int int int int) object) ;; 21 ;; (maybe-fill-for-position (_type_ int int) int)
|
||||
(draw-from-minimap (_type_ dma-buffer connection-minimap) none) ;; 22
|
||||
)
|
||||
)
|
||||
|
||||
@@ -11485,13 +11542,13 @@
|
||||
(scan-tmpl dma-gif-packet :inline :offset-assert 192)
|
||||
(color vector4w :inline :offset-assert 224)
|
||||
(line-color uint64 :offset-assert 240)
|
||||
(scan-colors vector4w 15 :inline :offset-assert 256) ;; guessed by decompiler
|
||||
(scan-colors vector4w 15 :inline :offset-assert 256) ;; guessed by decompiler
|
||||
(zoom-blur-pos vector :inline :offset-assert 496)
|
||||
(zoom-blur-count int32 :offset-assert 512)
|
||||
(zoom-blur-texels int32 :offset-assert 516)
|
||||
(zoom-blur-alpha-target float :offset-assert 520)
|
||||
(zoom-blur-alpha-current float :offset-assert 524)
|
||||
(zoom-blur-2d basic :offset-assert 528)
|
||||
(zoom-blur-2d symbol :offset-assert 528)
|
||||
(menu-mode symbol :offset-assert 532) ;; guessed by decompiler
|
||||
(screen-copied symbol :offset-assert 536) ;; guessed by decompiler
|
||||
(vu1-enable-user-menu vu1-renderer-mask :offset-assert 544)
|
||||
@@ -11509,18 +11566,18 @@
|
||||
:size-assert #x24c
|
||||
:flag-assert #x1b0000024c
|
||||
(:methods
|
||||
(blit-displays-work-method-9 () none) ;; 9
|
||||
(blit-displays-work-method-10 () none) ;; 10
|
||||
(blit-displays-work-method-11 () none) ;; 11
|
||||
(blit-displays-work-method-12 () none) ;; 12
|
||||
(blit-displays-work-method-13 () none) ;; 13
|
||||
(blit-displays-work-method-14 () none) ;; 14
|
||||
(blit-displays-work-method-15 () none) ;; 15
|
||||
(blit-displays-work-method-16 () none) ;; 16
|
||||
(blit-displays-work-method-17 (_type_ vector int float symbol) none) ;; 17
|
||||
(blit-displays-work-method-18 () none) ;; 18
|
||||
(blit-displays-work-method-19 (_type_) none) ;; 19 (called from main.gc)
|
||||
(blit-displays-work-method-20 (_type_) none) ;; 20
|
||||
(blit-displays-work-method-9 (_type_ dma-buffer int int int) none) ;; 9
|
||||
(blit-displays-work-method-10 (_type_ dma-buffer int int int) none) ;; 10
|
||||
(blit-displays-work-method-11 (_type_ dma-buffer int) none) ;; 11
|
||||
(draw-letterbox (_type_ dma-buffer float int float) none) ;; 12
|
||||
(blit-displays-work-method-13 (_type_ dma-buffer int int int) none) ;; 13
|
||||
(blit-displays-work-method-14 (_type_ dma-buffer vector) none) ;; 14
|
||||
(blit-displays-work-method-15 (_type_ dma-buffer) none) ;; 15
|
||||
(draw-zoom-blur (_type_ dma-buffer int) none) ;; 16
|
||||
(setup-zoom-blur-2d (_type_ vector int float symbol) none) ;; 17
|
||||
(setup-brightness-and-contrast (_type_ dma-buffer float float) none) ;; 18
|
||||
(do-blit-displays (_type_) none) ;; 19 (called from main.gc)
|
||||
(draw-sky (_type_ dma-buffer) none) ;; 20
|
||||
(get-menu-mode (_type_) symbol) ;; 21
|
||||
(get-screen-copied (_type_) symbol) ;; 22
|
||||
(get-horizontal-flip-flag (_type_) symbol) ;; 23
|
||||
@@ -23068,7 +23125,7 @@
|
||||
(disable-for-duration (_type_ time-frame) none) ;; 16
|
||||
(ragdoll-proc-method-17 (_type_ ragdoll-edit-info) none) ;; 17
|
||||
(ragdoll-proc-method-18 (_type_ ragdoll-edit-info) none) ;; 18
|
||||
(ragdoll-proc-method-19 (_type_) none) ;; 19
|
||||
(ragdoll-proc-method-19 (_type_) symbol) ;; 19
|
||||
)
|
||||
)
|
||||
|
||||
@@ -31064,7 +31121,7 @@
|
||||
|
||||
(define-extern *blit-displays-work* blit-displays-work)
|
||||
(define-extern draw-color-bars (function blit-displays-work none))
|
||||
(define-extern draw-raw-image (function bucket-id art-group int vector vector level int none))
|
||||
(define-extern draw-raw-image (function blit-displays-work bucket-id art-group vector vector level int none))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; font-data ;;
|
||||
@@ -39229,7 +39286,7 @@
|
||||
;; bigmap ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; (define-extern *bigmap-info-array* object) ;; bigmap-info-array
|
||||
(define-extern *bigmap-info-array* bigmap-info-array)
|
||||
(define-extern *bigmap* bigmap)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
@@ -42123,6 +42180,12 @@
|
||||
;; rigid-body ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(deftype rigid-body-stack (structure)
|
||||
((vec vector :inline)
|
||||
(mat matrix :inline)
|
||||
)
|
||||
)
|
||||
|
||||
(deftype rigid-body-work (structure)
|
||||
((max-ang-momentum float :offset-assert 0)
|
||||
(max-ang-velocity float :offset-assert 4)
|
||||
@@ -44394,9 +44457,9 @@
|
||||
(within-outer-ring symbol :offset-assert 136)
|
||||
(within-inner-ring symbol :offset-assert 140)
|
||||
(ouched symbol :offset-assert 144)
|
||||
(bound-cam basic :offset-assert 148)
|
||||
(bound-cam string :offset-assert 148)
|
||||
(trans vector :inline :offset-assert 160)
|
||||
(state-time uint64 :offset-assert 176)
|
||||
(state-time time-frame :offset-assert 176)
|
||||
(jak-in-hint-region symbol :offset-assert 184)
|
||||
(watchers-vulnerable symbol :offset-assert 188)
|
||||
)
|
||||
@@ -44429,7 +44492,7 @@
|
||||
standing-down ;; 31
|
||||
)
|
||||
(:methods
|
||||
(tpl-watcher-method-32 (_type_) none) ;; 32
|
||||
(init-collision! (_type_) none) ;; 32
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
"write_hex_near_instructions": false,
|
||||
|
||||
// to write out "scripts", which are currently just all the linked lists found. mostly a jak 2/3 thing
|
||||
"write_scripts": true,
|
||||
"write_scripts": false,
|
||||
|
||||
// hex dump of code/data files.
|
||||
"hexdump_code": false,
|
||||
|
||||
@@ -1000,5 +1000,10 @@
|
||||
[12, "(function none :behavior scene-player)"],
|
||||
[13, "(function none :behavior scene-player)"],
|
||||
[14, "(function none :behavior scene-player)"]
|
||||
],
|
||||
"bigmap": [
|
||||
[15, "(function external-art-buffer object)"],
|
||||
[16, "(function external-art-buffer object)"],
|
||||
[17, "(function external-art-buffer object)"]
|
||||
]
|
||||
}
|
||||
@@ -735,10 +735,6 @@
|
||||
// there are some missing textures. I don't know what the game actually does here.
|
||||
// the format for entries is [level, tpage, index]
|
||||
"missing_textures": [
|
||||
["lfac", 0, 0],
|
||||
["ltow", 0, 0],
|
||||
["lcit", 0, 0],
|
||||
["pow", 0, 0],
|
||||
["wasintro", 0, 0],
|
||||
["lfacctyb", 0, 0],
|
||||
["intpfall", 0, 0],
|
||||
|
||||
@@ -186,18 +186,18 @@
|
||||
"DGO/PRECA.DGO",
|
||||
"DGO/PRECB.DGO",
|
||||
"DGO/PRECC.DGO",
|
||||
// "DGO/PRECD.DGO",
|
||||
// // title/intro
|
||||
"DGO/PRECD.DGO",
|
||||
// title/intro
|
||||
"DGO/WIN.DGO", // wasintro
|
||||
"DGO/TITLE.DGO",
|
||||
"DGO/INTTITLE.DGO",
|
||||
"DGO/INTPALRF.DGO", // intro-palace-roof
|
||||
"DGO/IPF.DGO", // intro-palace-fall
|
||||
"DGO/INTROCST.DGO",
|
||||
// // outro
|
||||
// outro
|
||||
"DGO/OUTCAST3.DGO",
|
||||
"DGO/OUTROCST.DGO",
|
||||
// // museum
|
||||
// museum
|
||||
"DGO/MUSEUM.DGO",
|
||||
"DGO/MUSEUM2.DGO",
|
||||
"DGO/MUSEUM3.DGO",
|
||||
@@ -311,8 +311,245 @@
|
||||
"DGO/LWSTDPCK.DGO"
|
||||
],
|
||||
|
||||
// STR files containing a texture that should be used by
|
||||
// FR3 creation.
|
||||
"str_texture_file_names": ["STR/PRMINIMA.STR"],
|
||||
|
||||
// some objects are part of STR files (streaming data).
|
||||
"str_file_names": [],
|
||||
"str_file_names": [
|
||||
"STR/ARF1INTR.STR",
|
||||
"STR/ARF1RES.STR",
|
||||
"STR/ARF2INTR.STR",
|
||||
"STR/ARF2RES.STR",
|
||||
"STR/ARF3INTR.STR",
|
||||
"STR/ARF3RES.STR",
|
||||
"STR/AROUTRO.STR",
|
||||
"STR/ART1INTR.STR",
|
||||
"STR/CAGSHIEL.STR",
|
||||
"STR/CATRES.STR",
|
||||
"STR/CAWRRES.STR",
|
||||
"STR/CIATIDES.STR",
|
||||
"STR/CIATOUT.STR",
|
||||
"STR/CIBBINTR.STR",
|
||||
"STR/CIBBRES.STR",
|
||||
"STR/CIBTINTR.STR",
|
||||
"STR/CIDGRES.STR",
|
||||
"STR/CIFCEINT.STR",
|
||||
"STR/CIGC1RES.STR",
|
||||
"STR/CIGC2INT.STR",
|
||||
"STR/CIGC2RES.STR",
|
||||
"STR/CIGCINTR.STR",
|
||||
"STR/CIGDPUNC.STR",
|
||||
"STR/CIGTCINT.STR",
|
||||
"STR/CIHVRES.STR",
|
||||
"STR/CIPAIB.STR",
|
||||
"STR/CIPAINTR.STR",
|
||||
"STR/CIPARES.STR",
|
||||
"STR/CIPFINTR.STR",
|
||||
"STR/CIPGINTR.STR",
|
||||
"STR/CIPGRES.STR",
|
||||
"STR/CIPHINTR.STR",
|
||||
"STR/CIPHRES.STR",
|
||||
"STR/CISFINTR.STR",
|
||||
"STR/COETEMPL.STR",
|
||||
"STR/COEXIT.STR",
|
||||
"STR/DAD06.STR",
|
||||
"STR/DAD07.STR",
|
||||
"STR/DAD10.STR",
|
||||
"STR/DAD12.STR",
|
||||
"STR/DAD13.STR",
|
||||
"STR/DAD14.STR",
|
||||
"STR/DAD16.STR",
|
||||
"STR/DAD17.STR",
|
||||
"STR/DAD18.STR",
|
||||
"STR/DAD20.STR",
|
||||
"STR/DAD21.STR",
|
||||
"STR/DAD24.STR",
|
||||
"STR/DAD31.STR",
|
||||
"STR/DAD35.STR",
|
||||
"STR/DAD38.STR",
|
||||
"STR/DAD57.STR",
|
||||
"STR/DAD58.STR",
|
||||
"STR/DAD61.STR",
|
||||
"STR/DAMOLE.STR",
|
||||
"STR/DEAR1INT.STR",
|
||||
"STR/DEAR1RES.STR",
|
||||
"STR/DEAR2INT.STR",
|
||||
"STR/DEATIN.STR",
|
||||
"STR/DEATOUT.STR",
|
||||
"STR/DEBBINTR.STR",
|
||||
"STR/DECLINTR.STR",
|
||||
"STR/DECRINTR.STR",
|
||||
"STR/DECWIN.STR",
|
||||
"STR/DEFBIA.STR",
|
||||
"STR/DEFBINTR.STR",
|
||||
"STR/DEFBRB.STR",
|
||||
"STR/DEFBRES.STR",
|
||||
"STR/DEGRES.STR",
|
||||
"STR/DEHINTRO.STR",
|
||||
"STR/DEHRES.STR",
|
||||
"STR/DEJGOTA.STR",
|
||||
"STR/DEJGOTB.STR",
|
||||
"STR/DEJGOTC.STR",
|
||||
"STR/DEJMINTR.STR",
|
||||
"STR/DELC2.STR",
|
||||
"STR/DELC3.STR",
|
||||
"STR/DELCATCH.STR",
|
||||
"STR/DEODRB.STR",
|
||||
"STR/DEODRES.STR",
|
||||
"STR/DERINTRO.STR",
|
||||
"STR/DERRA.STR",
|
||||
// "STR/DESCREEN.STR",
|
||||
"STR/DPBTURRE.STR",
|
||||
"STR/FABINTRO.STR",
|
||||
"STR/FABRES.STR",
|
||||
"STR/FAI1INTR.STR",
|
||||
"STR/FAI2INTR.STR",
|
||||
"STR/FAI3INTR.STR",
|
||||
"STR/FAI4INTR.STR",
|
||||
"STR/FASBIB.STR",
|
||||
"STR/FASBINTR.STR",
|
||||
"STR/FASBRES.STR",
|
||||
"STR/FORB.STR",
|
||||
"STR/FORCRES.STR",
|
||||
"STR/FOTOMRES.STR",
|
||||
"STR/FOTOWER.STR",
|
||||
"STR/GRMANIMS.STR",
|
||||
"STR/INDROP.STR",
|
||||
"STR/INFFHQ.STR",
|
||||
"STR/INLOST.STR",
|
||||
"STR/INPALACE.STR",
|
||||
"STR/INRESCUE.STR",
|
||||
"STR/INTIRED.STR",
|
||||
"STR/INTRAINI.STR",
|
||||
"STR/JAA1.STR",
|
||||
"STR/JAA2.STR",
|
||||
"STR/JAA3.STR",
|
||||
"STR/JAA4.STR",
|
||||
"STR/JAA5.STR",
|
||||
"STR/JAA6.STR",
|
||||
"STR/JAA7.STR",
|
||||
"STR/JABOARD.STR",
|
||||
"STR/JACARRY.STR",
|
||||
"STR/JAD1.STR",
|
||||
"STR/JAD2.STR",
|
||||
"STR/JAD3.STR",
|
||||
"STR/JAD4.STR",
|
||||
"STR/JAD5.STR",
|
||||
"STR/JADARK.STR",
|
||||
"STR/JADON.STR",
|
||||
"STR/JADUMMY.STR",
|
||||
"STR/JAEBOARD.STR",
|
||||
"STR/JAEDARK.STR",
|
||||
"STR/JAEGC.STR",
|
||||
"STR/JAEGNORM.STR",
|
||||
"STR/JAEGOLD.STR",
|
||||
"STR/JAELIGHT.STR",
|
||||
"STR/JAENORMA.STR",
|
||||
// "STR/JAEXTERN.STR",
|
||||
"STR/JAFLDAX.STR",
|
||||
"STR/JAFLUT.STR",
|
||||
"STR/JAGUN.STR",
|
||||
"STR/JAICE.STR",
|
||||
"STR/JAINDAX.STR",
|
||||
"STR/JAKANGA.STR",
|
||||
"STR/JALADDER.STR",
|
||||
"STR/JALIGHT.STR",
|
||||
"STR/JAMECH.STR",
|
||||
"STR/JAPEGASU.STR",
|
||||
"STR/JAPGLIDE.STR",
|
||||
"STR/JAPGUN.STR",
|
||||
"STR/JAPHCAR.STR",
|
||||
"STR/JAPIDAX.STR",
|
||||
"STR/JAPILOT.STR",
|
||||
"STR/JAPOLE.STR",
|
||||
"STR/JAPWCAR.STR",
|
||||
"STR/JARACER.STR",
|
||||
"STR/JASWIM.STR",
|
||||
"STR/JATENTAC.STR",
|
||||
"STR/JATUBE.STR",
|
||||
"STR/JATURRET.STR",
|
||||
"STR/KRWB1.STR",
|
||||
"STR/KRWB2.STR",
|
||||
"STR/KRWB3.STR",
|
||||
"STR/MIBINTRO.STR",
|
||||
"STR/MIBRES.STR",
|
||||
"STR/MIERES.STR",
|
||||
"STR/MIGEXIT.STR",
|
||||
"STR/MITINTRO.STR",
|
||||
"STR/MITRES.STR",
|
||||
"STR/MU2ANIMS.STR",
|
||||
"STR/MU3ANIMS.STR",
|
||||
"STR/MU4ANIMS.STR",
|
||||
"STR/MUANIMS.STR",
|
||||
"STR/NEDBARRI.STR",
|
||||
"STR/NEEINTRO.STR",
|
||||
"STR/NEHINTRO.STR",
|
||||
"STR/NEHRES.STR",
|
||||
"STR/NSB1BREA.STR",
|
||||
"STR/NSB2BREA.STR",
|
||||
"STR/PARAINTR.STR",
|
||||
"STR/PARARA.STR",
|
||||
"STR/PARARES.STR",
|
||||
"STR/PARPINTR.STR",
|
||||
"STR/PEFLY.STR",
|
||||
"STR/POAINTRO.STR",
|
||||
"STR/PRDSERES.STR",
|
||||
"STR/PRDSLOSE.STR",
|
||||
"STR/PRDSRES.STR",
|
||||
"STR/PRHA.STR",
|
||||
"STR/PRHB.STR",
|
||||
"STR/PRHC.STR",
|
||||
"STR/PRHFINAL.STR",
|
||||
// "STR/PRMINIMA.STR",
|
||||
"STR/PRTRES.STR",
|
||||
"STR/RATA1INT.STR",
|
||||
"STR/RATA2INT.STR",
|
||||
// "STR/SCBOOK.STR",
|
||||
"STR/SEEINTRO.STR",
|
||||
"STR/SEGENTRA.STR",
|
||||
"STR/SEHKENTR.STR",
|
||||
"STR/SEHKRES.STR",
|
||||
"STR/SEKENTRA.STR",
|
||||
"STR/SEKEXIT.STR",
|
||||
"STR/SEKMINTR.STR",
|
||||
"STR/SEMEXIT.STR",
|
||||
"STR/SEMHINTR.STR",
|
||||
"STR/SEPEXIT.STR",
|
||||
"STR/SESGRUNT.STR",
|
||||
"STR/SEWATERS.STR",
|
||||
"STR/TECINTRO.STR",
|
||||
"STR/TECRES.STR",
|
||||
"STR/TEDINTRO.STR",
|
||||
"STR/TEDRES.STR",
|
||||
"STR/TEEANIMS.STR",
|
||||
"STR/TEELAANI.STR",
|
||||
"STR/TEELODS.STR",
|
||||
"STR/TEJGLGLI.STR",
|
||||
"STR/TEOINTRO.STR",
|
||||
"STR/TEORES.STR",
|
||||
"STR/TETINTRO.STR",
|
||||
"STR/TETRA.STR",
|
||||
"STR/TETRB.STR",
|
||||
"STR/TEWDESER.STR",
|
||||
"STR/TODINTRO.STR",
|
||||
"STR/TODRB.STR",
|
||||
"STR/TODRES.STR",
|
||||
"STR/VODRES.STR",
|
||||
"STR/VOI1INTR.STR",
|
||||
"STR/VOI1RES.STR",
|
||||
"STR/VOI2INTR.STR",
|
||||
"STR/VOI2RES.STR",
|
||||
"STR/WACINTRO.STR",
|
||||
"STR/WADRES.STR",
|
||||
"STR/WAGINTRO.STR",
|
||||
"STR/WAGRES.STR",
|
||||
"STR/WALRINTR.STR",
|
||||
"STR/WALRRES.STR",
|
||||
"STR/WAPGINTR.STR",
|
||||
"STR/WAPGRES.STR"
|
||||
// "STR/WOMAP.STR"
|
||||
],
|
||||
|
||||
// streaming "art" that should be added to GAME.FR3.
|
||||
"str_art_file_names": ["STR/JAEXTERN.STR"],
|
||||
@@ -343,6 +580,12 @@
|
||||
"VAGWAD.INT"
|
||||
],
|
||||
|
||||
// tpages that should always be possible to access.
|
||||
"common_tpages": [
|
||||
17, // PRMINIMA progress-minimap
|
||||
3349 // PRMINIMA progress-minimap2
|
||||
],
|
||||
|
||||
"animated_textures": [
|
||||
// dark jak
|
||||
"jakc-arm",
|
||||
|
||||
@@ -1046,7 +1046,7 @@
|
||||
"desertf-obs": [["L99", "(inline-array vector)", 2]],
|
||||
"desert-dust-storm": [["L89", "vector"]],
|
||||
"artifact-race": [
|
||||
["L162", "(inline-array talker-speech-class)", 16],
|
||||
["L162", "(inline-array talker-speech-class)", 32],
|
||||
["L160", "vector"],
|
||||
["L159", "vector"],
|
||||
["L158", "vector"],
|
||||
|
||||
@@ -429,7 +429,7 @@
|
||||
"(method 22 rigid-body-control)": [[16, ["inline-array", "vector", 2]]],
|
||||
"(method 23 rigid-body-control)": [[16, ["inline-array", "vector", 2]]],
|
||||
"(method 24 rigid-body-control)": [[16, ["inline-array", "vector", 2]]],
|
||||
"(method 28 rigid-body-control)": [[16, "rigid-body-impact"]],
|
||||
"(method 28 rigid-body-control)": [[16, "rigid-body-stack"]],
|
||||
"(method 50 rigid-body-object)": [[16, "rigid-body-impact"]],
|
||||
"(method 51 rigid-body-object)": [[16, "rigid-body-impact"]],
|
||||
"ptest": [[16, "vector"]],
|
||||
@@ -1067,7 +1067,7 @@
|
||||
[208, ["array", "uint32", 1]]
|
||||
],
|
||||
"(method 35 was-squad-control)": [
|
||||
[16, ["inline-array", "matrix", 2]],
|
||||
[16, ["inline-array", "matrix", 4]],
|
||||
[240, "cquery-with-5vec"]
|
||||
],
|
||||
"(method 39 vehicle-wheel)": [[16, "rigid-body-move-work"]],
|
||||
@@ -2513,5 +2513,12 @@
|
||||
[80, "matrix"],
|
||||
[144, "matrix"],
|
||||
[208, "matrix"]
|
||||
],
|
||||
"(method 12 bigmap)": [[32, "matrix"]],
|
||||
"(method 22 bigmap)": [
|
||||
[16, "vector4w"],
|
||||
[32, "vector"],
|
||||
[48, "vector"],
|
||||
[64, "vector"]
|
||||
]
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
[[224067587,{"idx":3,"name":"common-gray-dark","tpage_name":"museum4-water"}],[224067586,{"idx":2,"name":"common-glass","tpage_name":"museum4-water"}],[223936522,{"idx":10,"name":"bab-skin","tpage_name":"museum4b-pris"}],[223936521,{"idx":9,"name":"bab-shoulderstrap","tpage_name":"museum4b-pris"}],[223936520,{"idx":8,"name":"bab-pendant","tpage_name":"museum4b-pris"}],[223936519,{"idx":7,"name":"bab-nail-01","tpage_name":"museum4b-pris"}],[223936518,{"idx":6,"name":"bab-longfur","tpage_name":"museum4b-pris"}],[223936517,{"idx":5,"name":"bab-furtrans","tpage_name":"museum4b-pris"}],[223936516,{"idx":4,"name":"bab-furskin-trans","tpage_name":"museum4b-pris"}],[223936515,{"idx":3,"name":"bab-fur","tpage_name":"museum4b-pris"}],[223936514,{"idx":2,"name":"bab-eye","tpage_name":"museum4b-pris"}],[223936513,{"idx":1,"name":"bab-diaper","tpage_name":"museum4b-pris"}],[223936512,{"idx":0,"name":"bab-allfur","tpage_name":"museum4b-pris"}],[223871035,{"idx":59,"name":"environment-oldmetal","tpage_name":"museum3b-pris2"}],[223871034,{"idx":58,"name":"daxter-furhilite","tpage_name":"museum3b-pris2"}],[223871033,{"idx":57,"name":"charHOLD","tpage_name":"museum3b-pris2"}],[223871032,{"idx":56,"name":"brut-toenails","tpage_name":"museum3b-pris2"}],[223871031,{"idx":55,"name":"brut-ties","tpage_name":"museum3b-pris2"}],[223871030,{"idx":54,"name":"brut-teeth","tpage_name":"museum3b-pris2"}],[223871029,{"idx":53,"name":"brut-shirt","tpage_name":"museum3b-pris2"}],[223871028,{"idx":52,"name":"brut-metalrim","tpage_name":"museum3b-pris2"}],[223871027,{"idx":51,"name":"brut-lens","tpage_name":"museum3b-pris2"}],[223871026,{"idx":50,"name":"brut-legfur","tpage_name":"museum3b-pris2"}],[223871025,{"idx":49,"name":"brut-jaw","tpage_name":"museum3b-pris2"}],[223871024,{"idx":48,"name":"brut-jacket","tpage_name":"museum3b-pris2"}],[223871023,{"idx":47,"name":"brut-headtop","tpage_name":"museum3b-pris2"}],[223871022,{"idx":46,"name":"brut-handpalm","tpage_name":"museum3b-pris2"}],[223871021,{"idx":45,"name":"brut-hair","tpage_name":"museum3b-pris2"}],[223871020,{"idx":44,"name":"brut-foottop","tpage_name":"museum3b-pris2"}],[223871019,{"idx":43,"name":"brut-footstrap","tpage_name":"museum3b-pris2"}],[223871018,{"idx":42,"name":"brut-footbottom","tpage_name":"museum3b-pris2"}],[223871017,{"idx":41,"name":"brut-finger","tpage_name":"museum3b-pris2"}],[223871016,{"idx":40,"name":"brut-feather","tpage_name":"museum3b-pris2"}],[223871015,{"idx":39,"name":"brut-eyelid","tpage_name":"museum3b-pris2"}],[223871014,{"idx":38,"name":"brut-eye","tpage_name":"museum3b-pris2"}],[223871013,{"idx":37,"name":"brut-diaper","tpage_name":"museum3b-pris2"}],[223871012,{"idx":36,"name":"brut-cloaktop","tpage_name":"museum3b-pris2"}],[223871011,{"idx":35,"name":"brut-cloaktail","tpage_name":"museum3b-pris2"}],[223871010,{"idx":34,"name":"brut-button","tpage_name":"museum3b-pris2"}],[223871009,{"idx":33,"name":"brut-armsleeve","tpage_name":"museum3b-pris2"}],[223805572,{"idx":132,"name":"krew-rteye","tpage_name":"museum3b-pris"}],[223805571,{"idx":131,"name":"krew-lfteye","tpage_name":"museum3b-pris"}],[223805570,{"idx":130,"name":"krew-eyelid","tpage_name":"museum3b-pris"}],[223805569,{"idx":129,"name":"vin-waistband","tpage_name":"museum3b-pris"}],[223805568,{"idx":128,"name":"vin-teeth-01","tpage_name":"museum3b-pris"}],[223805567,{"idx":127,"name":"vin-suspendercenter","tpage_name":"museum3b-pris"}],[223805566,{"idx":126,"name":"vin-shoe-02","tpage_name":"museum3b-pris"}],[223805565,{"idx":125,"name":"vin-shoe-01","tpage_name":"museum3b-pris"}],[223805564,{"idx":124,"name":"vin-shirt-02","tpage_name":"museum3b-pris"}],[223805563,{"idx":123,"name":"vin-shirt-01","tpage_name":"museum3b-pris"}],[223805562,{"idx":122,"name":"vin-pants","tpage_name":"museum3b-pris"}],[223805561,{"idx":121,"name":"vin-metal","tpage_name":"museum3b-pris"}],[223805560,{"idx":120,"name":"vin-ltbrownstrap","tpage_name":"museum3b-pris"}],[223805559,{"idx":119,"name":"vin-lens","tpage_name":"museum3b-pris"}],[223805558,{"idx":118,"name":"vin-hair-02","tpage_name":"museum3b-pris"}],[223805557,{"idx":117,"name":"vin-hair-01","tpage_name":"museum3b-pris"}],[223805556,{"idx":116,"name":"vin-gunhandle-01","tpage_name":"museum3b-pris"}],[223805555,{"idx":115,"name":"vin-gunbarrel-02","tpage_name":"museum3b-pris"}],[223805554,{"idx":114,"name":"vin-gunbarrel","tpage_name":"museum3b-pris"}],[223805553,{"idx":113,"name":"vin-glove-02","tpage_name":"museum3b-pris"}],[223805552,{"idx":112,"name":"vin-glove-01","tpage_name":"museum3b-pris"}],[223805551,{"idx":111,"name":"vin-finger-01","tpage_name":"museum3b-pris"}],[223805550,{"idx":110,"name":"vin-face-01","tpage_name":"museum3b-pris"}],[223805549,{"idx":109,"name":"vin-emblem","tpage_name":"museum3b-pris"}],[223805548,{"idx":108,"name":"vin-ear","tpage_name":"museum3b-pris"}],[223805547,{"idx":107,"name":"vin-clip","tpage_name":"museum3b-pris"}],[223805546,{"idx":106,"name":"vin-blackstrap","tpage_name":"museum3b-pris"}],[223805545,{"idx"Line truncated
|
||||
[[1114251,{"idx":139,"name":"arena-04","tpage_name":"progress-minimap"}],[1114250,{"idx":138,"name":"arena-03","tpage_name":"progress-minimap"}],[1114246,{"idx":134,"name":"precursor-03","tpage_name":"progress-minimap"}],[1114245,{"idx":133,"name":"precursor-02","tpage_name":"progress-minimap"}],[1114238,{"idx":126,"name":"rubble-03","tpage_name":"progress-minimap"}],[1114235,{"idx":123,"name":"comb-04","tpage_name":"progress-minimap"}],[1114220,{"idx":108,"name":"factory-01","tpage_name":"progress-minimap"}],[1114150,{"idx":38,"name":"hud-bronzecup","tpage_name":"progress-minimap"}],[1114144,{"idx":32,"name":"forest-04","tpage_name":"progress-minimap"}],[1114143,{"idx":31,"name":"forest-03","tpage_name":"progress-minimap"}],[1114142,{"idx":30,"name":"forest-02","tpage_name":"progress-minimap"}],[1114141,{"idx":29,"name":"forest-01","tpage_name":"progress-minimap"}],[1114132,{"idx":20,"name":"default-jak-04","tpage_name":"progress-minimap"}],[1114131,{"idx":19,"name":"default-jak-03","tpage_name":"progress-minimap"}],[1114130,{"idx":18,"name":"default-jak-02","tpage_name":"progress-minimap"}],[1114129,{"idx":17,"name":"default-jak-01","tpage_name":"progress-minimap"}],[1114124,{"idx":12,"name":"city-04","tpage_name":"progress-minimap"}],[1114123,{"idx":11,"name":"city-03","tpage_name":"progress-minimap"}],[1114122,{"idx":10,"name":"city-02","tpage_name":"progress-minimap"}],[1114121,{"idx":9,"name":"city-01","tpage_name":"progress-minimap"}],[1114116,{"idx":4,"name":"big-map-icons","tpage_name":"progress-minimap"}],[1114113,{"idx":1,"name":"map-target-marker","tpage_name":"progress-minimap"}],[1114112,{"idx":0,"name":"hud-race-vehicle-01","tpage_name":"progress-minimap"}],[116916234,{"idx":10,"name":"sewcurved-door-06","tpage_name":"sewk-vis-pris"}],[99483714,{"idx":66,"name":"dp-bipedal-power-hose","tpage_name":"lformach-vis-pris"}],[106954794,{"idx":42,"name":"vola-rising-step-base","tpage_name":"volcanoa-vis-tfrag"}],[116916233,{"idx":9,"name":"sewcurved-door-05","tpage_name":"sewk-vis-pris"}],[99483713,{"idx":65,"name":"dp-bipedal-nose-01","tpage_name":"lformach-vis-pris"}],[106954793,{"idx":41,"name":"vola-cable","tpage_name":"volcanoa-vis-tfrag"}],[116916232,{"idx":8,"name":"sewcurved-door-04","tpage_name":"sewk-vis-pris"}],[99483712,{"idx":64,"name":"dp-bipedal-finger-plate-01","tpage_name":"lformach-vis-pris"}],[106954792,{"idx":40,"name":"vola-slide-metal","tpage_name":"volcanoa-vis-tfrag"}],[116916231,{"idx":7,"name":"sewcurved-door-01","tpage_name":"sewk-vis-pris"}],[99483711,{"idx":63,"name":"dp-bipedal-eye-01","tpage_name":"lformach-vis-pris"}],[116916230,{"idx":6,"name":"airlock-door-cog1","tpage_name":"sewk-vis-pris"}],[99483710,{"idx":62,"name":"dp-bipedal-dk-stomach-plate-01","tpage_name":"lformach-vis-pris"}],[106954790,{"idx":38,"name":"vola-grass-fringe-05-HI","tpage_name":"volcanoa-vis-tfrag"}],[116916228,{"idx":4,"name":"airlockl-door-metalframe","tpage_name":"sewk-vis-pris"}],[99483708,{"idx":60,"name":"dp-bipedal-dk-plate-04","tpage_name":"lformach-vis-pris"}],[116916227,{"idx":3,"name":"airlock-door-metal2","tpage_name":"sewk-vis-pris"}],[99483707,{"idx":59,"name":"dp-bipedal-dk-plate-03","tpage_name":"lformach-vis-pris"}],[116916226,{"idx":2,"name":"airlock-door-main","tpage_name":"sewk-vis-pris"}],[99483706,{"idx":58,"name":"dp-bipedal-dk-plate-02","tpage_name":"lformach-vis-pris"}],[106954786,{"idx":34,"name":"vola-rock-side-wall","tpage_name":"volcanoa-vis-tfrag"}],[116916225,{"idx":1,"name":"airlock-door-cog","tpage_name":"sewk-vis-pris"}],[99483705,{"idx":57,"name":"dp-bipedal-dk-plate-01","tpage_name":"lformach-vis-pris"}],[116916224,{"idx":0,"name":"airlock-door-bolt","tpage_name":"sewk-vis-pris"}],[99483704,{"idx":56,"name":"dp-bipedal-dk-hose-01","tpage_name":"lformach-vis-pris"}],[106954784,{"idx":32,"name":"vol-metal-01","tpage_name":"volcanoa-vis-tfrag"}],[116850690,{"idx":2,"name":"sewer-shrub-pitting-01","tpage_name":"sewk-vis-shrub"}],[99418170,{"idx":58,"name":"tpl-glider-metal02","tpage_name":"volcanox-pris"}],[111869970,{"idx":18,"name":"stadiumb-hud-ord-rd","tpage_name":"wasleapr-minimap"}],[116850689,{"idx":1,"name":"sewer-nut","tpage_name":"sewk-vis-shrub"}],[99418169,{"idx":57,"name":"tpl-glider-metal01","tpage_name":"volcanox-pris"}],[111869969,{"idx":17,"name":"stadiumb-hud-ord-o","tpage_name":"wasleapr-minimap"}],[116850688,{"idx":0,"name":"sewer-pipe-small-01","tpage_name":"sewk-vis-shrub"}],[99418168,{"idx":56,"name":"tpl-glider-grip01","tpage_name":"volcanox-pris"}],[111869968,{"idx":16,"name":"stadiumb-hud-ord-nd","tpage_name":"wasleapr-minimap"}],[115867650,{"idx":2,"name":"nst-spiderweb","tpage_name":"lnstcst-water"}],[115867649,{"idx":1,"name":"desert-nest-egg-piping","tpage_name":"lnstcst-water"}],[115867648,{"idx":0,"name":"sig-flatfangs","tpage_name":"lnstcst-water"}],[115802142,{"idx":30,"name":"vin-teeth-01","tpage_name":"lnstcst-pris2"}],[103350342,{"idx":70,"name":"jakchires-shoeteop","tpage_name":"comba-pris"}],[115802141,{"idx":29,"name":"sLine truncated
|
||||
@@ -10857,7 +10857,6 @@
|
||||
["_stack_", 76, "float"],
|
||||
["_stack_", 100, "float"]
|
||||
],
|
||||
"real-wang-texture-anim-func": [[[3, 31], "v1", "mood-context"]],
|
||||
"(method 24 sky-work)": [
|
||||
[256, "s4", "(pointer int32)"],
|
||||
[261, "s4", "(pointer int32)"]
|
||||
@@ -11266,5 +11265,80 @@
|
||||
[[191, 249], "gp", "shadow-dcache"],
|
||||
[96, "v1", "shadow-dcache"]
|
||||
],
|
||||
"real-fog-texture-anim-func": [[[6, 160], "s2", "(pointer uint32)"]]
|
||||
"real-fog-texture-anim-func": [[[6, 160], "s2", "(pointer uint32)"]],
|
||||
"(method 22 bigmap)": [
|
||||
[22, "s3", "process-drawable"],
|
||||
[[46, 49], "v1", "entity-actor"],
|
||||
[58, "a0", "process-drawable"],
|
||||
[65, "a0", "entity-actor"],
|
||||
[42, "v1", "entity-actor"],
|
||||
[55, "s3", "process-drawable"],
|
||||
[[201, 243], "a1", "(inline-array vector4w)"]
|
||||
],
|
||||
"(method 20 bigmap)": [
|
||||
[[3, 95], "s4", "(pointer uint32)"],
|
||||
[99, "a2", "(pointer uint32)"],
|
||||
[54, "a2", "(pointer uint32)"]
|
||||
],
|
||||
"(method 12 bigmap)": [
|
||||
[85, "v1", "(pointer uint32)"],
|
||||
[100, "v1", "(pointer uint32)"],
|
||||
[[142, 145], "s0", "(pointer uint128)"],
|
||||
["_stack_", 96, "(inline-array vector4w)"]
|
||||
],
|
||||
"(method 21 bigmap)": [[[10, 38], "v1", "(inline-array vector4w)"]],
|
||||
"(method 19 blit-displays-work)": [
|
||||
[764, "v1", "float"],
|
||||
[759, "v1", "float"],
|
||||
[[935, 954], "a1", "(inline-array vector4w)"],
|
||||
[[857, 875], "a1", "(inline-array vector4w)"],
|
||||
[[844, 847], "a0", "dma-gif-packet"],
|
||||
[[921, 924], "v1", "dma-gif-packet"]
|
||||
],
|
||||
"(method 9 blit-displays-work)": [[[2, 36], "v1", "(inline-array vector4w)"]],
|
||||
"(method 10 blit-displays-work)": [
|
||||
[[2, 141], "v1", "(inline-array vector4w)"]
|
||||
],
|
||||
"(method 11 blit-displays-work)": [
|
||||
[[2, 30], "v1", "(inline-array vector4w)"]
|
||||
],
|
||||
"(method 12 blit-displays-work)": [
|
||||
[[4, 41], "v1", "(inline-array vector4w)"],
|
||||
[[60, 112], "v1", "(inline-array vector4w)"]
|
||||
],
|
||||
"(method 13 blit-displays-work)": [
|
||||
[[41, 44], "v1", "(inline-array vector4w)"],
|
||||
[[53, 71], "a0", "(inline-array vector4w)"]
|
||||
],
|
||||
"(method 18 blit-displays-work)": [
|
||||
[[28, 33], "v1", "dma-gif-packet"],
|
||||
[[174, 177], "v1", "dma-gif-packet"],
|
||||
[[186, 202], "a0", "(inline-array vector4w)"]
|
||||
],
|
||||
"draw-raw-image": [[[104, 154], "v1", "(inline-array vector4w)"]],
|
||||
"draw-color-bars": [
|
||||
[[11, 16], "v1", "dma-gif-packet"],
|
||||
[[28, 54], "v1", "(inline-array vector4w)"]
|
||||
],
|
||||
"(method 20 blit-displays-work)": [
|
||||
[[57, 89], "a3", "(inline-array vector4w)"],
|
||||
[[102, 134], "t1", "(inline-array vector4w)"],
|
||||
[[176, 209], "t1", "(inline-array vector4w)"],
|
||||
[[310, 338], "t2", "(inline-array vector4w)"],
|
||||
[[385, 422], "v1", "(inline-array vector4w)"]
|
||||
],
|
||||
"(method 14 blit-displays-work)": [
|
||||
[[88, 91], "v1", "dma-gif-packet"],
|
||||
[[100, 120], "a0", "(inline-array vector4w)"]
|
||||
],
|
||||
"(method 16 blit-displays-work)": [
|
||||
[[35, 79], "s2", "(inline-array vector4w)"],
|
||||
[[134, 178], "s2", "(inline-array vector4w)"]
|
||||
],
|
||||
"(method 15 blit-displays-work)": [
|
||||
[[60, 63], "v1", "dma-gif-packet"],
|
||||
[[81, 99], "a0", "(inline-array vector4w)"],
|
||||
[[165, 190], "a0", "(inline-array vector4w)"]
|
||||
],
|
||||
"(event idle progress)": [[[10, 80], "v1", "mc-status-code"]]
|
||||
}
|
||||
@@ -2135,5 +2135,14 @@
|
||||
"vars": {
|
||||
"v0-0": ["type", "assault-target-type"]
|
||||
}
|
||||
},
|
||||
"(method 22 bigmap)": {
|
||||
"vars": {
|
||||
"a2-1": ["a2-1", "uint"],
|
||||
"a3-0": ["a3-0", "uint"]
|
||||
}
|
||||
},
|
||||
"set-font-color": {
|
||||
"args": ["idx", "clr0", "clr1", "clr2", "clr3"]
|
||||
}
|
||||
}
|
||||
@@ -166,7 +166,7 @@ FullName extract_name(const std::string& file_info_name) {
|
||||
name.name = name.name.substr(0, name.name.length() - 6);
|
||||
int chunk_id = 0;
|
||||
int place = 0;
|
||||
for (int i = 2; i-- > 0;) {
|
||||
for (int i = 3; i-- > 0;) {
|
||||
char c = name.name.back();
|
||||
if (c >= '0' && c <= '9') {
|
||||
int val = (c - '0');
|
||||
@@ -258,9 +258,8 @@ std::string StrFileReader::get_full_name(const std::string& short_name) const {
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string StrFileReader::get_texture_name() const {
|
||||
ASSERT(m_chunks.size() == 1);
|
||||
const auto& chunk = m_chunks[0];
|
||||
std::string StrFileReader::get_chunk_texture_name(int idx) const {
|
||||
const auto& chunk = m_chunks[idx];
|
||||
auto find_string = get_texture_page_file_info_string();
|
||||
int offset;
|
||||
if (find_string_in_data(chunk.data(), int(chunk.size()), find_string, &offset)) {
|
||||
|
||||
@@ -22,7 +22,7 @@ class StrFileReader {
|
||||
std::string get_chunk_art_name(int idx) const;
|
||||
|
||||
std::string get_full_name(const std::string& short_name) const;
|
||||
std::string get_texture_name() const;
|
||||
std::string get_chunk_texture_name(int idx) const;
|
||||
|
||||
private:
|
||||
void init_jak1(const fs::path& file_path);
|
||||
@@ -46,8 +46,9 @@ class StrFileReader {
|
||||
std::string get_texture_page_file_info_string() const {
|
||||
switch (m_version) {
|
||||
case GameVersion::Jak2:
|
||||
case GameVersion::Jak3:
|
||||
return "/src/jak2/final/texture-page8/";
|
||||
case GameVersion::Jak3:
|
||||
return "/src/jak3/final/texture-page8/";
|
||||
default:
|
||||
ASSERT_MSG(false, "NYI get_file_info_string version");
|
||||
break;
|
||||
|
||||
@@ -454,7 +454,7 @@ std::string write_spool_subtitles(
|
||||
bool has_spools = false;
|
||||
for (auto& [spool_name, subs] : data) {
|
||||
result += " \"" + spool_name + "\": {\n";
|
||||
result += " \"scene\": true,\n";
|
||||
// result += " \"scene\": true,\n";
|
||||
result += " \"lines\": [\n";
|
||||
bool has_subs = false;
|
||||
for (auto& sub : subs) {
|
||||
@@ -463,20 +463,20 @@ std::string write_spool_subtitles(
|
||||
continue;
|
||||
}
|
||||
result += " {\n";
|
||||
result += " \"end\": " + float_to_string(sub.end_frame) + ",\n";
|
||||
result += " \"frame_end\": " + float_to_string(sub.end_frame) + ",\n";
|
||||
result += " \"frame_start\": " + float_to_string(sub.start_frame) + ",\n";
|
||||
if (dump_text) {
|
||||
result += " \"merge\": false,\n";
|
||||
} else {
|
||||
result += " \"merge\": true,\n";
|
||||
}
|
||||
result += " \"offscreen\": false,\n";
|
||||
result += " \"speaker\": \"none\",\n";
|
||||
result += " \"start\": " + float_to_string(sub.start_frame) + ",\n";
|
||||
if (dump_text) {
|
||||
result += " \"text\": \"" + msg.text + "\"\n";
|
||||
result += " \"text\": \"" + msg.text + "\",\n";
|
||||
} else {
|
||||
result += " \"text\": \"\"\n";
|
||||
// result += " \"text\": \"\",\n";
|
||||
}
|
||||
result += " \"speaker\": \"none\"\n";
|
||||
result += " },\n";
|
||||
has_subs = true;
|
||||
}
|
||||
|
||||
@@ -164,13 +164,16 @@ AudioDir read_audio_dir(const decompiler::Config& config, const fs::path& path)
|
||||
u64 data;
|
||||
struct {
|
||||
u64 name : 42;
|
||||
bool stereo : 1;
|
||||
bool international : 1;
|
||||
u8 param : 4;
|
||||
u64 stereo : 1;
|
||||
u64 international : 1;
|
||||
u64 param : 4;
|
||||
u64 offset : 16;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
static_assert(sizeof(DirEntryJak3) == sizeof(u64));
|
||||
|
||||
dir = reader.read<VagDirJak3>();
|
||||
ASSERT(dir.id[0] == 0x41574756);
|
||||
ASSERT(dir.id[1] == 0x52494444);
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
enum class ExtractorErrorCode {
|
||||
SUCCESS = 0,
|
||||
INVALID_CLI_INPUT = 3990,
|
||||
INVALID_CLI_INPUT_MISSING_FOLDER = 3991,
|
||||
VALIDATION_CANT_LOCATE_ELF = 4000,
|
||||
VALIDATION_SERIAL_MISSING_FROM_DB = 4001,
|
||||
VALIDATION_ELF_MISSING_FROM_DB = 4002,
|
||||
|
||||
@@ -225,7 +225,7 @@ int main(int argc, char** argv) {
|
||||
if (!project_path_override.empty()) {
|
||||
if (!fs::exists(project_path_override)) {
|
||||
lg::error("Error: project path override '{}' does not exist", project_path_override.string());
|
||||
return static_cast<int>(ExtractorErrorCode::INVALID_CLI_INPUT);
|
||||
return static_cast<int>(ExtractorErrorCode::INVALID_CLI_INPUT_MISSING_FOLDER);
|
||||
}
|
||||
auto ok = file_util::setup_project_path(project_path_override);
|
||||
if (!ok) {
|
||||
@@ -255,7 +255,7 @@ int main(int argc, char** argv) {
|
||||
// - INPUT VALIDATION
|
||||
if (!fs::exists(input_file_path)) {
|
||||
lg::error("Error: input game file path '{}' does not exist", input_file_path.string());
|
||||
return static_cast<int>(ExtractorErrorCode::INVALID_CLI_INPUT);
|
||||
return static_cast<int>(ExtractorErrorCode::INVALID_CLI_INPUT_MISSING_FOLDER);
|
||||
}
|
||||
if (data_subfolders.count(game_name) == 0) {
|
||||
lg::error("Error: input game name '{}' is not valid", game_name);
|
||||
@@ -325,7 +325,7 @@ int main(int argc, char** argv) {
|
||||
} else if (fs::is_directory(input_file_path)) {
|
||||
if (!flag_folder) {
|
||||
// if we didn't request a folder explicitly, but we got one, assume something went wrong.
|
||||
lg::error("got a folder, but didn't get folder flag");
|
||||
lg::error("got a folder, but didn't provide the folder flag");
|
||||
return static_cast<int>(ExtractorErrorCode::INVALID_CLI_INPUT);
|
||||
}
|
||||
iso_data_path = input_file_path;
|
||||
|
||||
@@ -1017,7 +1017,8 @@ void PrototypeBucketTie::read_from_file(TypedRef ref,
|
||||
for (int i = 0; i < 4; i++) {
|
||||
u32 start = index_start[i];
|
||||
u32 end = start + frag_count[i];
|
||||
ASSERT(num_color_qwcs <= end);
|
||||
// precd tie has a bug where geo 3's
|
||||
// ASSERT(num_color_qwcs <= end);
|
||||
num_color_qwcs = std::max(end, num_color_qwcs);
|
||||
}
|
||||
|
||||
@@ -1987,6 +1988,13 @@ void HFragment::read_from_file(TypedRef ref, const decompiler::DecompilerTypeSys
|
||||
size = read_plain_data_field<u32>(ref, "size", dts);
|
||||
}
|
||||
|
||||
void AdgifShaderArray::read_from_file(TypedRef ref, const decompiler::DecompilerTypeSystem& dts) {
|
||||
auto length = read_plain_data_field<s32>(ref, "length", dts);
|
||||
adgifs.resize(length);
|
||||
memcpy_plain_data((u8*)adgifs.data(), get_field_ref(ref, "data", dts),
|
||||
sizeof(AdGifData) * length);
|
||||
}
|
||||
|
||||
void BspHeader::read_from_file(const decompiler::LinkedObjectFile& file,
|
||||
const decompiler::DecompilerTypeSystem& dts,
|
||||
GameVersion version,
|
||||
@@ -2001,6 +2009,19 @@ void BspHeader::read_from_file(const decompiler::LinkedObjectFile& file,
|
||||
bsphere.read_from_file(get_field_ref(ref, "bsphere", dts));
|
||||
name = read_symbol_field(ref, "name", dts);
|
||||
|
||||
if (version == GameVersion::Jak1) {
|
||||
adgifs.read_from_file(get_and_check_ref_to_basic(ref, "adgifs", "adgif-shader-array", dts),
|
||||
dts);
|
||||
}
|
||||
|
||||
texture_page_count = read_plain_data_field<s32>(ref, "texture-page-count", dts);
|
||||
if (texture_page_count > 0) {
|
||||
auto tex_id_ptr = deref_label(get_field_ref(ref, "texture-ids", dts));
|
||||
for (int i = 0; i < texture_page_count; i++) {
|
||||
texture_ids.push_back(deref_u32(tex_id_ptr, i));
|
||||
}
|
||||
}
|
||||
|
||||
texture_remap_table.clear();
|
||||
s32 tex_remap_len = read_plain_data_field<s32>(ref, "texture-remap-table-len", dts);
|
||||
if (tex_remap_len > 0) {
|
||||
|
||||
@@ -840,6 +840,12 @@ struct DrawableTreeArray {
|
||||
std::vector<std::unique_ptr<DrawableTree>> trees;
|
||||
};
|
||||
|
||||
struct AdgifShaderArray {
|
||||
std::vector<AdGifData> adgifs;
|
||||
|
||||
void read_from_file(TypedRef ref, const decompiler::DecompilerTypeSystem& dts);
|
||||
};
|
||||
|
||||
// The "file info"
|
||||
struct FileInfo {
|
||||
std::string file_type;
|
||||
@@ -884,7 +890,9 @@ struct BspHeader {
|
||||
u16 texture_flags[kNumTextureFlags]; // jak 2 only
|
||||
//
|
||||
// (texture-ids (pointer texture-id) :offset-assert 60)
|
||||
std::vector<u32> texture_ids;
|
||||
// (texture-page-count int32 :offset-assert 64)
|
||||
s32 texture_page_count;
|
||||
//
|
||||
// (unk-zero-0 basic :offset-assert 68)
|
||||
//
|
||||
@@ -907,6 +915,7 @@ struct BspHeader {
|
||||
// (unk-data-4 float :offset-assert 160)
|
||||
// (unk-data-5 float :offset-assert 164)
|
||||
// (adgifs adgif-shader-array :offset-assert 168)
|
||||
AdgifShaderArray adgifs;
|
||||
// (actor-birth-order (pointer uint32) :offset-assert 172)
|
||||
// (split-box-indices (pointer uint16) :offset-assert 176)
|
||||
// (unk-data-8 uint32 55 :offset-assert 180)
|
||||
|
||||
@@ -19,4 +19,5 @@ void extract_collide_frags(const level_tools::CollideHash& chash,
|
||||
const decompiler::DecompilerTypeSystem& dts,
|
||||
tfrag3::Level& out);
|
||||
|
||||
void set_vertices_for_tri(tfrag3::CollisionMesh::Vertex* out, const math::Vector4f* in);
|
||||
} // namespace decompiler
|
||||
@@ -279,20 +279,25 @@ void extract_common(const ObjectFileDB& db,
|
||||
extract_art_groups_from_level(db, tex_db, {}, "ARTSPOOL", tfrag_level, art_group_data);
|
||||
|
||||
std::set<std::string> textures_we_have;
|
||||
std::set<u32> textures_we_have_id;
|
||||
|
||||
// put _all_ index textures in common.
|
||||
for (const auto& [id, tex] : tex_db.index_textures_by_combo_id) {
|
||||
tfrag_level.index_textures.push_back(tex);
|
||||
}
|
||||
|
||||
// remember which textures we already added.
|
||||
// textures with the same name or the same ID always have the same data.
|
||||
for (const auto& t : tfrag_level.textures) {
|
||||
textures_we_have.insert(t.debug_name);
|
||||
textures_we_have_id.insert(t.combo_id);
|
||||
}
|
||||
|
||||
// for common textures, add if the ID isn't there - common textures are looked up by ID.
|
||||
for (const auto& [id, normal_texture] : tex_db.textures) {
|
||||
if (config.common_tpages.count(normal_texture.page) &&
|
||||
!textures_we_have.count(normal_texture.name)) {
|
||||
if (config.common_tpages.count(normal_texture.page) && !textures_we_have_id.count(id)) {
|
||||
textures_we_have.insert(normal_texture.name);
|
||||
textures_we_have_id.insert(id);
|
||||
tfrag_level.textures.push_back(
|
||||
make_texture(id, normal_texture, tex_db.tpage_names.at(normal_texture.page), true));
|
||||
}
|
||||
@@ -323,8 +328,7 @@ void extract_common(const ObjectFileDB& db,
|
||||
|
||||
if (config.rip_levels) {
|
||||
auto file_path = file_util::get_jak_project_dir() / "glb_out" /
|
||||
game_version_names[config.game_version] / "common.glb";
|
||||
file_util::create_dir_if_needed_for_file(file_path);
|
||||
game_version_names[config.game_version] / "common";
|
||||
save_level_foreground_as_gltf(tfrag_level, art_group_data, file_path);
|
||||
}
|
||||
}
|
||||
@@ -361,14 +365,12 @@ void extract_from_level(const ObjectFileDB& db,
|
||||
|
||||
if (config.rip_levels) {
|
||||
auto back_file_path = file_util::get_jak_project_dir() / "glb_out" /
|
||||
game_version_names[config.game_version] /
|
||||
game_version_names[config.game_version] / level_data.level_name /
|
||||
fmt::format("{}-background.glb", level_data.level_name);
|
||||
file_util::create_dir_if_needed_for_file(back_file_path);
|
||||
save_level_background_as_gltf(level_data, back_file_path);
|
||||
auto fore_file_path = file_util::get_jak_project_dir() / "glb_out" /
|
||||
game_version_names[config.game_version] /
|
||||
fmt::format("{}-foreground.glb", level_data.level_name);
|
||||
file_util::create_dir_if_needed_for_file(fore_file_path);
|
||||
game_version_names[config.game_version] / level_data.level_name;
|
||||
save_level_foreground_as_gltf(level_data, art_group_data, fore_file_path);
|
||||
}
|
||||
file_util::write_text_file(entities_folder / fmt::format("{}-actors.json", level_data.level_name),
|
||||
|
||||
@@ -26,4 +26,7 @@ tfrag3::Texture make_texture(u32 id,
|
||||
bool pool_load);
|
||||
std::vector<level_tools::TextureRemap> extract_tex_remap(const ObjectFileDB& db,
|
||||
const std::string& dgo_name);
|
||||
std::optional<ObjectFileRecord> get_bsp_file(const std::vector<ObjectFileRecord>& records,
|
||||
const std::string& dgo_name);
|
||||
bool is_valid_bsp(const LinkedObjectFile& file);
|
||||
} // namespace decompiler
|
||||
@@ -853,12 +853,19 @@ ConvertedMercEffect convert_merc_effect(const MercEffect& input_effect,
|
||||
u32 tidx = (env >> 8) & 0b1111'1111'1111;
|
||||
tex_combo = (((u32)tpage) << 16) | tidx;
|
||||
} break;
|
||||
case GameVersion::Jak2:
|
||||
case GameVersion::Jak3: {
|
||||
case GameVersion::Jak2: {
|
||||
u32 tpage = 0x1f;
|
||||
u32 tidx = 2;
|
||||
tex_combo = (((u32)tpage) << 16) | tidx;
|
||||
} break;
|
||||
case GameVersion::Jak3: {
|
||||
// (define *generic-envmap-texture* (get-texture pal-environment-front environment-generic))
|
||||
// (defconstant environment-generic 2) tpage
|
||||
// (def-tex pal-environment-front environment-generic 1) texture
|
||||
u32 tpage = 2;
|
||||
u32 tidx = 1;
|
||||
tex_combo = (((u32)tpage) << 16) | tidx;
|
||||
} break;
|
||||
default:
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
|
||||
@@ -2032,6 +2032,20 @@ s32 find_or_add_texture_to_level(u32 combo_tex_id,
|
||||
if (ok_to_miss) {
|
||||
// we're missing a texture, just use the first one.
|
||||
tex_it = tdb.textures.begin();
|
||||
// some tfrags in jak 3 are missing textures, so we use some suitable
|
||||
// replacements instead of the default eye texture
|
||||
static std::map<std::string, std::string> per_level_tex_hacks = {
|
||||
{"wasintro", "des-rock-01"},
|
||||
{"intpfall", "common-black"},
|
||||
{"powergd", "common-black"},
|
||||
};
|
||||
auto it = std::find_if(tdb.textures.begin(), tdb.textures.end(),
|
||||
[&](const std::pair<u32, TextureDB::TextureData> val) {
|
||||
return val.second.name == per_level_tex_hacks[level_name];
|
||||
});
|
||||
if (it != tdb.textures.end()) {
|
||||
tex_it = it;
|
||||
}
|
||||
} else {
|
||||
ASSERT_MSG(
|
||||
false,
|
||||
|
||||
@@ -2339,7 +2339,7 @@ TieCategoryInfo get_jak1_tie_category(u32 flags) {
|
||||
return result;
|
||||
}
|
||||
|
||||
u32 get_or_add_texture(u32 combo_tex, tfrag3::Level& lev, const TextureDB& tdb) {
|
||||
s32 get_or_add_texture(u32 combo_tex, tfrag3::Level& lev, const TextureDB& tdb) {
|
||||
if (combo_tex == 0) {
|
||||
// untextured
|
||||
combo_tex = (((u32)TextureDB::kPlaceholderWhiteTexturePage) << 16) |
|
||||
@@ -2348,7 +2348,7 @@ u32 get_or_add_texture(u32 combo_tex, tfrag3::Level& lev, const TextureDB& tdb)
|
||||
|
||||
// try looking it up in the existing textures that we have in the C++ renderer data.
|
||||
// (this is shared with tfrag)
|
||||
u32 idx_in_lev_data = UINT32_MAX;
|
||||
s32 idx_in_lev_data = INT32_MAX;
|
||||
for (u32 i = 0; i < lev.textures.size(); i++) {
|
||||
if (lev.textures[i].combo_id == combo_tex) {
|
||||
idx_in_lev_data = i;
|
||||
@@ -2356,7 +2356,7 @@ u32 get_or_add_texture(u32 combo_tex, tfrag3::Level& lev, const TextureDB& tdb)
|
||||
}
|
||||
}
|
||||
|
||||
if (idx_in_lev_data == UINT32_MAX) {
|
||||
if (idx_in_lev_data == INT32_MAX) {
|
||||
// didn't find it, have to add a new one texture.
|
||||
auto tex_it = tdb.textures.find(combo_tex);
|
||||
if (tex_it == tdb.textures.end()) {
|
||||
@@ -2378,14 +2378,20 @@ u32 get_or_add_texture(u32 combo_tex, tfrag3::Level& lev, const TextureDB& tdb)
|
||||
new_tex.debug_tpage_name = tdb.tpage_names.at(tex_it->second.page);
|
||||
new_tex.data = tex_it->second.rgba_bytes;
|
||||
}
|
||||
const auto& level_tex = lev.textures.at(idx_in_lev_data);
|
||||
const auto& it = tdb.animated_tex_output_to_anim_slot.find(level_tex.debug_name);
|
||||
if (it != tdb.animated_tex_output_to_anim_slot.end()) {
|
||||
// lg::warn("TIE animated texture: {}", level_tex.debug_name);
|
||||
return -int(it->second) - 1;
|
||||
}
|
||||
return idx_in_lev_data;
|
||||
}
|
||||
|
||||
void handle_wind_draw_for_strip(
|
||||
tfrag3::TieTree& tree,
|
||||
std::unordered_map<u32, std::vector<u32>>& wind_draws_by_tex,
|
||||
std::unordered_map<s32, std::vector<u32>>& wind_draws_by_tex,
|
||||
const std::vector<std::vector<std::pair<int, int>>>& packed_vert_indices,
|
||||
u32 idx_in_lev_data,
|
||||
s32 idx_in_lev_data,
|
||||
DrawMode mode,
|
||||
const TieStrip& strip,
|
||||
const TieInstanceInfo& inst,
|
||||
@@ -2452,7 +2458,7 @@ void handle_wind_draw_for_strip(
|
||||
}
|
||||
|
||||
void handle_draw_for_strip(tfrag3::TieTree& tree,
|
||||
std::unordered_map<u32, std::vector<u32>>& static_draws_by_tex,
|
||||
std::unordered_map<s32, std::vector<u32>>& static_draws_by_tex,
|
||||
std::vector<tfrag3::StripDraw>& category_draws,
|
||||
const std::vector<std::vector<std::pair<int, int>>>& packed_vert_indices,
|
||||
DrawMode mode,
|
||||
@@ -2542,8 +2548,8 @@ void add_vertices_and_static_draw(tfrag3::TieTree& tree,
|
||||
GameVersion version) {
|
||||
// our current approach for static draws is just to flatten to giant mesh, except for wind stuff.
|
||||
// this map sorts these two types of draws by texture.
|
||||
std::unordered_map<u32, std::vector<u32>> static_draws_by_tex;
|
||||
std::unordered_map<u32, std::vector<u32>> wind_draws_by_tex;
|
||||
std::unordered_map<s32, std::vector<u32>> static_draws_by_tex;
|
||||
std::unordered_map<s32, std::vector<u32>> wind_draws_by_tex;
|
||||
|
||||
std::array<std::vector<tfrag3::StripDraw>, tfrag3::kNumTieCategories> draws_by_category;
|
||||
|
||||
@@ -2632,7 +2638,7 @@ void add_vertices_and_static_draw(tfrag3::TieTree& tree,
|
||||
for (size_t strip_idx = 0; strip_idx < frag.strips.size(); strip_idx++) {
|
||||
auto& strip = frag.strips[strip_idx];
|
||||
|
||||
u32 idx_in_lev_data = get_or_add_texture(strip.adgif.combo_tex, lev, tdb);
|
||||
s32 idx_in_lev_data = get_or_add_texture(strip.adgif.combo_tex, lev, tdb);
|
||||
// determine the draw mode
|
||||
DrawMode mode = process_draw_mode(strip.adgif, frag.prog_info.misc_x == 0,
|
||||
frag.has_magic_tex0_bit, version, info.category);
|
||||
@@ -2649,7 +2655,7 @@ void add_vertices_and_static_draw(tfrag3::TieTree& tree,
|
||||
draws_by_category.at((int)info.category), packed_vert_indices,
|
||||
mode, idx_in_lev_data, strip, inst, ifrag, proto_idx, frag_idx,
|
||||
strip_idx, matrix_idx);
|
||||
u32 envmap_tex_idx =
|
||||
s32 envmap_tex_idx =
|
||||
get_or_add_texture(proto.envmap_adgif.value().combo_tex, lev, tdb);
|
||||
|
||||
// second pass envmap draw mode, in envmap bucket, envmap-specific draw list
|
||||
@@ -2747,6 +2753,10 @@ void extract_tie(const level_tools::DrawableTreeInstanceTie* tree,
|
||||
bool dump_level,
|
||||
GameVersion version) {
|
||||
for (int geo = 0; geo < GEOM_MAX; ++geo) {
|
||||
// as far as I can tell, this one has bad colors
|
||||
if (debug_name == "PRECD.DGO-2-tie" && geo == 3) {
|
||||
continue;
|
||||
}
|
||||
tfrag3::TieTree this_tree;
|
||||
|
||||
// sanity check the vis tree (not a perfect check, but this is used in game and should be right)
|
||||
|
||||
@@ -93,36 +93,33 @@ void unstrip_tie_wind(std::vector<u32>& unstripped,
|
||||
}
|
||||
|
||||
/*!
|
||||
* Convert merc strips. Doesn't assume anything about strips. Output is [model][effect][draw] format
|
||||
* Convert merc strips. Doesn't assume anything about strips. Output is [effect][draw] format (done
|
||||
* for each model)
|
||||
*/
|
||||
void unstrip_merc_draws(const std::vector<u32>& stripped_indices,
|
||||
const std::vector<tfrag3::MercModel>& models,
|
||||
const tfrag3::MercModel& model,
|
||||
std::vector<u32>& unstripped,
|
||||
std::vector<std::vector<std::vector<u32>>>& draw_to_start,
|
||||
std::vector<std::vector<std::vector<u32>>>& draw_to_count) {
|
||||
for (auto& model : models) {
|
||||
auto& model_dts = draw_to_start.emplace_back();
|
||||
auto& model_dtc = draw_to_count.emplace_back();
|
||||
for (auto& effect : model.effects) {
|
||||
auto& effect_dts = model_dts.emplace_back();
|
||||
auto& effect_dtc = model_dtc.emplace_back();
|
||||
for (auto& draw : effect.all_draws) {
|
||||
effect_dts.push_back(unstripped.size());
|
||||
std::vector<std::vector<u32>>& draw_to_start,
|
||||
std::vector<std::vector<u32>>& draw_to_count) {
|
||||
for (auto& effect : model.effects) {
|
||||
auto& effect_dts = draw_to_start.emplace_back();
|
||||
auto& effect_dtc = draw_to_count.emplace_back();
|
||||
for (auto& draw : effect.all_draws) {
|
||||
effect_dts.push_back(unstripped.size());
|
||||
|
||||
for (size_t i = 2; i < draw.index_count; i++) {
|
||||
int idx = i + draw.first_index;
|
||||
u32 a = stripped_indices[idx];
|
||||
u32 b = stripped_indices[idx - 1];
|
||||
u32 c = stripped_indices[idx - 2];
|
||||
if (a == UINT32_MAX || b == UINT32_MAX || c == UINT32_MAX) {
|
||||
continue;
|
||||
}
|
||||
unstripped.push_back(a);
|
||||
unstripped.push_back(b);
|
||||
unstripped.push_back(c);
|
||||
for (size_t i = 2; i < draw.index_count; i++) {
|
||||
int idx = i + draw.first_index;
|
||||
u32 a = stripped_indices[idx];
|
||||
u32 b = stripped_indices[idx - 1];
|
||||
u32 c = stripped_indices[idx - 2];
|
||||
if (a == UINT32_MAX || b == UINT32_MAX || c == UINT32_MAX) {
|
||||
continue;
|
||||
}
|
||||
effect_dtc.push_back(unstripped.size() - effect_dts.back());
|
||||
unstripped.push_back(a);
|
||||
unstripped.push_back(b);
|
||||
unstripped.push_back(c);
|
||||
}
|
||||
effect_dtc.push_back(unstripped.size() - effect_dts.back());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -485,12 +482,12 @@ int make_shrub_index_buffer_view(const std::vector<u32>& indices,
|
||||
}
|
||||
|
||||
int make_merc_index_buffer_view(const std::vector<u32>& indices,
|
||||
const std::vector<tfrag3::MercModel>& models,
|
||||
const tfrag3::MercModel& mmodel,
|
||||
tinygltf::Model& model,
|
||||
std::vector<std::vector<std::vector<u32>>>& draw_to_start,
|
||||
std::vector<std::vector<std::vector<u32>>>& draw_to_count) {
|
||||
std::vector<std::vector<u32>>& draw_to_start,
|
||||
std::vector<std::vector<u32>>& draw_to_count) {
|
||||
std::vector<u32> unstripped;
|
||||
unstrip_merc_draws(indices, models, unstripped, draw_to_start, draw_to_count);
|
||||
unstrip_merc_draws(indices, mmodel, unstripped, draw_to_start, draw_to_count);
|
||||
|
||||
// first create a buffer:
|
||||
int buffer_idx = (int)model.buffers.size();
|
||||
@@ -884,6 +881,7 @@ int make_inv_matrix_bind_poses(const std::vector<level_tools::Joint>& joints,
|
||||
|
||||
void add_merc(const tfrag3::Level& level,
|
||||
const std::map<std::string, level_tools::ArtData>& art_data,
|
||||
const tfrag3::MercModel& mmodel,
|
||||
tinygltf::Model& model,
|
||||
std::unordered_map<int, int>& tex_image_map) {
|
||||
const auto& mverts = level.merc_data.vertices;
|
||||
@@ -892,92 +890,89 @@ void add_merc(const tfrag3::Level& level,
|
||||
int position_buffer_accessor = make_position_buffer_accessor(mverts, model);
|
||||
int texture_buffer_accessor = make_tex_buffer_accessor(mverts, model, 1.f);
|
||||
|
||||
std::vector<std::vector<std::vector<u32>>> draw_to_start, draw_to_count;
|
||||
int index_buffer_view = make_merc_index_buffer_view(
|
||||
level.merc_data.indices, level.merc_data.models, model, draw_to_start, draw_to_count);
|
||||
std::vector<std::vector<u32>> draw_to_start, draw_to_count;
|
||||
int index_buffer_view = make_merc_index_buffer_view(level.merc_data.indices, mmodel, model,
|
||||
draw_to_start, draw_to_count);
|
||||
int colors = make_color_buffer_accessor(mverts, model);
|
||||
|
||||
auto joints_accessor = make_bones_accessor(mverts, model);
|
||||
auto weights_accessor = make_weights_accessor(mverts, model);
|
||||
|
||||
for (size_t model_idx = 0; model_idx < level.merc_data.models.size(); model_idx++) {
|
||||
const auto& mmodel = level.merc_data.models[model_idx];
|
||||
const auto& art = art_data.find(mmodel.name);
|
||||
int node_idx = (int)model.nodes.size();
|
||||
auto& node = model.nodes.emplace_back();
|
||||
model.scenes.at(0).nodes.push_back(node_idx);
|
||||
node.name = mmodel.name;
|
||||
int mesh_idx = (int)model.meshes.size();
|
||||
auto& mesh = model.meshes.emplace_back();
|
||||
mesh.name = node.name;
|
||||
node.mesh = mesh_idx;
|
||||
const auto& art = art_data.find(mmodel.name);
|
||||
int node_idx = (int)model.nodes.size();
|
||||
auto& node = model.nodes.emplace_back();
|
||||
model.scenes.at(0).nodes.push_back(node_idx);
|
||||
node.name = mmodel.name;
|
||||
int mesh_idx = (int)model.meshes.size();
|
||||
auto& mesh = model.meshes.emplace_back();
|
||||
mesh.name = node.name;
|
||||
node.mesh = mesh_idx;
|
||||
|
||||
if (art != art_data.end() && !art->second.joint_group.empty()) {
|
||||
node.skin = model.skins.size();
|
||||
auto& skin = model.skins.emplace_back();
|
||||
const auto& game_bones = art->second.joint_group;
|
||||
int n_bones = game_bones.size();
|
||||
std::vector<std::vector<int>> children(n_bones);
|
||||
for (size_t i = 0; i < game_bones.size(); i++) {
|
||||
if (game_bones[i].parent_idx >= 0) {
|
||||
children.at(game_bones[i].parent_idx).push_back(i);
|
||||
}
|
||||
if (art != art_data.end() && !art->second.joint_group.empty()) {
|
||||
node.skin = model.skins.size();
|
||||
auto& skin = model.skins.emplace_back();
|
||||
const auto& game_bones = art->second.joint_group;
|
||||
int n_bones = game_bones.size();
|
||||
std::vector<std::vector<int>> children(n_bones);
|
||||
for (size_t i = 0; i < game_bones.size(); i++) {
|
||||
if (game_bones[i].parent_idx >= 0) {
|
||||
children.at(game_bones[i].parent_idx).push_back(i);
|
||||
}
|
||||
skin.skeleton = model.nodes.size();
|
||||
for (int i = 0; i < n_bones; i++) {
|
||||
const auto& gbone = game_bones[i];
|
||||
skin.joints.push_back(skin.skeleton + i);
|
||||
auto& snode = model.nodes.emplace_back();
|
||||
snode.name = gbone.name;
|
||||
}
|
||||
skin.skeleton = model.nodes.size();
|
||||
for (int i = 0; i < n_bones; i++) {
|
||||
const auto& gbone = game_bones[i];
|
||||
skin.joints.push_back(skin.skeleton + i);
|
||||
auto& snode = model.nodes.emplace_back();
|
||||
snode.name = gbone.name;
|
||||
|
||||
// bind pose is bind_T_w
|
||||
// for glb we want bind_parent_T_bind_child
|
||||
// so bindp_T_w * inverse(bindc_T_w)
|
||||
math::Matrix4f matrix;
|
||||
if (gbone.parent_idx >= 0) {
|
||||
matrix = unscale_translation(game_bones.at(gbone.parent_idx).bind_pose_T_w) *
|
||||
inverse(unscale_translation(gbone.bind_pose_T_w));
|
||||
|
||||
} else {
|
||||
// I think this value is ignored anyway.
|
||||
for (int r = 0; r < 4; r++) {
|
||||
for (int c = 0; c < 4; c++) {
|
||||
matrix(r, c) = (r == c) ? 1 : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
// bind pose is bind_T_w
|
||||
// for glb we want bind_parent_T_bind_child
|
||||
// so bindp_T_w * inverse(bindc_T_w)
|
||||
math::Matrix4f matrix;
|
||||
if (gbone.parent_idx >= 0) {
|
||||
matrix = unscale_translation(game_bones.at(gbone.parent_idx).bind_pose_T_w) *
|
||||
inverse(unscale_translation(gbone.bind_pose_T_w));
|
||||
|
||||
} else {
|
||||
// I think this value is ignored anyway.
|
||||
for (int r = 0; r < 4; r++) {
|
||||
for (int c = 0; c < 4; c++) {
|
||||
snode.matrix.push_back(matrix(c, r));
|
||||
matrix(r, c) = (r == c) ? 1 : 0;
|
||||
}
|
||||
}
|
||||
for (auto child : children.at(i)) {
|
||||
snode.children.push_back(skin.skeleton + child);
|
||||
}
|
||||
|
||||
for (int r = 0; r < 4; r++) {
|
||||
for (int c = 0; c < 4; c++) {
|
||||
snode.matrix.push_back(matrix(c, r));
|
||||
}
|
||||
}
|
||||
ASSERT(skin.skeleton + n_bones == (int)model.nodes.size());
|
||||
skin.inverseBindMatrices = make_inv_matrix_bind_poses(game_bones, model);
|
||||
}
|
||||
|
||||
for (size_t effect_idx = 0; effect_idx < mmodel.effects.size(); effect_idx++) {
|
||||
const auto& effect = mmodel.effects[effect_idx];
|
||||
for (size_t draw_idx = 0; draw_idx < effect.all_draws.size(); draw_idx++) {
|
||||
const auto& draw = effect.all_draws[draw_idx];
|
||||
auto& prim = mesh.primitives.emplace_back();
|
||||
prim.material =
|
||||
add_material_for_tex(level, model, draw.tree_tex_id, tex_image_map, draw.mode);
|
||||
prim.indices = make_index_buffer_accessor(
|
||||
model, draw_to_start[model_idx][effect_idx][draw_idx],
|
||||
draw_to_count[model_idx][effect_idx][draw_idx], index_buffer_view);
|
||||
prim.attributes["POSITION"] = position_buffer_accessor;
|
||||
prim.attributes["TEXCOORD_0"] = texture_buffer_accessor;
|
||||
prim.attributes["COLOR_0"] = colors;
|
||||
prim.attributes["JOINTS_0"] = joints_accessor;
|
||||
prim.attributes["WEIGHTS_0"] = weights_accessor;
|
||||
prim.mode = TINYGLTF_MODE_TRIANGLES;
|
||||
for (auto child : children.at(i)) {
|
||||
snode.children.push_back(skin.skeleton + child);
|
||||
}
|
||||
}
|
||||
ASSERT(skin.skeleton + n_bones == (int)model.nodes.size());
|
||||
skin.inverseBindMatrices = make_inv_matrix_bind_poses(game_bones, model);
|
||||
}
|
||||
|
||||
for (size_t effect_idx = 0; effect_idx < mmodel.effects.size(); effect_idx++) {
|
||||
const auto& effect = mmodel.effects[effect_idx];
|
||||
for (size_t draw_idx = 0; draw_idx < effect.all_draws.size(); draw_idx++) {
|
||||
const auto& draw = effect.all_draws[draw_idx];
|
||||
auto& prim = mesh.primitives.emplace_back();
|
||||
prim.material =
|
||||
add_material_for_tex(level, model, draw.tree_tex_id, tex_image_map, draw.mode);
|
||||
prim.indices =
|
||||
make_index_buffer_accessor(model, draw_to_start[effect_idx][draw_idx],
|
||||
draw_to_count[effect_idx][draw_idx], index_buffer_view);
|
||||
prim.attributes["POSITION"] = position_buffer_accessor;
|
||||
prim.attributes["TEXCOORD_0"] = texture_buffer_accessor;
|
||||
prim.attributes["COLOR_0"] = colors;
|
||||
prim.attributes["JOINTS_0"] = joints_accessor;
|
||||
prim.attributes["WEIGHTS_0"] = weights_accessor;
|
||||
prim.mode = TINYGLTF_MODE_TRIANGLES;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
@@ -1026,30 +1021,38 @@ void save_level_background_as_gltf(const tfrag3::Level& level, const fs::path& g
|
||||
|
||||
void save_level_foreground_as_gltf(const tfrag3::Level& level,
|
||||
const std::map<std::string, level_tools::ArtData>& art_data,
|
||||
const fs::path& glb_file) {
|
||||
// the top level container for everything is the model.
|
||||
tinygltf::Model model;
|
||||
const fs::path& glb_path) {
|
||||
for (size_t model_idx = 0; model_idx < level.merc_data.models.size(); model_idx++) {
|
||||
const auto& mmodel = level.merc_data.models[model_idx];
|
||||
|
||||
// a "scene" is a traditional scene graph, made up of Nodes.
|
||||
// sadly, attempting to nest stuff makes the blender importer unhappy, so we just dump
|
||||
// everything into the top level.
|
||||
model.scenes.emplace_back();
|
||||
// the top level container for everything is the model.
|
||||
tinygltf::Model model;
|
||||
|
||||
// hack, add a default material.
|
||||
tinygltf::Material mat;
|
||||
mat.pbrMetallicRoughness.baseColorFactor = {1.0f, 0.9f, 0.9f, 1.0f};
|
||||
mat.doubleSided = true;
|
||||
model.materials.push_back(mat);
|
||||
// a "scene" is a traditional scene graph, made up of Nodes.
|
||||
// sadly, attempting to nest stuff makes the blender importer unhappy, so we just dump
|
||||
// everything into the top level.
|
||||
model.scenes.emplace_back();
|
||||
|
||||
std::unordered_map<int, int> tex_image_map;
|
||||
// hack, add a default material.
|
||||
tinygltf::Material mat;
|
||||
mat.pbrMetallicRoughness.baseColorFactor = {1.0f, 0.9f, 0.9f, 1.0f};
|
||||
mat.doubleSided = true;
|
||||
model.materials.push_back(mat);
|
||||
|
||||
add_merc(level, art_data, model, tex_image_map);
|
||||
std::unordered_map<int, int> tex_image_map;
|
||||
|
||||
model.asset.generator = "opengoal";
|
||||
tinygltf::TinyGLTF gltf;
|
||||
gltf.WriteGltfSceneToFile(&model, glb_file.string(),
|
||||
true, // embedImages
|
||||
true, // embedBuffers
|
||||
true, // pretty print
|
||||
true); // write binary
|
||||
add_merc(level, art_data, mmodel, model, tex_image_map);
|
||||
|
||||
model.asset.generator = "opengoal";
|
||||
|
||||
auto glb_file = glb_path / fmt::format("{}.glb", mmodel.name);
|
||||
file_util::create_dir_if_needed_for_file(glb_file);
|
||||
|
||||
tinygltf::TinyGLTF gltf;
|
||||
gltf.WriteGltfSceneToFile(&model, glb_file.string(),
|
||||
true, // embedImages
|
||||
true, // embedBuffers
|
||||
true, // pretty print
|
||||
true); // write binary
|
||||
}
|
||||
}
|
||||
@@ -13,4 +13,4 @@
|
||||
void save_level_background_as_gltf(const tfrag3::Level& level, const fs::path& glb_file);
|
||||
void save_level_foreground_as_gltf(const tfrag3::Level& level,
|
||||
const std::map<std::string, level_tools::ArtData>& art_data,
|
||||
const fs::path& glb_file);
|
||||
const fs::path& glb_path);
|
||||
@@ -3,18 +3,25 @@
|
||||
using namespace gltf_util;
|
||||
|
||||
namespace decompiler {
|
||||
|
||||
void extract(const std::string& name,
|
||||
MercExtractData& out,
|
||||
const tinygltf::Model& model,
|
||||
const std::vector<NodeWithTransform>& all_nodes,
|
||||
u32 index_offset,
|
||||
u32 vertex_offset,
|
||||
u32 tex_offset) {
|
||||
u32 tex_offset,
|
||||
bool& has_custom_weights) {
|
||||
ASSERT(out.new_vertices.empty());
|
||||
|
||||
std::map<int, tfrag3::MercDraw> draw_by_material;
|
||||
int mesh_count = 0;
|
||||
int prim_count = 0;
|
||||
int joints = 3;
|
||||
auto skin_idx = find_single_skin(model, all_nodes);
|
||||
if (skin_idx) {
|
||||
joints += get_joint_count(model, *skin_idx);
|
||||
}
|
||||
|
||||
for (const auto& n : all_nodes) {
|
||||
const auto& node = model.nodes[n.node_idx];
|
||||
@@ -24,6 +31,8 @@ void extract(const std::string& name,
|
||||
if (node.mesh >= 0) {
|
||||
const auto& mesh = model.meshes[node.mesh];
|
||||
mesh_count++;
|
||||
has_custom_weights = node.extras.Has("enable_custom_weights") &&
|
||||
node.extras.Get("enable_custom_weights").Get<int>();
|
||||
for (const auto& prim : mesh.primitives) {
|
||||
prim_count++;
|
||||
// extract index buffer
|
||||
@@ -39,6 +48,21 @@ void extract(const std::string& name,
|
||||
out.normals.insert(out.normals.end(), verts.normals.begin(), verts.normals.end());
|
||||
ASSERT(out.new_colors.size() == out.new_vertices.size());
|
||||
|
||||
if (prim.attributes.count("JOINTS_0") && prim.attributes.count("WEIGHTS_0")) {
|
||||
auto joints_and_weights = gltf_util::extract_and_flatten_joints_and_weights(model, prim);
|
||||
ASSERT(joints_and_weights.size() == verts.vtx.size());
|
||||
out.joints_and_weights.insert(out.joints_and_weights.end(), joints_and_weights.begin(),
|
||||
joints_and_weights.end());
|
||||
} else {
|
||||
// add fake data for vertices without this data
|
||||
gltf_util::JointsAndWeights dummy;
|
||||
dummy.joints[0] = 3;
|
||||
dummy.weights[0] = 1.f;
|
||||
for (size_t i = 0; i < out.new_vertices.size(); i++) {
|
||||
out.joints_and_weights.push_back(dummy);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: just putting it all in one material
|
||||
auto& draw = draw_by_material[prim.material];
|
||||
draw.mode = gltf_util::make_default_draw_mode(); // todo rm
|
||||
@@ -54,42 +78,111 @@ void extract(const std::string& name,
|
||||
}
|
||||
|
||||
tfrag3::MercEffect e;
|
||||
tfrag3::MercEffect envmap_eff;
|
||||
envmap_eff.has_envmap = false;
|
||||
out.new_model.name = name;
|
||||
out.new_model.max_bones = 120;
|
||||
out.new_model.max_draws = 200;
|
||||
for (const auto& [mat_idx, d_] : draw_by_material) {
|
||||
e.all_draws.push_back(d_);
|
||||
auto& draw = e.all_draws.back();
|
||||
draw.mode = make_default_draw_mode();
|
||||
out.new_model.max_bones = joints;
|
||||
out.new_model.max_draws = 0;
|
||||
|
||||
auto process_normal_draw = [&](tfrag3::MercEffect& eff, int mat_idx, const tfrag3::MercDraw& d_) {
|
||||
const auto& mat = model.materials[mat_idx];
|
||||
eff.all_draws.push_back(d_);
|
||||
auto& draw = eff.all_draws.back();
|
||||
draw.mode = gltf_util::make_default_draw_mode();
|
||||
|
||||
if (mat_idx == -1) {
|
||||
lg::warn("Draw had a material index of -1, using default texture.");
|
||||
draw.tree_tex_id = 0;
|
||||
continue;
|
||||
return;
|
||||
}
|
||||
const auto& mat = model.materials[mat_idx];
|
||||
int tex_idx = mat.pbrMetallicRoughness.baseColorTexture.index;
|
||||
if (tex_idx == -1) {
|
||||
lg::warn("Material {} has no texture, using default texture.", mat.name);
|
||||
draw.tree_tex_id = 0;
|
||||
continue;
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& tex = model.textures[tex_idx];
|
||||
ASSERT(tex.sampler >= 0);
|
||||
ASSERT(tex.source >= 0);
|
||||
draw.mode = draw_mode_from_sampler(model.samplers.at(tex.sampler));
|
||||
gltf_util::setup_draw_mode_from_sampler(model.samplers.at(tex.sampler), &draw.mode);
|
||||
gltf_util::setup_alpha_from_material(mat, &draw.mode);
|
||||
|
||||
const auto& img = model.images[tex.source];
|
||||
draw.tree_tex_id = tex_offset + texture_pool_add_texture(&out.tex_pool, img);
|
||||
}
|
||||
lg::info("total of {} unique materials", e.all_draws.size());
|
||||
e.has_mod_draw = false;
|
||||
out.new_model.effects.push_back(e);
|
||||
out.new_model.effects.push_back(e);
|
||||
out.new_model.effects.push_back(e);
|
||||
out.new_model.effects.push_back(e);
|
||||
};
|
||||
|
||||
auto process_envmap_draw = [&](tfrag3::MercEffect& eff, int mat_idx, const tfrag3::MercDraw& d_) {
|
||||
const auto& mat = model.materials[mat_idx];
|
||||
eff.all_draws.push_back(d_);
|
||||
auto& draw = eff.all_draws.back();
|
||||
draw.mode = gltf_util::make_default_draw_mode();
|
||||
|
||||
if (mat_idx == -1) {
|
||||
lg::warn("Envmap draw had a material index of -1, using default texture.");
|
||||
draw.tree_tex_id = texture_pool_debug_checker(&out.tex_pool);
|
||||
return;
|
||||
}
|
||||
int base_tex_idx = mat.pbrMetallicRoughness.baseColorTexture.index;
|
||||
if (base_tex_idx == -1) {
|
||||
lg::warn("Envmap material {} has no texture, using default texture.", mat.name);
|
||||
draw.tree_tex_id = texture_pool_debug_checker(&out.tex_pool);
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& base_tex = model.textures[base_tex_idx];
|
||||
ASSERT(base_tex.sampler >= 0);
|
||||
ASSERT(base_tex.source >= 0);
|
||||
gltf_util::setup_draw_mode_from_sampler(model.samplers.at(base_tex.sampler), &draw.mode);
|
||||
gltf_util::setup_alpha_from_material(mat, &draw.mode);
|
||||
const auto& roughness_tex =
|
||||
model.textures.at(mat.pbrMetallicRoughness.metallicRoughnessTexture.index);
|
||||
ASSERT(roughness_tex.sampler >= 0);
|
||||
ASSERT(roughness_tex.source >= 0);
|
||||
|
||||
draw.tree_tex_id =
|
||||
tex_offset + gltf_util::texture_pool_add_envmap_control_texture(
|
||||
&out.tex_pool, model, base_tex.source, roughness_tex.source,
|
||||
!draw.mode.get_clamp_s_enable(), !draw.mode.get_clamp_t_enable());
|
||||
|
||||
// now, setup envmap draw:
|
||||
auto envmap_settings = gltf_util::envmap_settings_from_gltf(mat);
|
||||
const auto& envmap_tex = model.textures[envmap_settings.texture_idx];
|
||||
ASSERT(envmap_tex.sampler >= 0);
|
||||
ASSERT(envmap_tex.source >= 0);
|
||||
auto env_mode = gltf_util::make_default_draw_mode();
|
||||
gltf_util::setup_draw_mode_from_sampler(model.samplers.at(envmap_tex.sampler), &env_mode);
|
||||
eff.envmap_texture = tex_offset + gltf_util::texture_pool_add_texture(
|
||||
&out.tex_pool, model.images[envmap_tex.source]);
|
||||
env_mode.set_alpha_blend(DrawMode::AlphaBlend::SRC_0_DST_DST);
|
||||
env_mode.enable_ab();
|
||||
eff.envmap_mode = env_mode;
|
||||
};
|
||||
|
||||
for (const auto& [mat_idx, d_] : draw_by_material) {
|
||||
const auto& mat = model.materials[mat_idx];
|
||||
if (!material_has_envmap(mat) || !envmap_is_valid(mat)) {
|
||||
process_normal_draw(e, mat_idx, d_);
|
||||
} else {
|
||||
envmap_eff.has_envmap = true;
|
||||
process_envmap_draw(envmap_eff, mat_idx, d_);
|
||||
}
|
||||
}
|
||||
|
||||
// in case a model only has envmap draws, we don't push the normal merc effect
|
||||
if (!e.all_draws.empty()) {
|
||||
out.new_model.effects.push_back(e);
|
||||
}
|
||||
if (envmap_eff.has_envmap) {
|
||||
out.new_model.effects.push_back(envmap_eff);
|
||||
}
|
||||
|
||||
for (auto& effect : out.new_model.effects) {
|
||||
out.new_model.max_draws += effect.all_draws.size();
|
||||
}
|
||||
|
||||
lg::info("total of {} unique materials ({} normal, {} envmap)", out.new_model.max_draws,
|
||||
e.all_draws.size(), envmap_eff.all_draws.size());
|
||||
lg::info("Merged {} meshes and {} prims into {} vertices", mesh_count, prim_count,
|
||||
out.new_vertices.size());
|
||||
}
|
||||
@@ -99,9 +192,9 @@ const tfrag3::MercVertex& find_closest(const std::vector<tfrag3::MercVertex>& ol
|
||||
float y,
|
||||
float z) {
|
||||
float best_dist = 1e10;
|
||||
int best_idx = 0;
|
||||
size_t best_idx = 0;
|
||||
|
||||
for (int i = 0; i < old.size(); i++) {
|
||||
for (size_t i = 0; i < old.size(); i++) {
|
||||
auto& v = old[i];
|
||||
float dx = v.pos[0] - x;
|
||||
float dy = v.pos[1] - y;
|
||||
@@ -118,7 +211,8 @@ const tfrag3::MercVertex& find_closest(const std::vector<tfrag3::MercVertex>& ol
|
||||
|
||||
void merc_convert_replacement(MercSwapData& out,
|
||||
const MercExtractData& in,
|
||||
const std::vector<tfrag3::MercVertex>& old_verts) {
|
||||
const std::vector<tfrag3::MercVertex>& old_verts,
|
||||
bool use_custom_weights) {
|
||||
out.new_model = in.new_model;
|
||||
out.new_indices = in.new_indices;
|
||||
out.new_textures = in.tex_pool.textures_by_idx;
|
||||
@@ -126,26 +220,36 @@ void merc_convert_replacement(MercSwapData& out,
|
||||
// convert vertices
|
||||
for (size_t i = 0; i < in.new_vertices.size(); i++) {
|
||||
const auto& y = in.new_vertices[i];
|
||||
|
||||
const auto& copy_from = find_closest(old_verts, y.x, y.y, y.z);
|
||||
auto& x = out.new_vertices.emplace_back();
|
||||
x.pos[0] = y.x;
|
||||
x.pos[1] = y.y;
|
||||
x.pos[2] = y.z;
|
||||
x.normal[0] = copy_from.normal[0];
|
||||
x.normal[1] = copy_from.normal[1];
|
||||
x.normal[2] = copy_from.normal[2];
|
||||
x.weights[0] = copy_from.weights[0];
|
||||
x.weights[1] = copy_from.weights[1];
|
||||
x.weights[2] = copy_from.weights[2];
|
||||
x.normal[0] = in.normals.at(i).x();
|
||||
x.normal[1] = in.normals.at(i).y();
|
||||
x.normal[2] = in.normals.at(i).z();
|
||||
if (use_custom_weights) {
|
||||
x.weights[0] = in.joints_and_weights.at(i).weights[0];
|
||||
x.weights[1] = in.joints_and_weights.at(i).weights[1];
|
||||
x.weights[2] = in.joints_and_weights.at(i).weights[2];
|
||||
x.mats[0] = in.joints_and_weights.at(i).joints[0];
|
||||
x.mats[1] = in.joints_and_weights.at(i).joints[1];
|
||||
x.mats[2] = in.joints_and_weights.at(i).joints[2];
|
||||
} else {
|
||||
x.weights[0] = copy_from.weights[0];
|
||||
x.weights[1] = copy_from.weights[1];
|
||||
x.weights[2] = copy_from.weights[2];
|
||||
x.mats[0] = copy_from.mats[0];
|
||||
x.mats[1] = copy_from.mats[1];
|
||||
x.mats[2] = copy_from.mats[2];
|
||||
}
|
||||
x.st[0] = y.s;
|
||||
x.st[1] = y.t;
|
||||
x.rgba[0] = in.new_colors[i][0];
|
||||
x.rgba[1] = in.new_colors[i][1];
|
||||
x.rgba[2] = in.new_colors[i][2];
|
||||
x.rgba[3] = in.new_colors[i][3];
|
||||
x.mats[0] = copy_from.mats[0];
|
||||
x.mats[1] = copy_from.mats[1];
|
||||
x.mats[2] = copy_from.mats[2];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,18 +268,18 @@ void merc_convert_custom(MercSwapData& out, const MercExtractData& in) {
|
||||
x.normal[0] = in.normals.at(i).x();
|
||||
x.normal[1] = in.normals.at(i).y();
|
||||
x.normal[2] = in.normals.at(i).z();
|
||||
x.weights[0] = 1.0f;
|
||||
x.weights[1] = 0.0f;
|
||||
x.weights[2] = 0.0f;
|
||||
x.weights[0] = in.joints_and_weights.at(i).weights[0];
|
||||
x.weights[1] = in.joints_and_weights.at(i).weights[1];
|
||||
x.weights[2] = in.joints_and_weights.at(i).weights[2];
|
||||
x.st[0] = y.s;
|
||||
x.st[1] = y.t;
|
||||
x.rgba[0] = in.new_colors[i][0];
|
||||
x.rgba[1] = in.new_colors[i][1];
|
||||
x.rgba[2] = in.new_colors[i][2];
|
||||
x.rgba[3] = in.new_colors[i][3];
|
||||
x.mats[0] = 3;
|
||||
x.mats[1] = 0;
|
||||
x.mats[2] = 0;
|
||||
x.mats[0] = in.joints_and_weights.at(i).joints[0];
|
||||
x.mats[1] = in.joints_and_weights.at(i).joints[1];
|
||||
x.mats[2] = in.joints_and_weights.at(i).joints[2];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -198,12 +302,13 @@ MercSwapData load_replacement_merc_model(const std::string& name,
|
||||
auto all_nodes = flatten_nodes_from_all_scenes(model);
|
||||
|
||||
MercExtractData extract_data;
|
||||
auto has_custom_weights = false;
|
||||
extract(name, extract_data, model, all_nodes, current_idx_count, current_vtx_count,
|
||||
current_tex_count);
|
||||
current_tex_count, has_custom_weights);
|
||||
if (custom_mdl) {
|
||||
merc_convert_custom(result, extract_data);
|
||||
} else {
|
||||
merc_convert_replacement(result, extract_data, old_verts);
|
||||
merc_convert_replacement(result, extract_data, old_verts, has_custom_weights);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
@@ -10,7 +10,7 @@ struct MercExtractData {
|
||||
std::vector<tfrag3::PreloadedVertex> new_vertices;
|
||||
std::vector<math::Vector<u8, 4>> new_colors;
|
||||
std::vector<math::Vector3f> normals;
|
||||
|
||||
std::vector<gltf_util::JointsAndWeights> joints_and_weights;
|
||||
tfrag3::MercModel new_model;
|
||||
};
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ FROM ubuntu:20.04
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
RUN apt-get update
|
||||
RUN apt-get install -y gcc make cmake build-essential g++ nasm clang-format libxrandr-dev libxinerama-dev libxcursor-dev libpulse-dev libxi-dev python lld clang curl
|
||||
RUN apt-get install -y gcc make cmake build-essential g++ nasm clang-format libxrandr-dev libxinerama-dev libxcursor-dev libpulse-dev libxi-dev python lld clang curl libssl-dev libstdc++-10-dev
|
||||
|
||||
RUN sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b /usr/local/bin
|
||||
|
||||
@@ -21,4 +21,4 @@ WORKDIR /home/$user/jak-project/build
|
||||
|
||||
RUN cmake -DCMAKE_SHARED_LINKER_FLAGS="-fuse-ld=lld" -DCMAKE_EXE_LINKER_FLAGS="-fuse-ld=lld" -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ ..
|
||||
WORKDIR /home/$user/jak-project
|
||||
RUN cmake -B build && cmake --build build -j 8
|
||||
RUN cmake -B build && cmake --build build -j 8
|
||||
@@ -322,3 +322,6 @@ endif()
|
||||
|
||||
add_executable(gk main.cpp)
|
||||
target_link_libraries(gk runtime)
|
||||
if(WIN32)
|
||||
set_target_properties(gk PROPERTIES VS_DPI_AWARE "PerMonitor")
|
||||
endif()
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 4.8 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 15 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 35 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 3.9 KiB |
@@ -815,6 +815,7 @@
|
||||
"JA NIITÄ VARMASTI LÖYTYY LISÄÄKIN LUONNOSTA ODOTTELEMASSA,",
|
||||
"ETTÄ JOKU ROHKEA SEIKKAILIJA LÖYTÄÄ NE.",
|
||||
"NO AINAKIN SE ROHKEA SEIKKAILIJA LÖYTYY OMASTA TAKAA.",
|
||||
"NO AINAKIN SE ROHKEA SEIKKAILIJA LÖYTYY OMASTA TAKAA.",
|
||||
"ROHKEA SEIKKAILIJA?",
|
||||
"TE KAKSI ETTE EDES LÖYTÄISI ULOS KYLÄSTÄ ILMAN HARJOITTELUA!",
|
||||
"ENNEN KUIN TEETTE YHTIKÄS MITÄÄN, TEIDÄN ON PARASTA KULKEA TELEPORTIN LÄPI",
|
||||
@@ -1919,7 +1920,8 @@
|
||||
"ANTAISIN TEILLE ONNITTELUNI,",
|
||||
"MUTTA TEILLÄ ON NIIN PALJON TEHTÄVÄÄ, ETTEN TUHLAA ENEMPÄÄ AIKAANNE.",
|
||||
"MUUTEN, JOS ASIANNE EIVÄT LUTVIUDU,",
|
||||
"DAXTERILLE ON AINA VAPAANA TYÖ HOITAA KYLÄMME ROTTAONGELMAA.",
|
||||
"MUUTEN, JOS ASIANNE EIVÄT LUTVIUDU,",
|
||||
"HE HA HA HA HA HA HA HA HA HAH...",
|
||||
"HE HA HA HA HA HA HA HA HA HAH..."
|
||||
],
|
||||
"sagevb02": [
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"TOT HET 500 GRADEN BEREIKT, DUS PROBEER HAAR KOEL TE HOUDEN.",
|
||||
"VLIEGEN OVER OPEN LAVA ZAL JE ZEKER SNEL OPWARMEN.",
|
||||
"ALS HET 500 GRADEN WORDT, IS HET VOORBIJ.",
|
||||
"OVER?! ALS IN BRANDEND GESMOLTEN METAAL OVER?!",
|
||||
"VOORBIJ?! ALS IN BRANDEND GESMOLTEN METAAL VOORBIJ?!",
|
||||
"DE VUURVALLEI WORDT BEHOORLIJK HEET, DUS KIJK UIT VOOR SCHANSEN",
|
||||
"OM JE VAN DE HETE GROND TE HOUDEN.",
|
||||
"IK HEB OOK EEN AANTAL BLAUWE KOELBALLONNEN UITGEBRACHT DIE JE KUNT GEBRUIKEN OM",
|
||||
@@ -1164,7 +1164,7 @@
|
||||
"OVER DAAR!"
|
||||
],
|
||||
"BIL-TA04": [
|
||||
"AW, DANG."
|
||||
"AW, PRUTS."
|
||||
],
|
||||
"BIL-TA05": [
|
||||
"RAT HEEFT EEN SNACK."
|
||||
@@ -1191,7 +1191,7 @@
|
||||
"OVER DAAR."
|
||||
],
|
||||
"BIL-TA4A": [
|
||||
"DANG!"
|
||||
"VERDOMME!"
|
||||
],
|
||||
"BIL-TA4B": [
|
||||
"VERDOMME!"
|
||||
@@ -1748,7 +1748,7 @@
|
||||
"(SNIKKEN)"
|
||||
],
|
||||
"WAR-LO1B": [
|
||||
"(SOBS)"
|
||||
"(JANKT)"
|
||||
],
|
||||
"WAR-LO1C": [
|
||||
"(BLAAST NEUS EN SPUTTERT)",
|
||||
|
||||
@@ -16,20 +16,20 @@
|
||||
"1024": "ミュージック ゲイン",
|
||||
"1025": "アクター カリング",
|
||||
"1026": "バックグラウンド カリング",
|
||||
"1027": "??マッピングを???に?行",
|
||||
"1027": "かんきょうマッピングをきょうせいてきにじっこう",
|
||||
"1030": "DISCORDリッチプレゼンス",
|
||||
"1031": "スクリーンモード",
|
||||
"1032": "ウィンドウ",
|
||||
"1033": "ボーダレス",
|
||||
"1034": "フルスクリーン",
|
||||
"1035": "?像?",
|
||||
"1035": "かいぞうど",
|
||||
"1036": "~D X ~D",
|
||||
"1037": "PS2 アスペクト?",
|
||||
"1038": "PS2アスペクト?が??になると、4?3と16?9しかのアスペクト?が??できません.?行しますか?",
|
||||
"1039": "アスペクト? (PS2)",
|
||||
"1040": "??あり",
|
||||
"1041": "??なし",
|
||||
"1042": "テキスト??",
|
||||
"1037": "PS2 アスペクト ひ",
|
||||
"1038": "PS2アスペクトひがゆうこうになると、4X3と16X9しかのアスペクトひがせんたくできません.つづきますか?",
|
||||
"1039": "アスペクト ひ (PS2)",
|
||||
"1040": "じまくあり",
|
||||
"1041": "じまくなし",
|
||||
"1042": "テキストのげんご",
|
||||
"1043": "ディスプレイ",
|
||||
"1044": "ディスプレイ ~D",
|
||||
"1050": "MSAA",
|
||||
@@ -38,46 +38,46 @@
|
||||
"1053": "4X",
|
||||
"1054": "8X",
|
||||
"1055": "16X",
|
||||
"1060": "フレームレート (???)",
|
||||
"1060": "フレームレート (じっけんてき)",
|
||||
"1061": "60",
|
||||
"1062": "100",
|
||||
"1063": "150",
|
||||
"1070": "LEVEL OF DETAIL (はいけい)",
|
||||
"1071": "LEVEL OF DETAIL (ぜんけい)",
|
||||
"1072": "??",
|
||||
"1073": "?",
|
||||
"1074": "中",
|
||||
"1075": "?",
|
||||
"1076": "??",
|
||||
"1072": "さいこう",
|
||||
"1073": "たかい",
|
||||
"1074": "ふつう",
|
||||
"1075": "ひくい",
|
||||
"1076": "さいてい",
|
||||
"1077": "PS2",
|
||||
"1078": "??",
|
||||
"1079": "ヒント??",
|
||||
"1078": "じまく",
|
||||
"1079": "ヒントじまく",
|
||||
"1080": "チート",
|
||||
"1081": "シークレット",
|
||||
"1082": "?を??する",
|
||||
"1083": "スタイルを??する",
|
||||
"1082": "きょくをせんたくする",
|
||||
"1083": "スタイルをせんたくする",
|
||||
"1084": "チューンドプリカーソルロボット",
|
||||
"1085": "スタッフロール",
|
||||
"1086": "?????",
|
||||
"1087": "ハイブリッドラーカー クロウ",
|
||||
"1088": "サカナとりゲームのテーマ",
|
||||
"1089": "チャレンジーのテーマ",
|
||||
"1090": "??の青のエコ",
|
||||
"1091": "??の赤のエコ",
|
||||
"1092": "??の緑のエコ",
|
||||
"1093": "??の黄のエコ",
|
||||
"1094": "?わりのダクスター",
|
||||
"1095": "??",
|
||||
"1096": "???トラック",
|
||||
"1090": "むげんの青のエコ",
|
||||
"1091": "むげんの赤のエコ",
|
||||
"1092": "むげんの緑のエコ",
|
||||
"1093": "むげんの黄のエコ",
|
||||
"1094": "かわりのダクスター",
|
||||
"1095": "むてき",
|
||||
"1096": "ぜんおんがくトラック",
|
||||
"1097": "リアルタイムオブデイ",
|
||||
"1098": "100%クリア",
|
||||
"1099": "ゲームクリア",
|
||||
"1100": "黄の賢者",
|
||||
"1101": "赤の賢者",
|
||||
"1102": "青の賢者",
|
||||
"1103": "城のハブ",
|
||||
"1103": "城エリア",
|
||||
"1104": "プリカーソルロボットの中?",
|
||||
"1105": "プリカーソルロボットの?わり",
|
||||
"1105": "プリカーソルロボットのおわり",
|
||||
"1106": "スタイル 1",
|
||||
"1107": "スタイル 2",
|
||||
"1110": "ENGLISH (UK)",
|
||||
@@ -94,20 +94,20 @@
|
||||
"111b": "POLSKI",
|
||||
"111c": "LIETUVIŲ KALBA",
|
||||
"1500": "スピードラン モード",
|
||||
"138": "????をぬいたり, さしたり, ??を?ったりは しないでください",
|
||||
"161": "このアイコンが あらわれている?、????をぬいたり, さしたり, ??を?ったりは しないでください",
|
||||
"138": "しゅうへんききをぬいたり, さしたり, でんげんを きったりは しないでください",
|
||||
"161": "このアイコンが あらわれているあいだ、しゅうへんききをぬいたり, さしたり, でんげんを きったりは しないでください",
|
||||
"100c": "オートセーブ オフ",
|
||||
"100d": "オートセーブを?っても よろしいでしょうか?",
|
||||
"100e": "オートセーブを??にする",
|
||||
"100f": "その?",
|
||||
"100e": "オートセーブをむこうにする",
|
||||
"100f": "そのほか",
|
||||
"103a": "スクリーンに合わせる",
|
||||
"103b": "????",
|
||||
"103b": "すいちょくどうき",
|
||||
"103c": "4X3 (PS2)",
|
||||
"103d": "16X9 (PS2)",
|
||||
"103e": "~DX~D",
|
||||
"103f": "<PAD_SQUARE> で ??の?り?え",
|
||||
"107a": "??の??",
|
||||
"107b": "??にスピーカーを??",
|
||||
"103f": "<PAD_SQUARE> をおすとじまくをトグルする",
|
||||
"107a": "じまくのことば",
|
||||
"107b": "じまくではなしてをひょうじする",
|
||||
"107c": "いつも",
|
||||
"107d": "いつもしなく",
|
||||
"107e": "オフ スクリーン",
|
||||
@@ -117,14 +117,14 @@
|
||||
"109c": "ビッグハンドジャック",
|
||||
"109d": "ビッグヘッドキャラクター",
|
||||
"109e": "テクスチャなしモード",
|
||||
"109f": "??世界",
|
||||
"109f": "ミラー・モード",
|
||||
"10a0": "ビッグヘッド ジャック",
|
||||
"10c0": "ミュージックプレイヤー",
|
||||
"10c1": "プレイヤーを??",
|
||||
"10c1": "シーンプレイヤー",
|
||||
"10c2": "スタッフロール",
|
||||
"10c3": "スクラップブック",
|
||||
"10d0": "デフォルト",
|
||||
"10d1": "???",
|
||||
"10d1": "みしよう",
|
||||
"10d2": "セイジィ",
|
||||
"10d3": "セイジィの家",
|
||||
"10d4": "小鳥のオバチャマ",
|
||||
@@ -133,11 +133,11 @@
|
||||
"10d7": "メイヨル",
|
||||
"10d8": "ほりものし",
|
||||
"10d9": "たんけん家のブロオラ",
|
||||
"10da": "DOCK",
|
||||
"10db": "FORBIDDEN TEMPLE EXIT",
|
||||
"10da": "ドック",
|
||||
"10db": "キンダン寺の出口",
|
||||
"10dc": "ラーカーのマシン",
|
||||
"10dd": "TOP OF THE TOWER",
|
||||
"10de": "BLUE VENT SWITCH",
|
||||
"10de": "青エコのふきだしぐちスイッチ",
|
||||
"10df": "みしよう",
|
||||
"10e0": "SENTINELS",
|
||||
"10e1": "LURKER CANNON",
|
||||
@@ -145,19 +145,19 @@
|
||||
"10e3": "みしよう1",
|
||||
"10e4": "LURKER BOAT",
|
||||
"10e5": "みしよう2",
|
||||
"10e6": "ZOOMER",
|
||||
"10e6": "ズーマー",
|
||||
"10e7": "フラフラ鳥",
|
||||
"10e8": "みしよう",
|
||||
"10e9": "WARRIOR",
|
||||
"10ea": "GEOLOGIST",
|
||||
"10eb": "GAMBLER",
|
||||
"10e9": "せんしヴォリア",
|
||||
"10ea": "がくしゃロジィ",
|
||||
"10eb": "ギャンブラーのタルパン",
|
||||
"10ec": "LEVITATOR MACHINE",
|
||||
"10ed": "みしよう1",
|
||||
"10ee": "LAUNCHER TRAPS",
|
||||
"10ef": "みしよう2",
|
||||
"10f0": "DEAD MAN'S GORGE",
|
||||
"10f1": "MIDDLE OF THE PASS",
|
||||
"10f2": "END OF THE PASS",
|
||||
"10f1": "谷のちゅうかん",
|
||||
"10f2": "谷のおわり",
|
||||
"10f3": "ヤミノ洞くつへ",
|
||||
"10f4": "ガイセツ山へ",
|
||||
"10f5": "宝石ほりたち",
|
||||
@@ -195,33 +195,33 @@
|
||||
"151d": "LAVA TUBE IL",
|
||||
"151e": "GOL AND MAIA'S CITADEL IL",
|
||||
"151f": "NEW CATEGORY EXTENSION RUN",
|
||||
"1520": "?しいゲーム+",
|
||||
"1521": "ハブ 1 100%",
|
||||
"1522": "ハブ 2 100%",
|
||||
"1523": "ハブ 3 100%",
|
||||
"1520": "つよくてニューゲーム",
|
||||
"1521": "エリア 1 100%",
|
||||
"1522": "エリア 2 100%",
|
||||
"1523": "エリア 3 100%",
|
||||
"1524": "すべてのシーン",
|
||||
"1600": "INPUT OPTIONS",
|
||||
"1600": "にゅうりょくせってい",
|
||||
"1601": "コントローラをせんたくする",
|
||||
"1602": "ANALOG DEADZONE",
|
||||
"1603": "IGNORE IF WINDOW UNFOCUSED",
|
||||
"1604": "コントローラのLEDでたい力をひょうじする",
|
||||
"1605": "コントローラのLEDでエコをひょうじする",
|
||||
"1606": "TRACK CAMERA",
|
||||
"1607": "HORIZONTAL SENSITIVITY",
|
||||
"1608": "VERTICAL SENSITIVITY",
|
||||
"1607": "よこかんど",
|
||||
"1608": "たてかんど",
|
||||
"1609": "PLAYER MOVEMENT",
|
||||
"160a": "コントローラのバインド",
|
||||
"160b": "キーボードのバインド",
|
||||
"160c": "マウスのバインド",
|
||||
"160d": "コントローラオプション",
|
||||
"160e": "ENABLE KEYBOARD",
|
||||
"160f": "ENABLE MOUSE",
|
||||
"160e": "キーボードゆうこう",
|
||||
"160f": "マウスゆうこう",
|
||||
"1610": "マウスオプション",
|
||||
"1611": "REASSIGN BINDS",
|
||||
"1612": "CONTROLLER ~D",
|
||||
"1613": "AUTO HIDE CURSOR",
|
||||
"1614": "みけってい",
|
||||
"1615": "?られていない",
|
||||
"1615": "ふめい",
|
||||
"1616": "アスペクトひのほかのせんたくしはありません",
|
||||
"1617": "コントローラのLEDでズーマーのおんどをひょうじする"
|
||||
}
|
||||
@@ -202,7 +202,7 @@
|
||||
"1524": "ALLA SCENER",
|
||||
"1600": "INMATNINGSINSTÄLLNINGAR",
|
||||
"1601": "VÄLJ HANDKONTROLL",
|
||||
"1602": "ANALOG DEADZONE",
|
||||
"1602": "ANALOG NEUTRAL ZON",
|
||||
"1603": "IGNORERA OM FÖNSTRET INTE HAR FOKUS",
|
||||
"1604": "LED REFLEKTERAR HP",
|
||||
"1605": "LED REFLEKTERAR ECO",
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 29 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 4.6 KiB |
@@ -54,4 +54,11 @@
|
||||
:lines "game/assets/jak2/subtitle/subtitle_lines_en-GB.json"
|
||||
:meta "game/assets/jak2/subtitle/subtitle_meta_en-GB.json"
|
||||
:lines-base "game/assets/jak2/subtitle/subtitle_lines_en-US.json"
|
||||
:meta-base "game/assets/jak2/subtitle/subtitle_meta_en-US.json")
|
||||
(file-json
|
||||
:language-id 9
|
||||
:text-version "jak2"
|
||||
:lines "game/assets/jak2/subtitle/subtitle_lines_fi-FI.json"
|
||||
:meta "game/assets/jak2/subtitle/subtitle_meta_fi-FI.json"
|
||||
:lines-base "game/assets/jak2/subtitle/subtitle_lines_en-US.json"
|
||||
:meta-base "game/assets/jak2/subtitle/subtitle_meta_en-US.json"))
|
||||
@@ -21,7 +21,8 @@
|
||||
(file-json 7 jak2 "common" '("game/assets/jak2/text/game_custom_text_en-GB.json"))
|
||||
;; custom languages
|
||||
(file-json 8 jak2 "common" '("game/assets/jak2/text/game_custom_text_pt-PT.json"))
|
||||
(file-json 9 jak2 "common" '("game/assets/jak2/text/game_custom_text_fi-FI.json"))
|
||||
(file-json 9 jak2 "common" '("game/assets/jak2/text/game_custom_text_fi-FI.json"
|
||||
"game/assets/jak2/text/game_base_text_fi-FI.json"))
|
||||
(file-json 10 jak2 "common" '("game/assets/jak2/text/game_custom_text_sv-SE.json"))
|
||||
(file-json 11 jak2 "common" '("game/assets/jak2/text/game_custom_text_da-DK.json"))
|
||||
(file-json 12 jak2 "common" '("game/assets/jak2/text/game_custom_text_no-NO.json"))
|
||||
|
||||
@@ -713,7 +713,8 @@
|
||||
],
|
||||
"bb06int": [
|
||||
"Jak, necessitem que treus un altre grup de Bomb Bots.",
|
||||
"Aquestes armes mòbils continuen apareixent a la ciutat, les hem de treure el més aviat possible."
|
||||
"These mobile weapons keep showing up in the city,",
|
||||
"we gotta take them out as soon as possible."
|
||||
],
|
||||
"bb06win": [
|
||||
"Un altre munt de ferralla de bombes per al KG",
|
||||
@@ -724,8 +725,10 @@
|
||||
"Has perdut un agent! No és gens bo, Jak! Missió fallida!"
|
||||
],
|
||||
"bb07int": [
|
||||
"Esquinçat aquí, necessito que surtis i traslladis més dels nostres agents a nous llocs de la ciutat.",
|
||||
"Els espies de KG estan vigilant tots els nostres moviments, així que vigileu els problemes. Bona sort."
|
||||
"Torn here, I need you to go out and move more of our Agents",
|
||||
"to new locations in the city.",
|
||||
"KG spies are watching our every move,",
|
||||
"so look out for trouble. Good luck."
|
||||
],
|
||||
"bb07win": [
|
||||
"Bona feina de llançadora! Estàs mantenint la gent viva allà fora."
|
||||
@@ -737,7 +740,8 @@
|
||||
"bb08int": [
|
||||
"Jak, alguns dels nostres agents s'han vist compromesos de nou.",
|
||||
"Trobeu-los i porteu-los a amagatalls especials de la ciutat.",
|
||||
"Les patrulles de guàrdia estan en alerta màxima, així que serà difícil. Mantingueu el cap avall!"
|
||||
"The guard patrols are on high alert,",
|
||||
"so this is going to be a tough one. Keep your head down!"
|
||||
],
|
||||
"bb08win": [
|
||||
"Va ser una bona conducció, Jak.",
|
||||
@@ -4911,10 +4915,10 @@
|
||||
"Activació de defenses de seguretat."
|
||||
],
|
||||
"kg121": [
|
||||
"Si us plau, aviseu, descripció del tema."
|
||||
"Please advise, suspect's description."
|
||||
],
|
||||
"kg121a": [
|
||||
"Si us plau, aviseu, descripció del tema."
|
||||
"Please advise, suspect's description."
|
||||
],
|
||||
"kg122": [
|
||||
"Tinc civismes a la vista."
|
||||
@@ -5689,11 +5693,11 @@
|
||||
"lluitant per l'Underground."
|
||||
],
|
||||
"kg233b": [
|
||||
"Estic preocupat perquè aquest nou noi lluita per l'Underground.",
|
||||
"I'm worried about this new guy",
|
||||
"lluitant per l'Underground."
|
||||
],
|
||||
"kg234": [
|
||||
"Sí, diuen que es pot convertir en una mena de... monstre."
|
||||
"Yeah, they say he can change into some kind of monster."
|
||||
],
|
||||
"kg234a": [
|
||||
"Sí, diuen que es pot convertir en una mena de monstre."
|
||||
@@ -6939,7 +6943,7 @@
|
||||
],
|
||||
"prop049": [
|
||||
"Estic decebut amb la manca d'aquesta ciutat",
|
||||
"compromís i sacrifici. Treballar més dur! Menja menys!",
|
||||
"commitment and sacrifice. Work harder! Eat less!",
|
||||
"Beu només quan et digui! Dormir és opcional.",
|
||||
"Estem en guerra amb una amenaça externa,",
|
||||
"no em feu declarar-vos la guerra també!"
|
||||
@@ -6947,13 +6951,14 @@
|
||||
"prop050": [
|
||||
"Salutacions, gent d'aquesta meravellosa utopia. La d'enguany",
|
||||
"la cursa del campionat començarà en breu. Tots els ciutadans",
|
||||
"no estan sota arrest domiciliari estan convidats a baixar",
|
||||
"l'Estadi i mira el teu fill preferit Erol",
|
||||
"not under house arrest are invited to come down",
|
||||
"to the Stadium and watch your favorite son Erol",
|
||||
"mostrar una vegada més com la Guàrdia Krimzon és l'elit",
|
||||
"guerrers d'aquesta ciutat. Porta tota la família! El primer",
|
||||
"mil nens tindran una obligatòria",
|
||||
"Paquet de contractació de Krimzon Guard i be",
|
||||
"\"demanat\" unir-se a la Guàrdia de per vida, quina delícia!"
|
||||
"warriors of this city. Bring the whole family!",
|
||||
"The first one thousand children will get",
|
||||
"a mandatory Krimzon Guard recruitment package",
|
||||
"and be \"asked\" to join the Guard for life!",
|
||||
"What a treat!"
|
||||
],
|
||||
"prop051": [
|
||||
"Aquest és el teu baró, encara tinc el control!",
|
||||
@@ -6984,22 +6989,24 @@
|
||||
"seria si els Metal Heads estiguessin al capdavant!"
|
||||
],
|
||||
"prop054": [
|
||||
"Hem tingut alguns incidents amb els nostres treballadors de classe baixa",
|
||||
"força últimament. Si el vostre Lurker està actuant, truqueu a Krimzon",
|
||||
"Control d'animals. El teu Lurker està en un arbre? Encallat en un",
|
||||
"reixa de clavegueram? Escuma a la boca? Anomenada",
|
||||
"els oficials amics de la K.A.C. i tractaran",
|
||||
"amb el teu esclau pelut. amb tot l'amor i cura",
|
||||
"es mereix... després traieu-lo per a un reacondicionament.",
|
||||
"Recordeu que els lurkers poden ser perillosos!"
|
||||
"We've had a few incidents with our lower class",
|
||||
"labor force lately. If your Lurker is acting up,",
|
||||
"call Krimzon Animal Control. Is your Lurker in a tree?",
|
||||
"Stuck in a sewer grate? Foaming at the mouth?",
|
||||
"Call the friendly officers of the K.A.C.",
|
||||
"and they will deal with your furry slave",
|
||||
"with all the love and care it deserves...",
|
||||
"then haul it away for reconditioning.",
|
||||
"Remember, Lurkers can be dangerous!"
|
||||
],
|
||||
"prop055": [
|
||||
"Si us plau, doneu generosament al fons ecològic Baron.",
|
||||
"La teva donació s'utilitzarà per a una varietat",
|
||||
"de necessitats humanitàries: bombes, pistoles, blindatges, genètica",
|
||||
"investigació sobre alteracions, tot en nom de preservar-ho",
|
||||
"meravellosa ciutat nostra. Donar sovint, donar lliurement...",
|
||||
"o t'ho prendran!"
|
||||
"Your munificent donation will be used for",
|
||||
"a variety of humanitarian needs:",
|
||||
"bombs, guns, armor, genetic alteration research,",
|
||||
"all in the name of preserving this",
|
||||
"wonderful city of ours. Give often, give freely...",
|
||||
"or it will be taken from you!"
|
||||
],
|
||||
"prop056": [
|
||||
"Pot estar tan sol a dalt i mirant cap avall",
|
||||
@@ -7549,15 +7556,17 @@
|
||||
"Fes un petó al teu cul brillant adéu!"
|
||||
],
|
||||
"sigt112": [
|
||||
"Nascut per matar un nadó!"
|
||||
"Born to kill, baby!"
|
||||
],
|
||||
"sigt113": [
|
||||
"Dos al pit, un al cap."
|
||||
],
|
||||
"spot004": [
|
||||
"Veniu a animar-me mentre destrueixo la competició una vegada més a la pista.",
|
||||
"La final de curses d'enguany serà per morir-se, us garanteixo més emocions i més vessars.",
|
||||
"Aquesta vegada vull sang!...Porteu els nens."
|
||||
"Come out and cheer for me",
|
||||
"as I destroy the competition once again on the track.",
|
||||
"This year's racing final will be to die for,",
|
||||
"I guarantee more thrills and more spills.",
|
||||
"This time I want blood! Bring the kids."
|
||||
],
|
||||
"tess001": [
|
||||
"Hola nois! Aquesta és la Tess. Abans que en Krew marxés, el vaig veure amagar-se",
|
||||
@@ -7566,23 +7575,32 @@
|
||||
"Potser vols venir a comprovar-ho."
|
||||
],
|
||||
"tor001": [
|
||||
"L'operació va ser un èxit. Tots els membres de Underground estan segurs.",
|
||||
"Torna a l'amagatall, tinc una nova missió per a tu mentre esperem que passi aquesta alerta."
|
||||
"The operation was a success.",
|
||||
"All Underground members are safe.",
|
||||
"Come back to the hideout, I have a new mission for you",
|
||||
"while we wait for this alert to blow over."
|
||||
],
|
||||
"tor002": [
|
||||
"Això hauria de treure una mica de calor als carrers. Bona feina, jo mateix no ho hauria pogut fer millor."
|
||||
"That should take some heat off the streets.",
|
||||
"Good work, I couldn't have done it better myself."
|
||||
],
|
||||
"tor003": [
|
||||
"Això és tot, Jak, estàs aixecat! Intenta no activar cap alarma, els guàrdies de la guarnició seran durs.",
|
||||
"Arriba al bloc de cel·les de la presó i troba els presoners. Un cop allà, encendrem la Warp Gate per dins per tornar-vos a sortir. Bona sort."
|
||||
"That's it, Jak, you're up! Try not to trigger any alarms,",
|
||||
"the garrison guards will be tough.",
|
||||
"Get to the prison cell block and find the prisoners.",
|
||||
"Once there, we'll turn on the Warp Gate inside",
|
||||
"to get you all back out. Good luck."
|
||||
],
|
||||
"tor004": [
|
||||
"D'acord, els meus codis d'accés antics haurien d'ajudar a Vin a apagar el segell magnètic de la porta de la fortalesa."
|
||||
"Okay, my old access codes should help Vin turn off",
|
||||
"the magnetic seal for the Fortress door."
|
||||
],
|
||||
"tor005": [
|
||||
"Jak, aquest és Torn, la ciutat està sota atac de Metal Head. Hi ha una gran força que es mou cap a la muralla de la ciutat des de l'oceà.",
|
||||
"Necessitem gent que s'encarrega de les pistoles de la torre per aturar aquest assalt. Trobeu-me a la paret marítima del Port, afanyeu-vos!",
|
||||
"Necessitem tots els homes que puguem aconseguir!"
|
||||
"Jak, this is Torn, the city is under Metal Head attack!",
|
||||
"There's a large force moving toward the city wall",
|
||||
"from the ocean. We need people manning the tower gunpods",
|
||||
"to stop that assault. Meet me at the seaside ocean wall",
|
||||
"in the Port. Hurry, we need every man we can get!"
|
||||
],
|
||||
"tor007": [
|
||||
"Jak, és un bloqueig de guàrdia, surt d'allà!"
|
||||
@@ -7807,8 +7825,8 @@
|
||||
"Massa d'ells!! Jak!!! AHHHH!!!"
|
||||
],
|
||||
"ys001": [
|
||||
"Excel·lent feina, nois! Torna a l'amagatall,",
|
||||
"Tinc una altra tasca per a tu."
|
||||
"Excellent work, boys! Come on back",
|
||||
"to the Hideout, I have another task for you."
|
||||
],
|
||||
"ys002": [
|
||||
"Bonic tiroteig, fill meu!",
|
||||
|
||||
@@ -713,7 +713,8 @@
|
||||
],
|
||||
"bb06int": [
|
||||
"Jak, vi har brug for dig til at fjerne endnu en gruppe Bombe-botter.",
|
||||
"Disse mobile våben bliver ved med at dukke op i byen, vi må fjerne dem hurtigst muligt."
|
||||
"These mobile weapons keep showing up in the city,",
|
||||
"we gotta take them out as soon as possible."
|
||||
],
|
||||
"bb06win": [
|
||||
"Endnu en bunke Bombe-bot skrot for KG'ernes",
|
||||
@@ -724,8 +725,10 @@
|
||||
"Du mistede en agent! IKKE godt overhovedet, Jak! Missionen fejlet!"
|
||||
],
|
||||
"bb07int": [
|
||||
"Torn her, Jeg skal bruge jer til at tage ud og flytte flere af vores Agenter til nye steder i byen.",
|
||||
"KG-spioner holder øje med alle vores bevægelser, så hold øje efter problemer. Held og lykke."
|
||||
"Torn here, I need you to go out and move more of our Agents",
|
||||
"to new locations in the city.",
|
||||
"KG spies are watching our every move,",
|
||||
"so look out for trouble. Good luck."
|
||||
],
|
||||
"bb07win": [
|
||||
"Fint flytte-arbejde! I holder folk i live derude."
|
||||
@@ -737,7 +740,8 @@
|
||||
"bb08int": [
|
||||
"Jak, nogle af vores agenter er blevet kompromitteret igen.",
|
||||
"Find hver enkelt og tag dem til specielle skjulesteder i byen.",
|
||||
"Vagtpatruljerne er i høj beredskab, så den her bliver svær. Hold hovedet nede!"
|
||||
"The guard patrols are on high alert,",
|
||||
"so this is going to be a tough one. Keep your head down!"
|
||||
],
|
||||
"bb08win": [
|
||||
"Det var god kørsel, Jak.",
|
||||
@@ -4911,10 +4915,10 @@
|
||||
"Aktivering af sikkerhedsforsvar."
|
||||
],
|
||||
"kg121": [
|
||||
"Giv venligst besked, emnebeskrivelse."
|
||||
"Please advise, suspect's description."
|
||||
],
|
||||
"kg121a": [
|
||||
"Giv venligst besked, emnebeskrivelse."
|
||||
"Please advise, suspect's description."
|
||||
],
|
||||
"kg122": [
|
||||
"Jeg har civvies i sigte."
|
||||
@@ -5689,11 +5693,11 @@
|
||||
"kæmper for undergrunden."
|
||||
],
|
||||
"kg233b": [
|
||||
"Jeg er bekymret for denne nye fyr, der kæmper for undergrunden.",
|
||||
"I'm worried about this new guy",
|
||||
"kæmper for undergrunden."
|
||||
],
|
||||
"kg234": [
|
||||
"Ja, de siger, at han kan ændre sig til en slags... monster."
|
||||
"Yeah, they say he can change into some kind of monster."
|
||||
],
|
||||
"kg234a": [
|
||||
"Ja, de siger, at han kan ændre sig til en slags monster."
|
||||
@@ -6939,7 +6943,7 @@
|
||||
],
|
||||
"prop049": [
|
||||
"Jeg er skuffet over denne bys mangel på",
|
||||
"engagement og opofrelse. Arbejd hårdere! Spis mindre!",
|
||||
"commitment and sacrifice. Work harder! Eat less!",
|
||||
"Drik kun når jeg fortæller dig! Søvn er valgfrit.",
|
||||
"Vi er i krig med en trussel udefra,",
|
||||
"lad mig heller ikke erklære krig mod dig!"
|
||||
@@ -6947,13 +6951,14 @@
|
||||
"prop050": [
|
||||
"Hilsen folk i denne vidunderlige utopi. Årets",
|
||||
"mesterskabsløbet begynder snart. Alle borgere",
|
||||
"ikke i husarrest inviteres til at komme ned til",
|
||||
"Stadion og se din yndlingssøn Erol",
|
||||
"not under house arrest are invited to come down",
|
||||
"to the Stadium and watch your favorite son Erol",
|
||||
"endnu en gang vise, hvordan Krimzon-garden er eliten",
|
||||
"krigere i denne by. Tag hele familien med! Den første",
|
||||
"tusinde børn vil få en obligatorisk",
|
||||
"Krimzon Guard rekrutteringspakke og være",
|
||||
"\"bad\" om at slutte sig til vagten for livet, sikke en godbid!"
|
||||
"warriors of this city. Bring the whole family!",
|
||||
"The first one thousand children will get",
|
||||
"a mandatory Krimzon Guard recruitment package",
|
||||
"and be \"asked\" to join the Guard for life!",
|
||||
"What a treat!"
|
||||
],
|
||||
"prop051": [
|
||||
"Dette er din baron, jeg har stadig kontrol!",
|
||||
@@ -6984,22 +6989,24 @@
|
||||
"det ville være, hvis Metal Heads havde ansvaret!"
|
||||
],
|
||||
"prop054": [
|
||||
"Vi har haft et par hændelser med vores lavere klasses arbejdskraft",
|
||||
"kraft på det seneste. Hvis din Lurker optræder, så ring til Krimzon",
|
||||
"Dyrekontrol. Er din Lurker i et træ? Sidder fast i en",
|
||||
"kloakrist? Skummer om munden? Opkald",
|
||||
"de venlige officerer i K.A.C. og de vil handle",
|
||||
"med din lodne slave. med al den kærlighed og omsorg det",
|
||||
"fortjener... så slæb den væk til renovering.",
|
||||
"Husk, Lurkers kan være farlige!"
|
||||
"We've had a few incidents with our lower class",
|
||||
"labor force lately. If your Lurker is acting up,",
|
||||
"call Krimzon Animal Control. Is your Lurker in a tree?",
|
||||
"Stuck in a sewer grate? Foaming at the mouth?",
|
||||
"Call the friendly officers of the K.A.C.",
|
||||
"and they will deal with your furry slave",
|
||||
"with all the love and care it deserves...",
|
||||
"then haul it away for reconditioning.",
|
||||
"Remember, Lurkers can be dangerous!"
|
||||
],
|
||||
"prop055": [
|
||||
"Giv venligst generøst til Baron økofond.",
|
||||
"Din overdådige donation vil blive brugt til en række forskellige",
|
||||
"af humanitære behov: bomber, våben, rustninger, genetiske",
|
||||
"ændringsforskning, alt sammen for at bevare dette",
|
||||
"vores vidunderlige by. Giv ofte, giv frit...",
|
||||
"eller det bliver taget fra dig!"
|
||||
"Your munificent donation will be used for",
|
||||
"a variety of humanitarian needs:",
|
||||
"bombs, guns, armor, genetic alteration research,",
|
||||
"all in the name of preserving this",
|
||||
"wonderful city of ours. Give often, give freely...",
|
||||
"or it will be taken from you!"
|
||||
],
|
||||
"prop056": [
|
||||
"Det kan være så ensomt på toppen og kigge ned fra",
|
||||
@@ -7549,15 +7556,17 @@
|
||||
"Kys din skinnende røv farvel!"
|
||||
],
|
||||
"sigt112": [
|
||||
"Født til at dræbe baby!"
|
||||
"Born to kill, baby!"
|
||||
],
|
||||
"sigt113": [
|
||||
"To til brystet, en til hovedet."
|
||||
],
|
||||
"spot004": [
|
||||
"Kom ud og hep på mig, mens jeg ødelægger konkurrencen igen på banen.",
|
||||
"Dette års løbsfinale bliver til at dø for, jeg garanterer mere spænding og mere spild.",
|
||||
"Denne gang vil jeg have blod!...Tag børnene med."
|
||||
"Come out and cheer for me",
|
||||
"as I destroy the competition once again on the track.",
|
||||
"This year's racing final will be to die for,",
|
||||
"I guarantee more thrills and more spills.",
|
||||
"This time I want blood! Bring the kids."
|
||||
],
|
||||
"tess001": [
|
||||
"Hej gutter! Det her er Tess. Før Krew gik, så jeg ham gemme sig",
|
||||
@@ -7566,23 +7575,32 @@
|
||||
"Du vil måske komme og tjekke det ud."
|
||||
],
|
||||
"tor001": [
|
||||
"Operationen var en succes. Alle underjordiske medlemmer er i sikkerhed.",
|
||||
"Kom tilbage til gemmestedet, jeg har en ny mission til dig, mens vi venter på, at denne alarm blæser over."
|
||||
"The operation was a success.",
|
||||
"All Underground members are safe.",
|
||||
"Come back to the hideout, I have a new mission for you",
|
||||
"while we wait for this alert to blow over."
|
||||
],
|
||||
"tor002": [
|
||||
"Det burde tage lidt varme fra gaderne. Godt arbejde, jeg kunne ikke have gjort det bedre selv."
|
||||
"That should take some heat off the streets.",
|
||||
"Good work, I couldn't have done it better myself."
|
||||
],
|
||||
"tor003": [
|
||||
"Det var det, Jak, du er oppe! Prøv ikke at udløse nogen alarmer, garnisonens vagter vil være hårde.",
|
||||
"Gå til fængselscelleblokken og find fangerne. Når vi er der, tænder vi Warp Gate inde for at få jer alle ud igen. Held og lykke."
|
||||
"That's it, Jak, you're up! Try not to trigger any alarms,",
|
||||
"the garrison guards will be tough.",
|
||||
"Get to the prison cell block and find the prisoners.",
|
||||
"Once there, we'll turn on the Warp Gate inside",
|
||||
"to get you all back out. Good luck."
|
||||
],
|
||||
"tor004": [
|
||||
"Ok, mine gamle adgangskoder skulle hjælpe Vin med at slukke for den magnetiske forsegling til fæstningsdøren."
|
||||
"Okay, my old access codes should help Vin turn off",
|
||||
"the magnetic seal for the Fortress door."
|
||||
],
|
||||
"tor005": [
|
||||
"Jak, det er Torn, byen er under Metal Head-angreb. Der er en stor styrke, der bevæger sig mod bymuren fra havet.",
|
||||
"Vi har brug for folk, der bemander tårnets geværbøjler for at stoppe det overfald. Mød mig ved havets havvæg i havnen, skynd dig!",
|
||||
"Vi har brug for hver mand, vi kan få!"
|
||||
"Jak, this is Torn, the city is under Metal Head attack!",
|
||||
"There's a large force moving toward the city wall",
|
||||
"from the ocean. We need people manning the tower gunpods",
|
||||
"to stop that assault. Meet me at the seaside ocean wall",
|
||||
"in the Port. Hurry, we need every man we can get!"
|
||||
],
|
||||
"tor007": [
|
||||
"Jak, det er en vagtspærring, kom ud derfra!"
|
||||
@@ -7807,8 +7825,8 @@
|
||||
"For mange af dem!! Jak!!! ARHHH!!!"
|
||||
],
|
||||
"ys001": [
|
||||
"Fremragende arbejde, drenge! Kom tilbage til skjulestedet,",
|
||||
"Jeg har endnu en opgave til jer."
|
||||
"Excellent work, boys! Come on back",
|
||||
"to the Hideout, I have another task for you."
|
||||
],
|
||||
"ys002": [
|
||||
"Godt skudt, min dreng!",
|
||||
|
||||
Loaded 100 of 2317 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user