mirror of
https://github.com/open-goal/jak-project
synced 2026-06-20 16:21:35 -04:00
Merge remote-tracking branch 'origin/master' into v/arm-instructions
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
13153231
|
||||
48171810
|
||||
7569514
|
||||
6624576
|
||||
2515356
|
||||
70249609
|
||||
5276694
|
||||
89345505
|
||||
@@ -26,7 +26,7 @@ jobs:
|
||||
libxi-dev zip ninja-build libgl1-mesa-dev libssl-dev
|
||||
|
||||
- name: Setup sccache
|
||||
uses: hendrikmuhs/ccache-action@v1.2.22
|
||||
uses: hendrikmuhs/ccache-action@v1.2.23
|
||||
with:
|
||||
variant: sccache
|
||||
key: linux-ubuntu-22.04--Release-linux-clang-static-${{ github.sha }}
|
||||
|
||||
@@ -74,6 +74,7 @@ jobs:
|
||||
path: |
|
||||
./jak1*.json
|
||||
./jak2*.json
|
||||
./jak3*.json
|
||||
|
||||
- name: Log Run ID
|
||||
run: echo ${{ github.run_id }}
|
||||
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
libxi-dev zip ninja-build libgl1-mesa-dev libssl-dev
|
||||
|
||||
- name: Setup sccache
|
||||
uses: hendrikmuhs/ccache-action@v1.2.22
|
||||
uses: hendrikmuhs/ccache-action@v1.2.23
|
||||
with:
|
||||
variant: sccache
|
||||
key: linux-ubuntu-22.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/ccache-action@v1.2.22
|
||||
uses: hendrikmuhs/ccache-action@v1.2.23
|
||||
with:
|
||||
variant: sccache
|
||||
key: linux-ubuntu-22.04-${{ inputs.cachePrefix }}-${{ inputs.cmakePreset }}-${{ github.sha }}
|
||||
|
||||
@@ -35,7 +35,7 @@ jobs:
|
||||
fi
|
||||
|
||||
- name: Setup sccache
|
||||
uses: hendrikmuhs/ccache-action@v1.2.22
|
||||
uses: hendrikmuhs/ccache-action@v1.2.23
|
||||
with:
|
||||
variant: sccache
|
||||
key: macos-15-${{ inputs.cachePrefix }}-${{ inputs.cmakePreset }}-${{ github.sha }}
|
||||
|
||||
@@ -45,7 +45,7 @@ jobs:
|
||||
fi
|
||||
|
||||
- name: Setup sccache
|
||||
uses: hendrikmuhs/ccache-action@v1.2.22
|
||||
uses: hendrikmuhs/ccache-action@v1.2.23
|
||||
with:
|
||||
variant: sccache
|
||||
key: macos-15-intel-${{ inputs.cachePrefix }}-${{ inputs.cmakePreset }}-${{ github.sha }}
|
||||
|
||||
@@ -0,0 +1,159 @@
|
||||
name: 🧪 Offline Tests
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
issue_comment:
|
||||
types: [created]
|
||||
|
||||
concurrency:
|
||||
group: offline-tests
|
||||
cancel-in-progress: false
|
||||
|
||||
# curl -s https://api.github.com/users/<GH_USER_NAME> | jq -r .id
|
||||
|
||||
jobs:
|
||||
validate-author:
|
||||
name: Verify Permissions
|
||||
runs-on: self-hosted
|
||||
if: github.repository == 'open-goal/jak-project'
|
||||
timeout-minutes: 5
|
||||
outputs:
|
||||
trusted: ${{ steps.verify.outputs.trusted }}
|
||||
sha: ${{ steps.verify.outputs.sha }}
|
||||
steps:
|
||||
- id: verify
|
||||
name: Verify Permissions
|
||||
if: github.event_name != 'issue_comment' || github.event.issue.pull_request
|
||||
env:
|
||||
EVENT: ${{ github.event_name }}
|
||||
AUTHOR_ID: ${{ github.event.pull_request.user.id }}
|
||||
COMMENT_ID: ${{ github.event.comment.user.id }}
|
||||
COMMENT: ${{ github.event.comment.body }}
|
||||
PR_NUMBER: ${{ github.event.issue.number }}
|
||||
run: |
|
||||
set -e
|
||||
|
||||
mkdir -p ./.tmp-ci
|
||||
|
||||
curl -fsSL \
|
||||
https://raw.githubusercontent.com/open-goal/jak-project/master/.github/offline-allowlist.txt \
|
||||
-o ./.tmp-ci/allowlist.txt
|
||||
|
||||
is_trusted=false
|
||||
|
||||
# ---- PUSH: always trusted ----
|
||||
if [ "$EVENT" = "push" ]; then
|
||||
echo "push event detected, these are always trusted"
|
||||
is_trusted=true
|
||||
SHA="${{ github.sha }}"
|
||||
|
||||
# ---- PULL REQUEST: check author ----
|
||||
elif [ "$EVENT" = "pull_request" ]; then
|
||||
echo "pull request event detected, these may be trusted if in the allowlist"
|
||||
SHA="${{ github.event.pull_request.head.sha }}"
|
||||
if grep -Fxq "$AUTHOR_ID" ./.tmp-ci/allowlist.txt; then
|
||||
echo "PR author found in the allowlist, it's trusted"
|
||||
is_trusted=true
|
||||
else
|
||||
echo "PR author NOT found in the allowlist"
|
||||
fi
|
||||
|
||||
# ---- ISSUE COMMENT: "ok to test" gate ----
|
||||
elif [ "$EVENT" = "issue_comment" ]; then
|
||||
echo "comment event detected, these may be trusted if in the allowlist"
|
||||
SHA=$(gh api repos/${{ github.repository }}/pulls/$PR_NUMBER --jq '.head.sha')
|
||||
if [ "$COMMENT" = "ok to test" ] && grep -Fxq "$COMMENT_ID" ./.tmp-ci/allowlist.txt; then
|
||||
is_trusted=true
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "trusted=$is_trusted" >> "$GITHUB_OUTPUT"
|
||||
echo "sha=$SHA" >> "$GITHUB_OUTPUT"
|
||||
|
||||
rm -rf ./.tmp-ci
|
||||
offline-tests:
|
||||
name: Run Tests
|
||||
needs: validate-author
|
||||
if: needs.validate-author.outputs.trusted == 'true' && github.repository == 'open-goal/jak-project'
|
||||
runs-on: self-hosted
|
||||
timeout-minutes: 60
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: ${{ github.repository }}
|
||||
ref: ${{ needs.validate-author.outputs.sha }}
|
||||
clean: false
|
||||
|
||||
- name: Build Binaries
|
||||
run: |
|
||||
cmake -B build --preset="Release-linux-clang-static" -DCMAKE_SHARED_LINKER_FLAGS="-fuse-ld=lld" -DCMAKE_EXE_LINKER_FLAGS="-fuse-ld=lld" -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_CXX_COMPILER_LAUNCHER=ccache
|
||||
cmake --build build --target offline-test --target extractor --parallel $(`nproc`)
|
||||
|
||||
- name: Build Release
|
||||
run: |
|
||||
rm -r ./ci-artifacts || true
|
||||
mkdir ./ci-artifacts
|
||||
chmod +x ./.github/scripts/releases/extract_build_unix.sh
|
||||
PREP_BIN=false ./.github/scripts/releases/extract_build_unix.sh ./ci-artifacts ./build ./
|
||||
cp ./build/decompiler/extractor ./ci-artifacts
|
||||
|
||||
- name: Install Jak 1
|
||||
run: |
|
||||
cd ./ci-artifacts
|
||||
./extractor ~/isos/jak1_ntsc.iso --game jak1 --extract --validate --proj-path "$PWD/data"
|
||||
./extractor ~/isos/jak1_ntsc.iso --game jak1 --decompile --proj-path "$PWD/data"
|
||||
./extractor ~/isos/jak1_ntsc.iso --game jak1 --compile --proj-path "$PWD/data"
|
||||
rm -r ./data/out || true
|
||||
rm -r ./data/iso_data || true
|
||||
rm -r ./data/decompiler_out || true
|
||||
|
||||
- name: Install Jak 2
|
||||
run: |
|
||||
cd ./ci-artifacts
|
||||
./extractor ~/isos/jak2_ntsc.iso --game jak2 --extract --validate --proj-path "$PWD/data"
|
||||
./extractor ~/isos/jak2_ntsc.iso --game jak2 --decompile --proj-path "$PWD/data"
|
||||
./extractor ~/isos/jak2_ntsc.iso --game jak2 --compile --proj-path "$PWD/data"
|
||||
rm -r ./data/out || true
|
||||
rm -r ./data/iso_data || true
|
||||
rm -r ./data/decompiler_out || true
|
||||
|
||||
- name: Install Jak 3
|
||||
run: |
|
||||
cd ./ci-artifacts
|
||||
./extractor ~/isos/jak3_ntsc.iso --game jak3 --extract --validate --proj-path "$PWD/data"
|
||||
./extractor ~/isos/jak3_ntsc.iso --game jak3 --decompile --proj-path "$PWD/data"
|
||||
./extractor ~/isos/jak3_ntsc.iso --game jak3 --compile --proj-path "$PWD/data"
|
||||
rm -r ./data/out || true
|
||||
rm -r ./data/iso_data || true
|
||||
rm -r ./data/decompiler_out || true
|
||||
|
||||
- name: Cleanup Installation
|
||||
run: |
|
||||
rm -r ./ci-artifacts || true
|
||||
|
||||
- name: Run Offline Tests - Jak 1
|
||||
run: |
|
||||
7z x ~/isos/jak1_ntsc.iso -o./iso_data/jak1 -aos
|
||||
task set-game-jak1
|
||||
task offline-tests
|
||||
rm -rf ./iso_data/jak1/*
|
||||
|
||||
- name: Run Offline Tests - Jak 2
|
||||
run: |
|
||||
7z x ~/isos/jak2_ntsc.iso -o./iso_data/jak2 -aos
|
||||
task set-game-jak2
|
||||
task offline-tests
|
||||
rm -rf ./iso_data/jak2/*
|
||||
|
||||
- name: Run Offline Tests - Jak 3
|
||||
run: |
|
||||
7z x ~/isos/jak3_ntsc.iso -o./iso_data/jak3 -aos
|
||||
task set-game-jak3
|
||||
task offline-tests
|
||||
rm -rf ./iso_data/jak3/*
|
||||
@@ -46,7 +46,7 @@ jobs:
|
||||
}
|
||||
|
||||
- name: Setup sccache
|
||||
uses: hendrikmuhs/ccache-action@v1.2.22
|
||||
uses: hendrikmuhs/ccache-action@v1.2.23
|
||||
with:
|
||||
variant: sccache
|
||||
key: windows-2022-${{ inputs.cachePrefix }}-${{ inputs.cmakePreset }}-${{ github.sha }}
|
||||
|
||||
@@ -31,7 +31,7 @@ jobs:
|
||||
}
|
||||
|
||||
- name: Setup sccache
|
||||
uses: hendrikmuhs/ccache-action@v1.2.22
|
||||
uses: hendrikmuhs/ccache-action@v1.2.23
|
||||
with:
|
||||
variant: sccache
|
||||
key: windows-2022-${{ inputs.cachePrefix }}-${{ inputs.cmakePreset }}-${{ github.sha }}
|
||||
|
||||
@@ -87,3 +87,4 @@ __pycache__/
|
||||
unifont-15.0.03.ttf
|
||||
*.diff
|
||||
goalc-report.html
|
||||
_new-all-types.gc
|
||||
@@ -96,6 +96,18 @@
|
||||
"jak3"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "default",
|
||||
"project": "CMakeLists.txt",
|
||||
"projectTarget": "offline-test.exe (bin\\offline-test.exe)",
|
||||
"name": "Tests - Offline Tests - Jak X",
|
||||
"args": [
|
||||
"--iso_data_path",
|
||||
"${workspaceRoot}/iso_data/jakx",
|
||||
"--game",
|
||||
"jakx"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "default",
|
||||
"project": "CMakeLists.txt",
|
||||
@@ -224,6 +236,20 @@
|
||||
"-debug"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "default",
|
||||
"project": "CMakeLists.txt",
|
||||
"projectTarget": "gk.exe (bin\\gk.exe)",
|
||||
"name": "Game - Jak 3 - Runtime (release)",
|
||||
"args": [
|
||||
"-v",
|
||||
"--game",
|
||||
"jak3",
|
||||
"--",
|
||||
"-boot",
|
||||
"-fakeiso"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "default",
|
||||
"project": "CMakeLists.txt",
|
||||
|
||||
@@ -3,6 +3,21 @@
|
||||
// For more documentation on how to configure debug tasks,
|
||||
// see: https://zed.dev/docs/debugger
|
||||
[
|
||||
{
|
||||
"label": "Run Debugger - Jak X",
|
||||
// "build": "Build - gk",
|
||||
"program": "$ZED_WORKTREE_ROOT/out/build/Debug/bin/decompiler.exe",
|
||||
"args": [
|
||||
"./decompiler/config/jakx/jakx_config.jsonc",
|
||||
"./iso_data",
|
||||
"./decompiler_out",
|
||||
"--version ntsc_v1",
|
||||
"--config-override",
|
||||
"{\"decompile_code\": true, \"levels_extract\": false}",
|
||||
],
|
||||
"request": "launch",
|
||||
"adapter": "CodeLLDB",
|
||||
},
|
||||
{
|
||||
"label": "Game - Jak 1 (Windows)",
|
||||
"build": "Build - gk",
|
||||
|
||||
+12
-3
@@ -97,7 +97,7 @@ tasks:
|
||||
build-debug:
|
||||
desc: "Build the project using the generated CMake"
|
||||
cmds:
|
||||
- "cmake {{.CMAKE_BUILD_DIR_DEBUG}} --parallel 8 --target goalc"
|
||||
- "cmake {{.CMAKE_BUILD_DIR_DEBUG}} --parallel 8"
|
||||
repl:
|
||||
desc: "Start the REPL"
|
||||
preconditions:
|
||||
@@ -126,9 +126,18 @@ tasks:
|
||||
cmds:
|
||||
- "{{.FORMATTER_BIN_RELEASE_DIR}}/formatter --write --file '{{.FILE}}'"
|
||||
# DECOMPILING
|
||||
disasm:
|
||||
cmds:
|
||||
- '{{.DECOMP_BIN_RELEASE_DIR}}/decompiler "./decompiler/config/{{.DECOMP_CONFIG}}" "./iso_data" "./decompiler_out" --version "{{.DECOMP_CONFIG_VERSION}}" --config-override ''{"disassemble_code": true, "dump_function_metadata": true, "levels_extract": false}'''
|
||||
decomp-no-override:
|
||||
cmds:
|
||||
- '{{.DECOMP_BIN_RELEASE_DIR}}/decompiler "./decompiler/config/{{.DECOMP_CONFIG}}" "./iso_data" "./decompiler_out" --version "{{.DECOMP_CONFIG_VERSION}}"'
|
||||
decomp:
|
||||
cmds:
|
||||
- '{{.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}'''
|
||||
disasm-file:
|
||||
cmds:
|
||||
- '{{.DECOMP_BIN_RELEASE_DIR}}/decompiler "./decompiler/config/{{.DECOMP_CONFIG}}" "./iso_data" "./decompiler_out" --version "{{.DECOMP_CONFIG_VERSION}}" --config-override ''{"disassemble_code": true, "decompile_code": false, "levels_extract": false, "allowed_objects": ["{{.FILE}}"]}'''
|
||||
decomp-file:
|
||||
cmds:
|
||||
- '{{.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}}"]}'''
|
||||
@@ -218,12 +227,12 @@ tasks:
|
||||
- '{{.OFFLINETEST_BIN_RELEASE_DIR}}/offline-test{{.EXE_FILE_EXTENSION}} --iso_data_path "./iso_data/{{.GAME}}" --game {{.GAME}} --file {{.FILE}}'
|
||||
offline-tests-fast:
|
||||
cmds:
|
||||
- '{{.OFFLINETEST_BIN_RELEASE_DIR}}/offline-test{{.EXE_FILE_EXTENSION}} --iso_data_path "./iso_data/{{.GAME}}" --game {{.GAME}} --pretty-print --num_threads 32 --dump_current_output --fail-on-cmp'
|
||||
- '{{.OFFLINETEST_BIN_RELEASE_DIR}}/offline-test{{.EXE_FILE_EXTENSION}} --iso_data_path "./iso_data/{{.GAME}}" --game {{.GAME}} --pretty-print --num_threads 8 --dump_current_output --fail-on-cmp'
|
||||
# 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: '{{.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'
|
||||
- cmd: '{{.OFFLINETEST_BIN_RELEASE_DIR}}/offline-test --iso_data_path "./iso_data/{{.GAME}}" --game {{.GAME}} --pretty-print --num_threads 8 --dump_current_output --fail-on-cmp'
|
||||
ignore_error: true
|
||||
- "{{.PYTHON}} ./scripts/update_decomp_reference.py ./failures ./test/decompiler/reference/ --game {{.GAME}}"
|
||||
- task: offline-tests-fast
|
||||
|
||||
@@ -284,16 +284,53 @@ std::vector<ReplaceInfo> replace_info_jak2 = {
|
||||
{"~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",
|
||||
{"~Y~1L<FLAG_PART_FILL>~Z~3L<FLAG_PART_TOP_BOTTOM_STRIPE>~]~-2H~Y~1L<FLAG_PART_FILL>~Z~3L<FLAG_"
|
||||
"PART_TOP_BOTTOM_STRIPE>~Z~-10H~1L<FLAG_PART_VERT_STRIPE_LEFT>~Z~-5H~1L<FLAG_PART_VERT_STRIPE_"
|
||||
"LEFT>~Z~-23H~7L<FLAG_PART_VERT_STRIPE_RIGHT>~Z~-22H~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",
|
||||
{"~Y~1L<FLAG_PART_FILL>~Z~7L<FLAG_PART_TOP_BOTTOM_STRIPE>~]~-2H~Y~1L<FLAG_PART_FILL>~Z~7L<FLAG_"
|
||||
"PART_TOP_BOTTOM_STRIPE>~Z~-10H~1L<FLAG_PART_VERT_STRIPE_LEFT>~Z~-5H~1L<FLAG_PART_VERT_STRIPE_"
|
||||
"LEFT>~Z~-23H~3L<FLAG_PART_VERT_STRIPE_RIGHT>~Z~-22H~3L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~3L"
|
||||
"<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~+26H",
|
||||
"<FLAG_ICELAND>"},
|
||||
{"~Y~6L<FLAG_PART_VERT_STRIPE_LARGE>~Z~+15H~3L<FLAG_PART_VERT_STRIPE_LARGE>~Z~+30H~3L<FLAG_"
|
||||
"PART_VERT_STRIPE_LARGE>~Z~+4H~+2V~5L<FLAG_PART_KOREA_CIRCLE_FILL>~Z~+47H",
|
||||
"<FLAG_PORTUGUAL>"},
|
||||
{"~Y~3L~~~Z~1L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~7L<FLAG_PART_HORZ_STRIPE_BOTTOM>~]~-2H~Y~3L~~"
|
||||
"~Z~1L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~7L<FLAG_PART_HORZ_STRIPE_BOTTOM>~Z~+26H",
|
||||
"<FLAG_DUTCH>"},
|
||||
{"~Y~26L<FLAG_PART_FILL>~]~-1H~Y~26L<FLAG_PART_FILL>~Z~-10H~-3V~5L<PAD_PART_DPAD_D>~Z~-10H"
|
||||
"~+6V~5L<PAD_PART_DPAD_U>~Z~-5H~+1V~5L<PAD_PART_DPAD_L>~Z~-14H~+1V~5L<PAD_PART_DPAD_R>~Z"
|
||||
"~-11H~+1V~7L<FLAG_PART_KOREA_CIRCLE_FILL>~Z~+26H",
|
||||
"<FLAG_BRAZIL>"},
|
||||
{"~Y~3L~~~Z~1L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~26L<FLAG_PART_HORZ_STRIPE_BOTTOM>~]~-2H~Y~3L~~"
|
||||
"~Z~1L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~26L<FLAG_PART_HORZ_STRIPE_BOTTOM>~Z~+26H",
|
||||
"<FLAG_HUNGARY>"},
|
||||
{"~Y~3L<FLAG_PART_FILL>~Z~5L<FLAG_PART_USA_STRIPES_RIGHT>~]~-2H~Y~3L<FLAG_PART_FILL>~Z~5L"
|
||||
"<FLAG_PART_USA_STRIPES_RIGHT>~Z~+26H",
|
||||
"<FLAG_CATALAN>"},
|
||||
{"~Y~1L<FLAG_PART_FILL>~Z~3L<FLAG_PART_HORZ_STRIPE_BOTTOM>~Z~-5V~3L<FLAG_PART_HORZ_STRIPE"
|
||||
"_BOTTOM>~]~-2H~+5V~Y~1L<FLAG_PART_FILL>~Z~3L<FLAG_PART_HORZ_STRIPE_BOTTOM>~Z~-5V~3L"
|
||||
"<FLAG_PART_HORZ_STRIPE_BOTTOM>~Z~+26H",
|
||||
"<FLAG_POLAND>"},
|
||||
{"~Y~5L~~~Z~26L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~3L<FLAG_PART_HORZ_STRIPE_BOTTOM>~]~-2H~Y~5L~~"
|
||||
"~Z~26L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~3L<FLAG_PART_HORZ_STRIPE_BOTTOM>~Z~+26H",
|
||||
"<FLAG_LITHUANIA>"},
|
||||
{"~Y~1L<FLAG_PART_FILL>~]~-2H~Y~1L<FLAG_PART_FILL>~Z~3L<FLAG_PART_HORZ_STRIPE_BOTTOM>~Z~-5V~3L"
|
||||
"<FLAG_PART_HORZ_STRIPE_BOTTOM>~Z~-22H~3L<FLAG_PART_HORZ_STRIPE_BOTTOM>~Z~-22H~-5V~3L"
|
||||
"<FLAG_PART_HORZ_STRIPE_BOTTOM>~Z~-23H~7L<FLAG_PART_VERT_STRIPE_LEFT>~Z~-26H~-3V~7L"
|
||||
"<PAD_PART_DPAD_D>~Z~+6V~-26H~7L<PAD_PART_DPAD_U>~Z~-21H~+1V~7L<PAD_PART_DPAD_L>~Z~+26H",
|
||||
"<FLAG_CZECH>"},
|
||||
{"~Y~3L~~~Z~1L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~7L<FLAG_PART_HORZ_STRIPE_BOTTOM>~]~-1H~Y~3L~~"
|
||||
"~Z~1L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~7L<FLAG_PART_HORZ_STRIPE_BOTTOM>~Z~-11H~+2V~3L"
|
||||
"<FLAG_PART_JAPAN_SUN>~Z~-9H~+2V~1L+~Z~-8V~-8H~7L-~Z~-8V~-3H~7L-~Z~+26H",
|
||||
"<FLAG_CROATIA>"},
|
||||
{"~Y~1L<FLAG_PART_FILL>~Z~21L<FLAG_PART_UK_CROSS_LEFT>~Z~1L<FLAG_PART_HORZ_STRIPE_MIDDLE>"
|
||||
"~Z~1L<FLAG_PART_HORZ_STRIPE_BOTTOM>~]~-1H~Y~1L<FLAG_PART_FILL>~Z~21L<FLAG_PART_UK_CROSS_"
|
||||
"RIGHT>~Z~1L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~-4H~1L<FLAG_PART_VERT_STRIPE_LEFT>~Z~1L~~"
|
||||
"~Z~-11H~7L<FLAG_PART_KOREA_CIRCLE_FILL>~Z~-8V~-8H~3L-~Z~-8V~-4H~3L-~Z~+26H",
|
||||
"<FLAG_GALICIA>"},
|
||||
|
||||
// korean jamo -- only relevant for the language selection since
|
||||
// non-korean languages don't run through the `convert-korean-text` function and hence the
|
||||
|
||||
@@ -284,20 +284,54 @@ std::vector<ReplaceInfo> replace_info_jak3 = {
|
||||
{"~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",
|
||||
{"~Y~1L<FLAG_PART_FILL>~Z~3L<FLAG_PART_TOP_BOTTOM_STRIPE>~]~-2H~Y~1L<FLAG_PART_FILL>~Z~3L<FLAG_"
|
||||
"PART_TOP_BOTTOM_STRIPE>~Z~-10H~1L<FLAG_PART_VERT_STRIPE_LEFT>~Z~-5H~1L<FLAG_PART_VERT_STRIPE_"
|
||||
"LEFT>~Z~-23H~7L<FLAG_PART_VERT_STRIPE_RIGHT>~Z~-22H~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",
|
||||
{"~Y~1L<FLAG_PART_FILL>~Z~7L<FLAG_PART_TOP_BOTTOM_STRIPE>~]~-2H~Y~1L<FLAG_PART_FILL>~Z~7L<FLAG_"
|
||||
"PART_TOP_BOTTOM_STRIPE>~Z~-10H~1L<FLAG_PART_VERT_STRIPE_LEFT>~Z~-5H~1L<FLAG_PART_VERT_STRIPE_"
|
||||
"LEFT>~Z~-23H~3L<FLAG_PART_VERT_STRIPE_RIGHT>~Z~-22H~3L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~3L"
|
||||
"<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~+26H",
|
||||
"<FLAG_ICELAND>"},
|
||||
{"~Y~6L<FLAG_PART_VERT_STRIPE_LARGE>~Z~+15H~3L<FLAG_PART_VERT_STRIPE_LARGE>~Z~+30H~3L<FLAG_"
|
||||
"PART_VERT_STRIPE_LARGE>~Z~+4H~5L<FLAG_PART_PORTUGUAL_1>~Z~+2H~3L<FLAG_PART_PORTUGUAL_2>~Z~+"
|
||||
"2H~1L<FLAG_PART_PORTUGUAL_3>~Z~+47H",
|
||||
"<FLAG_PORTUGUAL>"},
|
||||
{"~Y~3L~~~Z~1L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~7L<FLAG_PART_HORZ_STRIPE_BOTTOM>~]~-2H~Y~3L~~"
|
||||
"~Z~1L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~7L<FLAG_PART_HORZ_STRIPE_BOTTOM>~Z~+26H",
|
||||
"<FLAG_DUTCH>"},
|
||||
{"~Y~26L<FLAG_PART_FILL>~]~-1H~Y~26L<FLAG_PART_FILL>~Z~-10H~-3V~5L<PAD_PART_DPAD_D>~Z~-10H"
|
||||
"~+6V~5L<PAD_PART_DPAD_U>~Z~-5H~+1V~5L<PAD_PART_DPAD_L>~Z~-14H~+1V~5L<PAD_PART_DPAD_R>~Z"
|
||||
"~-11H~+1V~7L<FLAG_PART_KOREA_CIRCLE_FILL>~Z~+26H",
|
||||
"<FLAG_BRAZIL>"},
|
||||
{"~Y~3L~~~Z~1L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~26L<FLAG_PART_HORZ_STRIPE_BOTTOM>~]~-2H~Y~3L~~"
|
||||
"~Z~1L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~26L<FLAG_PART_HORZ_STRIPE_BOTTOM>~Z~+26H",
|
||||
"<FLAG_HUNGARY>"},
|
||||
{"~Y~3L<FLAG_PART_FILL>~Z~5L<FLAG_PART_USA_STRIPES_RIGHT>~]~-2H~Y~3L<FLAG_PART_FILL>~Z~5L"
|
||||
"<FLAG_PART_USA_STRIPES_RIGHT>~Z~+26H",
|
||||
"<FLAG_CATALAN>"},
|
||||
{"~Y~1L<FLAG_PART_FILL>~Z~3L<FLAG_PART_HORZ_STRIPE_BOTTOM>~Z~-5V~3L<FLAG_PART_HORZ_STRIPE"
|
||||
"_BOTTOM>~]~-2H~+5V~Y~1L<FLAG_PART_FILL>~Z~3L<FLAG_PART_HORZ_STRIPE_BOTTOM>~Z~-5V~3L"
|
||||
"<FLAG_PART_HORZ_STRIPE_BOTTOM>~Z~+26H",
|
||||
"<FLAG_POLAND>"},
|
||||
{"~Y~5L~~~Z~26L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~3L<FLAG_PART_HORZ_STRIPE_BOTTOM>~]~-2H~Y~5L~~"
|
||||
"~Z~26L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~3L<FLAG_PART_HORZ_STRIPE_BOTTOM>~Z~+26H",
|
||||
"<FLAG_LITHUANIA>"},
|
||||
{"~Y~1L<FLAG_PART_FILL>~]~-2H~Y~1L<FLAG_PART_FILL>~Z~3L<FLAG_PART_HORZ_STRIPE_BOTTOM>~Z~-5V~3L"
|
||||
"<FLAG_PART_HORZ_STRIPE_BOTTOM>~Z~-22H~3L<FLAG_PART_HORZ_STRIPE_BOTTOM>~Z~-22H~-5V~3L"
|
||||
"<FLAG_PART_HORZ_STRIPE_BOTTOM>~Z~-23H~7L<FLAG_PART_VERT_STRIPE_LEFT>~Z~-26H~-3V~7L"
|
||||
"<PAD_PART_DPAD_D>~Z~+6V~-26H~7L<PAD_PART_DPAD_U>~Z~-21H~+1V~7L<PAD_PART_DPAD_L>~Z~+26H",
|
||||
"<FLAG_CZECH>"},
|
||||
{"~Y~3L~~~Z~1L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~7L<FLAG_PART_HORZ_STRIPE_BOTTOM>~]~-1H~Y~3L~~"
|
||||
"~Z~1L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~7L<FLAG_PART_HORZ_STRIPE_BOTTOM>~Z~-11H~+2V~3L"
|
||||
"<FLAG_PART_JAPAN_SUN>~Z~-9H~+2V~1L+~Z~-8V~-8H~7L-~Z~-8V~-3H~7L-~Z~+26H",
|
||||
"<FLAG_CROATIA>"},
|
||||
{"~Y~1L<FLAG_PART_FILL>~Z~21L<FLAG_PART_UK_CROSS_LEFT>~Z~1L<FLAG_PART_HORZ_STRIPE_MIDDLE>"
|
||||
"~Z~1L<FLAG_PART_HORZ_STRIPE_BOTTOM>~]~-1H~Y~1L<FLAG_PART_FILL>~Z~21L<FLAG_PART_UK_CROSS_"
|
||||
"RIGHT>~Z~1L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~-4H~1L<FLAG_PART_VERT_STRIPE_LEFT>~Z~1L~~"
|
||||
"~Z~-11H~7L<FLAG_PART_KOREA_CIRCLE_FILL>~Z~-8V~-8H~3L-~Z~-8V~-4H~3L-~Z~+26H",
|
||||
"<FLAG_GALICIA>"},
|
||||
|
||||
// korean jamo -- only relevant for the language selection since
|
||||
// non-korean languages don't run through the `convert-korean-text` function and hence the
|
||||
|
||||
+17
@@ -26,3 +26,20 @@ files:
|
||||
- "en-GB"
|
||||
- "fi"
|
||||
- "fi-Fi"
|
||||
- source: /game/assets/jak3/text/game_custom_text_en-US.json
|
||||
translation: /game/assets/jak3/text/game_custom_text_%locale%.json
|
||||
- source: /game/assets/jak3/subtitle/subtitle_lines_en-US.json
|
||||
translation: /game/assets/jak3/subtitle/subtitle_lines_%locale%.json
|
||||
excluded_target_languages:
|
||||
- "fr-FR"
|
||||
- "de-DE"
|
||||
- "es-ES"
|
||||
- "it"
|
||||
- "it-IT"
|
||||
- "ja-JP"
|
||||
- "ko"
|
||||
- "en-GB"
|
||||
- "fi"
|
||||
- "fi-Fi"
|
||||
- "ru-RU"
|
||||
- "pt-PT"
|
||||
|
||||
@@ -26,6 +26,9 @@
|
||||
// float types: float, meters (1 meter = 4096.0 units), degrees (65536.0 = 360°)
|
||||
// vector types: vector (normal floats), vector4m (meters), vector3m (meters with w set to 1.0), vector-vol (normal floats with w in meters), movie-pos (meters with w in degrees)
|
||||
// special types: symbol, type, string, eco-info, cell-info, buzzer-info, water-height
|
||||
// by default, lumps will always use the default keyframe value of -1000000000.0 (DEFAULT_RES_TIME).
|
||||
// most of the actor code will be using that value, but there are some exceptions (camera entities, water volumes, etc.)
|
||||
// you can specify a different keyframe by suffixing the lump type with e.g. "@0.5", so for a float at keyframe 0.5, the type would be "float@0.5".
|
||||
//
|
||||
// examples:
|
||||
//
|
||||
@@ -137,6 +140,50 @@
|
||||
}
|
||||
],
|
||||
|
||||
// Camera entities you want to use in your level. These are used to dynamically adjust camera settings/modes when Jak enters a volume.
|
||||
// There are a couple of different camera modes, depending on what lumps are present:
|
||||
// - cam-circular: orbits a specified point. requires "pivot" lump.
|
||||
// - optional lumps: "maxAngle", "focalPull"
|
||||
// - cam-standoff: requires "align" lump.
|
||||
// - cam-string: the default camera mode. used when any of these lumps are present to override the default cam mode behavior:
|
||||
// - "stringMaxLength", "stringMinLength", "stringMaxHeight", "stringMinHeight"
|
||||
//
|
||||
// Some generic lumps that can be used for all camera modes:
|
||||
// - "fov": set the camera fov (default is 64).
|
||||
// - "interpTime": set the cam blend time when entering the camera entity volume.
|
||||
// - "tiltAdjust": set the camera roll value.
|
||||
//
|
||||
// There's a "flags" lump that takes a cam-slave-options enum value:
|
||||
// "flags": ["enum-uint32", "(cam-slave-options SAME_SIDE COLLIDE)"]
|
||||
//
|
||||
// There's three different volume types (these all have to be defined in keyframe 0, e.g. ["vector-vol@0.0": ...]):
|
||||
// vol: sets camera entity when Jak is inside.
|
||||
// pvol: preferred volume when camera entities overlap.
|
||||
// cutoutvol: disables camera entity when Jak is inside.
|
||||
//
|
||||
// "interesting" is an optional vector lump that can be set to be used as a "point of interest" for the camera to focus on.
|
||||
"cameras": [
|
||||
{
|
||||
"trans": [17.26, 9.0, 13.2],
|
||||
"quat": [0, 1, 0, 0],
|
||||
"lump": {
|
||||
"name": "test-cam",
|
||||
"flags": ["enum-uint32", "(cam-slave-options SAME_SIDE)"],
|
||||
"pivot": ["vector3m", [15.0761, 2.6482, 25.548]],
|
||||
"interpTime": ["float", 1.0],
|
||||
"vol": [
|
||||
"vector-vol@0",
|
||||
[-0.09046, 0.025624, 0.99557, 32.528575],
|
||||
[-0.995854, 0.007292, -0.090673, -8.671137],
|
||||
[0.09046, -0.025624, -0.99557, -16.528584],
|
||||
[0.995854, -0.007292, 0.090673, 24.671144],
|
||||
[-0.009584, -0.999645, 0.024858, 0.695884],
|
||||
[0.009584, 0.999645, -0.024858, 15.304117]
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
"actors": [
|
||||
{
|
||||
"trans": [-21.6238, 20.0496, 17.1191], // translation
|
||||
|
||||
@@ -26,6 +26,9 @@
|
||||
// float types: float, meters (1 meter = 4096.0 units), degrees (65536.0 = 360°)
|
||||
// vector types: vector (normal floats), vector4m (meters), vector3m (meters with w set to 1.0), vector-vol (normal floats with w in meters), movie-pos (meters with w in degrees)
|
||||
// special types: symbol, type, string, eco-info, cell-info, buzzer-info, water-height
|
||||
// by default, lumps will always use the default keyframe value of -1000000000.0 (DEFAULT_RES_TIME).
|
||||
// most of the actor code will be using that value, but there are some exceptions (camera entities, water volumes, etc.)
|
||||
// you can specify a different keyframe by suffixing the lump type with e.g. "@0.5", so for a float at keyframe 0.5, the type would be "float@0.5".
|
||||
//
|
||||
// examples:
|
||||
//
|
||||
@@ -53,9 +56,12 @@
|
||||
// The base actor id for your custom level. If you have multiple levels, this should be unique!
|
||||
"base_id": 100,
|
||||
|
||||
// Base id for regions.
|
||||
"base_region_id": 0,
|
||||
|
||||
// All art groups you want to use in your custom level. Will add their models and corresponding textures to the FR3 file.
|
||||
// Commented out so that the release builds don't have to double-decompile the game
|
||||
// "art_groups": ["yakow-ag"],
|
||||
// "art_groups": ["yakow-ag", "water-anim-fortress-ag"],
|
||||
|
||||
// If you have any custom models in the "custom_assets/jak2/models/custom_levels" folder that you want to use in your level, add them to this list.
|
||||
// Note: Like with art groups, these should also be added to your level's .gd file.
|
||||
@@ -69,6 +75,177 @@
|
||||
// If you want all textures from a tpage, you can just do ["tpage-name"].
|
||||
"textures": ["yak-medfur-end"], // for yakow texture fix
|
||||
|
||||
// Any regions you want to include in your custom level.
|
||||
// Regions run scripts that do things like loading specific levels,
|
||||
// playing ambient sounds, checking if a task is completed in order to e.g. open airlocks, play cutscenes, etc.
|
||||
//
|
||||
// They can have three scripts that run on different conditions:
|
||||
// - A single time when entering the region's bounds (on-enter)
|
||||
// - Once every frame while you are inside a region (on-inside)
|
||||
// - A single time when exiting a region's bounds (on-exit)
|
||||
// Scripts are Lisp pairs, e.g. (want-load 'ctysluma 'ctyindb 'ctywide).
|
||||
// The list of commands that can be used is too exhaustive to show here and there is no proper documentation for this,
|
||||
// but you can refer to https://github.com/open-goal/jak-project/blob/master/goal_src/jak2/engine/util/script.gc
|
||||
// for more information or inspect other regions via the debug menu in-game for examples.
|
||||
//
|
||||
// There are two special cases for script forms: "entity-actor" and "actor-group".
|
||||
// Region scripts can refer to entities or actor groups that are stored inside the level data,
|
||||
// so forms that start with either of these will be changed during the level building process to insert a reference
|
||||
// to the given object.
|
||||
//
|
||||
// Regions can either be spheres, planes or volumes.
|
||||
// Spheres do not need anything special, just the trans and bsphere, but if you want a face or a volume,
|
||||
// you need to additionally specify a "face" or a "volume" key.
|
||||
// A "face" key contains the face normal and a list of points.
|
||||
// A "volume" key contains a list of faces.
|
||||
//
|
||||
// There are different types of regions like ones that get triggered based on camera position, Jak's position, etc.
|
||||
// Each type of region is stored in its own region tree, each of which has its own bsphere that all its regions must be encompassed within.
|
||||
// The full list is as follows:
|
||||
// target (Jak based), camera (camera based), data (?), water (water volumes), city_vis (?),
|
||||
// sample (?), light (presumably for foreground lights), entity (?)
|
||||
"region_trees": {
|
||||
// camera regions are activated when the camera enters their bounds
|
||||
"camera": {
|
||||
// every region tree has its own bsphere. all of a tree's regions must be encompassed within this sphere.
|
||||
"bsphere": [0, 0, 0, 50],
|
||||
"regions": [
|
||||
{
|
||||
"id": 1,
|
||||
"shape": "sphere", // can be "sphere", "face" or "volume"
|
||||
"trans": [-17, 4, 30],
|
||||
"bsphere": [-17, 4, 30, 5],
|
||||
// "(actor-group 2)" will be replaced with an actual reference
|
||||
// to the actor-group in the level data with id 2.
|
||||
"on-enter": "(begin (print 'enter1) (send-event (actor-group 2) 'none))",
|
||||
"on-inside": "(begin (sound-play-loop \"punch\") (sound-play-loop \"spin\"))",
|
||||
"on-exit": "(print 'exit1)"
|
||||
}
|
||||
]
|
||||
},
|
||||
// target regions are activated when Jak enters their bounds
|
||||
"target": {
|
||||
"bsphere": [0, 0, 0, 50],
|
||||
"regions": [
|
||||
{
|
||||
"id": 2,
|
||||
"shape": "face",
|
||||
"on-enter": "(begin (print 'enter14) (send-event \"test-actor\" 'rot))",
|
||||
"bsphere": [3.37, 6.2, 16.59, 7.0711],
|
||||
"face": {
|
||||
"normal": [-0.615662, 0.0, -0.788011, -15.147877],
|
||||
"points": [
|
||||
[-0.570054, 0, 19.668308],
|
||||
[-0.570053, 11, 19.668308],
|
||||
[7.310053, 0, 13.511692],
|
||||
[7.310053, 11, 13.511692]
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
// water regions are used to define water volumes
|
||||
"water": {
|
||||
"bsphere": [0, 0, 0, 200],
|
||||
"regions": [
|
||||
{
|
||||
"id": 3,
|
||||
"shape": "sphere",
|
||||
// "(entity-actor water-anim-test-zone-1)" will be replaced with an actual reference of the entity with that name.
|
||||
"on-inside": "(water water-anim (entity-actor water-anim-test-zone-1) (swim wade))",
|
||||
"trans": [5.0, 6.0, -66.0],
|
||||
"bsphere": [5.0, 6.0, -66.0, 50.0]
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"shape": "volume",
|
||||
"on-inside": "(water height 0.0 (swim wade))",
|
||||
"bsphere": [5.1664, 9.4453, 51.2316, 25.2828],
|
||||
"volume": {
|
||||
"faces": [
|
||||
{
|
||||
"normal": [-1.0, 0.0, 0.0, 11.785238],
|
||||
"points": [
|
||||
[-11.785238, -2.468076, 65.720734],
|
||||
[-11.785238, 21.358631, 65.720734],
|
||||
[-11.785238, -2.468076, 36.742477],
|
||||
[-11.785238, 21.358631, 36.742477]
|
||||
]
|
||||
},
|
||||
{
|
||||
"normal": [0.0, 0.0, -1.0, -36.742475],
|
||||
"points": [
|
||||
[-11.785238, -2.468076, 36.742477],
|
||||
[-11.785238, 21.358631, 36.742477],
|
||||
[22.118128, -2.468076, 36.742477],
|
||||
[22.118128, 21.358631, 36.742477]
|
||||
]
|
||||
},
|
||||
{
|
||||
"normal": [1.0, 0.0, 0.0, 22.118128],
|
||||
"points": [
|
||||
[22.118128, -2.468076, 36.742477],
|
||||
[22.118128, 21.358631, 36.742477],
|
||||
[22.118128, -2.468076, 65.720734],
|
||||
[22.118128, 21.358631, 65.720734]
|
||||
]
|
||||
},
|
||||
{
|
||||
"normal": [0.0, 0.0, 1.0, 65.72073],
|
||||
"points": [
|
||||
[22.118128, -2.468076, 65.720734],
|
||||
[22.118128, 21.358631, 65.720734],
|
||||
[-11.785238, -2.468076, 65.720734],
|
||||
[-11.785238, 21.358631, 65.720734]
|
||||
]
|
||||
},
|
||||
{
|
||||
"normal": [0.0, -1.0, 0.0, 2.468076],
|
||||
"points": [
|
||||
[-11.785238, -2.468076, 36.742477],
|
||||
[22.118128, -2.468076, 36.742477],
|
||||
[-11.785238, -2.468076, 65.720734],
|
||||
[22.118128, -2.468076, 65.720734]
|
||||
]
|
||||
},
|
||||
{
|
||||
"normal": [0.0, 1.0, 0.0, 21.358631],
|
||||
"points": [
|
||||
[22.118128, 21.358631, 36.742477],
|
||||
[-11.785238, 21.358631, 36.742477],
|
||||
[22.118128, 21.358631, 65.720734],
|
||||
[-11.785238, 21.358631, 65.720734]
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"data": {},
|
||||
"city_vis": {},
|
||||
"sample": {},
|
||||
"light": {},
|
||||
"entity": {}
|
||||
},
|
||||
|
||||
// Actor groups you want to include in your level.
|
||||
//
|
||||
// Actor groups are arrays of entities, used for example in regions to send events to a list of actors
|
||||
// or in "battles" as a list of enemies that need to be defeated before being able to progress.
|
||||
// You can give them an id, this has no effect in-game, but it is used for region scripts so the level builder
|
||||
// knows which actor group to insert.
|
||||
"actor_groups": [
|
||||
{
|
||||
"id": 0,
|
||||
"entities": ["test-crate", "test-eco", "test-yakow"]
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"entities": ["test-crate", "test-actor"]
|
||||
}
|
||||
],
|
||||
|
||||
"actors": [
|
||||
{
|
||||
"trans": [-15.2818, 15.2461, 17.136], // translation
|
||||
@@ -115,6 +292,24 @@
|
||||
"lump": {
|
||||
"name": "test-actor"
|
||||
}
|
||||
},
|
||||
{
|
||||
"trans": [5, 6.778769493103027, -66],
|
||||
"etype": "water-anim-test-zone",
|
||||
"game_task": 0,
|
||||
"quat": [0.0, 0.0, 0.0, 1.0],
|
||||
"bsphere": [5, 6.778769493103027, -66, 50],
|
||||
"lump": {
|
||||
"look": ["int32", 21],
|
||||
"name": "water-anim-test-zone-1",
|
||||
"water-height": [
|
||||
"water-height",
|
||||
6.77869987487793,
|
||||
0.5,
|
||||
2.0,
|
||||
"(water-flags can-swim can-wade)"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -26,6 +26,9 @@
|
||||
// float types: float, meters (1 meter = 4096.0 units), degrees (65536.0 = 360°)
|
||||
// vector types: vector (normal floats), vector4m (meters), vector3m (meters with w set to 1.0), vector-vol (normal floats with w in meters), movie-pos (meters with w in degrees)
|
||||
// special types: symbol, type, string, eco-info, cell-info, buzzer-info, water-height
|
||||
// by default, lumps will always use the default keyframe value of -1000000000.0 (DEFAULT_RES_TIME).
|
||||
// most of the actor code will be using that value, but there are some exceptions (camera entities, water volumes, etc.)
|
||||
// you can specify a different keyframe by suffixing the lump type with e.g. "@0.5", so for a float at keyframe 0.5, the type would be "float@0.5".
|
||||
//
|
||||
// examples:
|
||||
//
|
||||
@@ -53,9 +56,12 @@
|
||||
// The base actor id for your custom level. If you have multiple levels, this should be unique!
|
||||
"base_id": 100,
|
||||
|
||||
// Base id for regions.
|
||||
"base_region_id": 0,
|
||||
|
||||
// All art groups you want to use in your custom level. Will add their models and corresponding textures to the FR3 file.
|
||||
// Commented out so that the release builds don't have to double-decompile the game
|
||||
// "art_groups": ["yakow-ag"],
|
||||
// "art_groups": ["yakow-ag", "water-anim-waspala-ag"],
|
||||
|
||||
// If you have any custom models in the "custom_assets/jak3/models/custom_levels" folder that you want to use in your level, add them to this list.
|
||||
// Note: Like with art groups, these should also be added to your level's .gd file.
|
||||
@@ -69,6 +75,177 @@
|
||||
// If you want all textures from a tpage, you can just do ["tpage-name"].
|
||||
"textures": ["yak-medfur-end"], // for yakow texture fix
|
||||
|
||||
// Any regions you want to include in your custom level.
|
||||
// Regions run scripts that do things like loading specific levels,
|
||||
// playing ambient sounds, checking if a task is completed in order to e.g. open airlocks, play cutscenes, etc.
|
||||
//
|
||||
// They can have three scripts that run on different conditions:
|
||||
// - A single time when entering the region's bounds (on-enter)
|
||||
// - Once every frame while you are inside a region (on-inside)
|
||||
// - A single time when exiting a region's bounds (on-exit)
|
||||
// Scripts are Lisp pairs, e.g. (want-load 'ctysluma 'ctyindb 'ctywide).
|
||||
// The list of commands that can be used is too exhaustive to show here and there is no proper documentation for this,
|
||||
// but you can refer to https://github.com/open-goal/jak-project/blob/master/goal_src/jak3/engine/util/script.gc
|
||||
// for more information or inspect other regions via the debug menu in-game for examples.
|
||||
//
|
||||
// There are two special cases for script forms: "entity-actor" and "actor-group".
|
||||
// Region scripts can refer to entities or actor groups that are stored inside the level data,
|
||||
// so forms that start with either of these will be changed during the level building process to insert a reference
|
||||
// to the given object.
|
||||
//
|
||||
// Regions can either be spheres, planes or volumes.
|
||||
// Spheres do not need anything special, just the trans and bsphere, but if you want a face or a volume,
|
||||
// you need to additionally specify a "face" or a "volume" key.
|
||||
// A "face" key contains the face normal and a list of points.
|
||||
// A "volume" key contains a list of faces.
|
||||
//
|
||||
// There are different types of regions like ones that get triggered based on camera position, Jak's position, etc.
|
||||
// Each type of region is stored in its own region tree, each of which has its own bsphere that all its regions must be encompassed within.
|
||||
// The full list is as follows:
|
||||
// target (Jak based), camera (camera based), data (?), water (water volumes), city_vis (?),
|
||||
// sample (?), light (presumably for foreground lights), entity (?)
|
||||
"region_trees": {
|
||||
// camera regions are activated when the camera enters their bounds
|
||||
"camera": {
|
||||
// every region tree has its own bsphere. all of a tree's regions must be encompassed within this sphere.
|
||||
"bsphere": [0, 0, 0, 50],
|
||||
"regions": [
|
||||
{
|
||||
"id": 1,
|
||||
"shape": "sphere", // can be "sphere", "face" or "volume"
|
||||
"trans": [-17, 4, 30],
|
||||
"bsphere": [-17, 4, 30, 5],
|
||||
// "(actor-group 2)" will be replaced with an actual reference
|
||||
// to the actor-group in the level data with id 2.
|
||||
"on-enter": "(begin (print 'enter1) (send-event (actor-group 2) 'none))",
|
||||
"on-inside": "(begin (sound-play-loop \"punch\") (sound-play-loop \"spin\"))",
|
||||
"on-exit": "(print 'exit1)"
|
||||
}
|
||||
]
|
||||
},
|
||||
// target regions are activated when Jak enters their bounds
|
||||
"target": {
|
||||
"bsphere": [0, 0, 0, 50],
|
||||
"regions": [
|
||||
{
|
||||
"id": 2,
|
||||
"shape": "face",
|
||||
"on-enter": "(begin (print 'enter14) (send-event \"test-actor\" 'rot))",
|
||||
"bsphere": [3.37, 6.2, 16.59, 7.0711],
|
||||
"face": {
|
||||
"normal": [-0.615662, 0.0, -0.788011, -15.147877],
|
||||
"points": [
|
||||
[-0.570054, 0, 19.668308],
|
||||
[-0.570053, 11, 19.668308],
|
||||
[7.310053, 0, 13.511692],
|
||||
[7.310053, 11, 13.511692]
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
// water regions are used to define water volumes
|
||||
"water": {
|
||||
"bsphere": [0, 0, 0, 200],
|
||||
"regions": [
|
||||
{
|
||||
"id": 3,
|
||||
"shape": "sphere",
|
||||
// "(entity-actor water-anim-test-zone-1)" will be replaced with an actual reference of the entity with that name.
|
||||
"on-inside": "(water water-anim (entity-actor water-anim-test-zone-1) (swim wade))",
|
||||
"trans": [5.0, 6.0, -66.0],
|
||||
"bsphere": [5.0, 6.0, -66.0, 50.0]
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"shape": "volume",
|
||||
"on-inside": "(water height 0.0 (swim wade))",
|
||||
"bsphere": [5.1664, 9.4453, 51.2316, 25.2828],
|
||||
"volume": {
|
||||
"faces": [
|
||||
{
|
||||
"normal": [-1.0, 0.0, 0.0, 11.785238],
|
||||
"points": [
|
||||
[-11.785238, -2.468076, 65.720734],
|
||||
[-11.785238, 21.358631, 65.720734],
|
||||
[-11.785238, -2.468076, 36.742477],
|
||||
[-11.785238, 21.358631, 36.742477]
|
||||
]
|
||||
},
|
||||
{
|
||||
"normal": [0.0, 0.0, -1.0, -36.742475],
|
||||
"points": [
|
||||
[-11.785238, -2.468076, 36.742477],
|
||||
[-11.785238, 21.358631, 36.742477],
|
||||
[22.118128, -2.468076, 36.742477],
|
||||
[22.118128, 21.358631, 36.742477]
|
||||
]
|
||||
},
|
||||
{
|
||||
"normal": [1.0, 0.0, 0.0, 22.118128],
|
||||
"points": [
|
||||
[22.118128, -2.468076, 36.742477],
|
||||
[22.118128, 21.358631, 36.742477],
|
||||
[22.118128, -2.468076, 65.720734],
|
||||
[22.118128, 21.358631, 65.720734]
|
||||
]
|
||||
},
|
||||
{
|
||||
"normal": [0.0, 0.0, 1.0, 65.72073],
|
||||
"points": [
|
||||
[22.118128, -2.468076, 65.720734],
|
||||
[22.118128, 21.358631, 65.720734],
|
||||
[-11.785238, -2.468076, 65.720734],
|
||||
[-11.785238, 21.358631, 65.720734]
|
||||
]
|
||||
},
|
||||
{
|
||||
"normal": [0.0, -1.0, 0.0, 2.468076],
|
||||
"points": [
|
||||
[-11.785238, -2.468076, 36.742477],
|
||||
[22.118128, -2.468076, 36.742477],
|
||||
[-11.785238, -2.468076, 65.720734],
|
||||
[22.118128, -2.468076, 65.720734]
|
||||
]
|
||||
},
|
||||
{
|
||||
"normal": [0.0, 1.0, 0.0, 21.358631],
|
||||
"points": [
|
||||
[22.118128, 21.358631, 36.742477],
|
||||
[-11.785238, 21.358631, 36.742477],
|
||||
[22.118128, 21.358631, 65.720734],
|
||||
[-11.785238, 21.358631, 65.720734]
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"data": {},
|
||||
"city_vis": {},
|
||||
"sample": {},
|
||||
"light": {},
|
||||
"entity": {}
|
||||
},
|
||||
|
||||
// Actor groups you want to include in your level.
|
||||
//
|
||||
// Actor groups are arrays of entities, used for example in regions to send events to a list of actors
|
||||
// or in "battles" as a list of enemies that need to be defeated before being able to progress.
|
||||
// You can give them an id, this has no effect in-game, but it is used for region scripts so the level builder
|
||||
// knows which actor group to insert.
|
||||
"actor_groups": [
|
||||
{
|
||||
"id": 0,
|
||||
"entities": ["test-crate", "test-eco", "test-yakow"]
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"entities": ["test-crate", "test-actor"]
|
||||
}
|
||||
],
|
||||
|
||||
"actors": [
|
||||
{
|
||||
"trans": [-15.2818, 15.2461, 17.136], // translation
|
||||
@@ -116,6 +293,24 @@
|
||||
"lump": {
|
||||
"name": "test-actor"
|
||||
}
|
||||
},
|
||||
{
|
||||
"trans": [5, 6.778769493103027, -66],
|
||||
"etype": "water-anim-test-zone",
|
||||
"game_task": 0,
|
||||
"quat": [0.0, 0.0, 0.0, 1.0],
|
||||
"bsphere": [5, 6.778769493103027, -66, 50],
|
||||
"lump": {
|
||||
"look": ["int32", 7],
|
||||
"name": "water-anim-test-zone-1",
|
||||
"water-height": [
|
||||
"water-height",
|
||||
6.77869987487793,
|
||||
0.5,
|
||||
2.0,
|
||||
"(water-flag can-swim can-wade)"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -60,6 +60,7 @@ add_library(
|
||||
level_extractor/extract_common.cpp
|
||||
level_extractor/extract_hfrag.cpp
|
||||
level_extractor/extract_joint_group.cpp
|
||||
level_extractor/extract_anim.cpp
|
||||
level_extractor/extract_level.cpp
|
||||
level_extractor/extract_merc.cpp
|
||||
level_extractor/extract_tfrag.cpp
|
||||
@@ -100,7 +101,7 @@ target_link_libraries(decomp
|
||||
stb_image
|
||||
xdelta3
|
||||
tiny_gltf
|
||||
)
|
||||
)
|
||||
|
||||
add_executable(decompiler
|
||||
main.cpp)
|
||||
|
||||
@@ -62,7 +62,8 @@ FormElement* SetVarOp::get_as_form(FormPool& pool, const Env& env) const {
|
||||
m_dst,
|
||||
pool.alloc_single_element_form<GenericElement>(
|
||||
nullptr, GenericOperator::make_fixed(FixedOperatorKind::ADDRESS_OF),
|
||||
pool.alloc_single_element_form<StackSpillValueElement>(nullptr, -1, offset, false)),
|
||||
pool.alloc_single_element_form<StackSpillValueElement>(
|
||||
nullptr, -1, offset, make_stack_slot_access(offset), false)),
|
||||
true, env.stack_slot_entries.at(offset).typespec);
|
||||
}
|
||||
} else {
|
||||
@@ -843,10 +844,16 @@ FormElement* StackSpillLoadOp::get_as_form(FormPool& pool, const Env& env) const
|
||||
if (kv != env.stack_slot_entries.end()) {
|
||||
type = kv->second.typespec;
|
||||
}
|
||||
return pool.alloc_element<SetVarElement>(m_dst,
|
||||
pool.alloc_single_element_form<StackSpillValueElement>(
|
||||
nullptr, m_size, m_offset, m_is_signed),
|
||||
true, type);
|
||||
std::optional<TypeSpec> read_type;
|
||||
if (env.has_type_analysis()) {
|
||||
read_type = env.get_types_before_op(m_my_idx).get_slot(m_offset).typespec();
|
||||
}
|
||||
return pool.alloc_element<SetVarElement>(
|
||||
m_dst,
|
||||
pool.alloc_single_element_form<StackSpillValueElement>(
|
||||
nullptr, m_size, m_offset, env.get_stack_slot_access_for_op(m_my_idx, m_offset),
|
||||
m_is_signed, read_type),
|
||||
true, type);
|
||||
}
|
||||
|
||||
FormElement* StackSpillStoreOp::get_as_form(FormPool& pool, const Env& env) const {
|
||||
@@ -866,6 +873,7 @@ FormElement* StackSpillStoreOp::get_as_form(FormPool& pool, const Env& env) cons
|
||||
}
|
||||
}
|
||||
|
||||
return pool.alloc_element<StackSpillStoreElement>(m_value, m_size, m_offset, cast_type);
|
||||
return pool.alloc_element<StackSpillStoreElement>(
|
||||
m_value, m_size, m_offset, env.get_stack_slot_access_for_op(m_my_idx, m_offset), cast_type);
|
||||
}
|
||||
} // namespace decompiler
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <stdexcept>
|
||||
#include <unordered_set>
|
||||
|
||||
#include "AtomicOp.h"
|
||||
#include "Form.h"
|
||||
|
||||
#include "common/goos/PrettyPrinter.h"
|
||||
@@ -162,6 +163,10 @@ std::string Env::get_variable_name(const RegisterAccess& access) const {
|
||||
}
|
||||
|
||||
std::string Env::get_variable_name_name_only(const RegisterAccess& access) const {
|
||||
if (is_stack_slot_access(access)) {
|
||||
return get_spill_slot_var_name(get_stack_slot_offset_from_access(access));
|
||||
}
|
||||
|
||||
if (access.reg().get_kind() == Reg::FPR || access.reg().get_kind() == Reg::GPR) {
|
||||
auto& var_info = m_var_names.lookup(access.reg(), access.idx(), access.mode());
|
||||
return var_info.name();
|
||||
@@ -172,6 +177,14 @@ std::string Env::get_variable_name_name_only(const RegisterAccess& access) const
|
||||
}
|
||||
|
||||
VariableWithCast Env::get_variable_and_cast(const RegisterAccess& access) const {
|
||||
if (is_stack_slot_access(access)) {
|
||||
VariableWithCast result;
|
||||
auto original_name = get_spill_slot_var_name(get_stack_slot_offset_from_access(access));
|
||||
auto remapped = m_var_remap.find(original_name);
|
||||
result.name = remapped != m_var_remap.end() ? remapped->second : original_name;
|
||||
return result;
|
||||
}
|
||||
|
||||
if (access.reg().get_kind() == Reg::FPR || access.reg().get_kind() == Reg::GPR) {
|
||||
auto& var_info = m_var_names.lookup(access.reg(), access.idx(), access.mode());
|
||||
// this is a bit of a confusing process. The first step is to grab the auto-generated name:
|
||||
@@ -272,6 +285,10 @@ goos::Object Env::get_variable_name_with_cast(Register reg, int atomic_idx, Acce
|
||||
}
|
||||
|
||||
std::optional<TypeSpec> Env::get_user_cast_for_access(const RegisterAccess& access) const {
|
||||
if (is_stack_slot_access(access)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
if (access.reg().get_kind() == Reg::FPR || access.reg().get_kind() == Reg::GPR) {
|
||||
auto& var_info = m_var_names.lookup(access.reg(), access.idx(), access.mode());
|
||||
std::string original_name = var_info.name();
|
||||
@@ -310,6 +327,22 @@ std::optional<TypeSpec> Env::get_user_cast_for_access(const RegisterAccess& acce
|
||||
* of the variable.
|
||||
*/
|
||||
TypeSpec Env::get_variable_type(const RegisterAccess& access, bool using_user_var_types) const {
|
||||
if (is_stack_slot_access(access)) {
|
||||
auto offset = get_stack_slot_offset_from_access(access);
|
||||
auto it = stack_slot_entries.find(offset);
|
||||
if (it != stack_slot_entries.end()) {
|
||||
auto type_of_var = it->second.typespec;
|
||||
if (using_user_var_types) {
|
||||
auto retype_kv = m_var_retype.find(it->second.name());
|
||||
if (retype_kv != m_var_retype.end()) {
|
||||
type_of_var = retype_kv->second;
|
||||
}
|
||||
}
|
||||
return type_of_var;
|
||||
}
|
||||
return TypeSpec("object");
|
||||
}
|
||||
|
||||
if (access.reg().get_kind() == Reg::FPR || access.reg().get_kind() == Reg::GPR) {
|
||||
auto& var_info = m_var_names.lookup(access.reg(), access.idx(), access.mode());
|
||||
std::string original_name = var_info.name();
|
||||
@@ -328,6 +361,37 @@ TypeSpec Env::get_variable_type(const RegisterAccess& access, bool using_user_va
|
||||
}
|
||||
}
|
||||
|
||||
TP_Type Env::get_variable_tp_type(const RegisterAccess& access, bool using_user_var_types) const {
|
||||
if (is_stack_slot_access(access)) {
|
||||
auto offset = get_stack_slot_offset_from_access(access);
|
||||
auto it = stack_slot_entries.find(offset);
|
||||
if (it != stack_slot_entries.end()) {
|
||||
auto type_of_var = it->second.tp_type;
|
||||
if (using_user_var_types) {
|
||||
auto retype_kv = m_var_retype.find(it->second.name());
|
||||
if (retype_kv != m_var_retype.end()) {
|
||||
type_of_var = TP_Type::make_from_ts(retype_kv->second);
|
||||
}
|
||||
}
|
||||
return type_of_var;
|
||||
}
|
||||
return TP_Type::make_from_ts(TypeSpec("object"));
|
||||
}
|
||||
|
||||
if (access.reg().get_kind() == Reg::FPR || access.reg().get_kind() == Reg::GPR) {
|
||||
auto& var_info = m_var_names.lookup(access.reg(), access.idx(), access.mode());
|
||||
if (using_user_var_types) {
|
||||
auto retype_kv = m_var_retype.find(var_info.name());
|
||||
if (retype_kv != m_var_retype.end()) {
|
||||
return TP_Type::make_from_ts(retype_kv->second);
|
||||
}
|
||||
}
|
||||
return var_info.type;
|
||||
}
|
||||
|
||||
throw std::runtime_error("TP types are not supported for this kind of register");
|
||||
}
|
||||
|
||||
/*!
|
||||
* Update the Env with the result of the type analysis pass.
|
||||
*/
|
||||
@@ -420,6 +484,9 @@ std::vector<VariableNames::VarInfo> Env::extract_visible_variables(
|
||||
std::vector<std::pair<RegId, RegisterAccess>> vars;
|
||||
|
||||
for (auto& x : var_set) {
|
||||
if (is_stack_slot_access(x)) {
|
||||
continue;
|
||||
}
|
||||
if (x.reg().get_kind() == Reg::FPR || x.reg().get_kind() == Reg::GPR) {
|
||||
vars.push_back(std::make_pair(get_program_var_id(x), x));
|
||||
}
|
||||
@@ -480,6 +547,16 @@ FunctionVariableDefinitions Env::local_var_type_list(const Form* top_level_form,
|
||||
int nargs_to_ignore) const {
|
||||
ASSERT(nargs_to_ignore <= 8);
|
||||
auto vars = extract_visible_variables(top_level_form);
|
||||
std::unordered_set<int> visible_stack_slots;
|
||||
if (top_level_form) {
|
||||
RegAccessSet var_set;
|
||||
top_level_form->collect_vars(var_set, true);
|
||||
for (const auto& var : var_set) {
|
||||
if (is_stack_slot_access(var)) {
|
||||
visible_stack_slots.insert(get_stack_slot_offset_from_access(var));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FunctionVariableDefinitions result;
|
||||
std::vector<goos::Object> elts;
|
||||
@@ -514,11 +591,17 @@ FunctionVariableDefinitions Env::local_var_type_list(const Form* top_level_form,
|
||||
// it looks like this is the order the GOAL compiler itself used.
|
||||
std::vector<StackSpillEntry> spills;
|
||||
for (auto& x : stack_slot_entries) {
|
||||
if (top_level_form && !visible_stack_slots.count(x.first)) {
|
||||
continue;
|
||||
}
|
||||
spills.push_back(x.second);
|
||||
}
|
||||
std::sort(spills.begin(), spills.end(),
|
||||
[](const StackSpillEntry& a, const StackSpillEntry& b) { return a.offset < b.offset; });
|
||||
for (auto& x : spills) {
|
||||
if (m_vars_defined_in_let.find(x.name()) != m_vars_defined_in_let.end()) {
|
||||
continue;
|
||||
}
|
||||
elts.push_back(pretty_print::build_list(x.name(), x.typespec.print()));
|
||||
count++;
|
||||
}
|
||||
@@ -539,27 +622,186 @@ std::unordered_set<RegId, RegId::hash> Env::get_ssa_var(const RegAccessSet& vars
|
||||
}
|
||||
|
||||
RegId Env::get_program_var_id(const RegisterAccess& var) const {
|
||||
if (is_stack_slot_access(var)) {
|
||||
return RegId(Register(Reg::GPR, Reg::SP), get_stack_slot_var_id_from_access(var));
|
||||
}
|
||||
return m_var_names.lookup(var.reg(), var.idx(), var.mode()).reg_id;
|
||||
}
|
||||
|
||||
const UseDefInfo& Env::get_use_def_info(const RegisterAccess& ra) const {
|
||||
ASSERT(has_local_vars());
|
||||
if (is_stack_slot_access(ra)) {
|
||||
return m_stack_slot_use_def_info.at(get_program_var_id(ra));
|
||||
}
|
||||
auto var_id = get_program_var_id(ra);
|
||||
return m_var_names.use_def_info.at(var_id);
|
||||
}
|
||||
|
||||
RegisterAccess Env::get_stack_slot_access_for_op(int op_id, int offset) const {
|
||||
auto it = m_stack_slot_var_by_op.find(op_id);
|
||||
if (it == m_stack_slot_var_by_op.end()) {
|
||||
return make_stack_slot_access(offset);
|
||||
}
|
||||
return make_stack_slot_access(offset, it->second);
|
||||
}
|
||||
|
||||
void Env::disable_def(const RegisterAccess& access, DecompWarnings& warnings) {
|
||||
if (is_stack_slot_access(access)) {
|
||||
// Stack-slot use/def info is intentionally immutable during expression building.
|
||||
// Unlike registers, the stack-slot analysis models value lifetimes through merged control flow
|
||||
// with synthetic phi-like vars, and mutating counts here would desynchronize later accesses
|
||||
// from that analysis.
|
||||
return;
|
||||
}
|
||||
if (has_local_vars()) {
|
||||
m_var_names.disable_def(access, warnings);
|
||||
}
|
||||
}
|
||||
|
||||
void Env::disable_use(const RegisterAccess& access) {
|
||||
if (is_stack_slot_access(access)) {
|
||||
// See disable_def above.
|
||||
return;
|
||||
}
|
||||
if (has_local_vars()) {
|
||||
m_var_names.disable_use(access);
|
||||
}
|
||||
}
|
||||
|
||||
void Env::rebuild_stack_slot_use_def_info() {
|
||||
m_stack_slot_use_def_info.clear();
|
||||
m_stack_slot_var_by_op.clear();
|
||||
|
||||
if (!func || !func->ir2.atomic_ops) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& ops = *func->ir2.atomic_ops;
|
||||
const int block_count = (int)ops.block_id_to_first_atomic_op.size();
|
||||
std::vector<int> op_to_block(ops.ops.size(), -1);
|
||||
for (int block_id = 0; block_id < block_count; block_id++) {
|
||||
for (int op_id = ops.block_id_to_first_atomic_op.at(block_id);
|
||||
op_id < ops.block_id_to_end_atomic_op.at(block_id); op_id++) {
|
||||
op_to_block.at(op_id) = block_id;
|
||||
}
|
||||
}
|
||||
|
||||
std::unordered_set<int> offsets;
|
||||
for (int op_id = 0; op_id < (int)ops.ops.size(); op_id++) {
|
||||
if (auto* store = dynamic_cast<const StackSpillStoreOp*>(ops.ops.at(op_id).get())) {
|
||||
offsets.insert(store->offset());
|
||||
} else if (auto* load = dynamic_cast<const StackSpillLoadOp*>(ops.ops.at(op_id).get())) {
|
||||
offsets.insert(load->offset());
|
||||
}
|
||||
}
|
||||
|
||||
int next_var_id = 1;
|
||||
for (int offset : offsets) {
|
||||
std::vector<bool> reads_before_write(block_count, false);
|
||||
std::vector<bool> writes(block_count, false);
|
||||
|
||||
for (int block_id = 0; block_id < block_count; block_id++) {
|
||||
bool seen_write = false;
|
||||
for (int op_id = ops.block_id_to_first_atomic_op.at(block_id);
|
||||
op_id < ops.block_id_to_end_atomic_op.at(block_id); op_id++) {
|
||||
const auto* op = ops.ops.at(op_id).get();
|
||||
if (auto* load = dynamic_cast<const StackSpillLoadOp*>(op)) {
|
||||
if (load->offset() == offset && !seen_write) {
|
||||
reads_before_write.at(block_id) = true;
|
||||
}
|
||||
} else if (auto* store = dynamic_cast<const StackSpillStoreOp*>(op)) {
|
||||
if (store->offset() == offset) {
|
||||
writes.at(block_id) = true;
|
||||
seen_write = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<bool> live_in(block_count, false);
|
||||
std::vector<bool> live_out(block_count, false);
|
||||
bool changed = true;
|
||||
while (changed) {
|
||||
changed = false;
|
||||
for (int block_id = block_count - 1; block_id >= 0; block_id--) {
|
||||
bool new_live_out = false;
|
||||
for (int succ : {func->basic_blocks.at(block_id).succ_branch,
|
||||
func->basic_blocks.at(block_id).succ_ft}) {
|
||||
if (succ != -1 && live_in.at(succ)) {
|
||||
new_live_out = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool new_live_in =
|
||||
reads_before_write.at(block_id) || (new_live_out && !writes.at(block_id));
|
||||
if (new_live_in != live_in.at(block_id) || new_live_out != live_out.at(block_id)) {
|
||||
live_in.at(block_id) = new_live_in;
|
||||
live_out.at(block_id) = new_live_out;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<int> phi_var(block_count, -1);
|
||||
std::vector<std::vector<int>> phi_sources(block_count);
|
||||
for (int block_id = 0; block_id < block_count; block_id++) {
|
||||
if (live_in.at(block_id)) {
|
||||
phi_var.at(block_id) = next_var_id++;
|
||||
}
|
||||
}
|
||||
|
||||
for (int block_id = 0; block_id < block_count; block_id++) {
|
||||
int current_var = live_in.at(block_id) ? phi_var.at(block_id) : -1;
|
||||
for (int op_id = ops.block_id_to_first_atomic_op.at(block_id);
|
||||
op_id < ops.block_id_to_end_atomic_op.at(block_id); op_id++) {
|
||||
const auto* op = ops.ops.at(op_id).get();
|
||||
if (auto* load = dynamic_cast<const StackSpillLoadOp*>(op)) {
|
||||
if (load->offset() != offset) {
|
||||
continue;
|
||||
}
|
||||
ASSERT(current_var != -1);
|
||||
m_stack_slot_var_by_op[op_id] = current_var;
|
||||
auto& info = m_stack_slot_use_def_info[RegId(Register(Reg::GPR, Reg::SP), current_var)];
|
||||
info.uses.push_back({op_id, block_id, AccessMode::READ, false});
|
||||
info.ssa_vars.insert(current_var);
|
||||
} else if (auto* store = dynamic_cast<const StackSpillStoreOp*>(op)) {
|
||||
if (store->offset() != offset) {
|
||||
continue;
|
||||
}
|
||||
current_var = next_var_id++;
|
||||
m_stack_slot_var_by_op[op_id] = current_var;
|
||||
auto& info = m_stack_slot_use_def_info[RegId(Register(Reg::GPR, Reg::SP), current_var)];
|
||||
info.defs.push_back({op_id, block_id, AccessMode::WRITE, false});
|
||||
info.ssa_vars.insert(current_var);
|
||||
}
|
||||
}
|
||||
|
||||
if (!live_out.at(block_id)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ASSERT(current_var != -1);
|
||||
for (int succ :
|
||||
{func->basic_blocks.at(block_id).succ_branch, func->basic_blocks.at(block_id).succ_ft}) {
|
||||
if (succ != -1 && live_in.at(succ)) {
|
||||
phi_sources.at(succ).push_back(current_var);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int block_id = 0; block_id < block_count; block_id++) {
|
||||
if (phi_var.at(block_id) == -1) {
|
||||
continue;
|
||||
}
|
||||
int first_op = ops.block_id_to_first_atomic_op.at(block_id);
|
||||
for (int src_var : phi_sources.at(block_id)) {
|
||||
auto& info = m_stack_slot_use_def_info[RegId(Register(Reg::GPR, Reg::SP), src_var)];
|
||||
info.uses.push_back({first_op, block_id, AccessMode::READ, false});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* Set the stack hints. This must be done before type analysis.
|
||||
* This actually parses the types, so it should be done after the dts is set up.
|
||||
|
||||
@@ -44,6 +44,36 @@ struct StackSpillEntry {
|
||||
}
|
||||
};
|
||||
|
||||
constexpr int STACK_SLOT_VAR_STRIDE = 1 << 16;
|
||||
|
||||
inline bool is_stack_slot_access(const RegisterAccess& access) {
|
||||
return access.reg() == Register(Reg::GPR, Reg::SP) && access.idx() < 0;
|
||||
}
|
||||
|
||||
inline int get_stack_slot_offset_from_access(const RegisterAccess& access) {
|
||||
ASSERT(is_stack_slot_access(access));
|
||||
return (-access.idx() - 1) / STACK_SLOT_VAR_STRIDE;
|
||||
}
|
||||
|
||||
inline int get_stack_slot_var_id_from_access(const RegisterAccess& access) {
|
||||
ASSERT(is_stack_slot_access(access));
|
||||
return (-access.idx() - 1) % STACK_SLOT_VAR_STRIDE;
|
||||
}
|
||||
|
||||
inline RegisterAccess make_stack_slot_access(int offset, int var_id = 0) {
|
||||
ASSERT(var_id >= 0);
|
||||
ASSERT(var_id < STACK_SLOT_VAR_STRIDE);
|
||||
return RegisterAccess(AccessMode::READ, Register(Reg::GPR, Reg::SP),
|
||||
-1 - (offset * STACK_SLOT_VAR_STRIDE + var_id), true);
|
||||
}
|
||||
|
||||
inline bool same_expression_var(const RegisterAccess& a, const RegisterAccess& b) {
|
||||
if (is_stack_slot_access(a) || is_stack_slot_access(b)) {
|
||||
return a == b;
|
||||
}
|
||||
return a.reg() == b.reg();
|
||||
}
|
||||
|
||||
struct FunctionVariableDefinitions {
|
||||
std::optional<goos::Object> local_vars;
|
||||
bool had_pp = false;
|
||||
@@ -126,6 +156,7 @@ class Env {
|
||||
void set_local_vars(const VariableNames& names) {
|
||||
m_var_names = names;
|
||||
m_has_local_vars = true;
|
||||
rebuild_stack_slot_use_def_info();
|
||||
}
|
||||
|
||||
void set_end_var(RegisterAccess var) { m_end_var = var; }
|
||||
@@ -193,6 +224,7 @@ class Env {
|
||||
}
|
||||
|
||||
const UseDefInfo& get_use_def_info(const RegisterAccess& ra) const;
|
||||
RegisterAccess get_stack_slot_access_for_op(int op_id, int offset) const;
|
||||
void disable_use(const RegisterAccess& access);
|
||||
|
||||
void disable_def(const RegisterAccess& access, DecompWarnings& warnings);
|
||||
@@ -228,6 +260,8 @@ class Env {
|
||||
bool pp_mapped_by_behavior() const { return m_pp_mapped_by_behavior; }
|
||||
|
||||
private:
|
||||
void rebuild_stack_slot_use_def_info();
|
||||
|
||||
RegisterAccess m_end_var;
|
||||
|
||||
bool m_has_reg_use = false;
|
||||
@@ -235,6 +269,8 @@ class Env {
|
||||
|
||||
bool m_has_local_vars = false;
|
||||
VariableNames m_var_names;
|
||||
std::unordered_map<RegId, UseDefInfo, RegId::hash> m_stack_slot_use_def_info;
|
||||
std::unordered_map<int, int> m_stack_slot_var_by_op;
|
||||
|
||||
bool m_has_types = false;
|
||||
bool m_pp_mapped_by_behavior = false;
|
||||
|
||||
+26
-5
@@ -7,6 +7,7 @@
|
||||
#include "common/type_system/TypeSystem.h"
|
||||
#include "common/util/print_float.h"
|
||||
|
||||
#include "decompiler/IR2/Env.h"
|
||||
#include "decompiler/ObjectFile/LinkedObjectFile.h"
|
||||
#include "decompiler/util/DecompilerTypeSystem.h"
|
||||
#include "decompiler/util/data_decompile.h"
|
||||
@@ -2775,8 +2776,13 @@ void VectorFloatLoadStoreElement::collect_vf_regs(RegSet& regs) const {
|
||||
StackSpillStoreElement::StackSpillStoreElement(SimpleAtom value,
|
||||
int size,
|
||||
int stack_offset,
|
||||
RegisterAccess access,
|
||||
const std::optional<TypeSpec>& cast_type)
|
||||
: m_value(value), m_size(size), m_stack_offset(stack_offset), m_cast_type(cast_type) {}
|
||||
: m_value(value),
|
||||
m_size(size),
|
||||
m_stack_offset(stack_offset),
|
||||
m_access(access),
|
||||
m_cast_type(cast_type) {}
|
||||
|
||||
goos::Object StackSpillStoreElement::to_form_internal(const Env& env) const {
|
||||
return pretty_print::build_list(
|
||||
@@ -2801,11 +2807,24 @@ void StackSpillStoreElement::get_modified_regs(RegSet&) const {}
|
||||
// StackSpillValueElement
|
||||
////////////////////////////////
|
||||
|
||||
StackSpillValueElement::StackSpillValueElement(int size, int stack_offset, bool is_signed)
|
||||
: m_size(size), m_stack_offset(stack_offset), m_is_signed(is_signed) {}
|
||||
StackSpillValueElement::StackSpillValueElement(int size,
|
||||
int stack_offset,
|
||||
RegisterAccess access,
|
||||
bool is_signed,
|
||||
std::optional<TypeSpec> read_type)
|
||||
: m_size(size),
|
||||
m_stack_offset(stack_offset),
|
||||
m_access(access),
|
||||
m_is_signed(is_signed),
|
||||
m_read_type(std::move(read_type)) {}
|
||||
|
||||
goos::Object StackSpillValueElement::to_form_internal(const Env& env) const {
|
||||
return pretty_print::to_symbol(env.get_spill_slot_var_name(m_stack_offset));
|
||||
auto var = m_access;
|
||||
auto base = pretty_print::to_symbol(env.get_spill_slot_var_name(m_stack_offset));
|
||||
if (m_read_type && env.get_variable_type(var, true) != *m_read_type) {
|
||||
return pretty_print::build_list("the-as", m_read_type->print(), base);
|
||||
}
|
||||
return base;
|
||||
}
|
||||
|
||||
void StackSpillValueElement::apply(const std::function<void(FormElement*)>& f) {
|
||||
@@ -2813,7 +2832,9 @@ void StackSpillValueElement::apply(const std::function<void(FormElement*)>& f) {
|
||||
}
|
||||
|
||||
void StackSpillValueElement::apply_form(const std::function<void(Form*)>&) {}
|
||||
void StackSpillValueElement::collect_vars(RegAccessSet&, bool) const {}
|
||||
void StackSpillValueElement::collect_vars(RegAccessSet& vars, bool) const {
|
||||
vars.insert(m_access);
|
||||
}
|
||||
void StackSpillValueElement::get_modified_regs(RegSet&) const {}
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
+13
-1
@@ -1545,6 +1545,7 @@ class StackSpillStoreElement : public FormElement {
|
||||
StackSpillStoreElement(SimpleAtom value,
|
||||
int size,
|
||||
int stack_offset,
|
||||
RegisterAccess access,
|
||||
const std::optional<TypeSpec>& cast_type);
|
||||
goos::Object to_form_internal(const Env& env) const override;
|
||||
void apply(const std::function<void(FormElement*)>& f) override;
|
||||
@@ -1553,18 +1554,27 @@ class StackSpillStoreElement : public FormElement {
|
||||
void get_modified_regs(RegSet& regs) const override;
|
||||
void push_to_stack(const Env& env, FormPool& pool, FormStack& stack) override;
|
||||
const std::optional<TypeSpec>& cast_type() const { return m_cast_type; }
|
||||
const RegisterAccess& access() const { return m_access; }
|
||||
int stack_offset() const { return m_stack_offset; }
|
||||
|
||||
private:
|
||||
SimpleAtom m_value;
|
||||
int m_size = -1;
|
||||
int m_stack_offset = -1;
|
||||
RegisterAccess m_access;
|
||||
std::optional<TypeSpec> m_cast_type;
|
||||
};
|
||||
|
||||
// the value from a stack load.
|
||||
class StackSpillValueElement : public FormElement {
|
||||
public:
|
||||
StackSpillValueElement(int size, int stack_offset, bool is_signed);
|
||||
StackSpillValueElement(int size,
|
||||
int stack_offset,
|
||||
RegisterAccess access,
|
||||
bool is_signed,
|
||||
std::optional<TypeSpec> read_type = std::nullopt);
|
||||
int stack_offset() const { return m_stack_offset; }
|
||||
const RegisterAccess& access() const { return m_access; }
|
||||
goos::Object to_form_internal(const Env& env) const override;
|
||||
void apply(const std::function<void(FormElement*)>& f) override;
|
||||
void apply_form(const std::function<void(Form*)>& f) override;
|
||||
@@ -1579,7 +1589,9 @@ class StackSpillValueElement : public FormElement {
|
||||
private:
|
||||
int m_size = -1;
|
||||
int m_stack_offset = -1;
|
||||
RegisterAccess m_access;
|
||||
bool m_is_signed = false;
|
||||
std::optional<TypeSpec> m_read_type;
|
||||
};
|
||||
|
||||
class MethodOfTypeElement : public FormElement {
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "common/util/BitUtils.h"
|
||||
#include "common/util/print_float.h"
|
||||
|
||||
#include "decompiler/IR2/Env.h"
|
||||
#include "decompiler/IR2/ExpressionHelpers.h"
|
||||
#include "decompiler/IR2/bitfields.h"
|
||||
#include "decompiler/ObjectFile/LinkedObjectFile.h"
|
||||
@@ -65,6 +66,56 @@
|
||||
namespace decompiler {
|
||||
|
||||
namespace {
|
||||
Form* cast_form(Form* in, const TypeSpec& new_type, FormPool& pool, const Env& env, bool tc_pass);
|
||||
|
||||
TypeSpec get_input_type_for_access(const Env& env, const RegisterAccess& access) {
|
||||
if (is_stack_slot_access(access)) {
|
||||
return env.get_variable_type(access, true);
|
||||
}
|
||||
return env.get_types_before_op(access.idx()).get(access.reg()).typespec();
|
||||
}
|
||||
|
||||
Form* cast_stack_slot_var_if_needed(Form* in,
|
||||
const TypeSpec& desired_type,
|
||||
FormPool& pool,
|
||||
const Env& env) {
|
||||
auto atom = form_as_atom(in);
|
||||
if (atom && atom->is_var() && is_stack_slot_access(atom->var()) &&
|
||||
env.get_variable_type(atom->var(), true) != desired_type) {
|
||||
return cast_form(in, desired_type, pool, env, false);
|
||||
}
|
||||
return in;
|
||||
}
|
||||
|
||||
Form* cast_inlined_function_symbol_if_needed(Form* in,
|
||||
const TypeSpec& desired_type,
|
||||
FormPool& pool,
|
||||
const Env& env) {
|
||||
if (!env.has_type_analysis() || desired_type.base_type() != "function") {
|
||||
return in;
|
||||
}
|
||||
|
||||
auto existing_cast = in->try_as_element<CastElement>();
|
||||
if (existing_cast && existing_cast->type() == desired_type) {
|
||||
return in;
|
||||
}
|
||||
|
||||
auto obj = in->to_form(env);
|
||||
if (!obj.is_symbol()) {
|
||||
return in;
|
||||
}
|
||||
|
||||
try {
|
||||
auto symbol_type = env.dts->lookup_symbol_type(obj.as_symbol().name_ptr);
|
||||
if (symbol_type.base_type() == "function" && symbol_type != desired_type) {
|
||||
return pool.form<CastElement>(desired_type, in);
|
||||
}
|
||||
} catch (const std::runtime_error&) {
|
||||
}
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
Form* strip_pcypld_64(Form* in) {
|
||||
auto m = match(Matcher::op(GenericOpMatcher::fixed(FixedOperatorKind::PCPYLD),
|
||||
{Matcher::integer(0), Matcher::any(0)}),
|
||||
@@ -347,6 +398,9 @@ Form* repop_passthrough_arg(Form* in,
|
||||
|
||||
auto as_atom = form_as_atom(in);
|
||||
if (as_atom && as_atom->is_var()) {
|
||||
if (is_stack_slot_access(as_atom->var())) {
|
||||
return in;
|
||||
}
|
||||
return stack.pop_reg(as_atom->var().reg(), {}, env, true, -1, orig_out, found_orig_out);
|
||||
}
|
||||
return in;
|
||||
@@ -377,18 +431,37 @@ void pop_helper(const std::vector<RegisterAccess>& vars,
|
||||
const std::optional<RegSet>& consumes = std::nullopt,
|
||||
const std::vector<int>& times_used = {}) {
|
||||
// to submit to stack to attempt popping
|
||||
std::vector<Register> submit_regs;
|
||||
// submit_reg[i] is for var submit_reg_to_var[i]
|
||||
std::vector<size_t> submit_reg_to_var;
|
||||
std::vector<RegisterAccess> submit_vars;
|
||||
// submit_vars[i] is for var submit_var_to_var[i]
|
||||
std::vector<size_t> submit_var_to_var;
|
||||
|
||||
// build submission for stack
|
||||
std::unordered_map<Register, int, Register::hash> reg_counts;
|
||||
std::unordered_map<std::string, int> stack_var_counts;
|
||||
for (auto& v : vars) {
|
||||
reg_counts[v.reg()]++;
|
||||
if (is_stack_slot_access(v)) {
|
||||
stack_var_counts[env.get_variable_name_name_only(v)]++;
|
||||
} else {
|
||||
reg_counts[v.reg()]++;
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t var_idx = 0; var_idx < vars.size(); var_idx++) {
|
||||
const auto& var = vars.at(var_idx);
|
||||
if (is_stack_slot_access(var)) {
|
||||
int times = 1;
|
||||
if (!times_used.empty()) {
|
||||
times = times_used.at(var_idx);
|
||||
}
|
||||
|
||||
auto& use_def = env.get_use_def_info(var);
|
||||
if (stack_var_counts.at(env.get_variable_name_name_only(var)) == 1 &&
|
||||
use_def.use_count() == times && use_def.def_count() == 1) {
|
||||
submit_var_to_var.push_back(var_idx);
|
||||
submit_vars.push_back(var);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
auto& ri = env.reg_use().op.at(var.idx());
|
||||
RegSet consumes_to_use = consumes.value_or(ri.consumes);
|
||||
if (consumes_to_use.find(var.reg()) != consumes_to_use.end()) {
|
||||
@@ -402,8 +475,8 @@ void pop_helper(const std::vector<RegisterAccess>& vars,
|
||||
|
||||
auto& use_def = env.get_use_def_info(var);
|
||||
if (use_def.use_count() == times && use_def.def_count() == 1) {
|
||||
submit_reg_to_var.push_back(var_idx);
|
||||
submit_regs.push_back(var.reg());
|
||||
submit_var_to_var.push_back(var_idx);
|
||||
submit_vars.push_back(var);
|
||||
} else {
|
||||
// auto var_id = env.get_program_var_id(var);
|
||||
// lg::print(
|
||||
@@ -429,9 +502,9 @@ void pop_helper(const std::vector<RegisterAccess>& vars,
|
||||
// submit and get a result! If the stack has nothing to pop, the result here may be nullptr.
|
||||
std::vector<Form*> pop_result;
|
||||
// loop in reverse (later vals first)
|
||||
for (size_t i = submit_regs.size(); i-- > 0;) {
|
||||
for (size_t i = submit_vars.size(); i-- > 0;) {
|
||||
// figure out what var we are:
|
||||
auto var_idx = submit_reg_to_var.at(i);
|
||||
auto var_idx = submit_var_to_var.at(i);
|
||||
|
||||
// anything _less_ than this should be unmodified by the pop
|
||||
// it's fine to modify yourself in your pop.
|
||||
@@ -442,7 +515,7 @@ void pop_helper(const std::vector<RegisterAccess>& vars,
|
||||
|
||||
// do the pop, with the barrier to prevent out-of-sequence popping.
|
||||
pop_result.push_back(
|
||||
stack.pop_reg(submit_regs.at(i), pop_barrier_regs, env, allow_side_effects));
|
||||
stack.pop_reg(submit_vars.at(i), pop_barrier_regs, env, allow_side_effects));
|
||||
}
|
||||
// now flip back to the source order for making the final result
|
||||
std::reverse(pop_result.begin(), pop_result.end());
|
||||
@@ -452,9 +525,9 @@ void pop_helper(const std::vector<RegisterAccess>& vars,
|
||||
forms.resize(vars.size(), nullptr);
|
||||
if (!pop_result.empty()) {
|
||||
// success!
|
||||
for (size_t i = 0; i < submit_regs.size(); i++) {
|
||||
for (size_t i = 0; i < submit_vars.size(); i++) {
|
||||
// fill out vars from our submission
|
||||
forms.at(submit_reg_to_var.at(i)) = pop_result.at(i);
|
||||
forms.at(submit_var_to_var.at(i)) = pop_result.at(i);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -555,6 +628,14 @@ std::vector<Form*> pop_to_forms(const std::vector<RegisterAccess>& vars,
|
||||
for (size_t i = 0; i < vars.size(); i++) {
|
||||
auto atom = form_as_atom(forms[i]);
|
||||
bool is_var = atom && atom->is_var();
|
||||
if (is_var && is_stack_slot_access(atom->var())) {
|
||||
auto access_type = get_input_type_for_access(env, vars[i]);
|
||||
if (env.get_variable_type(atom->var(), true) != access_type) {
|
||||
forms[i] = cast_form(forms[i], access_type, pool, env);
|
||||
atom = form_as_atom(forms[i]);
|
||||
is_var = atom && atom->is_var();
|
||||
}
|
||||
}
|
||||
auto cast = env.get_user_cast_for_access(vars[i]);
|
||||
// only cast if we didn't get a var (compacting expressions).
|
||||
// there is a separate system for casting variables that will do a better job.
|
||||
@@ -1008,6 +1089,26 @@ void SimpleExpressionElement::update_from_stack_float_2_nestable(const Env& env,
|
||||
bool allow_side_effects) {
|
||||
if (is_float_type(env, m_my_idx, m_expr.get_arg(0).var()) &&
|
||||
is_float_type(env, m_my_idx, m_expr.get_arg(1).var())) {
|
||||
if (m_expr.get_arg(0).var() == m_expr.get_arg(1).var()) {
|
||||
auto arg =
|
||||
pop_to_forms({m_expr.get_arg(0).var()}, env, pool, stack, allow_side_effects, {}, {2})
|
||||
.at(0);
|
||||
if (kind == FixedOperatorKind::MULTIPLICATION) {
|
||||
result->push_back(pool.alloc_element<GenericElement>(
|
||||
GenericOperator::make_function(pool.form<ConstantTokenElement>("square")), arg));
|
||||
return;
|
||||
}
|
||||
|
||||
auto atom = form_as_atom(arg);
|
||||
if (atom) {
|
||||
auto arg_copy = pool.form<SimpleAtomElement>(*atom);
|
||||
auto new_form =
|
||||
make_and_compact_math_op(arg, arg_copy, {}, {}, pool, env, kind, true, false);
|
||||
result->push_back(new_form);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
auto args = pop_to_forms({m_expr.get_arg(0).var(), m_expr.get_arg(1).var()}, env, pool, stack,
|
||||
allow_side_effects);
|
||||
auto new_form =
|
||||
@@ -1146,7 +1247,9 @@ void SimpleExpressionElement::update_from_stack_add_i(const Env& env,
|
||||
}
|
||||
}
|
||||
ASSERT(used_index);
|
||||
result->push_back(pool.alloc_element<DerefElement>(args.at(1), out.addr_of, tokens));
|
||||
result->push_back(pool.alloc_element<DerefElement>(
|
||||
cast_stack_slot_var_if_needed(args.at(1), arg1_type.typespec(), pool, env),
|
||||
out.addr_of, tokens));
|
||||
return;
|
||||
} else {
|
||||
throw std::runtime_error(
|
||||
@@ -1186,7 +1289,9 @@ void SimpleExpressionElement::update_from_stack_add_i(const Env& env,
|
||||
}
|
||||
}
|
||||
ASSERT(used_index);
|
||||
result->push_back(pool.alloc_element<DerefElement>(args.at(1), out.addr_of, tokens));
|
||||
result->push_back(pool.alloc_element<DerefElement>(
|
||||
cast_stack_slot_var_if_needed(args.at(1), arg1_type.typespec(), pool, env),
|
||||
out.addr_of, tokens));
|
||||
return;
|
||||
} else {
|
||||
throw std::runtime_error(
|
||||
@@ -1215,7 +1320,9 @@ void SimpleExpressionElement::update_from_stack_add_i(const Env& env,
|
||||
}
|
||||
}
|
||||
ASSERT(used_index);
|
||||
result->push_back(pool.alloc_element<DerefElement>(args.at(1), out.addr_of, tokens));
|
||||
result->push_back(pool.alloc_element<DerefElement>(
|
||||
cast_stack_slot_var_if_needed(args.at(1), arg1_type.typespec(), pool, env),
|
||||
out.addr_of, tokens));
|
||||
return;
|
||||
} else {
|
||||
throw std::runtime_error(
|
||||
@@ -1267,7 +1374,9 @@ void SimpleExpressionElement::update_from_stack_add_i(const Env& env,
|
||||
}
|
||||
}
|
||||
ASSERT(used_index);
|
||||
result->push_back(pool.alloc_element<DerefElement>(args.at(0), rd_ok.addr_of, tokens));
|
||||
result->push_back(pool.alloc_element<DerefElement>(
|
||||
cast_stack_slot_var_if_needed(args.at(0), arg0_type.typespec(), pool, env),
|
||||
rd_ok.addr_of, tokens));
|
||||
return;
|
||||
} else {
|
||||
throw std::runtime_error(fmt::format(
|
||||
@@ -1318,7 +1427,9 @@ void SimpleExpressionElement::update_from_stack_add_i(const Env& env,
|
||||
}
|
||||
}
|
||||
ASSERT(used_index);
|
||||
result->push_back(pool.alloc_element<DerefElement>(args.at(1), rd_ok.addr_of, tokens));
|
||||
result->push_back(pool.alloc_element<DerefElement>(
|
||||
cast_stack_slot_var_if_needed(args.at(1), arg1_type.typespec(), pool, env),
|
||||
rd_ok.addr_of, tokens));
|
||||
return;
|
||||
} else {
|
||||
// TODO - output error to IR
|
||||
@@ -1341,7 +1452,9 @@ void SimpleExpressionElement::update_from_stack_add_i(const Env& env,
|
||||
tokens.push_back(to_token(tok));
|
||||
}
|
||||
|
||||
result->push_back(pool.alloc_element<DerefElement>(args.at(1), out.addr_of, tokens));
|
||||
result->push_back(pool.alloc_element<DerefElement>(
|
||||
cast_stack_slot_var_if_needed(args.at(1), arg1_type.typespec(), pool, env), out.addr_of,
|
||||
tokens));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -2357,7 +2470,7 @@ void SimpleExpressionElement::update_from_stack_int_to_float(const Env& env,
|
||||
// the gpr->fpr operation beacuse it doesn't matter.
|
||||
auto fpr_convert_matcher =
|
||||
Matcher::op(GenericOpMatcher::fixed(FixedOperatorKind::GPR_TO_FPR), {Matcher::any(0)});
|
||||
auto type = env.get_types_before_op(var.idx()).get(var.reg()).typespec();
|
||||
auto type = get_input_type_for_access(env, var);
|
||||
// want to allow any child of integer so integer enums can also be converted to floats.
|
||||
if (env.dts->ts.tc(TypeSpec("integer"), type) || type == TypeSpec("seconds")) {
|
||||
auto mr = match(fpr_convert_matcher, arg);
|
||||
@@ -2379,7 +2492,7 @@ void SimpleExpressionElement::update_from_stack_float_to_int(const Env& env,
|
||||
bool allow_side_effects) {
|
||||
auto var = m_expr.get_arg(0).var();
|
||||
auto arg = pop_to_forms({var}, env, pool, stack, allow_side_effects).at(0);
|
||||
auto type = env.get_types_before_op(var.idx()).get(var.reg()).typespec();
|
||||
auto type = get_input_type_for_access(env, var);
|
||||
auto fpr_convert_matcher =
|
||||
Matcher::op(GenericOpMatcher::fixed(FixedOperatorKind::GPR_TO_FPR), {Matcher::any(0)});
|
||||
auto mr = match(fpr_convert_matcher, arg);
|
||||
@@ -2412,7 +2525,7 @@ void SimpleExpressionElement::update_from_stack_subu_l32_s7(const Env& env,
|
||||
bool allow_side_effects) {
|
||||
auto var = m_expr.get_arg(0).var();
|
||||
auto arg = pop_to_forms({var}, env, pool, stack, allow_side_effects).at(0);
|
||||
auto type = env.get_types_before_op(var.idx()).get(var.reg()).typespec();
|
||||
auto type = get_input_type_for_access(env, var);
|
||||
if (type != TypeSpec("handle")) {
|
||||
env.func->warnings.warning(
|
||||
".subu (32-bit) used on a {} at idx {}. This probably should be a handle.", type.print(),
|
||||
@@ -2623,6 +2736,12 @@ void SetVarElement::push_to_stack(const Env& env, FormPool& pool, FormStack& sta
|
||||
// if we are a reg-reg move that consumes the original, push it without popping from stack.
|
||||
// it is the Stack's responsibility to untangle these later on.
|
||||
if (m_src->is_single_element()) {
|
||||
auto spill_value = dynamic_cast<StackSpillValueElement*>(m_src->back());
|
||||
if (spill_value) {
|
||||
stack.push_non_seq_reg_to_reg(m_dst, spill_value->access(), m_src, m_src_type, m_var_info);
|
||||
return;
|
||||
}
|
||||
|
||||
auto src_as_se = dynamic_cast<SimpleExpressionElement*>(m_src->back());
|
||||
if (src_as_se) {
|
||||
if (src_as_se->expr().kind() == SimpleExpression::Kind::IDENTITY &&
|
||||
@@ -2634,9 +2753,15 @@ void SetVarElement::push_to_stack(const Env& env, FormPool& pool, FormStack& sta
|
||||
}
|
||||
|
||||
auto var = src_as_se->expr().get_arg(0).var();
|
||||
auto& info = env.reg_use().op.at(var.idx());
|
||||
if (var.reg() == Register(Reg::GPR, Reg::S6) ||
|
||||
info.consumes.find(var.reg()) != info.consumes.end()) {
|
||||
bool is_consumed_reg_move = false;
|
||||
if (is_stack_slot_access(var)) {
|
||||
auto& use_def = env.get_use_def_info(var);
|
||||
is_consumed_reg_move = use_def.use_count() == 1 && use_def.def_count() == 1;
|
||||
} else {
|
||||
auto& info = env.reg_use().op.at(var.idx());
|
||||
is_consumed_reg_move = info.consumes.find(var.reg()) != info.consumes.end();
|
||||
}
|
||||
if (var.reg() == Register(Reg::GPR, Reg::S6) || is_consumed_reg_move) {
|
||||
stack.push_non_seq_reg_to_reg(m_dst, src_as_se->expr().get_arg(0).var(), m_src,
|
||||
m_src_type, m_var_info);
|
||||
return;
|
||||
@@ -3495,8 +3620,14 @@ void FunctionCallElement::update_from_stack(const Env& env,
|
||||
}
|
||||
|
||||
TypeSpec function_type;
|
||||
auto& in_type_state = env.get_types_before_op(all_pop_vars.at(0).idx());
|
||||
auto& tp_type = in_type_state.get(all_pop_vars.at(0).reg());
|
||||
const TypeState* in_type_state = nullptr;
|
||||
TP_Type tp_type;
|
||||
if (!is_stack_slot_access(all_pop_vars.at(0))) {
|
||||
in_type_state = &env.get_types_before_op(all_pop_vars.at(0).idx());
|
||||
tp_type = in_type_state->get(all_pop_vars.at(0).reg());
|
||||
} else {
|
||||
tp_type = env.get_variable_tp_type(all_pop_vars.at(0), true);
|
||||
}
|
||||
if (env.has_type_analysis()) {
|
||||
function_type = tp_type.typespec();
|
||||
}
|
||||
@@ -3504,7 +3635,8 @@ void FunctionCallElement::update_from_stack(const Env& env,
|
||||
// if we're actually a go:
|
||||
Form* go_next_state = nullptr;
|
||||
if (tp_type.kind == TP_Type::Kind::ENTER_STATE_FUNCTION) {
|
||||
auto& next_state_type = in_type_state.next_state_type;
|
||||
ASSERT(in_type_state);
|
||||
auto& next_state_type = in_type_state->next_state_type;
|
||||
if (next_state_type.typespec().base_type() != "state") {
|
||||
throw std::runtime_error("Bad state type in expressions (not state): " +
|
||||
next_state_type.print());
|
||||
@@ -3591,7 +3723,7 @@ void FunctionCallElement::update_from_stack(const Env& env,
|
||||
auto val = unstacked.at(arg_id + 1); // first is the function itself.
|
||||
auto& var = all_pop_vars.at(arg_id + 1);
|
||||
if (has_good_types) {
|
||||
auto actual_arg_type = env.get_types_before_op(var.idx()).get(var.reg()).typespec();
|
||||
auto actual_arg_type = get_input_type_for_access(env, var);
|
||||
|
||||
if (arg_id == 0) {
|
||||
first_arg_type = actual_arg_type;
|
||||
@@ -3965,7 +4097,9 @@ void FunctionCallElement::update_from_stack(const Env& env,
|
||||
}
|
||||
}
|
||||
|
||||
new_form = pool.alloc_element<GenericElement>(GenericOperator::make_function(unstacked.at(0)),
|
||||
auto called_function =
|
||||
cast_inlined_function_symbol_if_needed(unstacked.at(0), function_type, pool, env);
|
||||
new_form = pool.alloc_element<GenericElement>(GenericOperator::make_function(called_function),
|
||||
arg_forms);
|
||||
|
||||
{
|
||||
@@ -3997,7 +4131,7 @@ void FunctionCallElement::update_from_stack(const Env& env,
|
||||
ASSERT(new_args.size() >= 3);
|
||||
for (size_t i = 0; i < 3; i++) {
|
||||
auto& var = all_pop_vars.at(i + 1); // 0 is the function itself.
|
||||
auto arg_type = env.get_types_before_op(var.idx()).get(var.reg()).typespec();
|
||||
auto arg_type = get_input_type_for_access(env, var);
|
||||
if (!env.dts->ts.tc(expected_arg_types.at(i), arg_type)) {
|
||||
new_args.at(i) = pool.form<CastElement>(expected_arg_types.at(i), new_args.at(i));
|
||||
}
|
||||
@@ -4027,7 +4161,7 @@ void FunctionCallElement::update_from_stack(const Env& env,
|
||||
if (match_result.matched) {
|
||||
auto& alloc = match_result.maps.strings.at(allocation);
|
||||
if (alloc != "global" && alloc != "debug" && alloc != "process" &&
|
||||
alloc != "loading-level") {
|
||||
alloc != "loading-level" && alloc != "process-level-heap") {
|
||||
throw std::runtime_error("Unrecognized heap symbol for new: " + alloc);
|
||||
}
|
||||
auto type_2 = match_result.maps.strings.at(type_for_arg);
|
||||
@@ -5031,9 +5165,11 @@ void CondWithElseElement::push_to_stack(const Env& env, FormPool& pool, FormStac
|
||||
// determine if set destination is used
|
||||
bool set_unused = false;
|
||||
if (rewrite_as_set) {
|
||||
auto& info = env.reg_use().op.at(last_var->idx());
|
||||
if (info.written_and_unused.find(last_var->reg()) != info.written_and_unused.end()) {
|
||||
set_unused = true;
|
||||
if (!is_stack_slot_access(*last_var)) {
|
||||
auto& info = env.reg_use().op.at(last_var->idx());
|
||||
if (info.written_and_unused.find(last_var->reg()) != info.written_and_unused.end()) {
|
||||
set_unused = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6019,7 +6155,7 @@ void ConditionElement::push_to_stack(const Env& env, FormPool& pool, FormStack&
|
||||
if (m_src[i]->is_var()) {
|
||||
auto& var = m_src[i]->var();
|
||||
vars.push_back(var);
|
||||
source_types.push_back(env.get_types_before_op(var.idx()).get(var.reg()).typespec());
|
||||
source_types.push_back(get_input_type_for_access(env, var));
|
||||
} else if (m_src[i]->is_int()) {
|
||||
if (m_src[i]->get_int() == 0 && condition_uses_float(m_kind)) {
|
||||
// if we're doing a floating point comparison, and one of our arguments is a constant
|
||||
@@ -6072,7 +6208,7 @@ void ConditionElement::update_from_stack(const Env& env,
|
||||
if (m_src[i]->is_var()) {
|
||||
auto& var = m_src[i]->var();
|
||||
vars.push_back(var);
|
||||
source_types.push_back(env.get_types_before_op(var.idx()).get(var.reg()).typespec());
|
||||
source_types.push_back(get_input_type_for_access(env, var));
|
||||
} else if (m_src[i]->is_int()) {
|
||||
if (m_src[i]->get_int() == 0 && condition_uses_float(m_kind)) {
|
||||
// if we're doing a floating point comparison, and one of our arguments is a constant
|
||||
@@ -6915,11 +7051,53 @@ void StackSpillStoreElement::push_to_stack(const Env& env, FormPool& pool, FormS
|
||||
src = pool.form<SimpleAtomElement>(m_value);
|
||||
}
|
||||
|
||||
auto dst = pool.form<ConstantTokenElement>(env.get_spill_slot_var_name(m_stack_offset));
|
||||
if (m_cast_type) {
|
||||
src = cast_form(src, *m_cast_type, pool, env);
|
||||
}
|
||||
stack.push_form_element(pool.alloc_element<SetFormFormElement>(dst, src), true);
|
||||
|
||||
TypeSpec stack_type("object");
|
||||
auto it = env.stack_slot_entries.find(m_stack_offset);
|
||||
if (it != env.stack_slot_entries.end()) {
|
||||
stack_type = it->second.typespec;
|
||||
} else if (m_cast_type) {
|
||||
stack_type = *m_cast_type;
|
||||
}
|
||||
|
||||
auto src_as_generic = src->try_as_element<GenericElement>();
|
||||
if (src_as_generic && !src_as_generic->op().is_func()) {
|
||||
using InplaceOpInfo = std::pair<FixedOperatorKind, FixedOperatorKind>;
|
||||
const static std::array<InplaceOpInfo, 6> in_place_ops = {
|
||||
InplaceOpInfo{FixedOperatorKind::ADDITION, FixedOperatorKind::ADDITION_IN_PLACE},
|
||||
InplaceOpInfo{FixedOperatorKind::ADDITION_PTR, FixedOperatorKind::ADDITION_PTR_IN_PLACE},
|
||||
InplaceOpInfo{FixedOperatorKind::LOGAND, FixedOperatorKind::LOGAND_IN_PLACE},
|
||||
InplaceOpInfo{FixedOperatorKind::LOGIOR, FixedOperatorKind::LOGIOR_IN_PLACE},
|
||||
InplaceOpInfo{FixedOperatorKind::LOGCLEAR, FixedOperatorKind::LOGCLEAR_IN_PLACE},
|
||||
InplaceOpInfo{FixedOperatorKind::LOGXOR, FixedOperatorKind::LOGXOR_IN_PLACE},
|
||||
};
|
||||
|
||||
auto dst_var = m_access;
|
||||
auto dst_form = pool.form<SimpleAtomElement>(SimpleAtom::make_var(dst_var))->to_form(env);
|
||||
for (const auto& [kind, inplace_kind] : in_place_ops) {
|
||||
if (!src_as_generic->op().is_fixed(kind)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int inplace_arg : {0, 1}) {
|
||||
if (src_as_generic->elts().at(inplace_arg)->to_form(env) != dst_form) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (inplace_arg != 0) {
|
||||
std::swap(src_as_generic->elts().at(0), src_as_generic->elts().at(1));
|
||||
}
|
||||
src_as_generic->op() = GenericOperator::make_fixed(inplace_kind);
|
||||
stack.push_form_element(src_as_generic, true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stack.push_value_to_reg(m_access, src, true, stack_type);
|
||||
}
|
||||
|
||||
namespace {
|
||||
@@ -7173,13 +7351,21 @@ void StackStructureDefElement::update_from_stack(const Env&,
|
||||
result->push_back(this);
|
||||
}
|
||||
|
||||
void StackSpillValueElement::update_from_stack(const Env&,
|
||||
FormPool&,
|
||||
void StackSpillValueElement::update_from_stack(const Env& env,
|
||||
FormPool& pool,
|
||||
FormStack&,
|
||||
std::vector<FormElement*>* result,
|
||||
bool) {
|
||||
mark_popped();
|
||||
result->push_back(this);
|
||||
auto var = m_access;
|
||||
Form* form =
|
||||
pool.alloc_single_element_form<SimpleAtomElement>(nullptr, SimpleAtom::make_var(var));
|
||||
if (m_read_type && env.get_variable_type(var, true) != *m_read_type) {
|
||||
form = cast_form(form, *m_read_type, pool, env);
|
||||
}
|
||||
for (auto elt : form->elts()) {
|
||||
result->push_back(elt);
|
||||
}
|
||||
}
|
||||
|
||||
void GetSymbolStringPointer::update_from_stack(const Env&,
|
||||
|
||||
@@ -9,6 +9,26 @@
|
||||
#include "decompiler/util/DecompilerTypeSystem.h"
|
||||
|
||||
namespace decompiler {
|
||||
namespace {
|
||||
bool nonempty_intersection(const RegSet& a, const RegSet& b) {
|
||||
for (auto x : a) {
|
||||
if (b.find(x) != b.end()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool can_inline_non_seq_source(const RegisterAccess& src, const Env& env) {
|
||||
if (!is_stack_slot_access(src)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const auto& use_def = env.get_use_def_info(src);
|
||||
return use_def.use_count() == 1 && use_def.def_count() == 1;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
std::string FormStack::StackEntry::print(const Env& env) const {
|
||||
if (destination.has_value()) {
|
||||
ASSERT(source && !elt);
|
||||
@@ -116,19 +136,61 @@ Form* FormStack::pop_reg(const RegisterAccess& var,
|
||||
const Env& env,
|
||||
bool allow_side_effects,
|
||||
int begin_idx) {
|
||||
return pop_reg(var.reg(), barrier, env, allow_side_effects, begin_idx);
|
||||
}
|
||||
RegSet modified;
|
||||
size_t begin = m_stack.size();
|
||||
if (begin_idx >= 0) {
|
||||
begin = begin_idx;
|
||||
}
|
||||
for (size_t i = begin; i-- > 0;) {
|
||||
auto& entry = m_stack.at(i);
|
||||
if (entry.active) {
|
||||
if (entry.destination.has_value() && same_expression_var(*entry.destination, var)) {
|
||||
entry.source->get_modified_regs(modified);
|
||||
if (!allow_side_effects && entry.source->has_side_effects()) {
|
||||
return nullptr;
|
||||
}
|
||||
if (nonempty_intersection(modified, barrier)) {
|
||||
return nullptr;
|
||||
}
|
||||
entry.active = false;
|
||||
ASSERT(entry.source);
|
||||
if (entry.non_seq_source.has_value()) {
|
||||
ASSERT(entry.sequence_point == false);
|
||||
if (can_inline_non_seq_source(*entry.non_seq_source, env)) {
|
||||
auto result = pop_reg(*entry.non_seq_source, barrier, env, allow_side_effects, i);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
bool nonempty_intersection(const RegSet& a, const RegSet& b) {
|
||||
for (auto x : a) {
|
||||
if (b.find(x) != b.end()) {
|
||||
return true;
|
||||
return entry.source;
|
||||
} else {
|
||||
if (entry.sequence_point) {
|
||||
return nullptr;
|
||||
}
|
||||
if (entry.source) {
|
||||
ASSERT(!entry.elt);
|
||||
entry.source->get_modified_regs(modified);
|
||||
if (!allow_side_effects) {
|
||||
return nullptr;
|
||||
}
|
||||
} else {
|
||||
ASSERT(entry.elt);
|
||||
entry.elt->get_modified_regs(modified);
|
||||
if (!allow_side_effects && entry.elt->has_side_effects()) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (entry.destination.has_value() && same_expression_var(*entry.destination, var)) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
Form* FormStack::pop_reg(Register reg,
|
||||
const RegSet& barrier,
|
||||
@@ -164,13 +226,15 @@ Form* FormStack::pop_reg(Register reg,
|
||||
ASSERT(entry.source);
|
||||
if (entry.non_seq_source.has_value()) {
|
||||
ASSERT(entry.sequence_point == false);
|
||||
auto result = pop_reg(entry.non_seq_source->reg(), barrier, env, allow_side_effects, i);
|
||||
if (result) {
|
||||
if (found_orig_out) {
|
||||
*found_orig_out = true;
|
||||
*orig_out = *entry.destination;
|
||||
if (can_inline_non_seq_source(*entry.non_seq_source, env)) {
|
||||
auto result = pop_reg(entry.non_seq_source->reg(), barrier, env, allow_side_effects, i);
|
||||
if (result) {
|
||||
if (found_orig_out) {
|
||||
*found_orig_out = true;
|
||||
*orig_out = *entry.destination;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -325,7 +389,7 @@ std::vector<FormElement*> FormStack::rewrite(FormPool& pool, const Env& env) con
|
||||
while (keep_going && !result.empty()) {
|
||||
keep_going = false;
|
||||
auto last_op_as_set = dynamic_cast<SetVarElement*>(result.back());
|
||||
if (last_op_as_set && last_op_as_set->dst().reg() == var_to_get.reg()) {
|
||||
if (last_op_as_set && same_expression_var(last_op_as_set->dst(), var_to_get)) {
|
||||
result.pop_back();
|
||||
auto as_one = dynamic_cast<SimpleExpressionElement*>(
|
||||
last_op_as_set->src()->try_as_single_element());
|
||||
@@ -384,7 +448,7 @@ std::optional<RegisterAccess> rewrite_to_get_var(std::vector<FormElement*>& defa
|
||||
while (keep_going && !default_result.empty()) {
|
||||
keep_going = false;
|
||||
auto last_op_as_set = dynamic_cast<SetVarElement*>(default_result.back());
|
||||
if (last_op_as_set && last_op_as_set->dst().reg() == var_to_get.reg() &&
|
||||
if (last_op_as_set && same_expression_var(last_op_as_set->dst(), var_to_get) &&
|
||||
(first || last_op_as_set->info().is_compactable)) {
|
||||
default_result.pop_back();
|
||||
auto as_one =
|
||||
|
||||
@@ -305,6 +305,13 @@ bool Matcher::do_match(Form* input, MatchResult::Maps* maps_out, const Env* cons
|
||||
}
|
||||
}
|
||||
|
||||
auto as_stack_spill =
|
||||
dynamic_cast<StackSpillValueElement*>(input->try_as_single_active_element());
|
||||
if (as_stack_spill) {
|
||||
got = true;
|
||||
result = as_stack_spill->access();
|
||||
}
|
||||
|
||||
if (got) {
|
||||
if (m_kind == Kind::REG) {
|
||||
return result.reg() == *m_reg;
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
#include "fmt/format.h"
|
||||
#include "third-party/json.hpp"
|
||||
#include "third-party/zstd/lib/common/xxhash.h"
|
||||
|
||||
namespace decompiler {
|
||||
/*!
|
||||
@@ -710,6 +711,21 @@ std::string LinkedObjectFile::print_asm_function_disassembly(const std::string&
|
||||
return result;
|
||||
}
|
||||
|
||||
// Currently, just hashes the contents of every function, this makes it easy to
|
||||
// compare between games to see if something is identical
|
||||
void LinkedObjectFile::dump_asm_function_metadata(
|
||||
std::unordered_map<std::string, std::string>& map) {
|
||||
ASSERT(segments <= 3);
|
||||
for (int seg = segments; seg-- > 0;) {
|
||||
// functions
|
||||
for (auto& func : functions_by_seg.at(seg)) {
|
||||
const auto& function_rep = print_function_disassembly(func, seg, false, "");
|
||||
const auto func_hash = XXH64(function_rep.data(), function_rep.size(), 0);
|
||||
map.emplace(func.name(), fmt::format("{}", func_hash));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* Print disassembled functions and data segments.
|
||||
*/
|
||||
|
||||
@@ -67,6 +67,7 @@ class LinkedObjectFile {
|
||||
bool write_hex,
|
||||
const std::string& extra_name);
|
||||
std::string print_asm_function_disassembly(const std::string& my_name);
|
||||
void dump_asm_function_metadata(std::unordered_map<std::string, std::string>& map);
|
||||
|
||||
u32 read_data_word(const DecompilerLabel& label);
|
||||
const DecompilerLabel& get_label_by_name(const std::string& name) const;
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <cstring>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "LinkedObjectFileCreation.h"
|
||||
|
||||
@@ -34,6 +35,7 @@
|
||||
#include "decompiler/data/game_text.h"
|
||||
#include "decompiler/data/tpage.h"
|
||||
|
||||
#include "third-party/json.hpp"
|
||||
#include "third-party/xdelta3/xdelta3.h"
|
||||
|
||||
namespace decompiler {
|
||||
@@ -630,18 +632,28 @@ void ObjectFileDB::write_object_file_words(const fs::path& output_dir,
|
||||
void ObjectFileDB::write_disassembly(const fs::path& output_dir,
|
||||
bool disassemble_data,
|
||||
bool disassemble_code,
|
||||
bool print_hex) {
|
||||
bool print_hex,
|
||||
bool dump_function_metadata) {
|
||||
lg::info("- Writing functions...");
|
||||
Timer timer;
|
||||
uint32_t total_bytes = 0, total_files = 0;
|
||||
|
||||
std::string asm_functions;
|
||||
std::unordered_map<std::string, std::unordered_map<std::string, std::string>>
|
||||
file_func_metadata_map = {};
|
||||
|
||||
for_each_obj([&](ObjectFileData& obj) {
|
||||
if (((obj.obj_version == 3 || (obj.obj_version == 5 && obj.linked_data.has_any_functions())) &&
|
||||
disassemble_code) ||
|
||||
(obj.obj_version != 3 && disassemble_data)) {
|
||||
auto file_text = obj.linked_data.print_disassembly(print_hex);
|
||||
if (dump_function_metadata) {
|
||||
if (!file_func_metadata_map.contains(obj.to_unique_name())) {
|
||||
file_func_metadata_map[obj.to_unique_name()] =
|
||||
std::unordered_map<std::string, std::string>{};
|
||||
}
|
||||
obj.linked_data.dump_asm_function_metadata(file_func_metadata_map[obj.to_unique_name()]);
|
||||
}
|
||||
asm_functions += obj.linked_data.print_asm_function_disassembly(obj.to_unique_name());
|
||||
auto file_name = output_dir / (obj.to_unique_name() + ".asm");
|
||||
|
||||
@@ -655,6 +667,11 @@ void ObjectFileDB::write_disassembly(const fs::path& output_dir,
|
||||
total_files++;
|
||||
file_util::write_text_file(output_dir / "asm_functions.func", asm_functions);
|
||||
|
||||
if (dump_function_metadata) {
|
||||
json data = file_func_metadata_map;
|
||||
file_util::write_text_file(output_dir / "_func_metadata.json", data.dump(2));
|
||||
}
|
||||
|
||||
lg::info("Wrote functions dumps:");
|
||||
lg::info(" Total {} files", total_files);
|
||||
lg::info(" Total {} MB", total_bytes / ((float)(1u << 20u)));
|
||||
@@ -751,6 +768,7 @@ std::string ObjectFileDB::process_tpages(TextureDB& tex_db,
|
||||
animated_slots = jak3_animated_texture_slots();
|
||||
break;
|
||||
case GameVersion::JakX:
|
||||
// TODO jakx - Implement animation
|
||||
break;
|
||||
default:
|
||||
ASSERT_NOT_REACHED();
|
||||
@@ -1109,6 +1127,7 @@ void ObjectFileDB::dump_art_info(const fs::path& output_dir) {
|
||||
ag_result += "\n";
|
||||
}
|
||||
|
||||
file_util::create_dir_if_needed_for_file(ag_fpath);
|
||||
file_util::write_text_file(ag_fpath, ag_result);
|
||||
|
||||
auto jg_fpath = output_dir / "import" / "joint-nodes.gc";
|
||||
|
||||
@@ -196,7 +196,8 @@ class ObjectFileDB {
|
||||
void write_disassembly(const fs::path& output_dir,
|
||||
bool disassemble_data,
|
||||
bool disassemble_code,
|
||||
bool print_hex);
|
||||
bool print_hex,
|
||||
bool dump_function_metadata);
|
||||
|
||||
void process_object_file_data(
|
||||
ObjectFileData& data,
|
||||
|
||||
@@ -315,6 +315,10 @@ FieldPrint get_field_print(const std::string& str) {
|
||||
if (c1 == '1' || c1 == '2') {
|
||||
c1 = next();
|
||||
}
|
||||
if (c1 != 'T' && c1 == 'd') {
|
||||
printf("HACK: skipping %s\n", str.data());
|
||||
return handle_custom_prints(field_print, str);
|
||||
}
|
||||
ASSERT(c1 == 'T');
|
||||
|
||||
// next the name:
|
||||
@@ -336,9 +340,12 @@ FieldPrint get_field_print(const std::string& str) {
|
||||
// (format "~Tstack[~D] @ #x~X~%" (-> obj allocated-length) (-> obj stack))
|
||||
if (num_char == '~') {
|
||||
num_char = next();
|
||||
ASSERT(num_char == 'D');
|
||||
if (num_char != 'D') {
|
||||
return handle_custom_prints(field_print, str);
|
||||
}
|
||||
ASSERT_MSG(num_char == 'D', fmt::format("unexpected: {}", num_char));
|
||||
num_char = next();
|
||||
ASSERT(num_char == ']');
|
||||
ASSERT_MSG(num_char == ']', fmt::format("unexpected: {}", num_char));
|
||||
// distinguish from dynamic arrays that are set to size 0
|
||||
field_print.array_size = size = FieldPrint::DYNAMIC_ARRAY;
|
||||
}
|
||||
@@ -1022,15 +1029,31 @@ bool get_ptr_offset_constant_nonzero(const SimpleExpression& math, Register base
|
||||
bool get_ptr_offset(AtomicOp* ir, Register dst, Register base, int* result) {
|
||||
auto as_set = dynamic_cast<SetVarOp*>(ir);
|
||||
if (!as_set) {
|
||||
printf("not a set, actual type: %s\n", typeid(*ir).name());
|
||||
return false;
|
||||
}
|
||||
if (as_set->dst().reg() != dst) {
|
||||
printf("bad dst");
|
||||
return false;
|
||||
}
|
||||
|
||||
return get_ptr_offset_constant_nonzero(as_set->src(), base, result);
|
||||
}
|
||||
|
||||
bool get_ptr_offset_load_var_op(AtomicOp* ir, Register dst, Register base, int* result) {
|
||||
auto as_load = dynamic_cast<LoadVarOp*>(ir);
|
||||
if (!as_load) {
|
||||
printf("not a set, actual type: %s\n", typeid(*ir).name());
|
||||
return false;
|
||||
}
|
||||
if (as_load->get_set_destination().reg() != dst) {
|
||||
printf("bad dst");
|
||||
return false;
|
||||
}
|
||||
|
||||
return get_ptr_offset_constant_nonzero(as_load->src(), base, result);
|
||||
}
|
||||
|
||||
int identify_array_field(int idx,
|
||||
Function& function,
|
||||
TypeInspectorResult* result,
|
||||
@@ -1050,6 +1073,10 @@ int identify_array_field(int idx,
|
||||
ptr = get_ptr_offset(get_op, make_gpr(Reg::A3), make_gpr(Reg::GP), &offset);
|
||||
} else {
|
||||
ptr = get_ptr_offset(get_op, make_gpr(Reg::A2), make_gpr(Reg::GP), &offset);
|
||||
// maybe they load it the other way (inline?)
|
||||
if (!ptr) {
|
||||
ptr = get_ptr_offset_load_var_op(get_op, make_gpr(Reg::A2), make_gpr(Reg::GP), &offset);
|
||||
}
|
||||
}
|
||||
|
||||
if (!ptr) {
|
||||
@@ -1352,6 +1379,10 @@ std::string inspect_inspect_method(Function& inspect_method,
|
||||
lg::print(" iim: {}\n", inspect_method.name());
|
||||
TypeInspectorResult result;
|
||||
ASSERT(type_name == inspect_method.guessed_name.type_name);
|
||||
if (inspect_method.name() == "(method 3 process-tree)") {
|
||||
printf("HACK: skipping method\n");
|
||||
return fmt::format(";; {} TODO: skipped!\n", type_name);
|
||||
}
|
||||
TypeFlags flags;
|
||||
flags.flag = 0;
|
||||
result.found_flags = dts.lookup_flags(type_name, &flags.flag);
|
||||
|
||||
@@ -110,13 +110,14 @@ void clean_up_cond_with_else(FormPool& pool, FormElement* ir, const Env& env) {
|
||||
*/
|
||||
void clean_up_until_loop(FormPool& pool, UntilElement* ir, const Env& env) {
|
||||
auto condition_branch = get_condition_branch(ir->condition);
|
||||
ASSERT(condition_branch.first);
|
||||
ASSERT_MSG(condition_branch.first, fmt::format("bad condition branch in {}\n", env.func->name()));
|
||||
if (condition_branch.first->op()->branch_delay().kind() != IR2_BranchDelay::Kind::NOP) {
|
||||
ASSERT_MSG(
|
||||
condition_branch.first->op()->branch_delay().kind() == IR2_BranchDelay::Kind::SET_REG_FALSE,
|
||||
fmt::format(
|
||||
"bad delay slot in until loop: {} in {}\n", env.func->name(),
|
||||
condition_branch.first->op()->branch_delay().to_form(env.file->labels, env).print()));
|
||||
"bad delay slot in until loop: {} in {}\n",
|
||||
condition_branch.first->op()->branch_delay().to_form(env.file->labels, env).print(),
|
||||
env.func->name()));
|
||||
ir->false_destination = condition_branch.first->op()->branch_delay().var(0);
|
||||
}
|
||||
auto replacement = condition_branch.first->op()->get_condition_as_form(pool, env);
|
||||
@@ -1974,7 +1975,8 @@ void clean_up_while_loops(FormPool& pool, Form* sequence, const Env& env) {
|
||||
|
||||
auto condition_branch = get_condition_branch(form_as_while->condition);
|
||||
|
||||
ASSERT(condition_branch.first);
|
||||
ASSERT_MSG(condition_branch.first,
|
||||
fmt::format("bad conditional branch in {}\n", env.func->name()));
|
||||
ASSERT(condition_branch.first->op()->branch_delay().kind() == IR2_BranchDelay::Kind::NOP);
|
||||
// printf("got while condition branch %s\n", condition_branch.first->print(file).c_str());
|
||||
auto replacement = condition_branch.first->op()->get_condition_as_form(pool, env);
|
||||
|
||||
@@ -45,6 +45,8 @@ If the previous let variables appear in the definition of new one, make the let
|
||||
|
||||
namespace {
|
||||
FormElement* rewrite_let(LetElement* in, const Env& env, FormPool& pool, LetRewriteStats& stats);
|
||||
FormElement* rewrite_multi_let_as_vector_dot(LetElement* in, const Env& env, FormPool& pool);
|
||||
bool let_uses_stack_slot_access(const LetElement* in);
|
||||
|
||||
std::vector<Form*> path_up_tree(Form* in, const Env&) {
|
||||
std::vector<Form*> path;
|
||||
@@ -2409,6 +2411,18 @@ FormElement* rewrite_set_font_single(LetElement* in,
|
||||
FormElement* rewrite_let(LetElement* in, const Env& env, FormPool& pool, LetRewriteStats& stats) {
|
||||
// ordered based on frequency. for best performance, you check the most likely rewrites first!
|
||||
|
||||
if (in->entries().size() >= 6) {
|
||||
auto as_vector_dot = rewrite_multi_let_as_vector_dot(in, env, pool);
|
||||
if (as_vector_dot) {
|
||||
stats.vector_dot++;
|
||||
return as_vector_dot;
|
||||
}
|
||||
}
|
||||
|
||||
if (let_uses_stack_slot_access(in)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto as_unused = rewrite_empty_let(in, env, pool);
|
||||
if (as_unused) {
|
||||
stats.unused++;
|
||||
@@ -3073,6 +3087,18 @@ FormElement* rewrite_multi_let(LetElement* in,
|
||||
const Env& env,
|
||||
FormPool& pool,
|
||||
LetRewriteStats& stats) {
|
||||
if (in->entries().size() >= 6) {
|
||||
auto as_vector_dot = rewrite_multi_let_as_vector_dot(in, env, pool);
|
||||
if (as_vector_dot) {
|
||||
stats.vector_dot++;
|
||||
return as_vector_dot;
|
||||
}
|
||||
}
|
||||
|
||||
if (let_uses_stack_slot_access(in)) {
|
||||
return in;
|
||||
}
|
||||
|
||||
if (in->entries().size() >= 2) {
|
||||
auto as_with_dma_buf_add_bucket = rewrite_with_dma_buf_add_bucket(in, env, pool);
|
||||
if (as_with_dma_buf_add_bucket) {
|
||||
@@ -3101,14 +3127,6 @@ FormElement* rewrite_multi_let(LetElement* in,
|
||||
}
|
||||
}
|
||||
|
||||
if (in->entries().size() >= 6) {
|
||||
auto as_vector_dot = rewrite_multi_let_as_vector_dot(in, env, pool);
|
||||
if (as_vector_dot) {
|
||||
stats.vector_dot++;
|
||||
return as_vector_dot;
|
||||
}
|
||||
}
|
||||
|
||||
auto as_font_set_origin = rewrite_set_font_origin(in, env, pool);
|
||||
if (as_font_set_origin) {
|
||||
stats.font_method++;
|
||||
@@ -3569,6 +3587,12 @@ FormElement* rewrite_let_sequence(const std::vector<LetElement*>& in,
|
||||
const Env& env,
|
||||
FormPool& pool,
|
||||
LetRewriteStats& stats) {
|
||||
for (const auto* let : in) {
|
||||
if (let_uses_stack_slot_access(let)) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (in.size() == 3) {
|
||||
auto as_dma_buffer_add_gs_set = rewrite_dma_buffer_add_gs_set(in, env, pool);
|
||||
if (as_dma_buffer_add_gs_set) {
|
||||
@@ -3609,6 +3633,15 @@ Form* insert_cast_for_let(RegisterAccess dst,
|
||||
return src;
|
||||
}
|
||||
|
||||
bool let_uses_stack_slot_access(const LetElement* in) {
|
||||
for (const auto& entry : in->entries()) {
|
||||
if (is_stack_slot_access(entry.dest)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool register_can_hold_var(const Register& reg) {
|
||||
return reg.get_kind() == Reg::FPR || reg.get_kind() == Reg::GPR;
|
||||
}
|
||||
|
||||
@@ -102,6 +102,9 @@ Config make_config_via_json(nlohmann::json& json) {
|
||||
config.obj_file_name_map_file = json.at("obj_file_name_map_file").get<std::string>();
|
||||
}
|
||||
config.disassemble_code = json.at("disassemble_code").get<bool>();
|
||||
if (json.contains("dump_function_metadata")) {
|
||||
config.dump_function_metadata = json.at("dump_function_metadata").get<bool>();
|
||||
}
|
||||
config.decompile_code = json.at("decompile_code").get<bool>();
|
||||
if (json.contains("format_code")) {
|
||||
config.format_code = json.at("format_code").get<bool>();
|
||||
|
||||
@@ -108,6 +108,7 @@ struct Config {
|
||||
std::string all_types_file;
|
||||
|
||||
bool disassemble_code = false;
|
||||
bool dump_function_metadata = false;
|
||||
bool decompile_code = false;
|
||||
bool format_code = false;
|
||||
bool write_scripts = false;
|
||||
|
||||
@@ -12103,17 +12103,17 @@
|
||||
(onground)
|
||||
(tsurf)
|
||||
(twall)
|
||||
(t-ciel)
|
||||
(t-ceil)
|
||||
(t-act)
|
||||
(csmf06)
|
||||
(csmf07)
|
||||
(csmf08)
|
||||
(csmf09)
|
||||
(on-water)
|
||||
(csmf11)
|
||||
(csmf12)
|
||||
(impact-surf)
|
||||
(t-bckgnd)
|
||||
(csmf13)
|
||||
(csmf14)
|
||||
(t-ceil-sticky)
|
||||
(csmf15)
|
||||
(csmf16)
|
||||
(csmf17)
|
||||
@@ -12415,6 +12415,93 @@
|
||||
(unknown-int34 int32 :offset 18992)
|
||||
(unknown-int35 int32 :offset 18996)
|
||||
(unknown-int36 int32 :offset 19000)
|
||||
(transv-ctrl vector :inline :overlay-at unknown-vector00 :score 1)
|
||||
(target-transv vector :inline :overlay-at unknown-vector01 :score 1)
|
||||
(bent-gravity-normal vector :inline :overlay-at unknown-vector02 :score 1)
|
||||
(last-transv vector :inline :overlay-at unknown-vector10 :score 1)
|
||||
(draw-offset vector :inline :overlay-at unknown-vector11 :score 1)
|
||||
(cspace-offset vector :inline :overlay-at unknown-vector12 :score 1)
|
||||
(anim-collide-offset-world vector :inline :overlay-at unknown-vector14 :score 1)
|
||||
(old-anim-collide-offset-world vector :inline :overlay-at unknown-vector15 :score 1)
|
||||
(anim-collide-offset-delta-world vector :inline :overlay-at unknown-vector16 :score 1)
|
||||
(to-target-pt-xz vector :inline :overlay-at unknown-vector20 :score 1)
|
||||
(last-to-target-pt-xz vector :inline :overlay-at unknown-vector21 :score 1)
|
||||
(turn-to-target vector :inline :overlay-at unknown-vector22 :score 1)
|
||||
(last-turn-to-target vector :inline :overlay-at unknown-vector23 :score 1)
|
||||
(pad-xz-dir vector :inline :overlay-at unknown-vector30 :score 1)
|
||||
(last-pad-xz-dir vector :inline :overlay-at unknown-vector31 :score 1)
|
||||
(force-turn-to-direction vector :inline :overlay-at unknown-vector40 :score 1)
|
||||
(gravity-normal vector :inline :overlay-at unknown-vector50 :score 1)
|
||||
(last-gravity-normal vector :inline :overlay-at unknown-vector51 :score 1)
|
||||
(last-trans-any-surf vector :inline :overlay-at unknown-vector52 :score 1)
|
||||
(ground-contact-normal vector :inline :overlay-at unknown-vector53 :score 1)
|
||||
(ground-contact-sphere-center vector :inline :overlay-at unknown-vector55 :score 1)
|
||||
(low-coverage-tangent vector :inline :overlay-at unknown-vector60 :score 1)
|
||||
(btransv vector :inline :overlay-at unknown-vector61 :score 1)
|
||||
(wall-contact-pt vector :inline :overlay-at unknown-vector70 :score 1)
|
||||
(wall-contact-poly-normal vector :inline :overlay-at unknown-vector71 :score 1)
|
||||
(actor-contact-pt vector :inline :overlay-at unknown-vector72 :score 1)
|
||||
(actor-contact-normal vector :inline :overlay-at unknown-vector73 :score 1)
|
||||
(ctrl-to-hands-offset vector :inline :overlay-at unknown-vector91 :score 1)
|
||||
(edge-grab-edge-dir vector :inline :overlay-at unknown-vector100 :score 1)
|
||||
(edge-grab-across-edge-dir vector :inline :overlay-at unknown-vector101 :score 1)
|
||||
(low-coverage-overhang-plane-normal vector :inline :overlay-at unknown-vector-coverage-2 :score 1)
|
||||
(low-coverage-tangent-xz vector :inline :overlay-at unknown-vector-coverage-3 :score 1)
|
||||
(last-trans-leaving-surf vector :inline :overlay-at unknown-vector110 :score 1)
|
||||
(highest-jump-mark vector :inline :overlay-at unknown-vector111 :score 1)
|
||||
(wall-contact-normal vector :inline :overlay-at unknown-vector121 :score 1)
|
||||
(quat-for-control quaternion :inline :overlay-at unknown-quaternion00 :score 1)
|
||||
(override-quat quaternion :inline :overlay-at unknown-quaternion01 :score 1)
|
||||
(w-R-c matrix :inline :overlay-at unknown-matrix00 :score 1)
|
||||
(c-R-w matrix :inline :overlay-at unknown-matrix01 :score 1)
|
||||
(ctrl-orientation matrix :inline :overlay-at unknown-matrix02 :score 1)
|
||||
(mod-surface surface :overlay-at unknown-surface00 :score 1)
|
||||
(current-surface surface :overlay-at unknown-surface01 :score 1)
|
||||
(override-quat-alpha float :overlay-at unknown-float00 :score 1)
|
||||
(ctrl-xz-vel float :overlay-at unknown-float01 :score 1)
|
||||
(velocity-after-thrust float :overlay-at unknown-float02 :score 1)
|
||||
(turn-to-angle float :overlay-at unknown-float10 :score 1)
|
||||
(last-turn-to-angle float :overlay-at unknown-float11 :score 1)
|
||||
(turn-to-magnitude float :overlay-at unknown-float12 :score 1)
|
||||
(last-turn-to-magnitude float :overlay-at unknown-float13 :score 1)
|
||||
(pad-magnitude float :overlay-at unknown-float20 :score 1)
|
||||
(last-pad-magnitude float :overlay-at unknown-float21 :score 1)
|
||||
(smack-speed-lerp-min float :overlay-at unknown-float40 :score 1)
|
||||
(force-turn-to-strength float :overlay-at unknown-float41 :score 1)
|
||||
(force-turn-to-speed float :overlay-at unknown-float50 :score 1)
|
||||
(ground-local-norm-dot-grav float :overlay-at unknown-float60 :score 1)
|
||||
(local-slope-z float :overlay-at unknown-float61 :score 1)
|
||||
(local-slope-x float :overlay-at unknown-float62 :score 1)
|
||||
(surface-slope-z float :overlay-at unknown-float63 :score 1)
|
||||
(surface-slope-x float :overlay-at unknown-float64 :score 1)
|
||||
(blocked-factor float :overlay-at unknown-float70 :score 1)
|
||||
(blocked-in-air-factor float :overlay-at unknown-float71 :score 1)
|
||||
(bend-amount float :overlay-at unknown-float80 :score 1)
|
||||
(bend-target float :overlay-at unknown-float81 :score 1)
|
||||
(bend-speed float :overlay-at unknown-float82 :score 1)
|
||||
(average-xz-vel float :overlay-at unknown-float100 :score 1)
|
||||
(low-coverage-slope-to-next1 float :overlay-at unknown-float-coverage-0 :score 1)
|
||||
(low-coverage-slope-to-next2 float :overlay-at unknown-float-coverage-2 :score 1)
|
||||
(idx-of-fastest-xz-vel int32 :overlay-at unknown-int10 :score 1)
|
||||
(did-move-to-pole-or-max-jump-height int32 :overlay-at unknown-int21 :score 1)
|
||||
(remaining-ctrl-iterations int32 :overlay-at unknown-int40 :score 1)
|
||||
(history-data-idx int16 :overlay-at unknown-halfword00 :score 1)
|
||||
(time-of-last-pad-read time-frame :overlay-at unknown-dword00 :score 1)
|
||||
(last-time-on-ground time-frame :overlay-at unknown-dword10 :score 1)
|
||||
(last-time-on-surface time-frame :overlay-at unknown-dword11 :score 1)
|
||||
(last-time-touching-actor time-frame :overlay-at unknown-dword20 :score 1)
|
||||
(time-of-last-lc time-frame :overlay-at unknown-dword21 :score 1)
|
||||
(last-attack-end-time time-frame :overlay-at unknown-dword33 :score 1)
|
||||
(last-time-of-stuck time-frame :overlay-at unknown-dword36 :score 1)
|
||||
(last-successful-compute-edge-time time-frame :overlay-at unknown-dword40 :score 1)
|
||||
(target-attack-id int64 :overlay-at unknown-dword50 :score 1)
|
||||
(attack-count int64 :overlay-at unknown-dword51 :score 1)
|
||||
(actor-contact-handle handle :overlay-at unknown-handle00 :score 1)
|
||||
(danger-mode symbol :overlay-at unknown-symbol30 :score 1)
|
||||
(cpad cpad-info :overlay-at unknown-cpad-info00 :score 1)
|
||||
(standard-dynamics dynamics :overlay-at unknown-dynamics00 :score 1)
|
||||
(transv-history vector 16 :inline :overlay-at unknown-vector-array10 :score 1)
|
||||
(camera-pos vector :inline :overlay-at unknown-qword00 :score 1)
|
||||
)
|
||||
:size-assert #x4a3c ;; #x4a2c
|
||||
:method-count-assert 65
|
||||
@@ -12690,9 +12777,17 @@
|
||||
|
||||
;; - Types
|
||||
|
||||
;; +++effect-control-h:effect-control-flag
|
||||
(defenum effect-control-flag
|
||||
:type uint32
|
||||
:bitfield #t
|
||||
(event 0)
|
||||
)
|
||||
;; ---effect-control-h:effect-control-flag
|
||||
|
||||
(deftype effect-control (basic)
|
||||
((process process-drawable :offset-assert 4)
|
||||
(flags uint32 :offset-assert 8)
|
||||
(flags effect-control-flag :offset-assert 8)
|
||||
(last-frame-group art-joint-anim :offset-assert 12)
|
||||
(last-frame-num float :offset-assert 16)
|
||||
(channel-offset int32 :offset-assert 20)
|
||||
@@ -14454,7 +14549,7 @@
|
||||
|
||||
(deftype entity-camera (entity)
|
||||
(
|
||||
(connect connectable :inline :offset-assert 64)
|
||||
(quat quaternion :inline :offset-assert 64)
|
||||
)
|
||||
:method-count-assert 27
|
||||
:size-assert #x50
|
||||
@@ -19634,6 +19729,43 @@
|
||||
(wt31)
|
||||
)
|
||||
|
||||
(defenum water-flag
|
||||
:bitfield #t
|
||||
:type uint32
|
||||
(water-marks)
|
||||
(active)
|
||||
(can-wade)
|
||||
(can-swim)
|
||||
(swim-ground)
|
||||
(part-splash)
|
||||
(part-drip)
|
||||
(wt07)
|
||||
(use-ocean)
|
||||
(touch-water)
|
||||
(wading)
|
||||
(swimming)
|
||||
(under-water)
|
||||
(head-under-water)
|
||||
(bouncing)
|
||||
(spawn-drip)
|
||||
(jump-out)
|
||||
(tar)
|
||||
(mud)
|
||||
(deadly)
|
||||
(use-ripple-offset)
|
||||
(no-grab-sound)
|
||||
(part-rings)
|
||||
(part-water)
|
||||
(dark-eco)
|
||||
(lava)
|
||||
(wt26)
|
||||
(wt27)
|
||||
(wt28)
|
||||
(wt29)
|
||||
(wt30)
|
||||
(wt31)
|
||||
)
|
||||
|
||||
(defenum water-look
|
||||
(water-anim-sunken-big-room 0)
|
||||
(water-anim-sunken-first-room-from-entrance 1)
|
||||
@@ -19720,6 +19852,7 @@
|
||||
(drip-speed float :offset-assert 272)
|
||||
(drip-height meters :offset-assert 276)
|
||||
(drip-mult float :offset-assert 280)
|
||||
(flag water-flag :overlay-at flags :score 1) ;; added
|
||||
)
|
||||
:method-count-assert 17
|
||||
:size-assert #x11c
|
||||
@@ -19745,6 +19878,7 @@
|
||||
(attack-event symbol :offset-assert 192)
|
||||
(target handle :offset-assert 200)
|
||||
(flags water-flags :offset-assert 208)
|
||||
(flag water-flag :overlay-at flags :score 1) ;; added
|
||||
)
|
||||
:heap-base #x70
|
||||
:method-count-assert 30
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -4008,5 +4008,11 @@
|
||||
"vars": {
|
||||
"gp-0": "active-buffer"
|
||||
}
|
||||
},
|
||||
"target-collision-reaction": {
|
||||
"vars": {
|
||||
"sv-96": "moving-flags",
|
||||
"sv-104": "react-flags"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2880,7 +2880,7 @@
|
||||
(shutdown sound-rpc-shutdown :offset 0)
|
||||
(list-sounds sound-rpc-list-sounds :offset 0)
|
||||
(unload-music sound-rpc-unload-music :offset 0)
|
||||
(mirror-mode sound-rpc-set-mirror-mode :overlay-at (-> data 0))
|
||||
(mirror-mode sound-rpc-set-mirror-mode :offset 0)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x50
|
||||
@@ -22506,7 +22506,7 @@ Levels store a reference to this which holds all the entities in the level."
|
||||
)
|
||||
|
||||
(deftype entity-camera (entity)
|
||||
((connect connectable :inline :offset-assert 64)) ;; guess from jak 1
|
||||
((quat quaternion :inline :offset-assert 64))
|
||||
:flag-assert #x1b00000050
|
||||
)
|
||||
|
||||
@@ -35329,7 +35329,7 @@ Consists of a header and a list of [[merc-effect]]s."
|
||||
(_type_) none) ;; 132
|
||||
(enemy-method-133 (_type_) symbol) ;; 133
|
||||
(get-attacker (_type_ process attack-info) process-focusable) ;; 134
|
||||
(enemy-method-135 (_type_ int) sound-id) ;; 135
|
||||
(play-damage-or-death-sound (_type_ int) sound-id) ;; 135
|
||||
(enemy-method-136 (_type_) enemy-flag) ;; 136
|
||||
)
|
||||
)
|
||||
|
||||
@@ -2778,7 +2778,7 @@
|
||||
[[1, 7], "v1", "drawable-region-prim"]
|
||||
],
|
||||
"(method 18 drawable-region-face)": [
|
||||
[[33, 84], "v1", "(inline-array vector)"]
|
||||
["_stack_", 56, "(inline-array vector)"]
|
||||
],
|
||||
"(method 18 drawable-tree-region-prim)": [
|
||||
[[22, 49], "s2", "drawable-region-prim"]
|
||||
@@ -4051,7 +4051,9 @@
|
||||
[64, "a0", "process-drawable"]
|
||||
],
|
||||
"process-drawable2-shock-effect": [[59, "v0", "lightning-tracker"]],
|
||||
"process-drawable-shock-effect": [[156, "v0", "lightning-tracker"]],
|
||||
"process-drawable-shock-effect": [
|
||||
["_stack_", 624, "(pointer lightning-tracker)"]
|
||||
],
|
||||
"(method 12 top-anim-joint-control)": [
|
||||
[8, "a1", "art-joint-anim"],
|
||||
[40, "a1", "art-joint-anim"]
|
||||
@@ -5967,7 +5969,7 @@
|
||||
"(post idle drill-plat)": [[4, "t9", "(function none)"]],
|
||||
"(post idle grenade-point)": [[122, "v1", "lightning-tracker"]],
|
||||
"(anon-function 12 strip-obs)": [
|
||||
[103, "a0", "(pointer entity-actor)"],
|
||||
["_stack_", 16, "(pointer entity-actor)"],
|
||||
[287, "v1", "int"]
|
||||
],
|
||||
"(method 11 strip-hazard)": [
|
||||
|
||||
+468
-407
File diff suppressed because it is too large
Load Diff
@@ -130,7 +130,7 @@
|
||||
// turn this on if you want extracted level collision to be saved as .obj files in decompiler_out/<game>/collision
|
||||
"rip_collision": false,
|
||||
// save game textures as .png files to decompiler_out/<game>/textures
|
||||
"save_texture_pngs": true,
|
||||
"save_texture_pngs": false,
|
||||
|
||||
// whether or not to dump out streamed audio files to decompiler_out/<game>/audio
|
||||
"rip_streamed_audio": false,
|
||||
|
||||
@@ -1005,5 +1005,14 @@
|
||||
[15, "(function external-art-buffer object)"],
|
||||
[16, "(function external-art-buffer object)"],
|
||||
[17, "(function external-art-buffer object)"]
|
||||
]
|
||||
],
|
||||
"editable-player": [
|
||||
[0, "(function object)"],
|
||||
[3, "(function object int float object)"],
|
||||
[4, "(function object int symbol)"],
|
||||
[31, "(function editable editable-region symbol)"],
|
||||
[32, "(function editable editable-region symbol)"],
|
||||
[35, "(function editable symbol)"]
|
||||
],
|
||||
"editable": [[101, "(function object editable-filter)"]]
|
||||
}
|
||||
|
||||
@@ -41,9 +41,6 @@
|
||||
"anim-test-anim-list-handler",
|
||||
"anim-test-sequence-list-handler",
|
||||
"anim-tester-get-playing-item",
|
||||
"start-pilot-recorder",
|
||||
"(anon-function 10 pilot-recorder)",
|
||||
"(anon-function 10 sig-recorder)",
|
||||
// actual asm
|
||||
"quad-copy!",
|
||||
"return-from-thread",
|
||||
@@ -89,7 +86,6 @@
|
||||
// CFG failed
|
||||
"draw-inline-array-instance-shrub",
|
||||
|
||||
"(method 9 editable-region)", // condition branch assert hit
|
||||
"test-to-from-spr",
|
||||
"test-from-spr",
|
||||
"test-to-spr",
|
||||
@@ -101,7 +97,6 @@
|
||||
"adgif-shader<-texture!",
|
||||
|
||||
// jak 3
|
||||
"(method 10 manipulator)",
|
||||
"(method 46 ff-squad-control)",
|
||||
"memcpy"
|
||||
],
|
||||
@@ -466,7 +461,11 @@
|
||||
"(anon-function 90 ctywide-obs)": [4],
|
||||
"(anon-function 10 cty-sniper-turret)": [44],
|
||||
"(method 33 rub-tower)": [9, 10],
|
||||
"(method 30 gungame-manager)": [0, 4, 5, 7]
|
||||
"(method 30 gungame-manager)": [0, 4, 5, 7],
|
||||
"(method 9 editable-region)": [63],
|
||||
"(method 10 manipulator)": [4],
|
||||
"(method 18 mysql-nav-graph)": [0, 1, 2, 3, 4, 7, 9],
|
||||
"(method 17 nav-mesh-editable)": [0, 1, 2, 7, 9, 24, 28, 33]
|
||||
},
|
||||
|
||||
// Sometimes the game might use format strings that are fetched dynamically,
|
||||
@@ -582,7 +581,8 @@
|
||||
[378, 0],
|
||||
[413, 0]
|
||||
],
|
||||
"(trans carry precur-bomb)": [[60, 0]]
|
||||
"(trans carry precur-bomb)": [[60, 0]],
|
||||
"hover-nav-graph-output": [[319, 0]]
|
||||
},
|
||||
|
||||
"mips2c_functions_by_name": [
|
||||
|
||||
@@ -2465,5 +2465,29 @@
|
||||
["L198", "(pointer uint8)", 16],
|
||||
["L197", "(pointer uint16)", 48]
|
||||
],
|
||||
"game-task": [["L18", "(array game-task-node-command)"]]
|
||||
"game-task": [["L18", "(array game-task-node-command)"]],
|
||||
"editable-player": [
|
||||
["L1431", "(inline-array vector4w)", 4],
|
||||
["L1499", "uint64", true]
|
||||
],
|
||||
"editable": [
|
||||
["L724", "rgba", true],
|
||||
["L725", "rgba", true],
|
||||
["L726", "rgba", true],
|
||||
["L727", "rgba", true],
|
||||
["L728", "rgba", true],
|
||||
["L729", "rgba", true],
|
||||
["L730", "rgba", true],
|
||||
["L680", "vector"],
|
||||
["L722", "uint64", true],
|
||||
["L723", "rgba", true]
|
||||
],
|
||||
"nav-mesh-editor": [
|
||||
["L560", "uint64", true],
|
||||
["L504", "(inline-array triangulation-vert)", 256],
|
||||
["L505", "(inline-array triangulation-vert)", 256],
|
||||
["L555", "(pointer int32)", 1024],
|
||||
["L556", "(inline-array vector)", 1024],
|
||||
["L557", "uint64", true]
|
||||
]
|
||||
}
|
||||
|
||||
@@ -7,5 +7,6 @@
|
||||
"task-manager-init-by-other": 2048,
|
||||
"race-manager-init-by-other": 1024,
|
||||
"neo-sat-shield-init-by-other": 64,
|
||||
"bt-gun-manager-init-by-other": 256
|
||||
"bt-gun-manager-init-by-other": 256,
|
||||
"(method 11 tpl-holo-eye)": 384
|
||||
}
|
||||
|
||||
@@ -195,8 +195,9 @@
|
||||
"(code target-hit)": [[16, "vector"]],
|
||||
"apply-pos-from-entity": [[208, "collide-query"]],
|
||||
"target-death-main": [
|
||||
[16, "event-message-block"],
|
||||
[96, ["array", "level", 1]]
|
||||
[16, "event-message-block"]
|
||||
// this wrong stack cast was the reason Daxter's death quotes scenes didn't work
|
||||
//[96, ["array", "level", 1]]
|
||||
],
|
||||
"find-nearest-focusable": [[48, "vector"]],
|
||||
"target-gun-joint-pre0": [
|
||||
@@ -1942,7 +1943,7 @@
|
||||
"(code wait title-control)": [[16, "event-message-block"]],
|
||||
"(code startup title-control)": [
|
||||
[16, ["array", "symbol", 10]],
|
||||
[64, "event-message-block"], // this memory is reused as both mc-slot-info and event-message-block
|
||||
[64, "event-message-block"],
|
||||
[368, ["array", "symbol", 10]]
|
||||
],
|
||||
"(method 9 nav-node)": [[48, ["inline-array", "vector", 2]]],
|
||||
@@ -2519,5 +2520,132 @@
|
||||
[32, "vector"],
|
||||
[48, "vector"],
|
||||
[64, "vector"]
|
||||
],
|
||||
"(method 9 editable-array)": [
|
||||
[16, "vector"],
|
||||
[96, "vector"]
|
||||
],
|
||||
"(method 23 editable-player)": [
|
||||
[128, "vector"],
|
||||
[112, "vector"]
|
||||
],
|
||||
"execute-move": [
|
||||
[16, "vector"],
|
||||
[32, "vector"]
|
||||
],
|
||||
"execute-mouse-move": [
|
||||
[16, "vector"],
|
||||
[32, "vector"],
|
||||
[48, "vector"],
|
||||
[64, "vector"],
|
||||
[80, "vector"],
|
||||
[112, "vector"]
|
||||
],
|
||||
"update-manipulator-position": [[16, "vector"]],
|
||||
"insert-wall": [[32, ["array", "int32", 2]]],
|
||||
"insert-box": [[32, ["array", "int32", 8]]],
|
||||
"(method 22 editable)": [
|
||||
[16, "vector"],
|
||||
[32, "vector"]
|
||||
],
|
||||
"(method 21 editable-entity)": [[80, "vector"]],
|
||||
"(method 13 editable-plane)": [[64, ["inline-array", "vector", 4]]],
|
||||
"(method 14 editable-point)": [
|
||||
[80, ["inline-array", "vector", 4]],
|
||||
[32, "vector"],
|
||||
[48, "vector"]
|
||||
],
|
||||
"(method 31 editable-face)": [
|
||||
[16, ["inline-array", "vector", 6]],
|
||||
[112, ["inline-array", "vector", 6]],
|
||||
[240, ["array", "editable-point", 6]],
|
||||
[304, "matrix"]
|
||||
],
|
||||
"(method 14 editable-face)": [
|
||||
[64, ["inline-array", "vector", 4]],
|
||||
[208, ["inline-array", "vector", 6]],
|
||||
[304, ["inline-array", "vector", 6]],
|
||||
[416, "vector"]
|
||||
],
|
||||
"(method 13 editable-face)": [[64, ["inline-array", "vector", 6]]],
|
||||
"(method 10 editable-face)": [[16, ["inline-array", "vector", 6]]],
|
||||
"(method 37 editable-face)": [[16, ["inline-array", "vector", 6]]],
|
||||
"(method 10 editable-plane)": [[16, ["inline-array", "vector", 4]]],
|
||||
"(method 13 editable-array)": [
|
||||
[96, "vector"],
|
||||
[160, "vector"]
|
||||
],
|
||||
"(method 23 mysql-nav-graph)": [[16, ["inline-array", "vector", 5]]],
|
||||
"(post draw-closest-minimap nav-graph-editor)": [
|
||||
[64, ["inline-array", "vector", 5]]
|
||||
],
|
||||
"(method 29 nav-graph-editor)": [
|
||||
[32, "vector"],
|
||||
[48, ["inline-array", "vector", 2]],
|
||||
[112, "vector"],
|
||||
[128, "vector"],
|
||||
[144, "vector"]
|
||||
],
|
||||
"(method 32 nav-graph-editor)": [[32, "vector"]],
|
||||
"(method 31 nav-graph-editor)": [[16, ["inline-array", "vector", 5]]],
|
||||
"(method 35 nav-graph-editor)": [[16, ["inline-array", "vector", 4]]],
|
||||
"(method 37 nav-graph-editor)": [
|
||||
[80, "vector"],
|
||||
[880, ["inline-array", "vector", 4]]
|
||||
],
|
||||
"update-height": [[16, "vector"]],
|
||||
"(method 33 nav-graph-editor)": [
|
||||
[16, "vector"],
|
||||
[48, ["inline-array", "vector", 2]]
|
||||
],
|
||||
"(method 49 nav-graph-editor)": [
|
||||
[16, "vector"],
|
||||
[32, "vector"]
|
||||
],
|
||||
"(method 47 nav-graph-editor)": [
|
||||
[48, "vector"],
|
||||
[96, "vector"],
|
||||
[128, "vector"]
|
||||
],
|
||||
"(method 22 nav-mesh-editor)": [[80, "vector"]],
|
||||
"(method 10 nav-mesh-poly)": [
|
||||
[16, "vector"],
|
||||
[32, "vector"],
|
||||
[48, "vector"],
|
||||
[64, "vector"],
|
||||
[80, "vector"],
|
||||
[96, "vector"],
|
||||
[112, "vector"],
|
||||
[128, "vector"]
|
||||
],
|
||||
"snap-level-navmesh": [
|
||||
[16, "vector"],
|
||||
[64, "vector"]
|
||||
],
|
||||
"(method 16 nav-mesh-editable)": [
|
||||
[16, "vector"],
|
||||
[48, "vector"],
|
||||
[32, "vector"]
|
||||
],
|
||||
"(method 15 nav-mesh-editable)": [[16, "vector"]],
|
||||
"(method 12 nav-mesh-editable)": [[32, "vector"]],
|
||||
"(method 14 nav-mesh-editable)": [
|
||||
[16, ["inline-array", "vector", 4]],
|
||||
[80, ["inline-array", "vector", 4]]
|
||||
],
|
||||
"camera-slave-debug": [
|
||||
[16, "vector"],
|
||||
[32, "vector"],
|
||||
[48, "matrix"],
|
||||
[128, "curve"]
|
||||
],
|
||||
"hover-nav-graph-output": [
|
||||
[32, "vector"],
|
||||
[48, "vector"]
|
||||
],
|
||||
"(method 25 pilot-recorder)": [[16, ["inline-array", "vector", 2]]],
|
||||
"(method 22 pilot-recorder)": [
|
||||
[16, ["inline-array", "vector", 4]],
|
||||
[80, ["inline-array", "vector", 4]]
|
||||
]
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2164,5 +2164,20 @@
|
||||
},
|
||||
"set-font-color": {
|
||||
"args": ["idx", "clr0", "clr1", "clr2", "clr3"]
|
||||
},
|
||||
"(anon-function 101 editable)": {
|
||||
"vars": {
|
||||
"gp-0": ["filter-type", "editable-filter"]
|
||||
}
|
||||
},
|
||||
"(method 12 editable-region)": {
|
||||
"vars": {
|
||||
"v0-3": ["filter", "editable-filter"]
|
||||
}
|
||||
},
|
||||
"(method 28 pilot-recorder)": {
|
||||
"vars": {
|
||||
"v0-0": ["flag", "pilrec-sample-flag"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+13575
-12439
File diff suppressed because it is too large
Load Diff
@@ -43,15 +43,21 @@
|
||||
"process_game_count": false,
|
||||
// write goal imports for art groups
|
||||
"process_art_groups": false,
|
||||
// write goal imports for the part group table
|
||||
"process_part_group_table": false,
|
||||
// write out a json file containing the art info mapping, run this with all objects allowed
|
||||
"dump_art_group_info": false,
|
||||
// write out a json file containing the joint node mapping, run this with all objects allowed
|
||||
"dump_joint_geo_info": false,
|
||||
// TODO - not done yet
|
||||
"dump_joint_geo_info": true,
|
||||
// write out a json file containing tpage and texture mappings, run with all objects allowed
|
||||
"dump_tex_info": false,
|
||||
// write out a json file containing the part group table, run with all objects allowed
|
||||
// TODO - not done yet
|
||||
"dump_part_group_table": true,
|
||||
|
||||
// set to false to skip adding .STR files to the decompiler database
|
||||
"read_spools": true,
|
||||
"read_spools": false,
|
||||
// write out spool subtitle text, implies read_spools
|
||||
"process_subtitle_text": false,
|
||||
// write out spool subtitle images, implies read_spools
|
||||
@@ -102,15 +108,17 @@
|
||||
"inputs_file": "decompiler/config/jakx/ntsc_v1/inputs.jsonc",
|
||||
"art_info_file": "decompiler/config/jakx/ntsc_v1/art_info.jsonc",
|
||||
"import_deps_file": "decompiler/config/jakx/ntsc_v1/import_deps.jsonc",
|
||||
"all_types_file": "decompiler/config/ntsc_v1/all-types.gc",
|
||||
"art_group_dump_file": "decompiler/config/ntsc_v1/art-group-info.min.json",
|
||||
"joint_node_dump_file": "decompiler/config/ntsc_v1/joint-node-info.min.json",
|
||||
"tex_dump_file": "decompiler/config/ntsc_v1/tex-info.min.json",
|
||||
"process_stack_size_file": "decompiler/config/ntsc_v1/process_stack_size_overrides.jsonc",
|
||||
"art_group_dump_file": "decompiler/config/jakx/ntsc_v1/art-group-info.min.json",
|
||||
"joint_node_dump_file": "decompiler/config/jakx/ntsc_v1/joint-node-info.min.json",
|
||||
"tex_dump_file": "decompiler/config/jakx/ntsc_v1/tex-info.min.json",
|
||||
// TODO - regenerate once sparticle is decompiled
|
||||
// "part_group_table_dump_file": "decompiler/config/jakx/ntsc_v1/part-groups.min.json",
|
||||
"process_stack_size_file": "decompiler/config/jakx/ntsc_v1/process_stack_size_overrides.jsonc",
|
||||
"all_types_file": "decompiler/config/jakx/all-types.gc",
|
||||
|
||||
// optional: a predetermined object file name map from a file.
|
||||
// this will make decompilation naming consistent even if you only run on some objects.
|
||||
"obj_file_name_map_file": "goal_src/jakx/build/all_objs.json",
|
||||
// "obj_file_name_map_file": "goal_src/jakx/build/all_objs.json",
|
||||
|
||||
////////////////////////////
|
||||
// LEVEL EXTRACTION
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
{
|
||||
// "gkernel": [
|
||||
// [17, "(function process symbol)"]
|
||||
// ]
|
||||
"profile": [[3, "(function profile-segment-array profile-collapse none)"]]
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -8,48 +8,12 @@
|
||||
// so you only need to specify it when that's not the case.
|
||||
|
||||
// remap names for states and behaviors of these types
|
||||
"type_remap": {
|
||||
// "target": "jakb-ag",
|
||||
// "sidekick": "daxter-ag",
|
||||
// "wings": "jakb-ag",
|
||||
// "lightjak-shield": "jakb-ag",
|
||||
// "freeze-screen": "collectables-ag",
|
||||
// "red-3-sphere": "gun-ag",
|
||||
// "gun-dark-3-sphere": "gun-ag",
|
||||
// "marauder": "marauder-male-ag",
|
||||
// "glider-ring": "des-glider-ring-ag",
|
||||
// "flut-racer": "flut-wild-ag",
|
||||
// "was-pre-heart": "neo-satellite-heart-ag",
|
||||
// "was-pre-beam": "neo-satellite-game-ring-ag",
|
||||
// "was-pre-bubble": "neo-satellite-ps-symbols-ag",
|
||||
// "maker": "dm-robot-ag",
|
||||
// "mh-wasp": "neo-wasp-ag",
|
||||
// "factory-boss": "errol-lowres-ag",
|
||||
// "fac-robotank-turret": "fac-robotank-ag",
|
||||
// "neo-sat-shield": "neo-satellite-shield-ag",
|
||||
// "neo-sat": "neo-satellite-ag",
|
||||
// "power-game-switcher": "switcher-ag",
|
||||
// "power-game-player": "daxter-pac-man-ag",
|
||||
// "power-game-glyph": "cipher-ag",
|
||||
// "power-game-rings": "pow-rings-ag",
|
||||
// "power-game-chaser": "flitter-ag",
|
||||
// "power-game-zapper": "grunt-head-ag",
|
||||
// "gungame-door": "fort-entry-gate-ag",
|
||||
// "bt-mh-flyer": "bt-wasp-ag",
|
||||
// "gunship-exploder": "kg-robot-transport-break",
|
||||
// "gunship-engine": "kg-robot-transport-bomb",
|
||||
// "protect-gunship": "kg-robot-transport",
|
||||
// "gunship-missile": "cty-homing-missile"
|
||||
},
|
||||
"type_remap": {},
|
||||
|
||||
// remap names for types in an entire file (higher priority)
|
||||
"file_override": {
|
||||
// "target-indax": { "target": "daxter-ag" } // in target-indax.gc, the remap for 'target' will be set to 'daxter-ag'
|
||||
},
|
||||
"file_override": {},
|
||||
|
||||
// some art groups (like robotboss-ag) have a name for their model that differs
|
||||
// from the usual ag-name + "-lod0". you can add those exceptions here.
|
||||
"joint_node_hacks": {
|
||||
// "robotboss-ag": "robotboss-basic"
|
||||
}
|
||||
"joint_node_hacks": {}
|
||||
}
|
||||
|
||||
@@ -2,73 +2,131 @@
|
||||
////////////////////////////
|
||||
// HACKS and ASM FUNCTIONS
|
||||
////////////////////////////
|
||||
|
||||
"types_with_bad_inspect_methods": [
|
||||
// "game-task-event"
|
||||
],
|
||||
|
||||
"types_with_bad_inspect_methods": ["game-task-event", "game-task-control"],
|
||||
"no_type_analysis_functions_by_name": [],
|
||||
|
||||
// this limits the number of cases in a cond. The first argument is the name of the function.
|
||||
// the second argument is the name of the first condition in the cond. Use print_cfg to find it out.
|
||||
// The third argument is the number of cases. If you set it too small it may fail to build the CFG.
|
||||
"cond_with_else_max_lengths": [
|
||||
// ["(method 20 res-lump)", "b0", 2],
|
||||
],
|
||||
|
||||
"cond_with_else_max_lengths": [],
|
||||
// if a cond with an else case is being used a value in a place where it looks wrong
|
||||
// you can add the function name to this list and it will more aggressively reject this rewrite.
|
||||
"aggressively_reject_cond_to_value_rewrite": [
|
||||
// "(method 10 res-lump)",
|
||||
],
|
||||
|
||||
"aggressively_reject_cond_to_value_rewrite": [],
|
||||
// this provides a hint to the decompiler that these functions will have a lot of inline assembly.
|
||||
// currently it just leaves pcpyld as an asm op.
|
||||
"hint_inline_assembly_functions": [],
|
||||
|
||||
"asm_functions_by_name": [
|
||||
// "name=",
|
||||
// checking boxed type is different now - these make the cfg stuff sad
|
||||
"name=",
|
||||
// disabled to get decomp to work
|
||||
"water-anim-event-handler",
|
||||
"(anon-function 55 task-control)",
|
||||
"(method 22 level)",
|
||||
"(method 11 medius-cache)",
|
||||
"(method 13 race-line)",
|
||||
"(method 11 collide-mesh)",
|
||||
// dma
|
||||
"symlink2",
|
||||
// actual asm
|
||||
"quad-copy!",
|
||||
"sin-rad",
|
||||
"cos-rad",
|
||||
"atan-series-rad",
|
||||
"sign-float",
|
||||
"(method 9 matrix)",
|
||||
"quaternion->matrix-2",
|
||||
"vector-rotate-y-fast!",
|
||||
"(method 11 collide-mesh-cache)",
|
||||
"generic-light-proc",
|
||||
"dma-count-until-done"
|
||||
],
|
||||
|
||||
// these functions use pairs and the decompiler
|
||||
// will be less picky about types related to pairs.
|
||||
"pair_functions_by_name": [
|
||||
// "ref",
|
||||
"ref",
|
||||
"ref&",
|
||||
"(method 4 pair)",
|
||||
"last",
|
||||
"member",
|
||||
"nmember",
|
||||
"assoc",
|
||||
"assoce",
|
||||
"nassoc",
|
||||
"nassoce",
|
||||
"append!",
|
||||
"delete!",
|
||||
"delete-car!",
|
||||
"insert-cons!",
|
||||
"sort"
|
||||
],
|
||||
|
||||
// If format is used with the wrong number of arguments,
|
||||
// it will often mess up the decompilation, as the decompiler assumes
|
||||
// that they used the correct number. This will override the decompiler's
|
||||
// automatic detection.
|
||||
"bad_format_strings": {
|
||||
// "~170h~5d~220h~5d~280h~5,,2f": 3,
|
||||
"~170h~5d~220h~5d~280h~5,,2f": 3,
|
||||
"~338h~5d~388h~5d~448h~5,,2f": 3
|
||||
},
|
||||
|
||||
"blocks_ending_in_asm_branch": {
|
||||
// "light-merge!": [1, 2, 3, 5, 7],
|
||||
"sqlpipe-query": [21],
|
||||
"(method 9 editable-region)": [63],
|
||||
"find-nearest-entity": [7, 9],
|
||||
// collide-shape
|
||||
"(method 42 collide-shape)": [0, 1, 2, 3, 4, 7],
|
||||
"(method 18 collide-shape-prim-mesh)": [2, 3, 4, 5, 6, 7],
|
||||
"(method 12 collide-shape-prim-sphere)": [
|
||||
1, 2, 3, 4, 5, 8, 10, 11, 13, 14, 15
|
||||
],
|
||||
"(method 12 collide-shape-prim-mesh)": [
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 15, 16
|
||||
],
|
||||
// collide-mesh
|
||||
"(method 11 collide-mesh)": [2, 4],
|
||||
"(method 12 collide-mesh-cache)": [0, 1, 2, 3, 4, 5],
|
||||
"(method 10 collide-mesh)": [2]
|
||||
},
|
||||
|
||||
// Sometimes the game might use format strings that are fetched dynamically,
|
||||
// for example using the game text lookup method
|
||||
// Add information about those format instructions here.
|
||||
// e.g. "function-name":[[op, argc], [op, argc], ...]
|
||||
// where "op" is the op number for the call to format.
|
||||
"dynamic_format_arg_counts": {
|
||||
// "auto-save-post": [[182, 1]],
|
||||
},
|
||||
|
||||
"dynamic_format_arg_counts": {},
|
||||
"mips2c_functions_by_name": [
|
||||
// "collide-do-primitives",
|
||||
// collide-cache
|
||||
"(method 9 collide-cache-prim)",
|
||||
"(method 10 collide-cache-prim)",
|
||||
"(method 17 collide-cache)",
|
||||
// collide-mesh
|
||||
"(method 12 collide-mesh)",
|
||||
"(method 14 collide-mesh)",
|
||||
"(method 15 collide-mesh)",
|
||||
// shadow
|
||||
"shadow-execute",
|
||||
"shadow-add-double-edges",
|
||||
"shadow-add-single-edges",
|
||||
"shadow-add-facing-single-tris",
|
||||
"shadow-add-double-tris",
|
||||
"shadow-xform-verts",
|
||||
"shadow-calc-dual-verts",
|
||||
"shadow-scissor-edges",
|
||||
"shadow-scissor-top",
|
||||
"shadow-init-vars",
|
||||
"shadow-find-facing-single-tris",
|
||||
"shadow-find-single-edges",
|
||||
"shadow-find-facing-double-tris",
|
||||
"shadow-find-double-edges",
|
||||
"shadow-add-verts",
|
||||
"shadow-add-single-tris",
|
||||
// foreground
|
||||
"foreground-check-longest-edge-asm",
|
||||
"foreground-merc",
|
||||
// merc-blend-shape
|
||||
"blerc-a-fragment",
|
||||
"blerc-execute"
|
||||
],
|
||||
|
||||
"mips2c_jump_table_functions": {},
|
||||
|
||||
// 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": [
|
||||
// ["wasintro", 0, 0],
|
||||
],
|
||||
|
||||
"missing_textures": [],
|
||||
// some object files have garbage pad data at the end which makes the decompiler
|
||||
// assume they must be different files, such as the art group for orb-cache-top.
|
||||
// this just suppresses a message.
|
||||
|
||||
@@ -9,377 +9,377 @@
|
||||
// you want to run on the entire game.
|
||||
"dgo_names": [
|
||||
// engine files
|
||||
"CGO/ART.CGO",
|
||||
"CGO/COMMON.CGO",
|
||||
"CGO/ENGINE.CGO",
|
||||
// "CGO/ART.CGO",
|
||||
// "CGO/COMMON.CGO",
|
||||
// "CGO/ENGINE.CGO",
|
||||
"CGO/KERNEL.CGO",
|
||||
"CGO/GAME.CGO"
|
||||
// "DGO/ASHCRED.DGO",
|
||||
// "DGO/ASHLEV.DGO",
|
||||
// "DGO/ASHVL.DGO",
|
||||
// "DGO/ASHVL2.DGO",
|
||||
// "DGO/ASHVL3.DGO",
|
||||
// "DGO/ATL.DGO",
|
||||
// "DGO/ATOLLART.DGO",
|
||||
// "DGO/ATOLLCTF.DGO",
|
||||
// "DGO/ATOLLS.DGO",
|
||||
// "DGO/ATOPLOW.DGO",
|
||||
// "DGO/ATX.DGO",
|
||||
// "DGO/BEARL.DGO",
|
||||
// "DGO/BOBCL.DGO",
|
||||
// "DGO/BRDROOM.DGO",
|
||||
// "DGO/BRDROOMF.DGO",
|
||||
// "DGO/CANFOOT.DGO",
|
||||
// "DGO/CANSPARS.DGO",
|
||||
// "DGO/CANSPARW.DGO",
|
||||
// "DGO/CANTBOX.DGO",
|
||||
// "DGO/CANYONS.DGO",
|
||||
// "DGO/CANYONTT.DGO",
|
||||
// "DGO/CANYONW.DGO",
|
||||
// "DGO/CARS.DGO",
|
||||
// "DGO/CHEEL.DGO",
|
||||
// "DGO/CLF.DGO",
|
||||
// "DGO/CLFX.DGO",
|
||||
// "DGO/CLIFCTF.DGO",
|
||||
// "DGO/CLIFFART.DGO",
|
||||
// "DGO/CLIFFSS.DGO",
|
||||
// "DGO/CLIFHUNT.DGO",
|
||||
// "DGO/CLIFTRN.DGO",
|
||||
// "DGO/CNSPFOOT.DGO",
|
||||
// "DGO/CNSPTBOX.DGO",
|
||||
// "DGO/CNSPTT.DGO",
|
||||
// "DGO/COL.DGO",
|
||||
// "DGO/COLART.DGO",
|
||||
// "DGO/COLICLCT.DGO",
|
||||
// "DGO/COLICTF.DGO",
|
||||
// "DGO/COLIREV.DGO",
|
||||
// "DGO/COLISEUS.DGO",
|
||||
// "DGO/COLX.DGO",
|
||||
// "DGO/COUGL.DGO",
|
||||
// "DGO/CREDITS.DGO",
|
||||
// "DGO/CSX.DGO",
|
||||
// "DGO/CSY.DGO",
|
||||
// "DGO/CYA.DGO",
|
||||
// "DGO/CYB.DGO",
|
||||
// "DGO/CYC.DGO",
|
||||
// "DGO/CYD.DGO",
|
||||
// "DGO/CYE.DGO",
|
||||
// "DGO/CYX.DGO",
|
||||
// "DGO/CYY.DGO",
|
||||
// "DGO/DAXCRED.DGO",
|
||||
// "DGO/DAXLEV.DGO",
|
||||
// "DGO/DAXTL.DGO",
|
||||
// "DGO/DESACTF.DGO",
|
||||
// "DGO/DESARENS.DGO",
|
||||
// "DGO/DESART.DGO",
|
||||
// "DGO/DESCLCT.DGO",
|
||||
// "DGO/DESHUNT.DGO",
|
||||
// "DGO/DESHUNT2.DGO",
|
||||
// "DGO/DESISLES.DGO",
|
||||
// "DGO/DESRAPT.DGO",
|
||||
// "DGO/DESREV.DGO",
|
||||
// "DGO/DETHRACE.DGO",
|
||||
// "DGO/DISLEART.DGO",
|
||||
// "DGO/DISLECTF.DGO",
|
||||
// "DGO/DKA.DGO",
|
||||
// "DGO/DKB.DGO",
|
||||
// "DGO/DKC.DGO",
|
||||
// "DGO/DKD.DGO",
|
||||
// "DGO/DKE.DGO",
|
||||
// "DGO/DKKRFOOT.DGO",
|
||||
// "DGO/DKKRTBOX.DGO",
|
||||
// "DGO/DKKRTT.DGO",
|
||||
// "DGO/DKKX.DGO",
|
||||
// "DGO/DKKY.DGO",
|
||||
// "DGO/DKX.DGO",
|
||||
// "DGO/DOCKFOOT.DGO",
|
||||
// "DGO/DOCKKRAS.DGO",
|
||||
// "DGO/DOCKKRAW.DGO",
|
||||
// "DGO/DOCKSS.DGO",
|
||||
// "DGO/DOCKSTT.DGO",
|
||||
// "DGO/DOCKSW.DGO",
|
||||
// "DGO/DOCKTBOX.DGO",
|
||||
// "DGO/DRA.DGO",
|
||||
// "DGO/DRB.DGO",
|
||||
// "DGO/DRC.DGO",
|
||||
// "DGO/DRD.DGO",
|
||||
// "DGO/DRDKFOOT.DGO",
|
||||
// "DGO/DRDKTBOX.DGO",
|
||||
// "DGO/DRDKTT.DGO",
|
||||
// "DGO/DRDX.DGO",
|
||||
// "DGO/DRDY.DGO",
|
||||
// "DGO/DROMDOCS.DGO",
|
||||
// "DGO/DROMDOCW.DGO",
|
||||
// "DGO/DROMES.DGO",
|
||||
// "DGO/DROMETT.DGO",
|
||||
// "DGO/DROMEW.DGO",
|
||||
// "DGO/DROMEX.DGO",
|
||||
// "DGO/DROMFOOT.DGO",
|
||||
// "DGO/DROMTBOX.DGO",
|
||||
// "DGO/DRONE.DGO",
|
||||
// "DGO/DRX.DGO",
|
||||
// "DGO/DRY.DGO",
|
||||
// "DGO/DSI.DGO",
|
||||
// "DGO/DSR.DGO",
|
||||
// "DGO/DSRX.DGO",
|
||||
// "DGO/DSX.DGO",
|
||||
// "DGO/EIGHT.DGO",
|
||||
// "DGO/EIGHTB.DGO",
|
||||
// "DGO/FALCL.DGO",
|
||||
// "DGO/FMVLEV.DGO",
|
||||
// "DGO/FOXL.DGO",
|
||||
// "DGO/GARAGE.DGO",
|
||||
// "DGO/GARAGEB.DGO",
|
||||
// "DGO/GILAL.DGO",
|
||||
// "DGO/GTBCRED.DGO",
|
||||
// "DGO/GTBLEV.DGO",
|
||||
// "DGO/GTBVL.DGO",
|
||||
// "DGO/HAVENS.DGO",
|
||||
// "DGO/HAVENW.DGO",
|
||||
// "DGO/HAVJUNGS.DGO",
|
||||
// "DGO/HAVJUNGW.DGO",
|
||||
// "DGO/HAVNFOOT.DGO",
|
||||
// "DGO/HAVNTBOX.DGO",
|
||||
// "DGO/HAVSEWS.DGO",
|
||||
// "DGO/HAVSEWW.DGO",
|
||||
// "DGO/HAVTFOOT.DGO",
|
||||
// "DGO/HAVTOURS.DGO",
|
||||
// "DGO/HAVTOURW.DGO",
|
||||
// "DGO/HAVTT.DGO",
|
||||
// "DGO/HAVTTBOX.DGO",
|
||||
// "DGO/HJNGFOOT.DGO",
|
||||
// "DGO/HJX.DGO",
|
||||
// "DGO/HJY.DGO",
|
||||
// "DGO/HSX.DGO",
|
||||
// "DGO/HSY.DGO",
|
||||
// "DGO/HVA.DGO",
|
||||
// "DGO/HVB.DGO",
|
||||
// "DGO/HVC.DGO",
|
||||
// "DGO/HVD.DGO",
|
||||
// "DGO/HVE.DGO",
|
||||
// "DGO/HVJGTBOX.DGO",
|
||||
// "DGO/HVJGTT.DGO",
|
||||
// "DGO/HVSWFOOT.DGO",
|
||||
// "DGO/HVSWTBOX.DGO",
|
||||
// "DGO/HVSWTT.DGO",
|
||||
// "DGO/HVTRTT.DGO",
|
||||
// "DGO/HVX.DGO",
|
||||
// "DGO/HVY.DGO",
|
||||
// "DGO/IBX.DGO",
|
||||
// "DGO/IBY.DGO",
|
||||
// "DGO/ICA.DGO",
|
||||
// "DGO/ICB.DGO",
|
||||
// "DGO/ICBGTT.DGO",
|
||||
// "DGO/ICC.DGO",
|
||||
// "DGO/ICD.DGO",
|
||||
// "DGO/ICEBERGS.DGO",
|
||||
// "DGO/ICEBERGW.DGO",
|
||||
// "DGO/ICEBFOOT.DGO",
|
||||
// "DGO/ICEBTBOX.DGO",
|
||||
// "DGO/ICEFOOT.DGO",
|
||||
// "DGO/ICEPASSS.DGO",
|
||||
// "DGO/ICEPASSW.DGO",
|
||||
// "DGO/ICEPFOOT.DGO",
|
||||
// "DGO/ICEPTBOX.DGO",
|
||||
// "DGO/ICES.DGO",
|
||||
// "DGO/ICETBOX.DGO",
|
||||
// "DGO/ICETFOOT.DGO",
|
||||
// "DGO/ICETOURS.DGO",
|
||||
// "DGO/ICETOURW.DGO",
|
||||
// "DGO/ICETRN.DGO",
|
||||
// "DGO/ICETT.DGO",
|
||||
// "DGO/ICETTBOX.DGO",
|
||||
// "DGO/ICEW.DGO",
|
||||
// "DGO/ICPSTT.DGO",
|
||||
// "DGO/ICTRTT.DGO",
|
||||
// "DGO/ICX.DGO",
|
||||
// "DGO/ICY.DGO",
|
||||
// "DGO/IPX.DGO",
|
||||
// "DGO/IPY.DGO",
|
||||
// "DGO/JAKCRED.DGO",
|
||||
// "DGO/JAKLEV.DGO",
|
||||
// "DGO/JAKVL.DGO",
|
||||
// "DGO/JGA.DGO",
|
||||
// "DGO/JGB.DGO",
|
||||
// "DGO/JGC.DGO",
|
||||
// "DGO/JGD.DGO",
|
||||
// "DGO/JGE.DGO",
|
||||
// "DGO/JGF.DGO",
|
||||
// "DGO/JGG.DGO",
|
||||
// "DGO/JGX.DGO",
|
||||
// "DGO/JGY.DGO",
|
||||
// "DGO/JKALEV.DGO",
|
||||
// "DGO/JKBLEV.DGO",
|
||||
// "DGO/JKCLEV.DGO",
|
||||
// "DGO/JUNGFOOT.DGO",
|
||||
// "DGO/JUNGLES.DGO",
|
||||
// "DGO/JUNGLETT.DGO",
|
||||
// "DGO/JUNGLEW.DGO",
|
||||
// "DGO/JUNGTBOX.DGO",
|
||||
// "DGO/JUNGTRN.DGO",
|
||||
// "DGO/KAELEV.DGO",
|
||||
// "DGO/KCR.DGO",
|
||||
// "DGO/KCROSART.DGO",
|
||||
// "DGO/KCROSCTF.DGO",
|
||||
// "DGO/KCROSSS.DGO",
|
||||
// "DGO/KCRSCLCT.DGO",
|
||||
// "DGO/KCRSPLOW.DGO",
|
||||
// "DGO/KCRX.DGO",
|
||||
// "DGO/KEICRED.DGO",
|
||||
// "DGO/KIELEV.DGO",
|
||||
// "DGO/KIEVL.DGO",
|
||||
// "DGO/KLECRED.DGO",
|
||||
// "DGO/KLELEV.DGO",
|
||||
// "DGO/KLEVL.DGO",
|
||||
// "DGO/KLEVL2.DGO",
|
||||
// "DGO/KRA.DGO",
|
||||
// "DGO/KRASFOOT.DGO",
|
||||
// "DGO/KRASS.DGO",
|
||||
// "DGO/KRASTBOX.DGO",
|
||||
// "DGO/KRASTRN.DGO",
|
||||
// "DGO/KRASTT.DGO",
|
||||
// "DGO/KRASW.DGO",
|
||||
// "DGO/KRATFOOT.DGO",
|
||||
// "DGO/KRATOURS.DGO",
|
||||
// "DGO/KRATOURW.DGO",
|
||||
// "DGO/KRATTBOX.DGO",
|
||||
// "DGO/KRB.DGO",
|
||||
// "DGO/KRC.DGO",
|
||||
// "DGO/KRTRTT.DGO",
|
||||
// "DGO/KRX.DGO",
|
||||
// "DGO/KRY.DGO",
|
||||
// "DGO/LEOPL.DGO",
|
||||
// "DGO/MENU2.DGO",
|
||||
// "DGO/MENUMAP.DGO",
|
||||
// "DGO/MONGL.DGO",
|
||||
// "DGO/OSMLEV.DGO",
|
||||
// "DGO/PANTL.DGO",
|
||||
// "DGO/PEAKFOOT.DGO",
|
||||
// "DGO/PEAKS.DGO",
|
||||
// "DGO/PEAKTBOX.DGO",
|
||||
// "DGO/PEAKTT.DGO",
|
||||
// "DGO/PEAKW.DGO",
|
||||
// "DGO/PECCRED.DGO",
|
||||
// "DGO/PECLEV.DGO",
|
||||
// "DGO/PECVL.DGO",
|
||||
// "DGO/PKA.DGO",
|
||||
// "DGO/PKB.DGO",
|
||||
// "DGO/PKC.DGO",
|
||||
// "DGO/PKD.DGO",
|
||||
// "DGO/PKE.DGO",
|
||||
// "DGO/PKX.DGO",
|
||||
// "DGO/POSSL.DGO",
|
||||
// "DGO/RACEWEAP.DGO",
|
||||
// "DGO/RATLEV.DGO",
|
||||
// "DGO/RAYCRED.DGO",
|
||||
// "DGO/RAYLEV.DGO",
|
||||
// "DGO/RAYVL.DGO",
|
||||
// "DGO/RAYVL2.DGO",
|
||||
// "DGO/RAZCRED.DGO",
|
||||
// "DGO/RAZLEV.DGO",
|
||||
// "DGO/RAZVL.DGO",
|
||||
// "DGO/RTH.DGO",
|
||||
// "DGO/RUSTYH.DGO",
|
||||
// "DGO/S2A.DGO",
|
||||
// "DGO/S3A.DGO",
|
||||
// "DGO/SBWLCTF.DGO",
|
||||
// "DGO/SEWERS.DGO",
|
||||
// "DGO/SEWERTT.DGO",
|
||||
// "DGO/SEWERW.DGO",
|
||||
// "DGO/SEWFOOT.DGO",
|
||||
// "DGO/SEWTBOX.DGO",
|
||||
// "DGO/SIGCRED.DGO",
|
||||
// "DGO/SIGLEV.DGO",
|
||||
// "DGO/SIGVL.DGO",
|
||||
// "DGO/SIGVL2.DGO",
|
||||
// "DGO/SIGVL3.DGO",
|
||||
// "DGO/SNAKL.DGO",
|
||||
// "DGO/SNO.DGO",
|
||||
// "DGO/SNOBART.DGO",
|
||||
// "DGO/SNOBOWLS.DGO",
|
||||
// "DGO/SNOWFOOT.DGO",
|
||||
// "DGO/SNOWS.DGO",
|
||||
// "DGO/SNOWTBOX.DGO",
|
||||
// "DGO/SNOWTRN2.DGO",
|
||||
// "DGO/SNOWTT.DGO",
|
||||
// "DGO/SNOX.DGO",
|
||||
// "DGO/SNW.DGO",
|
||||
// "DGO/SNWX.DGO",
|
||||
// "DGO/SPA.DGO",
|
||||
// "DGO/SPARFOOT.DGO",
|
||||
// "DGO/SPARGUSS.DGO",
|
||||
// "DGO/SPARGUSW.DGO",
|
||||
// "DGO/SPARTEMS.DGO",
|
||||
// "DGO/SPARTEMW.DGO",
|
||||
// "DGO/SPARTT.DGO",
|
||||
// "DGO/SPATFOOT.DGO",
|
||||
// "DGO/SPATOURS.DGO",
|
||||
// "DGO/SPATOURW.DGO",
|
||||
// "DGO/SPATTBOX.DGO",
|
||||
// "DGO/SPB.DGO",
|
||||
// "DGO/SPC.DGO",
|
||||
// "DGO/SPD.DGO",
|
||||
// "DGO/SPE.DGO",
|
||||
// "DGO/SPRGSTBX.DGO",
|
||||
// "DGO/SPTMFOOT.DGO",
|
||||
// "DGO/SPTMTBOX.DGO",
|
||||
// "DGO/SPTMTT.DGO",
|
||||
// "DGO/SPTRTT.DGO",
|
||||
// "DGO/SPX.DGO",
|
||||
// "DGO/SPY.DGO",
|
||||
// "DGO/STX.DGO",
|
||||
// "DGO/STY.DGO",
|
||||
// "DGO/SWA.DGO",
|
||||
// "DGO/SWB.DGO",
|
||||
// "DGO/SWC.DGO",
|
||||
// "DGO/SWD.DGO",
|
||||
// "DGO/SWE.DGO",
|
||||
// "DGO/SWF.DGO",
|
||||
// "DGO/SWX.DGO",
|
||||
// "DGO/TARLEV.DGO",
|
||||
// "DGO/TEMPFOOT.DGO",
|
||||
// "DGO/TEMPLES.DGO",
|
||||
// "DGO/TEMPLETT.DGO",
|
||||
// "DGO/TEMPLEW.DGO",
|
||||
// "DGO/TEMPTBOX.DGO",
|
||||
// "DGO/THACRED.DGO",
|
||||
// "DGO/THALEV.DGO",
|
||||
// "DGO/THAVL.DGO",
|
||||
// "DGO/THAVL2.DGO",
|
||||
// "DGO/THAVL3.DGO",
|
||||
// "DGO/THBCRED.DGO",
|
||||
// "DGO/THBLEV.DGO",
|
||||
// "DGO/THBVL.DGO",
|
||||
// "DGO/THBVL2.DGO",
|
||||
// "DGO/THBVL3.DGO",
|
||||
// "DGO/THCCRED.DGO",
|
||||
// "DGO/THCLEV.DGO",
|
||||
// "DGO/THCVL.DGO",
|
||||
// "DGO/THCVL2.DGO",
|
||||
// "DGO/THCVL3.DGO",
|
||||
// "DGO/TIGEL.DGO",
|
||||
// "DGO/TOADL.DGO",
|
||||
// "DGO/TORCRED.DGO",
|
||||
// "DGO/TORLEV.DGO",
|
||||
// "DGO/TORVL.DGO",
|
||||
// "DGO/TORVL2.DGO",
|
||||
// "DGO/TORVL3.DGO",
|
||||
// "DGO/TPA.DGO",
|
||||
// "DGO/TPB.DGO",
|
||||
// "DGO/TPC.DGO",
|
||||
// "DGO/TPD.DGO",
|
||||
// "DGO/TPE.DGO",
|
||||
// "DGO/TPX.DGO",
|
||||
// "DGO/TPY.DGO",
|
||||
// "DGO/TURTL.DGO",
|
||||
// "DGO/UR8CRED.DGO",
|
||||
// "DGO/UR8LEV.DGO",
|
||||
// "DGO/UR8VL.DGO",
|
||||
// "DGO/UR8VL2.DGO",
|
||||
// "DGO/UR8VL3.DGO",
|
||||
// "DGO/WOLFL.DGO",
|
||||
// "DGO/WOMBL.DGO",
|
||||
// "DGO/XIMLEV.DGO"
|
||||
"CGO/GAME.CGO",
|
||||
"DGO/ASHCRED.DGO",
|
||||
"DGO/ASHLEV.DGO",
|
||||
"DGO/ASHVL.DGO",
|
||||
"DGO/ASHVL2.DGO",
|
||||
"DGO/ASHVL3.DGO",
|
||||
"DGO/ATL.DGO",
|
||||
"DGO/ATOLLART.DGO",
|
||||
"DGO/ATOLLCTF.DGO",
|
||||
"DGO/ATOLLS.DGO",
|
||||
"DGO/ATOPLOW.DGO",
|
||||
"DGO/ATX.DGO",
|
||||
"DGO/BEARL.DGO",
|
||||
"DGO/BOBCL.DGO",
|
||||
"DGO/BRDROOM.DGO",
|
||||
"DGO/BRDROOMF.DGO",
|
||||
"DGO/CANFOOT.DGO",
|
||||
"DGO/CANSPARS.DGO",
|
||||
"DGO/CANSPARW.DGO",
|
||||
"DGO/CANTBOX.DGO",
|
||||
"DGO/CANYONS.DGO",
|
||||
"DGO/CANYONTT.DGO",
|
||||
"DGO/CANYONW.DGO",
|
||||
"DGO/CARS.DGO",
|
||||
"DGO/CHEEL.DGO",
|
||||
"DGO/CLF.DGO",
|
||||
"DGO/CLFX.DGO",
|
||||
"DGO/CLIFCTF.DGO",
|
||||
"DGO/CLIFFART.DGO",
|
||||
"DGO/CLIFFSS.DGO",
|
||||
"DGO/CLIFHUNT.DGO",
|
||||
"DGO/CLIFTRN.DGO",
|
||||
"DGO/CNSPFOOT.DGO",
|
||||
"DGO/CNSPTBOX.DGO",
|
||||
"DGO/CNSPTT.DGO",
|
||||
"DGO/COL.DGO",
|
||||
"DGO/COLART.DGO",
|
||||
"DGO/COLICLCT.DGO",
|
||||
"DGO/COLICTF.DGO",
|
||||
"DGO/COLIREV.DGO",
|
||||
"DGO/COLISEUS.DGO",
|
||||
"DGO/COLX.DGO",
|
||||
"DGO/COUGL.DGO",
|
||||
"DGO/CREDITS.DGO",
|
||||
"DGO/CSX.DGO",
|
||||
"DGO/CSY.DGO",
|
||||
"DGO/CYA.DGO",
|
||||
"DGO/CYB.DGO",
|
||||
"DGO/CYC.DGO",
|
||||
"DGO/CYD.DGO",
|
||||
"DGO/CYE.DGO",
|
||||
"DGO/CYX.DGO",
|
||||
"DGO/CYY.DGO",
|
||||
"DGO/DAXCRED.DGO",
|
||||
"DGO/DAXLEV.DGO",
|
||||
"DGO/DAXTL.DGO",
|
||||
"DGO/DESACTF.DGO",
|
||||
"DGO/DESARENS.DGO",
|
||||
"DGO/DESART.DGO",
|
||||
"DGO/DESCLCT.DGO",
|
||||
"DGO/DESHUNT.DGO",
|
||||
"DGO/DESHUNT2.DGO",
|
||||
"DGO/DESISLES.DGO",
|
||||
"DGO/DESRAPT.DGO",
|
||||
"DGO/DESREV.DGO",
|
||||
"DGO/DETHRACE.DGO",
|
||||
"DGO/DISLEART.DGO",
|
||||
"DGO/DISLECTF.DGO",
|
||||
"DGO/DKA.DGO",
|
||||
"DGO/DKB.DGO",
|
||||
"DGO/DKC.DGO",
|
||||
"DGO/DKD.DGO",
|
||||
"DGO/DKE.DGO",
|
||||
"DGO/DKKRFOOT.DGO",
|
||||
"DGO/DKKRTBOX.DGO",
|
||||
"DGO/DKKRTT.DGO",
|
||||
"DGO/DKKX.DGO",
|
||||
"DGO/DKKY.DGO",
|
||||
"DGO/DKX.DGO",
|
||||
"DGO/DOCKFOOT.DGO",
|
||||
"DGO/DOCKKRAS.DGO",
|
||||
"DGO/DOCKKRAW.DGO",
|
||||
"DGO/DOCKSS.DGO",
|
||||
"DGO/DOCKSTT.DGO",
|
||||
"DGO/DOCKSW.DGO",
|
||||
"DGO/DOCKTBOX.DGO",
|
||||
"DGO/DRA.DGO",
|
||||
"DGO/DRB.DGO",
|
||||
"DGO/DRC.DGO",
|
||||
"DGO/DRD.DGO",
|
||||
"DGO/DRDKFOOT.DGO",
|
||||
"DGO/DRDKTBOX.DGO",
|
||||
"DGO/DRDKTT.DGO",
|
||||
"DGO/DRDX.DGO",
|
||||
"DGO/DRDY.DGO",
|
||||
"DGO/DROMDOCS.DGO",
|
||||
"DGO/DROMDOCW.DGO",
|
||||
"DGO/DROMES.DGO",
|
||||
"DGO/DROMETT.DGO",
|
||||
"DGO/DROMEW.DGO",
|
||||
"DGO/DROMEX.DGO",
|
||||
"DGO/DROMFOOT.DGO",
|
||||
"DGO/DROMTBOX.DGO",
|
||||
"DGO/DRONE.DGO",
|
||||
"DGO/DRX.DGO",
|
||||
"DGO/DRY.DGO",
|
||||
"DGO/DSI.DGO",
|
||||
"DGO/DSR.DGO",
|
||||
"DGO/DSRX.DGO",
|
||||
"DGO/DSX.DGO",
|
||||
"DGO/EIGHT.DGO",
|
||||
"DGO/EIGHTB.DGO",
|
||||
"DGO/FALCL.DGO",
|
||||
"DGO/FMVLEV.DGO",
|
||||
"DGO/FOXL.DGO",
|
||||
"DGO/GARAGE.DGO",
|
||||
"DGO/GARAGEB.DGO",
|
||||
"DGO/GILAL.DGO",
|
||||
"DGO/GTBCRED.DGO",
|
||||
"DGO/GTBLEV.DGO",
|
||||
"DGO/GTBVL.DGO",
|
||||
"DGO/HAVENS.DGO",
|
||||
"DGO/HAVENW.DGO",
|
||||
"DGO/HAVJUNGS.DGO",
|
||||
"DGO/HAVJUNGW.DGO",
|
||||
"DGO/HAVNFOOT.DGO",
|
||||
"DGO/HAVNTBOX.DGO",
|
||||
"DGO/HAVSEWS.DGO",
|
||||
"DGO/HAVSEWW.DGO",
|
||||
"DGO/HAVTFOOT.DGO",
|
||||
"DGO/HAVTOURS.DGO",
|
||||
"DGO/HAVTOURW.DGO",
|
||||
"DGO/HAVTT.DGO",
|
||||
"DGO/HAVTTBOX.DGO",
|
||||
"DGO/HJNGFOOT.DGO",
|
||||
"DGO/HJX.DGO",
|
||||
"DGO/HJY.DGO",
|
||||
"DGO/HSX.DGO",
|
||||
"DGO/HSY.DGO",
|
||||
"DGO/HVA.DGO",
|
||||
"DGO/HVB.DGO",
|
||||
"DGO/HVC.DGO",
|
||||
"DGO/HVD.DGO",
|
||||
"DGO/HVE.DGO",
|
||||
"DGO/HVJGTBOX.DGO",
|
||||
"DGO/HVJGTT.DGO",
|
||||
"DGO/HVSWFOOT.DGO",
|
||||
"DGO/HVSWTBOX.DGO",
|
||||
"DGO/HVSWTT.DGO",
|
||||
"DGO/HVTRTT.DGO",
|
||||
"DGO/HVX.DGO",
|
||||
"DGO/HVY.DGO",
|
||||
"DGO/IBX.DGO",
|
||||
"DGO/IBY.DGO",
|
||||
"DGO/ICA.DGO",
|
||||
"DGO/ICB.DGO",
|
||||
"DGO/ICBGTT.DGO",
|
||||
"DGO/ICC.DGO",
|
||||
"DGO/ICD.DGO",
|
||||
"DGO/ICEBERGS.DGO",
|
||||
"DGO/ICEBERGW.DGO",
|
||||
"DGO/ICEBFOOT.DGO",
|
||||
"DGO/ICEBTBOX.DGO",
|
||||
"DGO/ICEFOOT.DGO",
|
||||
"DGO/ICEPASSS.DGO",
|
||||
"DGO/ICEPASSW.DGO",
|
||||
"DGO/ICEPFOOT.DGO",
|
||||
"DGO/ICEPTBOX.DGO",
|
||||
"DGO/ICES.DGO",
|
||||
"DGO/ICETBOX.DGO",
|
||||
"DGO/ICETFOOT.DGO",
|
||||
"DGO/ICETOURS.DGO",
|
||||
"DGO/ICETOURW.DGO",
|
||||
"DGO/ICETRN.DGO",
|
||||
"DGO/ICETT.DGO",
|
||||
"DGO/ICETTBOX.DGO",
|
||||
"DGO/ICEW.DGO",
|
||||
"DGO/ICPSTT.DGO",
|
||||
"DGO/ICTRTT.DGO",
|
||||
"DGO/ICX.DGO",
|
||||
"DGO/ICY.DGO",
|
||||
"DGO/IPX.DGO",
|
||||
"DGO/IPY.DGO",
|
||||
"DGO/JAKCRED.DGO",
|
||||
"DGO/JAKLEV.DGO",
|
||||
"DGO/JAKVL.DGO",
|
||||
"DGO/JGA.DGO",
|
||||
"DGO/JGB.DGO",
|
||||
"DGO/JGC.DGO",
|
||||
"DGO/JGD.DGO",
|
||||
"DGO/JGE.DGO",
|
||||
"DGO/JGF.DGO",
|
||||
"DGO/JGG.DGO",
|
||||
"DGO/JGX.DGO",
|
||||
"DGO/JGY.DGO",
|
||||
"DGO/JKALEV.DGO",
|
||||
"DGO/JKBLEV.DGO",
|
||||
"DGO/JKCLEV.DGO",
|
||||
"DGO/JUNGFOOT.DGO",
|
||||
"DGO/JUNGLES.DGO",
|
||||
"DGO/JUNGLETT.DGO",
|
||||
"DGO/JUNGLEW.DGO",
|
||||
"DGO/JUNGTBOX.DGO",
|
||||
"DGO/JUNGTRN.DGO",
|
||||
"DGO/KAELEV.DGO",
|
||||
"DGO/KCR.DGO",
|
||||
"DGO/KCROSART.DGO",
|
||||
"DGO/KCROSCTF.DGO",
|
||||
"DGO/KCROSSS.DGO",
|
||||
"DGO/KCRSCLCT.DGO",
|
||||
"DGO/KCRSPLOW.DGO",
|
||||
"DGO/KCRX.DGO",
|
||||
"DGO/KEICRED.DGO",
|
||||
"DGO/KIELEV.DGO",
|
||||
"DGO/KIEVL.DGO",
|
||||
"DGO/KLECRED.DGO",
|
||||
"DGO/KLELEV.DGO",
|
||||
"DGO/KLEVL.DGO",
|
||||
"DGO/KLEVL2.DGO",
|
||||
"DGO/KRA.DGO",
|
||||
"DGO/KRASFOOT.DGO",
|
||||
"DGO/KRASS.DGO",
|
||||
"DGO/KRASTBOX.DGO",
|
||||
"DGO/KRASTRN.DGO",
|
||||
"DGO/KRASTT.DGO",
|
||||
"DGO/KRASW.DGO",
|
||||
"DGO/KRATFOOT.DGO",
|
||||
"DGO/KRATOURS.DGO",
|
||||
"DGO/KRATOURW.DGO",
|
||||
"DGO/KRATTBOX.DGO",
|
||||
"DGO/KRB.DGO",
|
||||
"DGO/KRC.DGO",
|
||||
"DGO/KRTRTT.DGO",
|
||||
"DGO/KRX.DGO",
|
||||
"DGO/KRY.DGO",
|
||||
"DGO/LEOPL.DGO",
|
||||
"DGO/MENU2.DGO",
|
||||
"DGO/MENUMAP.DGO",
|
||||
"DGO/MONGL.DGO",
|
||||
"DGO/OSMLEV.DGO",
|
||||
"DGO/PANTL.DGO",
|
||||
"DGO/PEAKFOOT.DGO",
|
||||
"DGO/PEAKS.DGO",
|
||||
"DGO/PEAKTBOX.DGO",
|
||||
"DGO/PEAKTT.DGO",
|
||||
"DGO/PEAKW.DGO",
|
||||
"DGO/PECCRED.DGO",
|
||||
"DGO/PECLEV.DGO",
|
||||
"DGO/PECVL.DGO",
|
||||
"DGO/PKA.DGO",
|
||||
"DGO/PKB.DGO",
|
||||
"DGO/PKC.DGO",
|
||||
"DGO/PKD.DGO",
|
||||
"DGO/PKE.DGO",
|
||||
"DGO/PKX.DGO",
|
||||
"DGO/POSSL.DGO",
|
||||
"DGO/RACEWEAP.DGO",
|
||||
"DGO/RATLEV.DGO",
|
||||
"DGO/RAYCRED.DGO",
|
||||
"DGO/RAYLEV.DGO",
|
||||
"DGO/RAYVL.DGO",
|
||||
"DGO/RAYVL2.DGO",
|
||||
"DGO/RAZCRED.DGO",
|
||||
"DGO/RAZLEV.DGO",
|
||||
"DGO/RAZVL.DGO",
|
||||
"DGO/RTH.DGO",
|
||||
"DGO/RUSTYH.DGO",
|
||||
"DGO/S2A.DGO",
|
||||
"DGO/S3A.DGO",
|
||||
"DGO/SBWLCTF.DGO",
|
||||
"DGO/SEWERS.DGO",
|
||||
"DGO/SEWERTT.DGO",
|
||||
"DGO/SEWERW.DGO",
|
||||
"DGO/SEWFOOT.DGO",
|
||||
"DGO/SEWTBOX.DGO",
|
||||
"DGO/SIGCRED.DGO",
|
||||
"DGO/SIGLEV.DGO",
|
||||
"DGO/SIGVL.DGO",
|
||||
"DGO/SIGVL2.DGO",
|
||||
"DGO/SIGVL3.DGO",
|
||||
"DGO/SNAKL.DGO",
|
||||
"DGO/SNO.DGO",
|
||||
"DGO/SNOBART.DGO",
|
||||
"DGO/SNOBOWLS.DGO",
|
||||
"DGO/SNOWFOOT.DGO",
|
||||
"DGO/SNOWS.DGO",
|
||||
"DGO/SNOWTBOX.DGO",
|
||||
"DGO/SNOWTRN2.DGO",
|
||||
"DGO/SNOWTT.DGO",
|
||||
"DGO/SNOX.DGO",
|
||||
"DGO/SNW.DGO",
|
||||
"DGO/SNWX.DGO",
|
||||
"DGO/SPA.DGO",
|
||||
"DGO/SPARFOOT.DGO",
|
||||
"DGO/SPARGUSS.DGO",
|
||||
"DGO/SPARGUSW.DGO",
|
||||
"DGO/SPARTEMS.DGO",
|
||||
"DGO/SPARTEMW.DGO",
|
||||
"DGO/SPARTT.DGO",
|
||||
"DGO/SPATFOOT.DGO",
|
||||
"DGO/SPATOURS.DGO",
|
||||
"DGO/SPATOURW.DGO",
|
||||
"DGO/SPATTBOX.DGO",
|
||||
"DGO/SPB.DGO",
|
||||
"DGO/SPC.DGO",
|
||||
"DGO/SPD.DGO",
|
||||
"DGO/SPE.DGO",
|
||||
"DGO/SPRGSTBX.DGO",
|
||||
"DGO/SPTMFOOT.DGO",
|
||||
"DGO/SPTMTBOX.DGO",
|
||||
"DGO/SPTMTT.DGO",
|
||||
"DGO/SPTRTT.DGO",
|
||||
"DGO/SPX.DGO",
|
||||
"DGO/SPY.DGO",
|
||||
"DGO/STX.DGO",
|
||||
"DGO/STY.DGO",
|
||||
"DGO/SWA.DGO",
|
||||
"DGO/SWB.DGO",
|
||||
"DGO/SWC.DGO",
|
||||
"DGO/SWD.DGO",
|
||||
"DGO/SWE.DGO",
|
||||
"DGO/SWF.DGO",
|
||||
"DGO/SWX.DGO",
|
||||
"DGO/TARLEV.DGO",
|
||||
"DGO/TEMPFOOT.DGO",
|
||||
"DGO/TEMPLES.DGO",
|
||||
"DGO/TEMPLETT.DGO",
|
||||
"DGO/TEMPLEW.DGO",
|
||||
"DGO/TEMPTBOX.DGO",
|
||||
"DGO/THACRED.DGO",
|
||||
"DGO/THALEV.DGO",
|
||||
"DGO/THAVL.DGO",
|
||||
"DGO/THAVL2.DGO",
|
||||
"DGO/THAVL3.DGO",
|
||||
"DGO/THBCRED.DGO",
|
||||
"DGO/THBLEV.DGO",
|
||||
"DGO/THBVL.DGO",
|
||||
"DGO/THBVL2.DGO",
|
||||
"DGO/THBVL3.DGO",
|
||||
"DGO/THCCRED.DGO",
|
||||
"DGO/THCLEV.DGO",
|
||||
"DGO/THCVL.DGO",
|
||||
"DGO/THCVL2.DGO",
|
||||
"DGO/THCVL3.DGO",
|
||||
"DGO/TIGEL.DGO",
|
||||
"DGO/TOADL.DGO",
|
||||
"DGO/TORCRED.DGO",
|
||||
"DGO/TORLEV.DGO",
|
||||
"DGO/TORVL.DGO",
|
||||
"DGO/TORVL2.DGO",
|
||||
"DGO/TORVL3.DGO",
|
||||
"DGO/TPA.DGO",
|
||||
"DGO/TPB.DGO",
|
||||
"DGO/TPC.DGO",
|
||||
"DGO/TPD.DGO",
|
||||
"DGO/TPE.DGO",
|
||||
"DGO/TPX.DGO",
|
||||
"DGO/TPY.DGO",
|
||||
"DGO/TURTL.DGO",
|
||||
"DGO/UR8CRED.DGO",
|
||||
"DGO/UR8LEV.DGO",
|
||||
"DGO/UR8VL.DGO",
|
||||
"DGO/UR8VL2.DGO",
|
||||
"DGO/UR8VL3.DGO",
|
||||
"DGO/WOLFL.DGO",
|
||||
"DGO/WOMBL.DGO",
|
||||
"DGO/XIMLEV.DGO"
|
||||
],
|
||||
|
||||
"levels_to_extract": [],
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,6 +1,14 @@
|
||||
{
|
||||
// "math": [
|
||||
// ["L108", "(pointer float)", 32],
|
||||
// ["L109", "(pointer float)", 32]
|
||||
// ],
|
||||
"ambient-h": [["L1", "(inline-array talker-speech-class)", 233]],
|
||||
"pat-h": [["L1", "(inline-array pat-mode-info)", 4]],
|
||||
"foreground-h": [["L4", "(pointer bucket-id-16)", 462]],
|
||||
"texture-anim-h": [["L1", "(pointer uint8)", 256]],
|
||||
"process-nettable-h": [["L13", "(pointer uint32)", 95]],
|
||||
"math": [
|
||||
["L109", "(pointer float)", 32],
|
||||
["L108", "(pointer float)", 32]
|
||||
],
|
||||
"timer-h": [["L15", "(pointer uint32)", 12]],
|
||||
"game-task-h": [["L178", "(pointer text-id)", 24]],
|
||||
"profile": [["L3", "(inline-array profile-spec)", 13]]
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,4 +1,2 @@
|
||||
// This overrides the stack size for calls to stack-size-set! in given functions.
|
||||
{
|
||||
// "(method 29 target)": 2048,
|
||||
}
|
||||
{}
|
||||
|
||||
@@ -1,3 +1,77 @@
|
||||
{
|
||||
// "quaternion-smooth-seek!": [[16, ["inline-array", "quaternion", 2]]],
|
||||
"quaternion-smooth-seek!": [[16, ["inline-array", "quaternion", 2]]],
|
||||
"rotate-vector-to-vector": [[16, "quaternion"]],
|
||||
"nearest-dist2-between-moving-points": [[16, ["inline-array", "vector", 2]]],
|
||||
"vector-segment-xz-distance-point!": [[16, "matrix"]],
|
||||
"vector-interp-angle!": [[16, "quaternion"]],
|
||||
"vector-cap-rotation!": [[16, "quaternion"]],
|
||||
"vector-line-xz-distance-point!": [[16, "matrix"]],
|
||||
"vector-circle-tangent-new": [
|
||||
[32, "vector"],
|
||||
[48, "vector"]
|
||||
],
|
||||
"v-slrp2!": [
|
||||
[32, "vector"],
|
||||
[64, "matrix"]
|
||||
],
|
||||
"v-slrp3!": [[32, "vector"]],
|
||||
"collide-list-fill-bg-using-box": [
|
||||
[32, "matrix"],
|
||||
[96, "collide-query"]
|
||||
],
|
||||
"collide-list-fill-bg-using-line-sphere": [
|
||||
[32, "matrix"],
|
||||
[96, "collide-query"]
|
||||
],
|
||||
"(method 9 touching-list)": [[16, "add-prims-touching-work"]],
|
||||
"(method 9 curve-color-fast)": [[16, "rgbaf"]],
|
||||
"(method 9 curve2d-fast)": [
|
||||
[16, "vector"],
|
||||
[32, "vector"]
|
||||
],
|
||||
"evaluate-color-curve-fast": [[16, "vector"]],
|
||||
"evaluate-curve-fast": [
|
||||
[16, "vector"],
|
||||
[32, "vector"]
|
||||
],
|
||||
"add-debug-box-with-transform": [
|
||||
[16, ["inline-array", "vector", 8]],
|
||||
[144, ["inline-array", "vector", 2]],
|
||||
[176, "vector"]
|
||||
],
|
||||
"add-debug-curve": [
|
||||
[16, "vector"],
|
||||
[32, "vector"]
|
||||
],
|
||||
"add-debug-sphere-from-table": [
|
||||
[16, "vector"],
|
||||
[48, "vector"],
|
||||
[64, "vector"]
|
||||
],
|
||||
"make-debug-sphere-table": [
|
||||
[16, "vector"],
|
||||
[32, "vector"],
|
||||
[48, "vector"],
|
||||
[64, "vector"],
|
||||
[80, "vector"],
|
||||
[96, "vector"],
|
||||
[112, "vector"]
|
||||
],
|
||||
"eul->matrix": [[16, "vector"]],
|
||||
"joint-mod-joint-set-world-handler": [
|
||||
[32, "vector"],
|
||||
[48, "vector"]
|
||||
],
|
||||
"joint-mod-blend-world-callback": [[16, "joint-mod-blend-world-work"]],
|
||||
"(method 20 lightning-bolt)": [[16, "vector"]],
|
||||
"update-light-hash": [
|
||||
[16, "bounding-box"],
|
||||
[48, "vector"],
|
||||
[64, "vector"]
|
||||
],
|
||||
"(method 10 simple-sprite-system)": [[16, ["array", "texture-id", 128]]],
|
||||
"(method 10 cubic-curve)": [[16, "trajectory"]],
|
||||
"(method 11 cubic-curve)": [[16, "trajectory"]],
|
||||
"(method 12 cubic-curve)": [[16, "trajectory"]],
|
||||
"matrix<-parented-transformq!": [[16, "vector"]]
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,18 +1,467 @@
|
||||
{
|
||||
// "(method 2 array)": [
|
||||
// [23, "gp", "(array int32)"],
|
||||
// [43, "gp", "(array uint32)"],
|
||||
// [63, "gp", "(array int64)"],
|
||||
// [83, "gp", "(array uint64)"],
|
||||
// [102, "gp", "(array int8)"],
|
||||
// [121, "gp", "(array uint8)"],
|
||||
// [141, "gp", "(array int16)"],
|
||||
// [161, "gp", "(array uint16)"],
|
||||
// [186, "gp", "(array uint128)"],
|
||||
// [204, "gp", "(array int32)"],
|
||||
// [223, "gp", "(array float)"],
|
||||
// [232, "gp", "(array float)"],
|
||||
// [249, "gp", "(array basic)"],
|
||||
// [258, "gp", "(array basic)"]
|
||||
// ],
|
||||
"entity-actor-count": [["_stack_", 16, "res-tag"]],
|
||||
"entity-actor-lookup": [["_stack_", 16, "res-tag"]],
|
||||
"build-masks": [
|
||||
[[18, 22], "a1", "drawable-tree-tfrag"],
|
||||
[24, "a2", "drawable-inline-array-tfrag"],
|
||||
[[27, 31], "a2", "(inline-array tfragment)"],
|
||||
[[38, 42], "a1", "drawable-tree-tfrag-trans"],
|
||||
[44, "a2", "drawable-inline-array-tfrag"],
|
||||
[[47, 51], "a2", "(inline-array tfragment)"],
|
||||
[[58, 62], "a1", "drawable-tree-tfrag-water"],
|
||||
[64, "a2", "drawable-inline-array-tfrag"],
|
||||
[[67, 71], "a2", "(inline-array tfragment)"],
|
||||
[[78, 79], "a1", "drawable-tree-instance-tie"],
|
||||
[123, "a1", "drawable-tree-instance-shrub"],
|
||||
[[129, 133], "a2", "(inline-array prototype-bucket-shrub)"]
|
||||
],
|
||||
"cam-layout-function-call": [
|
||||
[15, "gp", "(function string int basic object)"]
|
||||
],
|
||||
"cam-layout-save-cam-rot": [[13, "v0", "vector"]],
|
||||
"cam-layout-save-campointsoffset": [[12, "v0", "vector"]],
|
||||
"cam-layout-save-splineoffset": [
|
||||
[37, "v0", "vector"],
|
||||
[25, "v0", "vector"]
|
||||
],
|
||||
"clmf-save-all": [[18, "v1", "connection"]],
|
||||
"execute-cam-post-hook-engine": [
|
||||
[8, "s5", "connection"],
|
||||
[[14, 17], "s5", "connection"],
|
||||
[18, "t9", "(function object object object object object)"],
|
||||
[9, "s5", "connection"]
|
||||
],
|
||||
"collide-list-fill-bg-using-box": [
|
||||
[223, "a0", "collide-hash-scratch"],
|
||||
[255, "a0", "collide-hash-scratch"],
|
||||
[208, "v1", "collide-hash-scratch"],
|
||||
[210, "v1", "collide-hash-scratch"],
|
||||
[212, "v1", "collide-hash-scratch"],
|
||||
[241, "v1", "collide-hash-scratch"],
|
||||
[243, "v1", "collide-hash-scratch"],
|
||||
[246, "v1", "collide-hash-scratch"]
|
||||
],
|
||||
"collide-list-fill-bg-using-line-sphere": [
|
||||
[287, "a0", "collide-hash-scratch"],
|
||||
[[272, 280], "v1", "collide-hash-scratch"],
|
||||
[[239, 246], "v1", "collide-hash-scratch"],
|
||||
[255, "a0", "collide-hash-scratch"],
|
||||
[102, "v1", "float"]
|
||||
],
|
||||
"(method 0 collide-shape-prim-group)": [
|
||||
[[6, 12], "v0", "collide-shape-prim-group"]
|
||||
],
|
||||
"(method 0 collide-shape-prim-mesh)": [
|
||||
[[6, 11], "v0", "collide-shape-prim-mesh"]
|
||||
],
|
||||
"(method 0 collide-shape-prim-sphere)": [
|
||||
[[5, 8], "v0", "collide-shape-prim-sphere"]
|
||||
],
|
||||
"(method 10 touching-list)": [[[5, 11], "s5", "touching-shapes-entry"]],
|
||||
"(method 11 touching-list)": [
|
||||
[8, "s5", "touching-shapes-entry"],
|
||||
[11, "s5", "touching-shapes-entry"],
|
||||
[13, "s5", "touching-shapes-entry"],
|
||||
[48, "s5", "touching-shapes-entry"],
|
||||
[52, "s5", "touching-shapes-entry"],
|
||||
[10, "s5", "touching-shapes-entry"],
|
||||
[33, "s5", "touching-shapes-entry"],
|
||||
[50, "s5", "touching-shapes-entry"]
|
||||
],
|
||||
"(method 0 touching-list)": [[[6, 8], "v0", "touching-list"]],
|
||||
"(method 11 touching-prims-entry-pool)": [
|
||||
[[0, 8], "v1", "touching-prims-entry"],
|
||||
[8, "v1", "pointer"],
|
||||
[[9, 11], "v1", "touching-prims-entry"],
|
||||
[[1, 20], "a1", "touching-prims-entry"]
|
||||
],
|
||||
"(method 0 engine)": [
|
||||
[44, "v1", "pointer"],
|
||||
[47, "v1", "pointer"],
|
||||
[53, "v1", "connectable"],
|
||||
[65, "v1", "connectable"]
|
||||
],
|
||||
"(method 0 engine-pers)": [
|
||||
[32, "v1", "pointer"],
|
||||
[23, "v1", "pointer"],
|
||||
[26, "v1", "pointer"],
|
||||
[24, "v1", "(pointer pointer)"]
|
||||
],
|
||||
"(method 11 connection)": [[5, "a1", "pointer"]],
|
||||
"(method 12 engine)": [
|
||||
[[0, 25], "s4", "connection"],
|
||||
[13, "t9", "(function object object object object object)"]
|
||||
],
|
||||
"(method 13 engine)": [
|
||||
[[0, 25], "s4", "connection"],
|
||||
[13, "t9", "(function object object object object object)"]
|
||||
],
|
||||
"(method 19 engine)": [[8, "a0", "connection"]],
|
||||
"(method 20 engine)": [[8, "a0", "connection"]],
|
||||
"(method 21 engine)": [[8, "a0", "connection"]],
|
||||
"(method 3 connection-pers)": [[97, "f0", "float"]],
|
||||
"(method 9 connection)": [[8, "a0", "pointer"]],
|
||||
"drawable-frag-count": [[[14, 20], "s5", "drawable-group"]],
|
||||
"add-debug-sphere-from-table": [
|
||||
[[38, 41], "v1", "vector"],
|
||||
[[55, 59], "s0", "(inline-array vector)"]
|
||||
],
|
||||
"unpack-comp-huf": [[[21, 23], "t3", "(pointer uint16)"]],
|
||||
"unpack-comp-rle": [[[10, 26], "a0", "(pointer int8)"]],
|
||||
"dma-bucket-insert-tag": [
|
||||
[[2, 6], "v1", "dma-bucket"],
|
||||
[3, "a0", "dma-bucket"]
|
||||
],
|
||||
"dma-buffer-add-buckets": [
|
||||
[[1, 4], "v1", "dma-bucket"],
|
||||
[5, "v1", "pointer"],
|
||||
[[9, 11], "v1", "dma-bucket"],
|
||||
[11, "v1", "pointer"]
|
||||
],
|
||||
"dma-buffer-patch-buckets": [
|
||||
[[3, 34], "a0", "dma-bucket"],
|
||||
[[34, 38], "a0", "dma-packet"]
|
||||
],
|
||||
"disasm-dma-list": [
|
||||
[43, "v1", "dma-packet"],
|
||||
[266, "v1", "(pointer uint64)"],
|
||||
[272, "v1", "(pointer uint64)"],
|
||||
[133, "v1", "(pointer uint64)"],
|
||||
[152, "v1", "(pointer uint64)"],
|
||||
[167, "v1", "(pointer uint64)"],
|
||||
[176, "v1", "(pointer uint64)"],
|
||||
[198, "v1", "(pointer uint64)"],
|
||||
[207, "v1", "(pointer uint64)"],
|
||||
[238, "v1", "(pointer uint64)"],
|
||||
[247, "v1", "(pointer uint64)"],
|
||||
[282, "v1", "(pointer uint64)"],
|
||||
[291, "v1", "(pointer uint64)"],
|
||||
[324, "v1", "(pointer uint64)"],
|
||||
[334, "v1", "(pointer uint64)"],
|
||||
[141, "v1", "int"],
|
||||
[25, "v1", "dma-tag"],
|
||||
["_stack_", 16, "uint"],
|
||||
["_stack_", 32, "dma-packet"],
|
||||
["_stack_", 64, "dma-packet"],
|
||||
["_stack_", 80, "dma-packet"]
|
||||
],
|
||||
"(method 16 drawable-inline-array-node)": [[[1, 7], "v1", "draw-node"]],
|
||||
"(method 15 drawable-tree)": [
|
||||
[[1, 4], "v1", "drawable-inline-array-node"],
|
||||
[[29, 34], "t0", "drawable-inline-array-node"],
|
||||
[[28, 32], "t2", "drawable-inline-array-node"],
|
||||
[[42, 46], "t2", "(pointer int8)"]
|
||||
],
|
||||
"glst-find-node-by-name": [[6, "s5", "glst-named-node"]],
|
||||
"glst-length-of-longest-name": [[5, "s5", "glst-named-node"]],
|
||||
"history-print": [[20, "a1", "int"]],
|
||||
"joint-mod-foot-rot-handler": [
|
||||
[[0, 7], "s5", "joint-mod"],
|
||||
[[35, 152], "s5", "joint-mod"]
|
||||
],
|
||||
"joint-mod-joint-set-handler": [[[2, 23], "s4", "joint-mod"]],
|
||||
"joint-mod-joint-set-world-handler": [[[6, 197], "s5", "joint-mod"]],
|
||||
"joint-mod-polar-look-at-callback": [
|
||||
[[0, 363], "s5", "joint-mod-polar-look-at"]
|
||||
],
|
||||
"joint-mod-scale-handler": [[[1, 14], "s5", "joint-mod"]],
|
||||
"real-joint-mod-gun-look-at-handler": [
|
||||
[1, "v1", "joint-mod"],
|
||||
[2, "v1", "joint-mod"]
|
||||
],
|
||||
"joint-mod-blend-local-callback": [[[1, 28], "gp", "joint-mod-blend-local"]],
|
||||
"joint-mod-blend-world-callback": [[[1, 150], "gp", "joint-mod-blend-world"]],
|
||||
"joint-mod-rotate-world-callback": [
|
||||
[[0, 24], "s3", "joint-mod-rotate-world"]
|
||||
],
|
||||
"joint-mod-set-local-callback": [[[1, 24], "v1", "joint-mod-set-local"]],
|
||||
"joint-mod-set-world-callback": [[[1, 4], "v1", "joint-mod-set-local"]],
|
||||
"joint-mod-set-world-no-trans-callback": [
|
||||
[[1, 25], "s4", "joint-mod-set-world-no-trans"]
|
||||
],
|
||||
"(method 15 lightning-bolt)": [
|
||||
[47, "v1", "float"],
|
||||
[64, "v1", "float"]
|
||||
],
|
||||
"(method 17 lightning-bolt)": [[36, "v1", "float"]],
|
||||
"(method 20 lightning-bolt)": [
|
||||
[15, "v1", "float"],
|
||||
[32, "v1", "float"]
|
||||
],
|
||||
"(method 21 lightning-bolt)": [
|
||||
[49, "v1", "float"],
|
||||
[77, "v1", "float"],
|
||||
["_stack_", 32, "float"]
|
||||
],
|
||||
"update-light-hash": [
|
||||
[[234, 239], "a1", "light-hash-bucket"],
|
||||
[[207, 211], "a0", "light-hash-bucket"]
|
||||
],
|
||||
"dgo-load-begin": [[[19, 43], "s1", "load-dgo-msg"]],
|
||||
"dgo-load-continue": [[[5, 23], "gp", "load-dgo-msg"]],
|
||||
"dgo-load-get-next": [[[14, 31], "v1", "load-dgo-msg"]],
|
||||
"str-ambient-play": [[[7, 20], "s5", "play-chunk-msg"]],
|
||||
"str-ambient-stop": [[[7, 20], "s5", "play-chunk-msg"]],
|
||||
"str-load": [[[18, 44], "s2", "load-chunk-msg"]],
|
||||
"str-load-status": [
|
||||
[[18, 22], "v1", "load-chunk-msg"],
|
||||
[26, "v1", "load-chunk-msg"]
|
||||
],
|
||||
"str-play-async": [[[7, 40], "s2", "play-chunk-msg"]],
|
||||
"str-play-queue": [[[7, 98], "s4", "play-chunk-msg"]],
|
||||
"str-play-stop": [[[7, 36], "s4", "play-chunk-msg"]],
|
||||
"cube-root": [
|
||||
[17, "f0", "float"],
|
||||
[17, "f1", "float"],
|
||||
[18, "f0", "float"],
|
||||
[18, "f1", "float"],
|
||||
[[23, 32], "f0", "float"]
|
||||
],
|
||||
"log2f": [
|
||||
[12, "f0", "float"],
|
||||
[12, "f1", "float"],
|
||||
[19, "f0", "float"],
|
||||
[19, "f1", "float"]
|
||||
],
|
||||
"logf": [
|
||||
[12, "f0", "float"],
|
||||
[12, "f1", "float"],
|
||||
[19, "f0", "float"],
|
||||
[19, "f1", "float"]
|
||||
],
|
||||
"debug-menu-find-from-template": [
|
||||
[9, "s5", "string"],
|
||||
[10, "s4", "debug-menu-item"],
|
||||
[18, "s4", "debug-menu-item-submenu"],
|
||||
[3, "s5", "debug-menu"]
|
||||
],
|
||||
"debug-menu-func-decode": [[18, "a0", "symbol"]],
|
||||
"debug-menu-item-get-max-width": [
|
||||
[5, "a0", "debug-menu-item-submenu"],
|
||||
[20, "a0", "debug-menu-item-var"]
|
||||
],
|
||||
"debug-menu-item-var-joypad-handler": [
|
||||
[206, "a1", "int"],
|
||||
[207, "v1", "int"]
|
||||
],
|
||||
"debug-menu-item-var-make-float": [[32, "f0", "int"]],
|
||||
"debug-menu-item-var-update-display-str": [
|
||||
[48, "v1", "int"],
|
||||
[63, "v1", "int"],
|
||||
[68, "v1", "int"],
|
||||
[46, "v1", "int"],
|
||||
[45, "v1", "int"],
|
||||
[65, "v1", "int"],
|
||||
[66, "v1", "int"]
|
||||
],
|
||||
"debug-menu-rebuild": [[7, "a0", "debug-menu-item"]],
|
||||
"debug-menu-send-msg": [
|
||||
[17, "s2", "debug-menu-item-submenu"],
|
||||
[12, "s2", "debug-menu-item"]
|
||||
],
|
||||
"(method 10 mysql-nav-node)": [[4, "v1", "mysql-nav-edge"]],
|
||||
"(method 19 mysql-nav-graph)": [
|
||||
[42, "a0", "mysql-nav-edge"],
|
||||
[46, "a0", "mysql-nav-edge"],
|
||||
[60, "a0", "mysql-nav-edge"]
|
||||
],
|
||||
"joint-channel-float-delete!": [
|
||||
[7, "a0", "pointer"],
|
||||
[7, "a1", "pointer"]
|
||||
],
|
||||
"num-func-chan": [[7, "v1", "joint-control-channel"]],
|
||||
"ramdisk-load": [[[7, 12], "v1", "ramdisk-rpc-load"]],
|
||||
"(method 15 res-lump)": [[132, "s5", "res-tag-pair"]],
|
||||
"(method 16 res-lump)": [
|
||||
[22, "t1", "(pointer uint64)"],
|
||||
[29, "t2", "(pointer uint64)"]
|
||||
],
|
||||
"(method 17 res-lump)": [[22, "s4", "(pointer pointer)"]],
|
||||
"(method 18 res-lump)": [["_stack_", 16, "object"]],
|
||||
"(method 19 res-lump)": [
|
||||
[38, "t2", "int"],
|
||||
[38, "a2", "int"]
|
||||
],
|
||||
"(method 20 res-lump)": [[341, "t0", "(pointer uint128)"]],
|
||||
"(method 21 res-lump)": [
|
||||
["_stack_", 16, "res-tag"],
|
||||
["_stack_", 32, "res-tag"]
|
||||
],
|
||||
"(method 0 script-context)": [[[8, 17], "v0", "script-context"]],
|
||||
"shadow-vu1-add-matrix": [
|
||||
[[11, 19], "a3", "dma-packet"],
|
||||
[[26, 30], "v1", "matrix"]
|
||||
],
|
||||
"shrubbery-login-post-texture": [
|
||||
[[13, 15], "a3", "qword"],
|
||||
[16, "a3", "pointer"],
|
||||
[24, "a3", "pointer"],
|
||||
[[17, 23], "a3", "qword"],
|
||||
[[13, 23], "a1", "qword"],
|
||||
[14, "a2", "qword"],
|
||||
[[27, 29], "a3", "qword"],
|
||||
[[27, 29], "a1", "qword"],
|
||||
[[35, 37], "a3", "qword"],
|
||||
[[35, 37], "a2", "qword"]
|
||||
],
|
||||
"(method 2 sparticle-cpuinfo)": [[14, "f0", "float"]],
|
||||
"sprite-add-2d-chunk": [
|
||||
[[7, 21], "a0", "dma-packet"],
|
||||
[[33, 53], "a0", "dma-packet"],
|
||||
[[57, 77], "a0", "dma-packet"],
|
||||
[[78, 88], "v1", "dma-packet"],
|
||||
[65, "a3", "int"]
|
||||
],
|
||||
"sprite-add-3d-chunk": [
|
||||
[[7, 21], "a0", "dma-packet"],
|
||||
[[33, 53], "a0", "dma-packet"],
|
||||
[[57, 77], "a0", "dma-packet"],
|
||||
[[78, 88], "v1", "dma-packet"],
|
||||
[65, "a3", "int"]
|
||||
],
|
||||
"sprite-add-frame-data": [[[3, 17], "a0", "dma-packet"]],
|
||||
"add-shader-to-dma": [[[6, 8], "v1", "(pointer uint32)"]],
|
||||
"sprite-glow-add-simple-sprite": [
|
||||
[[0, 33], "v1", "sprite-glow-ref-template"]
|
||||
],
|
||||
"sprite-glow-add-sprite": [[[0, 33], "v1", "sprite-glow-cnt-template"]],
|
||||
"(method 9 texture-anim-layer)": [
|
||||
[5, "v1", "symbol"],
|
||||
[11, "v1", "symbol"]
|
||||
],
|
||||
"add-tfrag-data": [
|
||||
[[3, 17], "a0", "dma-packet"],
|
||||
[[24, 31], "v1", "dma-packet"]
|
||||
],
|
||||
"tfrag-end-buffer": [
|
||||
[[21, 28], "a2", "dma-packet"],
|
||||
[[31, 38], "a0", "(pointer vif-tag)"],
|
||||
[[38, 42], "a0", "(pointer int32)"],
|
||||
[[43, 49], "a0", "(pointer vif-tag)"]
|
||||
],
|
||||
"(method 9 clock)": [[47, "v1", "float"]],
|
||||
"vector4-array-add!": [
|
||||
[11, "s5", "(inline-array vector4)"],
|
||||
[12, "s4", "(inline-array vector4)"],
|
||||
[13, "gp", "(inline-array vector4)"]
|
||||
],
|
||||
"vector4-array-lerp!": [
|
||||
[13, "s5", "(inline-array vector4)"],
|
||||
[14, "s4", "(inline-array vector4)"],
|
||||
[15, "gp", "(inline-array vector4)"]
|
||||
],
|
||||
"vector4-array-madd!": [
|
||||
[13, "s5", "(inline-array vector4)"],
|
||||
[14, "s4", "(inline-array vector4)"],
|
||||
[15, "gp", "(inline-array vector4)"]
|
||||
],
|
||||
"vector4-array-msub!": [
|
||||
[13, "s5", "(inline-array vector4)"],
|
||||
[14, "s4", "(inline-array vector4)"],
|
||||
[15, "gp", "(inline-array vector4)"]
|
||||
],
|
||||
"vector4-array-mul!": [
|
||||
[11, "s5", "(inline-array vector4)"],
|
||||
[12, "s4", "(inline-array vector4)"],
|
||||
[13, "gp", "(inline-array vector4)"]
|
||||
],
|
||||
"vector4-array-scale!": [
|
||||
[11, "s5", "(inline-array vector4)"],
|
||||
[12, "gp", "(inline-array vector4)"]
|
||||
],
|
||||
"vector4-array-sub!": [
|
||||
[11, "s5", "(inline-array vector4)"],
|
||||
[12, "s4", "(inline-array vector4)"],
|
||||
[13, "gp", "(inline-array vector4)"]
|
||||
],
|
||||
"ellipsoid-random-point-on!": [
|
||||
[19, "v1", "float"],
|
||||
[44, "v1", "float"]
|
||||
],
|
||||
"(method 15 engine)": [[[0, 36], "v1", "connection"]],
|
||||
"(method 10 connection)": [[8, "a0", "pointer"]],
|
||||
"(method 3 connection-minimap)": [
|
||||
[97, "a3", "float"],
|
||||
[[97, 99], "a3", "float"],
|
||||
[97, "f0", "float"]
|
||||
],
|
||||
"(method 0 prim-strip)": [[[101, 121], "a0", "vector"]],
|
||||
"(method 0 fact-info-target)": [[3, "v0", "fact-info-target"]],
|
||||
"(method 0 fact-info-crate)": [[3, "v0", "fact-info-crate"]],
|
||||
"(method 0 fact-info-enemy)": [
|
||||
[7, "v0", "fact-info-enemy"],
|
||||
["_stack_", 16, "res-tag"],
|
||||
["_stack_", 32, "res-tag"]
|
||||
],
|
||||
"(method 0 fact-info)": [
|
||||
[87, "v1", "(pointer int32)"],
|
||||
[11, "v1", "res-lump"]
|
||||
],
|
||||
"(method 0 collide-shape-moving)": [[[5, 12], "v0", "collide-shape-moving"]],
|
||||
"joint-mod-spinner-callback": [[[2, 63], "gp", "joint-mod-spinner"]],
|
||||
"joint-mod-add-local-callback": [[[1, 37], "s4", "joint-mod-add-local"]],
|
||||
"(top-level-login eye-h)": [[76, "a3", "eye-control"]],
|
||||
"joint-mod-rotate-local-callback": [
|
||||
[[2, 16], "v1", "joint-mod-rotate-local"]
|
||||
],
|
||||
"joint-mod-trans-rot-local-callback": [
|
||||
[[2, 16], "v1", "joint-mod-trans-rot-local"]
|
||||
],
|
||||
"(method 8 res-lump)": [
|
||||
[258, "s0", "array"],
|
||||
[[157, 239], "s0", "(array object)"]
|
||||
],
|
||||
"(method 2 array)": [
|
||||
[23, "gp", "(array int32)"],
|
||||
[43, "gp", "(array uint32)"],
|
||||
[63, "gp", "(array int64)"],
|
||||
[83, "gp", "(array uint64)"],
|
||||
[102, "gp", "(array int8)"],
|
||||
[121, "gp", "(array uint8)"],
|
||||
[141, "gp", "(array int16)"],
|
||||
[161, "gp", "(array uint16)"],
|
||||
[186, "gp", "(array uint128)"],
|
||||
[204, "gp", "(array int32)"],
|
||||
[223, "gp", "(array float)"],
|
||||
[232, "gp", "(array float)"],
|
||||
[249, "gp", "(array basic)"],
|
||||
[258, "gp", "(array basic)"]
|
||||
],
|
||||
"(method 3 array)": [
|
||||
[51, "gp", "(array int32)"],
|
||||
[69, "gp", "(array uint32)"],
|
||||
[87, "gp", "(array int64)"],
|
||||
[105, "gp", "(array uint64)"],
|
||||
[122, "gp", "(array int8)"],
|
||||
[139, "gp", "(array int8)"],
|
||||
[157, "gp", "(array int16)"],
|
||||
[175, "gp", "(array uint16)"],
|
||||
[198, "gp", "(array uint128)"],
|
||||
[214, "gp", "(array int32)"],
|
||||
[233, "gp", "(array float)"],
|
||||
[250, "gp", "(array basic)"]
|
||||
],
|
||||
"(method 9 bounding-box)": [
|
||||
[13, "a1", "(inline-array sphere)"],
|
||||
[24, "a1", "(inline-array sphere)"],
|
||||
[31, "a1", "(inline-array sphere)"],
|
||||
[38, "a1", "(inline-array sphere)"]
|
||||
],
|
||||
"generate-rand-vector-on-sphere": [
|
||||
[12, "v1", "float"],
|
||||
[28, "v1", "float"]
|
||||
],
|
||||
"vector-segment-distance-point!": [[[21, 30], "f1", "float"]],
|
||||
"string-cat-to-last-char": [
|
||||
[3, "s5", "(pointer uint8)"],
|
||||
[4, "s5", "string"]
|
||||
],
|
||||
"to-upper": [
|
||||
[6, "a0", "(pointer uint8)"],
|
||||
[8, "a0", "string"]
|
||||
],
|
||||
"mem-copy!": [
|
||||
[[18, 69], "s5", "(pointer uint128)"],
|
||||
[[18, 69], "s4", "(pointer uint128)"]
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,5 +1,519 @@
|
||||
{
|
||||
// "(method 0 inline-array-class)": {
|
||||
// "args": ["allocation", "type-to-make", "count"]
|
||||
// },
|
||||
"(method 0 inline-array-class)": {
|
||||
"args": ["allocation", "type-to-make", "count"]
|
||||
},
|
||||
"(method 9 inline-array-class)": {
|
||||
"args": ["object-to-insert"]
|
||||
},
|
||||
"(method 3 inline-array-class)": {
|
||||
"args": ["idx-to-remove"]
|
||||
},
|
||||
"identity": {
|
||||
"args": ["obj"]
|
||||
},
|
||||
"1/": {
|
||||
"args": ["x"]
|
||||
},
|
||||
"+": {
|
||||
"args": ["a", "b"]
|
||||
},
|
||||
"-": {
|
||||
"args": ["a", "b"]
|
||||
},
|
||||
"*": {
|
||||
"args": ["a", "b"]
|
||||
},
|
||||
"/": {
|
||||
"args": ["a", "b"]
|
||||
},
|
||||
"ash": {
|
||||
"args": ["x", "shift-amount"]
|
||||
},
|
||||
"mod": {
|
||||
"args": ["a", "b"]
|
||||
},
|
||||
"rem": {
|
||||
"args": ["a", "b"]
|
||||
},
|
||||
"abs": {
|
||||
"args": ["x"]
|
||||
},
|
||||
"min": {
|
||||
"args": ["a", "b"]
|
||||
},
|
||||
"max": {
|
||||
"args": ["a", "b"]
|
||||
},
|
||||
"logior": {
|
||||
"args": ["a", "b"]
|
||||
},
|
||||
"logand": {
|
||||
"args": ["a", "b"]
|
||||
},
|
||||
"lognor": {
|
||||
"args": ["a", "b"]
|
||||
},
|
||||
"logxor": {
|
||||
"args": ["a", "b"]
|
||||
},
|
||||
"lognot": {
|
||||
"args": ["x"]
|
||||
},
|
||||
"basic-type?": {
|
||||
"args": ["obj", "typ"]
|
||||
},
|
||||
"type-type?": {
|
||||
"args": ["check-type", "parent-type"]
|
||||
},
|
||||
"type?": {
|
||||
"args": ["obj", "desired-type"]
|
||||
},
|
||||
"find-parent-method": {
|
||||
"args": ["typ", "method-id"]
|
||||
},
|
||||
"ref&": {
|
||||
"args": ["list", "idx"]
|
||||
},
|
||||
"ref": {
|
||||
"args": ["list", "idx"]
|
||||
},
|
||||
"last": {
|
||||
"args": ["list"]
|
||||
},
|
||||
"member": {
|
||||
"args": ["obj-to-find", "list"]
|
||||
},
|
||||
"nmember": {
|
||||
"args": ["obj-to-find", "list"]
|
||||
},
|
||||
"assoc": {
|
||||
"args": ["key", "assoc-list"]
|
||||
},
|
||||
"assoce": {
|
||||
"args": ["key", "assoc-list"]
|
||||
},
|
||||
"nassoc": {
|
||||
"args": ["key", "assoc-list"]
|
||||
},
|
||||
"nassoce": {
|
||||
"args": ["key", "assoc-list"]
|
||||
},
|
||||
"append!": {
|
||||
"args": ["list", "new-obj"]
|
||||
},
|
||||
"delete!": {
|
||||
"args": ["obj", "list"]
|
||||
},
|
||||
"delete-car!": {
|
||||
"args": ["car-to-match", "list"]
|
||||
},
|
||||
"insert-cons!": {
|
||||
"args": ["new-obj", "list"]
|
||||
},
|
||||
"sort": {
|
||||
"args": ["list", "compare-func"]
|
||||
},
|
||||
"string->symbol-debug": {
|
||||
"args": ["str"]
|
||||
},
|
||||
"symbol->string-debug": {
|
||||
"args": ["sym"]
|
||||
},
|
||||
"symbol->hash": {
|
||||
"args": ["sym"]
|
||||
},
|
||||
"mem-copy!": {
|
||||
"args": ["dst", "src", "bytes"]
|
||||
},
|
||||
"qmem-copy<-!": {
|
||||
"args": ["dst", "src", "qwc"]
|
||||
},
|
||||
"qmem-copy->!": {
|
||||
"args": ["dst", "src", "qwc"]
|
||||
},
|
||||
"qmem-clear!": {
|
||||
"args": ["dst", "qwc"]
|
||||
},
|
||||
"mem-set32!": {
|
||||
"args": ["dst", "word-count", "value"]
|
||||
},
|
||||
"mem-or!": {
|
||||
"args": ["dst", "src", "bytes"]
|
||||
},
|
||||
"fact": {
|
||||
"args": ["x"]
|
||||
},
|
||||
"print": {
|
||||
"args": ["obj"]
|
||||
},
|
||||
"printl": {
|
||||
"args": ["obj"]
|
||||
},
|
||||
"inspect": {
|
||||
"args": ["obj"]
|
||||
},
|
||||
"mem-print": {
|
||||
"args": ["ptr", "word-count"]
|
||||
},
|
||||
"print-tree-bitmask": {
|
||||
"args": ["mask", "count"]
|
||||
},
|
||||
"valid?": {
|
||||
"args": [
|
||||
"obj",
|
||||
"expected-type",
|
||||
"err-msg-str",
|
||||
"allow-false",
|
||||
"err-msg-dest"
|
||||
]
|
||||
},
|
||||
"(method 10 collide-mesh-cache)": {
|
||||
"args": ["this", "id"]
|
||||
},
|
||||
"(method 11 touching-prims-entry-pool)": {
|
||||
"vars": {
|
||||
"v1-0": "prev",
|
||||
"a1-0": "current",
|
||||
"a2-0": "next"
|
||||
}
|
||||
},
|
||||
"add-debug-box-with-transform": {
|
||||
"args": ["enable", "bucket", "box", "mat", "color"]
|
||||
},
|
||||
"add-debug-cspace": {
|
||||
"args": ["enable", "bucket", "cs"]
|
||||
},
|
||||
"add-debug-text-sphere": {
|
||||
"args": ["enable", "bucket", "pos", "radius", "text", "color"]
|
||||
},
|
||||
"add-debug-vector": {
|
||||
"args": ["enable", "bucket", "base", "dir", "len-scale", "color"]
|
||||
},
|
||||
"debug-reset-buffers": {
|
||||
"args": ["enable", "bucket", "p0", "p1", "color"]
|
||||
},
|
||||
"get-debug-text-3d": {
|
||||
"args": ["enable", "bucket", "p0", "p1", "color", "mode", "color2"]
|
||||
},
|
||||
"transform-float-point": {
|
||||
"args": ["src-world-pt", "dst-gs-screen-pt"]
|
||||
},
|
||||
"dma-bucket-insert-tag": {
|
||||
"args": ["buckets", "bucket", "start-tag", "end-tag-to-patch"]
|
||||
},
|
||||
"dma-buffer-add-buckets": {
|
||||
"args": ["dma-buf", "bucket-count"]
|
||||
},
|
||||
"dma-buffer-patch-buckets": {
|
||||
"args": ["base", "count"]
|
||||
},
|
||||
"(method 0 dma-buffer)": {
|
||||
"args": ["allocation", "type-to-make", "size-bytes"]
|
||||
},
|
||||
"dma-buffer-add-vu-function": {
|
||||
"args": ["dma-buf", "vu-func", "flush-path-3"]
|
||||
},
|
||||
"dma-buffer-free": {
|
||||
"args": ["dma-buf"]
|
||||
},
|
||||
"dma-buffer-inplace-new": {
|
||||
"args": ["dma-buff", "size-bytes"]
|
||||
},
|
||||
"dma-buffer-length": {
|
||||
"args": ["dma-buf"]
|
||||
},
|
||||
"dma-buffer-send": {
|
||||
"args": ["chan", "buf"]
|
||||
},
|
||||
"dma-buffer-send-chain": {
|
||||
"args": ["chan", "buf"]
|
||||
},
|
||||
"disasm-dma-list": {
|
||||
"args": ["data", "mode", "verbose", "stream", "expected-size"]
|
||||
},
|
||||
"disasm-dma-tag": {
|
||||
"args": ["tag", "format-dest"]
|
||||
},
|
||||
"disasm-vif-details": {
|
||||
"args": ["fmt-dest", "vif-data", "unpack-cmd", "unpack-count"]
|
||||
},
|
||||
"disasm-vif-tag": {
|
||||
"args": ["tag", "count", "format-dest", "details?"]
|
||||
},
|
||||
"(method 13 effect-control)": {
|
||||
"args": ["this", "offset"]
|
||||
},
|
||||
"(method 11 focus)": {
|
||||
"args": ["this", "cspec"]
|
||||
},
|
||||
"(method 0 clock)": {
|
||||
"args": ["allocation", "type-to-make", "index"]
|
||||
},
|
||||
"(method 0 sql-result)": {
|
||||
"args": ["allocation", "type-to-make", "num-elts"]
|
||||
},
|
||||
"(method 16 clock)": {
|
||||
"args": ["this", "xor-val"]
|
||||
},
|
||||
"(method 17 clock)": {
|
||||
"args": ["this", "xor-val"]
|
||||
},
|
||||
"(method 18 clock)": {
|
||||
"args": ["this", "xor-val"]
|
||||
},
|
||||
"(method 19 clock)": {
|
||||
"args": ["this", "xor-val"]
|
||||
},
|
||||
"(method 20 clock)": {
|
||||
"args": ["this", "xor-val"]
|
||||
},
|
||||
"(method 21 clock)": {
|
||||
"args": ["this", "xor-val"]
|
||||
},
|
||||
"(method 22 clock)": {
|
||||
"args": ["this", "xor-val"]
|
||||
},
|
||||
"(method 23 clock)": {
|
||||
"args": ["this", "xor-val"]
|
||||
},
|
||||
"(method 10 joint-mod-polar-look-at)": {
|
||||
"args": ["this", "pos"]
|
||||
},
|
||||
"(method 11 joint-mod-polar-look-at)": {
|
||||
"args": ["this", "other", "pos"]
|
||||
},
|
||||
"(method 12 joint-mod-polar-look-at)": {
|
||||
"args": ["this", "duration", "final-val", "restart-if-in-progress"]
|
||||
},
|
||||
"(method 13 joint-mod)": {
|
||||
"args": ["this", "x", "y", "z"]
|
||||
},
|
||||
"(method 13 joint-mod-polar-look-at)": {
|
||||
"args": ["this", "duration", "restart-if-in-progress"]
|
||||
},
|
||||
"(method 14 joint-mod)": {
|
||||
"args": ["this", "trans", "quat", "scale"]
|
||||
},
|
||||
"(method 9 joint-mod)": {
|
||||
"args": ["this", "mode"]
|
||||
},
|
||||
"(method 9 joint-mod-ik)": {
|
||||
"args": ["this", "pos"]
|
||||
},
|
||||
"joint-mod-blend-local-callback": {
|
||||
"args": ["bone-cspace", "joint-transform"]
|
||||
},
|
||||
"joint-mod-blend-world-callback": {
|
||||
"args": ["bone-cspace", "joint-transform"]
|
||||
},
|
||||
"joint-mod-rotate-world-callback": {
|
||||
"args": ["bone-cspace", "joint-transform"]
|
||||
},
|
||||
"joint-mod-set-local-callback": {
|
||||
"args": ["bone-cspace", "joint-transform"]
|
||||
},
|
||||
"joint-mod-set-world-callback": {
|
||||
"args": ["bone-cspace", "joint-trasnform"]
|
||||
},
|
||||
"joint-mod-set-world-no-trans-callback": {
|
||||
"args": ["bone-cspace", "joint-transform"]
|
||||
},
|
||||
"vector<-cspace2!": {
|
||||
"args": ["output-vec", "input-cspace"]
|
||||
},
|
||||
"light-group-lerp!": {
|
||||
"args": ["group", "backup-ptr", "other", "scalar"]
|
||||
},
|
||||
"light-group-madd!": {
|
||||
"args": ["group", "backup-ptr", "other", "scalar"],
|
||||
"vars": {
|
||||
"s4-0": "new-light",
|
||||
"f30-0": "ambi-scaled",
|
||||
"f24-0": "dir0-scaled",
|
||||
"f26-0": "dir1-scaled",
|
||||
"f28-0": "dir2-scaled"
|
||||
}
|
||||
},
|
||||
"light-group-process!": {
|
||||
"args": ["vu-lights", "light-group", "vec1", "vec2"]
|
||||
},
|
||||
"light-group-scale!": {
|
||||
"args": ["group", "backup-ptr", "scale"],
|
||||
"vars": {
|
||||
"arg1": "other",
|
||||
"v1-4": "light-idx"
|
||||
}
|
||||
},
|
||||
"light-group-slerp": {
|
||||
"args": ["light-group-out", "light-group-a", "light-group-b", "alpha"],
|
||||
"vars": {
|
||||
"s2-0": "group-idx"
|
||||
}
|
||||
},
|
||||
"light-merge!": {
|
||||
"args": ["out", "other"]
|
||||
},
|
||||
"light-slerp": {
|
||||
"args": ["light-out", "light-a", "light-b", "alpha"],
|
||||
"vars": {
|
||||
"s3-0": "clamped-alpha",
|
||||
"f0-2": "extra-x-a",
|
||||
"f1-2": "extra-x-b"
|
||||
}
|
||||
},
|
||||
"lookup-light-sphere-by-name": {
|
||||
"args": ["name", "hash"],
|
||||
"vars": {
|
||||
"s4-0": "num-lights",
|
||||
"s3-0": "light"
|
||||
}
|
||||
},
|
||||
"shadow-info-copy!": {
|
||||
"args": ["dest", "src"],
|
||||
"vars": {
|
||||
"v1-0": "light-idx"
|
||||
}
|
||||
},
|
||||
"vu-lights-default!": {
|
||||
"args": ["lights"]
|
||||
},
|
||||
"destroy-mem": {
|
||||
"args": ["start", "end"]
|
||||
},
|
||||
"dgo-load-begin": {
|
||||
"args": ["name", "buffer1", "buffer2", "buffer-top"]
|
||||
},
|
||||
"dgo-load-continue": {
|
||||
"args": ["buffer1", "buffer2", "buffer-top"]
|
||||
},
|
||||
"dgo-load-get-next": {
|
||||
"args": ["done-out"]
|
||||
},
|
||||
"find-temp-buffer": {
|
||||
"args": ["size"]
|
||||
},
|
||||
"str-ambient-play": {
|
||||
"args": ["name"]
|
||||
},
|
||||
"str-ambient-stop": {
|
||||
"args": ["name"]
|
||||
},
|
||||
"str-load": {
|
||||
"args": ["name", "chunk-idx", "dest-addr", "max-len"]
|
||||
},
|
||||
"str-load-status": {
|
||||
"args": ["maxlen-out"]
|
||||
},
|
||||
"str-play-async": {
|
||||
"args": ["name", "id", "volume", "group"]
|
||||
},
|
||||
"str-play-queue": {
|
||||
"args": ["name0", "name1", "name2", "name3", "ids", "mask"]
|
||||
},
|
||||
"str-play-stop": {
|
||||
"args": ["name", "id"]
|
||||
},
|
||||
"merc-fragment-fp-data": {
|
||||
"args": ["frag"]
|
||||
},
|
||||
"(method 13 mood-control)": {
|
||||
"args": ["this", "target-interp", "rate-interp", "set-current-interp?"],
|
||||
"vars": {
|
||||
"f0-1": "clamped-interp"
|
||||
}
|
||||
},
|
||||
"init-mood-control": {
|
||||
"args": ["ctrl"]
|
||||
},
|
||||
"cspace-index-by-name-no-fail": {
|
||||
"args": ["proc", "name"],
|
||||
"vars": {
|
||||
"v0-0": "idx"
|
||||
}
|
||||
},
|
||||
"joint-channel-float-delete!": {
|
||||
"args": ["chan"]
|
||||
},
|
||||
"num-func-+!": {
|
||||
"args": ["chan", "arg1", "arg2", "arg3"]
|
||||
},
|
||||
"num-func--!": {
|
||||
"args": ["chan", "arg1", "arg2", "arg3"]
|
||||
},
|
||||
"num-func-identity": {
|
||||
"args": ["chan", "arg1", "arg2", "arg3"]
|
||||
},
|
||||
"num-func-loop!": {
|
||||
"args": ["chan", "arg1", "arg2", "arg3"]
|
||||
},
|
||||
"num-func-loop-set!": {
|
||||
"args": ["chan", "frame"]
|
||||
},
|
||||
"num-func-none": {
|
||||
"args": ["chan", "arg1", "arg2", "arg3"]
|
||||
},
|
||||
"num-func-seek!": {
|
||||
"args": ["chan", "arg1", "arg2", "arg3"]
|
||||
},
|
||||
"(method 15 res-lump)": {
|
||||
"vars": {
|
||||
"s5-0": ["tag-pair", "res-tag-pair"],
|
||||
"s2-0": "existing-tag",
|
||||
"s3-0": "data-size",
|
||||
"v1-25": "resource-mem"
|
||||
}
|
||||
},
|
||||
"(method 17 res-lump)": {
|
||||
"args": ["this", "tag", "arg2"]
|
||||
},
|
||||
"(method 20 res-lump)": {
|
||||
"args": ["this", "arg1", "tag-pair", "arg3"]
|
||||
},
|
||||
"(method 9 res-lump)": {
|
||||
"args": ["this", "name", "mode", "time"]
|
||||
},
|
||||
"(method 0 rpc-buffer)": {
|
||||
"args": ["allocation", "type-to-make", "elt-size", "elt-count"]
|
||||
},
|
||||
"(method 0 rpc-buffer-pair)": {
|
||||
"args": ["allocation", "type-to-make", "elt-size", "elt-count", "rpc-port"]
|
||||
},
|
||||
"(method 12 rpc-buffer-pair)": {
|
||||
"args": ["this", "print-stall-warning"]
|
||||
},
|
||||
"(method 9 rpc-buffer-pair)": {
|
||||
"args": ["this", "fno", "recv-buffer", "recv-buffer-size"]
|
||||
},
|
||||
"(method 10 smush-control)": {
|
||||
"vars": {
|
||||
"f30-0": "elapsed-time",
|
||||
"f0-2": "period"
|
||||
}
|
||||
},
|
||||
"(method 11 smush-control)": {
|
||||
"vars": {
|
||||
"f30-0": "elapsed-time",
|
||||
"f0-2": "period"
|
||||
}
|
||||
},
|
||||
"(method 12 smush-control)": {
|
||||
"args": [
|
||||
"this",
|
||||
"amplitude",
|
||||
"period",
|
||||
"duration",
|
||||
"damp-amplitude",
|
||||
"damp-period",
|
||||
"clock"
|
||||
]
|
||||
},
|
||||
"(method 9 clock)": {
|
||||
"args": ["this", "rate"]
|
||||
},
|
||||
"vector-rad<-vector-deg!": {
|
||||
"args": ["out", "in"]
|
||||
},
|
||||
"vector-rad<-vector-deg/2!": {
|
||||
"args": ["out", "in"]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,901 +0,0 @@
|
||||
{
|
||||
// NOTE: almost all of these were just copy pasted from jak2
|
||||
// so it's impossible to know which are actually needed for jakx...
|
||||
// commenting out incase there's something here actually needed
|
||||
|
||||
"gkernel": [
|
||||
[17, "(function process symbol)"],
|
||||
[24, "(function process symbol)"],
|
||||
[26, "(function process symbol)"],
|
||||
[29, "(function process symbol)"],
|
||||
[32, "(function process symbol)"],
|
||||
[34, "(function process symbol)"],
|
||||
[36, "(function process symbol)"]
|
||||
],
|
||||
"profile": [[3, "(function profile-segment-array profile-collapse none)"]],
|
||||
"surface-h": [
|
||||
[0, "(function none)"],
|
||||
[1, "(function none)"],
|
||||
[2, "(function none)"]
|
||||
],
|
||||
"gsound": [
|
||||
[1, "(function none)"],
|
||||
[3, "(function none)"],
|
||||
[5, "(function none)"]
|
||||
],
|
||||
"joint-mod": [[21, "(function cspace transformq none)"]],
|
||||
"level-info": [
|
||||
[0, "(function int)"],
|
||||
[1, "(function int)"],
|
||||
[2, "(function int)"]
|
||||
],
|
||||
"game-info": [
|
||||
[11, "(function string none :behavior process)"],
|
||||
[17, "(function symbol symbol int none :behavior process)"],
|
||||
[
|
||||
22,
|
||||
"(function symbol symbol continue-point game-save resetter-spec none :behavior process)"
|
||||
]
|
||||
],
|
||||
"game-task": [
|
||||
[0, "(function symbol)"],
|
||||
[1, "(function symbol)"],
|
||||
[2, "(function symbol)"],
|
||||
[3, "(function symbol)"]
|
||||
],
|
||||
"settings": [
|
||||
[6, "(function engine-pers connection-pers object object symbol)"]
|
||||
],
|
||||
"generic-obs": [[51, "(function symbol :behavior touch-tracker)"]],
|
||||
"target-util": [
|
||||
[2, "(function none :behavior target)"],
|
||||
[3, "(function none :behavior target)"],
|
||||
[4, "(function none :behavior manipy)"],
|
||||
[5, "(function none :behavior manipy)"],
|
||||
[6, "(function none :behavior target)"]
|
||||
],
|
||||
"logic-target": [
|
||||
[0, "(function external-art-buffer none)"],
|
||||
[1, "(function external-art-buffer none)"]
|
||||
],
|
||||
"sidekick": [[6, "(function object vector int string :behavior sidekick)"]],
|
||||
"target-handler": [
|
||||
[10, "(function handle none :behavior target)"],
|
||||
[14, "(function none :behavior target)"]
|
||||
],
|
||||
"target-anim": [
|
||||
[3, "(function none :behavior target)"],
|
||||
[4, "(function none :behavior target)"],
|
||||
[7, "(function none :behavior target)"],
|
||||
[8, "(function none :behavior target)"],
|
||||
[13, "(function (pointer time-frame) none :behavior target)"],
|
||||
[14, "(function none :behavior target)"],
|
||||
[15, "(function none :behavior target)"],
|
||||
[16, "(function none :behavior target)"],
|
||||
[17, "(function none :behavior target)"]
|
||||
],
|
||||
"target": [
|
||||
[1, "(function object :behavior target)"],
|
||||
[7, "(function object :behavior target)"],
|
||||
[18, "(function process-focusable object :behavior target)"],
|
||||
[29, "(function surface surface surface int object :behavior target)"],
|
||||
[35, "(function surface surface surface int object :behavior target)"],
|
||||
[45, "(function surface surface surface int object :behavior target)"],
|
||||
[46, "(function surface surface surface int object :behavior target)"],
|
||||
[77, "(function surface surface surface int object :behavior target)"]
|
||||
],
|
||||
"target2": [
|
||||
[12, "(function vector time-frame float object :behavior process)"],
|
||||
[15, "(function object :behavior target)"],
|
||||
[23, "(function object :behavior target)"],
|
||||
[64, "(function symbol :behavior target)"]
|
||||
],
|
||||
"target-lightjak": [[68, "(function symbol object :behavior target)"]],
|
||||
"target-invisible": [[10, "(function object :behavior target)"]],
|
||||
"target-death": [
|
||||
[1, "(function object :behavior target)"],
|
||||
[2, "(function object :behavior target)"],
|
||||
[3, "(function symbol object :behavior target)"],
|
||||
[4, "(function object :behavior target)"],
|
||||
[9, "(function handle object :behavior target)"],
|
||||
[10, "(function object :behavior target)"],
|
||||
[14, "(function process-drawable object)"],
|
||||
[25, "(function surface surface surface int object :behavior target)"],
|
||||
[26, "(function surface surface surface int object :behavior target)"],
|
||||
[28, "(function continue-point object)"],
|
||||
[34, "(function process symbol)"],
|
||||
[35, "(function process symbol)"],
|
||||
[36, "(function process symbol)"],
|
||||
[37, "(function process symbol)"],
|
||||
[38, "(function process symbol)"]
|
||||
],
|
||||
"target-gun": [
|
||||
[15, "(function pickup-type pickup-type none :behavior target)"],
|
||||
[16, "(function pickup-type none :behavior target)"],
|
||||
[25, "(function surface surface surface int object :behavior target)"]
|
||||
],
|
||||
"target-board": [
|
||||
[30, "(function surface surface surface int object :behavior target)"],
|
||||
[31, "(function surface surface surface int object :behavior target)"],
|
||||
[32, "(function surface surface surface int object :behavior target)"],
|
||||
[33, "(function surface surface surface int object :behavior target)"],
|
||||
[34, "(function surface surface surface int object :behavior target)"]
|
||||
],
|
||||
"vent": [
|
||||
[26, "(function vent symbol)"],
|
||||
[27, "(function vent symbol)"],
|
||||
[28, "(function vent symbol)"],
|
||||
[29, "(function vent symbol)"]
|
||||
],
|
||||
"crates": [[35, "(function process symbol)"]],
|
||||
"collectables": [
|
||||
[77, "(function part-tracker vector)"],
|
||||
[78, "(function part-tracker vector)"]
|
||||
],
|
||||
"trajectory": [[15, "(function trajectory none)"]],
|
||||
"progress": [[3, "(function int none :behavior process)"]],
|
||||
"level": [
|
||||
[25, "(function level-group int symbol)"],
|
||||
[7, "(function none)"],
|
||||
[4, "(function load-state sound-bank-state symbol)"]
|
||||
],
|
||||
"main": [
|
||||
[11, "(function int none)"],
|
||||
[9, "(function none)"],
|
||||
[8, "(function none)"],
|
||||
[7, "(function none)"],
|
||||
[3, "(function symbol :behavior process)"]
|
||||
],
|
||||
"scene": [[4, "(function symbol :behavior scene-player)"]],
|
||||
"pov-camera": [
|
||||
[
|
||||
7,
|
||||
"(function process int symbol event-message-block object :behavior pov-camera)"
|
||||
]
|
||||
],
|
||||
"airlock": [
|
||||
[7, "(function object :behavior com-airlock)"],
|
||||
[11, "(function object :behavior com-airlock)"],
|
||||
[12, "(function object :behavior com-airlock)"]
|
||||
],
|
||||
"default-menu": [
|
||||
[3, "(function object)"],
|
||||
[4, "(function object)"],
|
||||
[5, "(function object)"],
|
||||
[6, "(function object)"],
|
||||
[7, "(function int debug-menu-msg object)"],
|
||||
[8, "(function object)"],
|
||||
[9, "(function object)"],
|
||||
[10, "(function object)"],
|
||||
[11, "(function object)"],
|
||||
[12, "(function object)"],
|
||||
[13, "(function object)"],
|
||||
[14, "(function object)"],
|
||||
[15, "(function object)"],
|
||||
[16, "(function object)"],
|
||||
[17, "(function object)"],
|
||||
[18, "(function int debug-menu-msg float object)"],
|
||||
[20, "(function object)"],
|
||||
[21, "(function object)"],
|
||||
[22, "(function object)"],
|
||||
[23, "(function object)"],
|
||||
[24, "(function object)"],
|
||||
[25, "(function object)"],
|
||||
[26, "(function object)"],
|
||||
[27, "(function int debug-menu-msg float object)"],
|
||||
[28, "(function int debug-menu-msg float object)"],
|
||||
[29, "(function object)"],
|
||||
[30, "(function int debug-menu-msg float object)"],
|
||||
[31, "(function int debug-menu-msg float object)"],
|
||||
[32, "(function int debug-menu-msg float object)"],
|
||||
[33, "(function int debug-menu-msg float object)"],
|
||||
[34, "(function object)"],
|
||||
[35, "(function object)"],
|
||||
[36, "(function int debug-menu-msg float object)"],
|
||||
[37, "(function int debug-menu-msg float object)"],
|
||||
[38, "(function int debug-menu-msg float object)"],
|
||||
[39, "(function int debug-menu-msg float object)"],
|
||||
[40, "(function object)"],
|
||||
[41, "(function object)"],
|
||||
[42, "(function int debug-menu-msg float object)"],
|
||||
[43, "(function int debug-menu-msg float object)"],
|
||||
[44, "(function int debug-menu-msg float object)"],
|
||||
[45, "(function int debug-menu-msg float object)"],
|
||||
[46, "(function int debug-menu-msg float object)"],
|
||||
[47, "(function int debug-menu-msg float object)"],
|
||||
[48, "(function int debug-menu-msg float object)"],
|
||||
[49, "(function int debug-menu-msg float object)"],
|
||||
[50, "(function int debug-menu-msg float object)"],
|
||||
[51, "(function int debug-menu-msg float object)"],
|
||||
[52, "(function int debug-menu-msg float object)"],
|
||||
[53, "(function int debug-menu-msg float object)"],
|
||||
[54, "(function int debug-menu-msg float object)"],
|
||||
[55, "(function int debug-menu-msg float object)"],
|
||||
[56, "(function int debug-menu-msg float object)"],
|
||||
[57, "(function int debug-menu-msg float object)"],
|
||||
[58, "(function int debug-menu-msg float object)"],
|
||||
[59, "(function int debug-menu-msg float object)"],
|
||||
[60, "(function int debug-menu-msg float object)"],
|
||||
[61, "(function int debug-menu-msg float object)"],
|
||||
[62, "(function int debug-menu-msg float object)"],
|
||||
[63, "(function int debug-menu-msg float object)"],
|
||||
[64, "(function int debug-menu-msg float object)"],
|
||||
[65, "(function int debug-menu-msg float object)"],
|
||||
[66, "(function int debug-menu-msg float object)"],
|
||||
[67, "(function int debug-menu-msg float object)"],
|
||||
[68, "(function int debug-menu-msg float object)"],
|
||||
[69, "(function int debug-menu-msg float object)"],
|
||||
[70, "(function int debug-menu-msg float object)"],
|
||||
[71, "(function int debug-menu-msg float object)"],
|
||||
[72, "(function int debug-menu-msg float object)"],
|
||||
[73, "(function int debug-menu-msg float object)"],
|
||||
[74, "(function int debug-menu-msg float object)"],
|
||||
[75, "(function int debug-menu-msg float object)"],
|
||||
[76, "(function int debug-menu-msg float object)"],
|
||||
[77, "(function int debug-menu-msg float object)"],
|
||||
[78, "(function int debug-menu-msg float object)"],
|
||||
[79, "(function int debug-menu-msg float object)"],
|
||||
[80, "(function int debug-menu-msg float object)"],
|
||||
[81, "(function int debug-menu-msg float object)"],
|
||||
[82, "(function int debug-menu-msg float object)"],
|
||||
[83, "(function int debug-menu-msg float object)"],
|
||||
[84, "(function int debug-menu-msg float object)"],
|
||||
[85, "(function int debug-menu-msg float object)"],
|
||||
[86, "(function int debug-menu-msg float object)"],
|
||||
[87, "(function int debug-menu-msg float object)"],
|
||||
[88, "(function int debug-menu-msg float object)"],
|
||||
[89, "(function int debug-menu-msg float object)"],
|
||||
[90, "(function int debug-menu-msg float object)"],
|
||||
[91, "(function int debug-menu-msg float object)"],
|
||||
[92, "(function int debug-menu-msg float object)"],
|
||||
[93, "(function int debug-menu-msg float object)"],
|
||||
[94, "(function int debug-menu-msg float object)"],
|
||||
[95, "(function int debug-menu-msg float object)"],
|
||||
[96, "(function int debug-menu-msg float object)"],
|
||||
[97, "(function int debug-menu-msg float object)"],
|
||||
[98, "(function int debug-menu-msg float object)"],
|
||||
[99, "(function int debug-menu-msg float object)"],
|
||||
[100, "(function int debug-menu-msg float object)"],
|
||||
[101, "(function int debug-menu-msg float object)"],
|
||||
[102, "(function int debug-menu-msg float object)"],
|
||||
[103, "(function int debug-menu-msg float object)"],
|
||||
[104, "(function int debug-menu-msg float object)"],
|
||||
[105, "(function int debug-menu-msg float object)"],
|
||||
[106, "(function int debug-menu-msg float object)"],
|
||||
[107, "(function int debug-menu-msg float object)"],
|
||||
[108, "(function int debug-menu-msg float object)"],
|
||||
[109, "(function int debug-menu-msg float object)"],
|
||||
[110, "(function int debug-menu-msg float object)"],
|
||||
[111, "(function int debug-menu-msg float object)"],
|
||||
[112, "(function int debug-menu-msg float object)"],
|
||||
[113, "(function int debug-menu-msg float object)"],
|
||||
[114, "(function int debug-menu-msg float object)"],
|
||||
[115, "(function int debug-menu-msg float object)"],
|
||||
[116, "(function int debug-menu-msg float object)"],
|
||||
[117, "(function int debug-menu-msg float object)"],
|
||||
[118, "(function int debug-menu-msg float object)"],
|
||||
[119, "(function int debug-menu-msg float object)"],
|
||||
[120, "(function int debug-menu-msg float object)"],
|
||||
[121, "(function int debug-menu-msg float object)"],
|
||||
[122, "(function int debug-menu-msg float object)"],
|
||||
[123, "(function int debug-menu-msg float object)"],
|
||||
[124, "(function int debug-menu-msg float object)"],
|
||||
[125, "(function int debug-menu-msg float object)"],
|
||||
[126, "(function int debug-menu-msg float object)"],
|
||||
[127, "(function int debug-menu-msg float object)"],
|
||||
[128, "(function int debug-menu-msg float object)"],
|
||||
[129, "(function int debug-menu-msg float object)"],
|
||||
[130, "(function int debug-menu-msg float object)"],
|
||||
[131, "(function int debug-menu-msg float object)"],
|
||||
[132, "(function int debug-menu-msg float object)"],
|
||||
[133, "(function int debug-menu-msg float object)"],
|
||||
[134, "(function int debug-menu-msg float object)"],
|
||||
[135, "(function int debug-menu-msg float object)"],
|
||||
[136, "(function int debug-menu-msg float object)"],
|
||||
[137, "(function int debug-menu-msg float object)"],
|
||||
[138, "(function int debug-menu-msg float object)"],
|
||||
[139, "(function int debug-menu-msg float object)"],
|
||||
[140, "(function int debug-menu-msg float object)"],
|
||||
[141, "(function int debug-menu-msg float object)"],
|
||||
[142, "(function int debug-menu-msg float object)"],
|
||||
[143, "(function int debug-menu-msg float object)"],
|
||||
[144, "(function int debug-menu-msg float object)"],
|
||||
[145, "(function int debug-menu-msg float object)"],
|
||||
[146, "(function int debug-menu-msg float object)"],
|
||||
[147, "(function int debug-menu-msg float object)"],
|
||||
[148, "(function int debug-menu-msg float object)"],
|
||||
[149, "(function int debug-menu-msg float object)"],
|
||||
[150, "(function int debug-menu-msg float object)"],
|
||||
[151, "(function int debug-menu-msg float object)"],
|
||||
[152, "(function int debug-menu-msg float object)"],
|
||||
[153, "(function int debug-menu-msg float object)"],
|
||||
[154, "(function int debug-menu-msg float object)"],
|
||||
[155, "(function int debug-menu-msg float object)"],
|
||||
[156, "(function int debug-menu-msg float object)"],
|
||||
[157, "(function int debug-menu-msg float object)"],
|
||||
[158, "(function int debug-menu-msg float object)"],
|
||||
[159, "(function int debug-menu-msg float object)"],
|
||||
[160, "(function object)"],
|
||||
[161, "(function object)"],
|
||||
[162, "(function object)"],
|
||||
[163, "(function object)"],
|
||||
[164, "(function object)"],
|
||||
[165, "(function object)"],
|
||||
[166, "(function object)"],
|
||||
[167, "(function object)"],
|
||||
[168, "(function int debug-menu-msg object)"],
|
||||
[169, "(function int debug-menu-msg object)"],
|
||||
[170, "(function int debug-menu-msg object)"],
|
||||
[171, "(function int debug-menu-msg object)"],
|
||||
[172, "(function int debug-menu-msg object)"],
|
||||
[173, "(function int debug-menu-msg float object)"],
|
||||
[174, "(function int debug-menu-msg float object)"],
|
||||
[175, "(function int debug-menu-msg float object)"],
|
||||
[176, "(function int debug-menu-msg float object)"],
|
||||
[177, "(function int debug-menu-msg float object)"],
|
||||
[178, "(function int debug-menu-msg float object)"],
|
||||
[179, "(function int debug-menu-msg float object)"],
|
||||
[180, "(function int debug-menu-msg float object)"],
|
||||
[181, "(function int debug-menu-msg float object)"],
|
||||
[182, "(function int debug-menu-msg float object)"],
|
||||
[183, "(function int debug-menu-msg float object)"],
|
||||
[184, "(function int debug-menu-msg float object)"],
|
||||
[185, "(function int debug-menu-msg float object)"],
|
||||
[186, "(function int debug-menu-msg float object)"],
|
||||
[187, "(function int debug-menu-msg float object)"],
|
||||
[188, "(function int debug-menu-msg float object)"],
|
||||
[189, "(function int debug-menu-msg float object)"],
|
||||
[190, "(function int debug-menu-msg float object)"],
|
||||
[191, "(function int debug-menu-msg float object)"],
|
||||
[192, "(function int debug-menu-msg float object)"],
|
||||
[193, "(function int debug-menu-msg float object)"],
|
||||
[194, "(function int debug-menu-msg float object)"],
|
||||
[195, "(function int debug-menu-msg float object)"],
|
||||
[196, "(function int debug-menu-msg float object)"],
|
||||
[197, "(function int debug-menu-msg float object)"],
|
||||
[198, "(function int debug-menu-msg float object)"],
|
||||
[199, "(function int debug-menu-msg float object)"],
|
||||
[200, "(function int debug-menu-msg float object)"],
|
||||
[201, "(function int debug-menu-msg float object)"],
|
||||
[202, "(function int debug-menu-msg float object)"],
|
||||
[203, "(function int debug-menu-msg float object)"],
|
||||
[204, "(function int debug-menu-msg float object)"],
|
||||
[205, "(function int debug-menu-msg float object)"],
|
||||
[206, "(function int debug-menu-msg float object)"],
|
||||
[207, "(function int debug-menu-msg float object)"],
|
||||
[208, "(function int debug-menu-msg float object)"],
|
||||
[209, "(function int debug-menu-msg float object)"],
|
||||
[210, "(function int debug-menu-msg float object)"],
|
||||
[211, "(function int debug-menu-msg float object)"],
|
||||
[212, "(function int debug-menu-msg float object)"],
|
||||
[213, "(function int debug-menu-msg float object)"],
|
||||
[214, "(function int debug-menu-msg float object)"],
|
||||
[215, "(function symbol debug-menu-msg float float object)"],
|
||||
[216, "(function symbol debug-menu-msg float float object)"],
|
||||
[217, "(function int debug-menu-msg float object)"],
|
||||
[218, "(function symbol debug-menu-msg float float object)"],
|
||||
[219, "(function symbol debug-menu-msg float float object)"],
|
||||
[220, "(function symbol debug-menu-msg float float object)"],
|
||||
[221, "(function symbol debug-menu-msg float float object)"],
|
||||
[222, "(function symbol debug-menu-msg float float object)"],
|
||||
[223, "(function symbol debug-menu-msg float float object)"],
|
||||
[224, "(function symbol debug-menu-msg float float object)"],
|
||||
[225, "(function symbol debug-menu-msg float float object)"],
|
||||
[226, "(function symbol debug-menu-msg float float object)"],
|
||||
[227, "(function symbol debug-menu-msg float float object)"],
|
||||
[228, "(function symbol debug-menu-msg float float object)"],
|
||||
[229, "(function symbol debug-menu-msg float float object)"],
|
||||
[230, "(function symbol debug-menu-msg float float object)"],
|
||||
[231, "(function symbol debug-menu-msg float float object)"],
|
||||
[232, "(function symbol debug-menu-msg float float object)"],
|
||||
[233, "(function symbol debug-menu-msg float float object)"],
|
||||
[234, "(function symbol debug-menu-msg float float object)"],
|
||||
[235, "(function object)"],
|
||||
[236, "(function object)"],
|
||||
[237, "(function symbol debug-menu-msg float float object)"],
|
||||
[239, "(function symbol debug-menu-msg object)"],
|
||||
[240, "(function int debug-menu-msg float object)"],
|
||||
[241, "(function int debug-menu-msg float object)"],
|
||||
[242, "(function int debug-menu-msg float object)"],
|
||||
[243, "(function int debug-menu-msg float object)"],
|
||||
[244, "(function debug-menu debug-menu symbol)"],
|
||||
[245, "(function debug-menu debug-menu symbol)"],
|
||||
[246, "(function debug-menu debug-menu symbol)"],
|
||||
[247, "(function debug-menu debug-menu symbol)"]
|
||||
],
|
||||
"enemy-states": [[38, "(function object :behavior enemy)"]],
|
||||
"scene-actor": [
|
||||
[0, "(function none)"],
|
||||
[1, "(function flut-npc none)"],
|
||||
[2, "(function flut-npc art-element)"],
|
||||
[39, "(function flut-npc flut-npc)"]
|
||||
],
|
||||
"warp-gate": [
|
||||
[0, "(function object)"],
|
||||
[8, "(function string object :behavior process)"],
|
||||
[12, "(function object :behavior target)"]
|
||||
],
|
||||
"gun-yellow-shot": [[59, "(function handle object :behavior process)"]],
|
||||
"gun-dark-shot": [
|
||||
[25, "(function collide-shape-prim none :behavior gravity-spinner)"],
|
||||
[34, "(function handle float object :behavior process)"]
|
||||
],
|
||||
"entity": [
|
||||
[11, "(function process object)"],
|
||||
[16, "(function process object)"],
|
||||
[57, "(function process object)"],
|
||||
[61, "(function process object)"]
|
||||
],
|
||||
"target-darkjak": [
|
||||
[5, "(function object :behavior target)"],
|
||||
[
|
||||
20,
|
||||
"(function (pointer float) (pointer int64) (pointer int64) object :behavior target)"
|
||||
],
|
||||
[21, "(function object :behavior target)"]
|
||||
],
|
||||
"memory-usage": [
|
||||
[2, "(function process-drawable symbol)"],
|
||||
[3, "(function basic symbol)"]
|
||||
],
|
||||
"bug-report": [
|
||||
[0, "(function object :behavior bug-report)"],
|
||||
[1, "(function object :behavior bug-report)"]
|
||||
],
|
||||
"relocate": [[7, "(function sparticle-system sparticle-cpuinfo none)"]],
|
||||
"target-mech": [
|
||||
[7, "(function object :behavior target)"],
|
||||
[8, "(function object :behavior target)"],
|
||||
[9, "(function object :behavior target)"],
|
||||
[18, "(function surface surface surface int object :behavior target)"],
|
||||
[19, "(function surface surface surface int object :behavior target)"]
|
||||
],
|
||||
"mech-states": [[57, "(function object :behavior target)"]],
|
||||
"target-flut": [
|
||||
[14, "(function surface surface surface int object :behavior target)"],
|
||||
[20, "(function object :behavior target)"],
|
||||
[21, "(function object :behavior target)"],
|
||||
[33, "(function process-focusable object)"],
|
||||
[72, "(function object)"],
|
||||
[73, "(function object :behavior target)"],
|
||||
[74, "(function object :behavior target)"]
|
||||
],
|
||||
"nav-control": [
|
||||
[0, "(function object nav-control none)"],
|
||||
[1, "(function object nav-control none)"],
|
||||
[2, "(function object nav-control none)"],
|
||||
[3, "(function object nav-control none)"],
|
||||
[4, "(function object nav-control none)"],
|
||||
[5, "(function object nav-control none)"],
|
||||
[6, "(function object nav-control none)"],
|
||||
[7, "(function object nav-control none)"],
|
||||
[8, "(function object nav-control none)"],
|
||||
[9, "(function object nav-control none)"]
|
||||
],
|
||||
"nav-enemy": [[7, "(function enemy-jump-info none :behavior nav-enemy)"]],
|
||||
"task-control": [
|
||||
[53, "(function game-task-node-info symbol object)"],
|
||||
[54, "(function game-task-node-info object)"],
|
||||
[67, "(function pair symbol)"]
|
||||
],
|
||||
"merc-death": [[3, "(function time-frame :behavior process-drawable)"]],
|
||||
"vehicle-states": [
|
||||
[10, "(function collide-shape-prim none)"],
|
||||
[12, "(function collide-shape-prim none)"]
|
||||
],
|
||||
"prebot-states": [[21, "(function vector :behavior prebot)"]],
|
||||
"wasall-obs": [
|
||||
[0, "(function object)"],
|
||||
[1, "(function object)"],
|
||||
[2, "(function object)"],
|
||||
[3, "(function object)"]
|
||||
],
|
||||
"roboguard": [
|
||||
[1, "(function cspace transformq none)"],
|
||||
[2, "(function cspace transformq none)"],
|
||||
[25, "(function int int float object :behavior roboguard)"],
|
||||
[45, "(function roboguard symbol object)"]
|
||||
],
|
||||
"vehicle": [
|
||||
[6, "(function collide-shape-prim none)"],
|
||||
[7, "(function collide-shape-prim none)"]
|
||||
],
|
||||
"wvehicle-wheel": [
|
||||
[7, "(function collide-shape-prim none)"],
|
||||
[11, "(function collide-shape-prim none)"],
|
||||
[17, "(function collide-shape-prim none)"]
|
||||
],
|
||||
"wvehicle-states": [
|
||||
[20, "(function collide-shape-prim none)"],
|
||||
[22, "(function collide-shape-prim none)"]
|
||||
],
|
||||
"wvehicle": [[6, "(function collide-shape-prim none)"]],
|
||||
"pilot-states": [
|
||||
[15, "(function surface surface surface int object :behavior target)"]
|
||||
],
|
||||
"was-squad-control": [[16, "(function object object)"]],
|
||||
"des-cactus": [[13, "(function collide-shape-prim none)"]],
|
||||
"desertg-obs": [
|
||||
[4, "(function collide-shape-prim none)"],
|
||||
[7, "(function collide-shape-prim none)"]
|
||||
],
|
||||
"desertf-obs": [[7, "(function none)"]],
|
||||
"temple-obs2": [
|
||||
[43, "(function symbol)"],
|
||||
[46, "(function object :behavior tpl-watcher)"]
|
||||
],
|
||||
"temple-scenes": [
|
||||
[0, "(function none)"],
|
||||
[1, "(function none)"],
|
||||
[2, "(function none)"],
|
||||
[3, "(function none :behavior scene-player)"],
|
||||
[4, "(function none :behavior scene-player)"]
|
||||
],
|
||||
"des-beast-2": [
|
||||
[1, "(function cspace transformq none)"],
|
||||
[2, "(function cspace transformq none)"],
|
||||
[23, "(function projectile none)"]
|
||||
],
|
||||
"scorpion-gun": [
|
||||
[33, "(function cspace transformq none)"],
|
||||
[34, "(function cspace transformq none)"]
|
||||
],
|
||||
"hover-formation": [
|
||||
[10, "(function form-search-info float)"],
|
||||
[11, "(function int int form-search-info uint)"],
|
||||
[14, "(function vector object)"],
|
||||
[15, "(function int int (pointer object) int)"]
|
||||
],
|
||||
"robo-hover": [
|
||||
[14, "(function robo-hover cspace float float vector vector int object)"]
|
||||
],
|
||||
"tower-scenes": [
|
||||
[0, "(function none :behavior scene-player)"],
|
||||
[1, "(function none :behavior scene-player)"]
|
||||
],
|
||||
"forest-kill-plants": [
|
||||
[5, "(function engine-pers connection-pers object object symbol)"],
|
||||
[7, "(function engine-pers connection-pers object object symbol)"]
|
||||
],
|
||||
"forest-tasks": [
|
||||
[0, "(function none :behavior scene-player)"],
|
||||
[1, "(function none :behavior scene-player)"],
|
||||
[2, "(function none :behavior scene-player)"],
|
||||
[3, "(function none :behavior scene-player)"],
|
||||
[4, "(function none :behavior scene-player)"],
|
||||
[5, "(function none :behavior scene-player)"],
|
||||
[6, "(function none :behavior scene-player)"],
|
||||
[7, "(function none :behavior scene-player)"],
|
||||
[8, "(function none :behavior scene-player)"],
|
||||
[9, "(function none :behavior scene-player)"],
|
||||
[10, "(function none :behavior scene-player)"],
|
||||
[11, "(function none :behavior scene-player)"],
|
||||
[12, "(function none :behavior scene-player)"],
|
||||
[13, "(function none :behavior scene-player)"],
|
||||
[14, "(function none :behavior scene-player)"],
|
||||
[15, "(function none :behavior scene-player)"],
|
||||
[16, "(function none :behavior scene-player)"],
|
||||
[17, "(function none :behavior scene-player)"],
|
||||
[18, "(function none :behavior scene-player)"],
|
||||
[19, "(function none :behavior scene-player)"],
|
||||
[20, "(function none :behavior scene-player)"],
|
||||
[21, "(function none :behavior scene-player)"]
|
||||
],
|
||||
"neo-wasp": [[15, "(function neo-wasp cspace transformq float float none)"]],
|
||||
"for-turret": [
|
||||
[1, "(function cspace transformq none)"],
|
||||
[2, "(function cspace transformq none)"],
|
||||
[3, "(function cspace transformq none)"],
|
||||
[4, "(function cspace transformq none)"]
|
||||
],
|
||||
"volcano-obs": [[38, "(function cspace transformq none)"]],
|
||||
"spiky-frog": [[9, "(function cspace transformq none)"]],
|
||||
"volcano-scenes": [
|
||||
[1, "(function none :behavior scene-player)"],
|
||||
[2, "(function none :behavior scene-player)"]
|
||||
],
|
||||
"mantis": [
|
||||
[8, "(function mantis vector float int vector vector)"],
|
||||
[15, "(function mantis collide-shape-moving vector symbol)"]
|
||||
],
|
||||
"wcar-faccar": [[9, "(function handle object :behavior process)"]],
|
||||
"wasstadb-obs": [[5, "(function object)"]],
|
||||
"arena-scenes": [
|
||||
[0, "(function none :behavior scene-player)"],
|
||||
[1, "(function none :behavior scene-player)"],
|
||||
[2, "(function none :behavior scene-player)"],
|
||||
[3, "(function none :behavior scene-player)"],
|
||||
[4, "(function none :behavior scene-player)"],
|
||||
[5, "(function none :behavior scene-player)"],
|
||||
[6, "(function none :behavior scene-player)"],
|
||||
[7, "(function none :behavior scene-player)"],
|
||||
[8, "(function none :behavior scene-player)"],
|
||||
[9, "(function none :behavior scene-player)"]
|
||||
],
|
||||
"traffic-engine": [
|
||||
[24, "(function traffic-find-segment-struct nav-segment none)"]
|
||||
],
|
||||
"desert-scenes": [
|
||||
[5, "(function none :behavior scene-player)"],
|
||||
[6, "(function none :behavior scene-player)"],
|
||||
[7, "(function none :behavior scene-player)"],
|
||||
[8, "(function none :behavior scene-player)"],
|
||||
[9, "(function none :behavior scene-player)"],
|
||||
[10, "(function none :behavior scene-player)"],
|
||||
[11, "(function none :behavior scene-player)"],
|
||||
[12, "(function none :behavior scene-player)"],
|
||||
[13, "(function none :behavior scene-player)"],
|
||||
[14, "(function none :behavior scene-player)"],
|
||||
[15, "(function none :behavior scene-player)"],
|
||||
[16, "(function none :behavior scene-player)"],
|
||||
[17, "(function none :behavior scene-player)"],
|
||||
[18, "(function none :behavior scene-player)"],
|
||||
[19, "(function none :behavior scene-player)"],
|
||||
[20, "(function none :behavior scene-player)"],
|
||||
[21, "(function none :behavior scene-player)"],
|
||||
[22, "(function none :behavior scene-player)"],
|
||||
[23, "(function none :behavior scene-player)"],
|
||||
[24, "(function none :behavior scene-player)"],
|
||||
[25, "(function none :behavior scene-player)"],
|
||||
[26, "(function none :behavior scene-player)"],
|
||||
[27, "(function none :behavior scene-player)"],
|
||||
[28, "(function none :behavior scene-player)"],
|
||||
[29, "(function none :behavior scene-player)"],
|
||||
[30, "(function none :behavior scene-player)"],
|
||||
[31, "(function none :behavior scene-player)"],
|
||||
[32, "(function none :behavior scene-player)"],
|
||||
[33, "(function none :behavior scene-player)"],
|
||||
[34, "(function none :behavior scene-player)"],
|
||||
[35, "(function none :behavior scene-player)"],
|
||||
[36, "(function symbol :behavior scene-player)"]
|
||||
],
|
||||
"throne-scenes": [[0, "(function none :behavior scene-player)"]],
|
||||
"terraformer-setup": [[38, "(function object :behavior manipy)"]],
|
||||
"mined-scenes": [
|
||||
[6, "(function none :behavior scene-player)"],
|
||||
[7, "(function process-drawable vector none :behavior scene-player)"],
|
||||
[8, "(function process-drawable vector none :behavior scene-player)"]
|
||||
],
|
||||
"wasteland-scenes": [
|
||||
[0, "(function none :behavior scene-player)"],
|
||||
[1, "(function none :behavior scene-player)"],
|
||||
[2, "(function none :behavior scene-player)"],
|
||||
[3, "(function none :behavior scene-player)"],
|
||||
[4, "(function none :behavior scene-player)"],
|
||||
[5, "(function none :behavior scene-player)"],
|
||||
[6, "(function none :behavior scene-player)"],
|
||||
[7, "(function none :behavior scene-player)"],
|
||||
[8, "(function none :behavior scene-player)"],
|
||||
[9, "(function none :behavior scene-player)"],
|
||||
[10, "(function none :behavior scene-player)"]
|
||||
],
|
||||
"wasdoors-scenes": [[2, "(function none :behavior scene-player)"]],
|
||||
"wasdef-manager": [
|
||||
[7, "(function process-tree object)"],
|
||||
[8, "(function process-tree object)"],
|
||||
[9, "(function process-tree object)"]
|
||||
],
|
||||
"des-burning-bush": [[37, "(function symbol)"]],
|
||||
"mh-wasp": [
|
||||
[9, "(function mh-wasp cspace float float vector vector int none)"]
|
||||
],
|
||||
"mh-bat": [
|
||||
[1, "(function cspace transformq none)"],
|
||||
[21, "(function object :behavior mh-bat)"],
|
||||
[26, "(function object :behavior mh-bat)"],
|
||||
[30, "(function object :behavior mh-bat)"],
|
||||
[34, "(function object :behavior mh-bat)"],
|
||||
[39, "(function object :behavior mh-bat)"]
|
||||
],
|
||||
"factoryc-obs2": [
|
||||
[67, "(function (pointer joint-exploder) :behavior fac-break-floor)"]
|
||||
],
|
||||
"factory-scenes": [
|
||||
[0, "(function none :behavior scene-player)"],
|
||||
[1, "(function none :behavior scene-player)"],
|
||||
[2, "(function none :behavior scene-player)"],
|
||||
[3, "(function none :behavior scene-player)"],
|
||||
[4, "(function none :behavior scene-player)"],
|
||||
[5, "(function none :behavior scene-player)"],
|
||||
[6, "(function none :behavior scene-player)"],
|
||||
[7, "(function none :behavior scene-player)"],
|
||||
[8, "(function none :behavior scene-player)"],
|
||||
[9, "(function none :behavior scene-player)"],
|
||||
[10, "(function process-drawable none :behavior scene-player)"],
|
||||
[11, "(function none :behavior scene-player)"],
|
||||
[12, "(function none :behavior scene-player)"],
|
||||
[13, "(function none :behavior scene-player)"],
|
||||
[14, "(function none :behavior scene-player)"],
|
||||
[15, "(function none :behavior scene-player)"]
|
||||
],
|
||||
"factory-boss-setup": [[37, "(function object :behavior manipy)"]],
|
||||
"factory-boss-scenes": [
|
||||
[1, "(function none :behavior scene-player)"],
|
||||
[2, "(function none :behavior scene-player)"]
|
||||
],
|
||||
"bot": [[25, "(function gui-connection symbol :behavior bot)"]],
|
||||
"oasis-defense": [
|
||||
[4, "(function collide-shape-prim none)"],
|
||||
[11, "(function collide-shape-prim none)"]
|
||||
],
|
||||
"ash-oasis-course": [
|
||||
[0, "(function ashelin-oasis object)"],
|
||||
[1, "(function ashelin-oasis object)"],
|
||||
[2, "(function asht-wait-spot ashelin-oasis object)"],
|
||||
[3, "(function ashelin-oasis symbol)"]
|
||||
],
|
||||
"comb-obs": [
|
||||
[16, "(function collide-shape-prim none)"],
|
||||
[33, "(function collide-shape-prim none)"],
|
||||
[49, "(function collide-shape-prim none)"]
|
||||
],
|
||||
"comb-sentry": [[19, "(function collide-shape-prim none)"]],
|
||||
"comb-field": [[5, "(function symbol)"]],
|
||||
"comb-scenes": [
|
||||
[0, "(function none :behavior scene-player)"],
|
||||
[1, "(function none :behavior scene-player)"],
|
||||
[2, "(function none :behavior scene-player)"],
|
||||
[3, "(function none :behavior scene-player)"],
|
||||
[4, "(function none :behavior scene-player)"],
|
||||
[5, "(function none :behavior scene-player)"],
|
||||
[6, "(function none :behavior scene-player)"],
|
||||
[7, "(function none :behavior scene-player)"],
|
||||
[8, "(function none :behavior scene-player)"]
|
||||
],
|
||||
"railx-scenes": [
|
||||
[0, "(function none :behavior scene-player)"],
|
||||
[1, "(function none :behavior scene-player)"],
|
||||
[2, "(function none :behavior scene-player)"],
|
||||
[3, "(function none :behavior scene-player)"],
|
||||
[4, "(function none :behavior scene-player)"],
|
||||
[5, "(function none :behavior scene-player)"],
|
||||
[6, "(function none :behavior scene-player)"],
|
||||
[7, "(function none :behavior scene-player)"],
|
||||
[8, "(function none :behavior scene-player)"],
|
||||
[9, "(function none :behavior scene-player)"],
|
||||
[10, "(function none :behavior scene-player)"],
|
||||
[11, "(function none :behavior scene-player)"]
|
||||
],
|
||||
"title-obs": [
|
||||
[20, "(function external-art-buffer int)"],
|
||||
[22, "(function game-task object)"],
|
||||
[26, "(function vector :behavior manipy)"],
|
||||
[30, "(function object :behavior manipy)"]
|
||||
],
|
||||
"ff-squad-control": [
|
||||
[6, "(function process-focusable traffic-object-type-info none)"],
|
||||
[7, "(function process-focusable traffic-object-type-info none)"],
|
||||
[8, "(function process-focusable traffic-object-type-info none)"],
|
||||
[9, "(function crimson-guard traffic-object-type-info none)"]
|
||||
],
|
||||
"guard": [
|
||||
[31, "(function crimson-guard collide-shape vector symbol)"],
|
||||
[49, "(function process city-attacker-info int)"]
|
||||
],
|
||||
"guard-tazer": [
|
||||
[7, "(function collide-shape-prim none)"],
|
||||
[13, "(function collide-shape-prim none)"]
|
||||
],
|
||||
"roboguard-city": [
|
||||
[13, "(function cspace transformq none)"],
|
||||
[78, "(function roboguard-city symbol quaternion :behavior process)"]
|
||||
],
|
||||
"ctywide-obs": [[93, "(function symbol)"]],
|
||||
"ctywide-scenes": [
|
||||
[1, "(function none :behavior scene-player)"],
|
||||
[2, "(function none :behavior scene-player)"],
|
||||
[3, "(function none :behavior scene-player)"]
|
||||
],
|
||||
"ctyport-obs": [[5, "(function collide-shape-prim none)"]],
|
||||
"ctyport-scenes": [
|
||||
[3, "(function none :behavior scene-player)"],
|
||||
[4, "(function none :behavior scene-player)"],
|
||||
[5, "(function none :behavior scene-player)"],
|
||||
[6, "(function none :behavior scene-player)"]
|
||||
],
|
||||
"ctyport-attack": [[45, "(function object :behavior process)"]],
|
||||
"intro-scenes": [
|
||||
[0, "(function none :behavior scene-player)"],
|
||||
[1, "(function none :behavior scene-player)"],
|
||||
[2, "(function none :behavior scene-player)"],
|
||||
[3, "(function none :behavior scene-player)"],
|
||||
[4, "(function none :behavior scene-player)"],
|
||||
[5, "(function none :behavior scene-player)"],
|
||||
[6, "(function none :behavior scene-player)"],
|
||||
[7, "(function none :behavior scene-player)"],
|
||||
[8, "(function none :behavior scene-player)"],
|
||||
[9, "(function none :behavior scene-player)"],
|
||||
[10, "(function none :behavior scene-player)"],
|
||||
[11, "(function none :behavior scene-player)"],
|
||||
[12, "(function none :behavior scene-player)"],
|
||||
[13, "(function none :behavior scene-player)"],
|
||||
[14, "(function none :behavior scene-player)"],
|
||||
[15, "(function none :behavior scene-player)"],
|
||||
[16, "(function none :behavior scene-player)"],
|
||||
[17, "(function none :behavior scene-player)"],
|
||||
[18, "(function none :behavior scene-player)"],
|
||||
[19, "(function none :behavior scene-player)"],
|
||||
[20, "(function none :behavior scene-player)"],
|
||||
[21, "(function none :behavior scene-player)"],
|
||||
[22, "(function none :behavior scene-player)"],
|
||||
[23, "(function none :behavior scene-player)"],
|
||||
[24, "(function none :behavior scene-player)"],
|
||||
[25, "(function none :behavior scene-player)"],
|
||||
[26, "(function none :behavior scene-player)"],
|
||||
[27, "(function none :behavior scene-player)"],
|
||||
[28, "(function none :behavior scene-player)"],
|
||||
[29, "(function none :behavior scene-player)"],
|
||||
[30, "(function none :behavior scene-player)"],
|
||||
[31, "(function none :behavior scene-player)"],
|
||||
[32, "(function none :behavior scene-player)"],
|
||||
[33, "(function none :behavior scene-player)"],
|
||||
[34, "(function none :behavior scene-player)"],
|
||||
[35, "(function none :behavior scene-player)"],
|
||||
[36, "(function none :behavior scene-player)"],
|
||||
[37, "(function none :behavior scene-player)"],
|
||||
[38, "(function none :behavior scene-player)"],
|
||||
[39, "(function none :behavior scene-player)"]
|
||||
],
|
||||
"freehq-scenes": [[0, "(function none :behavior scene-player)"]],
|
||||
"hiphog-scenes": [
|
||||
[0, "(function none :behavior scene-player)"],
|
||||
[1, "(function none :behavior scene-player)"],
|
||||
[2, "(function none :behavior scene-player)"],
|
||||
[3, "(function none :behavior scene-player)"]
|
||||
],
|
||||
"rubble-attack": [[7, "(function int)"]],
|
||||
"rublcst-scenes": [
|
||||
[0, "(function none :behavior scene-player)"],
|
||||
[1, "(function none :behavior scene-player)"],
|
||||
[2, "(function none :behavior scene-player)"],
|
||||
[3, "(function none :behavior scene-player)"],
|
||||
[4, "(function none :behavior scene-player)"],
|
||||
[5, "(function none :behavior scene-player)"],
|
||||
[6, "(function none :behavior scene-player)"],
|
||||
[7, "(function none :behavior scene-player)"],
|
||||
[8, "(function none :behavior scene-player)"],
|
||||
[9, "(function none :behavior scene-player)"],
|
||||
[10, "(function none :behavior scene-player)"],
|
||||
[11, "(function none :behavior scene-player)"],
|
||||
[12, "(function none :behavior scene-player)"],
|
||||
[13, "(function none :behavior scene-player)"]
|
||||
],
|
||||
"vinroom-scenes": [
|
||||
[0, "(function none :behavior scene-player)"],
|
||||
[1, "(function none :behavior scene-player)"]
|
||||
],
|
||||
"gungame-manager": [[6, "(function process symbol)"]],
|
||||
"blow-tower-obs2": [
|
||||
[16, "(function bt-mh-flyer cspace float float vector vector int none)"],
|
||||
[117, "(function bt-roboguard symbol quaternion)"],
|
||||
[124, "(function cspace transformq none)"]
|
||||
],
|
||||
"cty-blow-tower": [
|
||||
[39, "(function collide-shape-prim none)"],
|
||||
[27, "(function process symbol)"],
|
||||
[46, "(function collide-shape-prim none)"],
|
||||
[69, "(function process object)"]
|
||||
],
|
||||
"assault-enemies": [
|
||||
[36, "(function assault-crimson-guard city-attacker-info int)"]
|
||||
],
|
||||
"assault-task": [[11, "(function symbol :behavior process)"]],
|
||||
"precura-obs": [[98, "(function symbol :behavior process)"]],
|
||||
"precurd-scenes": [
|
||||
[0, "(function none :behavior scene-player)"],
|
||||
[1, "(function none :behavior scene-player)"],
|
||||
[2, "(function none :behavior scene-player)"],
|
||||
[3, "(function none :behavior scene-player)"],
|
||||
[4, "(function none :behavior scene-player)"],
|
||||
[5, "(function none :behavior scene-player)"],
|
||||
[6, "(function none :behavior scene-player)"],
|
||||
[7, "(function none :behavior scene-player)"],
|
||||
[8, "(function none :behavior scene-player)"],
|
||||
[9, "(function none :behavior scene-player)"],
|
||||
[10, "(function none :behavior scene-player)"],
|
||||
[11, "(function none :behavior scene-player)"],
|
||||
[12, "(function none :behavior scene-player)"],
|
||||
[13, "(function none :behavior scene-player)"],
|
||||
[14, "(function none :behavior scene-player)"]
|
||||
]
|
||||
}
|
||||
@@ -1,785 +0,0 @@
|
||||
{
|
||||
////////////////////////////
|
||||
// HACKS and ASM FUNCTIONS
|
||||
////////////////////////////
|
||||
|
||||
"types_with_bad_inspect_methods": [
|
||||
"game-task-event",
|
||||
"game-task-control",
|
||||
"predator-edge",
|
||||
"manipy",
|
||||
"process-tree",
|
||||
"vector",
|
||||
"target",
|
||||
"vehicle-load-parts"
|
||||
],
|
||||
|
||||
"no_type_analysis_functions_by_name": [],
|
||||
|
||||
// this limits the number of cases in a cond. The first argument is the name of the function.
|
||||
// the second argument is the name of the first condition in the cond. Use print_cfg to find it out.
|
||||
// The third argument is the number of cases. If you set it too small it may fail to build the CFG.
|
||||
"cond_with_else_max_lengths": [
|
||||
["(method 20 res-lump)", "b0", 2],
|
||||
["(method 11 res-lump)", "b0", 1],
|
||||
["(method 12 res-lump)", "b0", 1]
|
||||
],
|
||||
|
||||
// if a cond with an else case is being used a value in a place where it looks wrong
|
||||
// you can add the function name to this list and it will more aggressively reject this rewrite.
|
||||
"aggressively_reject_cond_to_value_rewrite": [
|
||||
"(method 10 res-lump)",
|
||||
"(method 11 res-lump)",
|
||||
"(method 12 res-lump)"
|
||||
],
|
||||
|
||||
// this provides a hint to the decompiler that these functions will have a lot of inline assembly.
|
||||
// currently it just leaves pcpyld as an asm op.
|
||||
"hint_inline_assembly_functions": [],
|
||||
|
||||
"asm_functions_by_name": [
|
||||
// checking boxed type is different now - these make the cfg stuff sad
|
||||
"name=",
|
||||
"(method 77 grenadier)",
|
||||
"display-list-control",
|
||||
"anim-test-anim-list-handler",
|
||||
"anim-test-sequence-list-handler",
|
||||
"anim-tester-get-playing-item",
|
||||
"start-pilot-recorder",
|
||||
"(anon-function 10 pilot-recorder)",
|
||||
"(anon-function 10 sig-recorder)",
|
||||
// actual asm
|
||||
"quad-copy!",
|
||||
"return-from-thread",
|
||||
"return-from-thread-dead",
|
||||
"reset-and-call",
|
||||
"(method 10 cpu-thread)",
|
||||
"(method 11 cpu-thread)",
|
||||
"(method 0 catch-frame)",
|
||||
"throw-dispatch",
|
||||
"throw",
|
||||
"run-function-in-process",
|
||||
"set-to-run-bootstrap",
|
||||
"return-from-exception",
|
||||
"exp",
|
||||
"(method 17 bounding-box)",
|
||||
"(method 9 bounding-box)",
|
||||
"(method 9 matrix)",
|
||||
"quaternion->matrix-2",
|
||||
"sin-rad",
|
||||
"cos-rad",
|
||||
"atan-series-rad",
|
||||
"sign-float",
|
||||
"dma-count-until-done",
|
||||
"(method 11 collide-mesh-cache)",
|
||||
"cpu-delay",
|
||||
"qword-read-time",
|
||||
"dma-test-func",
|
||||
"move-test-func",
|
||||
|
||||
"symlink2",
|
||||
"blerc-a-fragment",
|
||||
"blerc-execute",
|
||||
"foreground-check-longest-edge-asm",
|
||||
"generic-light-proc",
|
||||
"(method 17 collide-edge-work)",
|
||||
"(method 10 collide-cache-prim)",
|
||||
"(method 17 collide-cache)",
|
||||
"(method 16 ocean)",
|
||||
|
||||
// unknown instructions
|
||||
// logand with #f arg
|
||||
// "bugfix?",
|
||||
// CFG failed
|
||||
"draw-inline-array-instance-shrub",
|
||||
|
||||
"(method 9 editable-region)", // condition branch assert hit
|
||||
"test-to-from-spr",
|
||||
"test-from-spr",
|
||||
"test-to-spr",
|
||||
"test-seq-read",
|
||||
"test-worst-read",
|
||||
"test-seq-write",
|
||||
"test-worst-write",
|
||||
// texture
|
||||
"adgif-shader<-texture!",
|
||||
|
||||
// jak 3
|
||||
"(method 10 manipulator)",
|
||||
"(method 46 ff-squad-control)",
|
||||
"memcpy",
|
||||
|
||||
// jak x
|
||||
"get-string-length",
|
||||
"rand-uint31-gen",
|
||||
"vector-rotate-y-fast!",
|
||||
|
||||
// jak x decompiler crashes
|
||||
"(method 13 race-line)",
|
||||
"(method 23 gui-control)",
|
||||
"(method 34 sky-work)",
|
||||
"(method 35 sky-work)",
|
||||
"(method 11 collide-mesh)",
|
||||
"target-standard-event-handler",
|
||||
"display-loop-main",
|
||||
"(method 22 level)",
|
||||
"(method 11 medius-cache)",
|
||||
"water-anim-event-handler"
|
||||
],
|
||||
|
||||
// these functions use pairs and the decompiler
|
||||
// will be less picky about types related to pairs.
|
||||
"pair_functions_by_name": [
|
||||
"ref",
|
||||
"ref&",
|
||||
"(method 4 pair)",
|
||||
"last",
|
||||
"member",
|
||||
"nmember",
|
||||
"assoc",
|
||||
"assoce",
|
||||
"nassoc",
|
||||
"nassoce",
|
||||
"append!",
|
||||
"delete!",
|
||||
"delete-car!",
|
||||
"insert-cons!",
|
||||
"sort",
|
||||
"unload-package",
|
||||
"display-loop-main",
|
||||
"lookup-level-info",
|
||||
"(method 24 level-group)",
|
||||
"(method 19 level-group)",
|
||||
// script
|
||||
"command-get-time",
|
||||
"command-get-param",
|
||||
"command-get-quoted-param",
|
||||
"command-get-entity",
|
||||
"(method 9 script-context)",
|
||||
"(anon-function 6 script)",
|
||||
"(anon-function 49 script)",
|
||||
"(anon-function 52 script)",
|
||||
"(anon-function 72 script)",
|
||||
"(anon-function 73 script)",
|
||||
"(anon-function 74 script)",
|
||||
"(anon-function 75 script)",
|
||||
"(anon-function 76 script)",
|
||||
"(anon-function 80 script)",
|
||||
"(method 11 script-context)",
|
||||
"(method 10 script-context)",
|
||||
"command-get-trans",
|
||||
"key-assoc",
|
||||
"(anon-function 0 script)",
|
||||
// default-menu
|
||||
"dm-scene-load-pick-func",
|
||||
"debug-menu-make-continue-sub-menu",
|
||||
"debug-menu-make-from-template",
|
||||
"debug-menu-context-make-default-menus",
|
||||
"debug-menu-make-task-menu",
|
||||
"(method 19 gui-control)",
|
||||
// menu
|
||||
"debug-menu-rebuild",
|
||||
"debug-menu-find-from-template",
|
||||
"debug-menu-render",
|
||||
"debug-menu-context-select-next-or-prev-item",
|
||||
"debug-menu-context-select-new-item",
|
||||
"debug-menu-send-msg",
|
||||
// airlock
|
||||
"(method 24 com-airlock)",
|
||||
"(method 19 gui-control)",
|
||||
"(method 28 editable)",
|
||||
"execute-select",
|
||||
"(method 29 editable)",
|
||||
"(method 25 editable)",
|
||||
// game-info
|
||||
"(method 20 game-info)",
|
||||
"print-continues",
|
||||
// task-control
|
||||
"(anon-function 55 task-control)",
|
||||
"(method 17 load-state)",
|
||||
"(method 12 level)",
|
||||
"bg",
|
||||
"update-sound-banks",
|
||||
"entity-remap-names",
|
||||
"(method 8 process-tree)",
|
||||
"(post play-anim scene-player)",
|
||||
"(method 25 scene-player)",
|
||||
"(method 25 scene-player)",
|
||||
"scene-player-init",
|
||||
"next-continue",
|
||||
"(method 25 warp-gate)",
|
||||
"(code use warp-gate)",
|
||||
"cspace-inspect-tree",
|
||||
"(method 11 mtn-step-plat-rocks-a)",
|
||||
"(method 11 mtn-step-plat-rocks-b)",
|
||||
"(method 11 mtn-step-plat-rocks-c)",
|
||||
"(method 22 fort-floor-spike-b)",
|
||||
"prototypes-game-visible-set!",
|
||||
"(method 22 fort-floor-spike-a)",
|
||||
"(method 22 fort-floor-spike-b)",
|
||||
"(method 22 fort-floor-spike-c)",
|
||||
"(method 11 sew-catwalk)",
|
||||
"(method 11 mtn-aval-rocks)",
|
||||
"(method 11 gar-curtain)",
|
||||
"(method 10 level-load-info)",
|
||||
"(method 29 level-group)",
|
||||
"(method 26 level-group)",
|
||||
"(method 19 level)",
|
||||
"(method 10 level)",
|
||||
"update-sound-banks",
|
||||
"level-base-level-name",
|
||||
"borrow-city-expansion",
|
||||
"add-want-level",
|
||||
"level-find-borrow-slot",
|
||||
"(method 18 level)",
|
||||
"(method 11 tow-tentacle)",
|
||||
"city-sound-expand-want-list",
|
||||
"(method 12 cty-borrow-manager)",
|
||||
"(method 16 cty-borrow-manager)",
|
||||
"mark-permanent-holds",
|
||||
"update-sound-info",
|
||||
"insert-into-sound-list",
|
||||
// title-obs
|
||||
"(anon-function 22 title-obs)",
|
||||
"cty-faction-evaluate-commands",
|
||||
"traffic-manager-event-handler",
|
||||
"(method 20 cty-faction-manager)"
|
||||
],
|
||||
|
||||
// If format is used with the wrong number of arguments,
|
||||
// it will often mess up the decompilation, as the decompiler assumes
|
||||
// that they used the correct number. This will override the decompiler's
|
||||
// automatic detection.
|
||||
"bad_format_strings": {
|
||||
"~170h~5d~220h~5d~280h~5,,2f": 3,
|
||||
"~338h~5d~388h~5d~448h~5,,2f": 3,
|
||||
"~30Htf: ~8D~134Hpr: ~8D~252Hsh: ~8D~370Hhd: ~8D~%": 4,
|
||||
"~30Hal: ~8D~131Hwa: ~8D~252Hsp: ~8D~370Hwp: ~8D~%": 4,
|
||||
"ERROR: <asg> ~A in spool anim loop for ~A ~D, but not loaded.~": 3,
|
||||
// TODO - these should be automatic
|
||||
" tfrag ~192H~5DK ~280Htfragment~456H~5DK~%": 2,
|
||||
" tie-proto ~192H~5DK ~280Hsky~456H~5DK~%": 2,
|
||||
" tie-instance ~192H~5DK ~280Htie-fragment~456H~5DK~%": 2,
|
||||
" shrub-proto ~192H~5DK ~280Htie-scissor~456H~5DK~%": 2,
|
||||
" shrub-instance ~192H~5DK ~280Hshrubbery~456H~5DK~%": 2,
|
||||
" collision ~192H~5DK ~280Htie-generic~456H~5DK~%": 2,
|
||||
" pris-anim ~192H~5DK ~280Hpris-generic~456H~5DK~%": 2,
|
||||
" textures ~192H~5DK ~280Htextures~456H~5DK~%": 2,
|
||||
" misc ~192H~5DK ~280Hsprite~456H~5DK~%": 2,
|
||||
" entity ~192H~5DK~%": 1,
|
||||
" pris-geo ~192H~5DK ~280Hpris-fragment~456H~5DK~%": 2,
|
||||
"~33L~S~32L ~S": 2,
|
||||
"~32L~S ~33L~S~1L": 2,
|
||||
"~35L~S~33L ~S": 2,
|
||||
"~1L~S~35L ~S": 2,
|
||||
"~35L~S ~1L~S~1L": 2,
|
||||
"~33L~S~35L ~S": 2,
|
||||
"~33L~C~34L~S~33L~C": 3,
|
||||
"~35L~S ~33L~S~1L": 2,
|
||||
"~33L~S ~35L~S~1L": 2,
|
||||
"~33L~C": 1,
|
||||
"~33L~S~44L ~S": 2,
|
||||
"~44L~S ~33L~S": 2,
|
||||
"~10Htfrag: ~8,,0m": 1,
|
||||
"~140Hshrub: ~8,,0m": 1,
|
||||
"~272Halpha: ~8,,0m~%": 1,
|
||||
"~27Htie: ~8,,0m": 1,
|
||||
"~140Hfg-tf: ~8,,0m": 1,
|
||||
"~270Hfg-pr: ~8,,0m~%": 1,
|
||||
"~10Hfg-wa: ~8,,0m": 1,
|
||||
"~140Hfg-sh: ~8,,0m": 1,
|
||||
"~267Hfg-p2: ~8,,0m~%": 1,
|
||||
"~30Hp2: ~8D~131Hhf: ~8D~%~1K": 2,
|
||||
"Current time (~d:~d) [mission-percentage ~f~%": 2,
|
||||
"~0K~Name~130HID~+50HVol~+15HPitch~+24HPan~+18HEar~+24HDist~%": 1,
|
||||
"~130H~5D ~4D ~5D ~4D ~3D ~5,,0M~%": 5
|
||||
},
|
||||
|
||||
"blocks_ending_in_asm_branch": {
|
||||
"light-merge!": [1, 2, 3, 5, 7],
|
||||
"bsp-camera-asm": [1, 2, 3, 4, 6, 7],
|
||||
"level-remap-texture": [2, 3, 4, 5, 6],
|
||||
"start-perf-stat-collection": [26],
|
||||
"end-perf-stat-collection": [0],
|
||||
|
||||
"(method 23 gui-control)": [10, 46, 50, 58, 81, 90, 101],
|
||||
|
||||
"find-offending-process-focusable": [16, 19],
|
||||
"(method 19 process-drawable)": [0, 2, 3, 7, 10, 11, 30],
|
||||
"(anon-function 11 game-save)": [0, 3, 4, 5],
|
||||
"(anon-function 3 game-save)": [15, 16],
|
||||
"(anon-function 12 lightjak-wings)": [2, 3],
|
||||
"target-standard-event-handler": [
|
||||
5, 6, 7, 20, 64, 65, 66, 67, 72, 73, 83, 84, 85, 86, 87, 88, 96, 97, 109,
|
||||
264, 265, 282, 283, 284, 290, 291, 306, 336, 350, 351, 412, 415, 427
|
||||
],
|
||||
"(method 9 curve-color-fast)": [0, 1],
|
||||
"evaluate-color-curve-fast": [0, 1],
|
||||
"(anon-function 0 target-death)": [71, 131, 132, 137],
|
||||
"target-board-handler": [15, 16, 20],
|
||||
"sprite-draw-distorters": [4, 5],
|
||||
"(method 10 simple-sprite-system)": [0],
|
||||
"add-debug-box-with-transform": [0, 3],
|
||||
"add-debug-line-sphere": [0],
|
||||
"bones-mtx-calc-execute": [19, 7],
|
||||
"foreground-draw": [0, 1, 126],
|
||||
"unpack-comp-rle": [1, 3, 5, 6],
|
||||
"unpack-comp-huf": [2, 4, 5, 6, 7, 8, 9],
|
||||
"unpack-comp-lzo": [
|
||||
0,
|
||||
1,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
15,
|
||||
16,
|
||||
17,
|
||||
18,
|
||||
19,
|
||||
20,
|
||||
21,
|
||||
22,
|
||||
23,
|
||||
24,
|
||||
25,
|
||||
26,
|
||||
27,
|
||||
28,
|
||||
29,
|
||||
30,
|
||||
31,
|
||||
32,
|
||||
33,
|
||||
34,
|
||||
35, // branch fwd 39
|
||||
39, // branch fwd no delay
|
||||
43, // goto 18
|
||||
45 // goto 6
|
||||
],
|
||||
"(method 16 level)": [0, 1, 5, 13, 14, 15],
|
||||
"upload-vis-bits": [2, 6, 3, 0],
|
||||
"set-background-regs!": [4, 3],
|
||||
"draw-drawable-tree-instance-shrub": [5, 7, 9, 11],
|
||||
"draw-drawable-tree-instance-tie": [21, 23, 31, 33],
|
||||
"(method 12 flow-control)": [3, 9, 22],
|
||||
"(method 26 level-group)": [40, 41, 67],
|
||||
"borrow-city-expansion": [0, 9, 13, 15, 17],
|
||||
"dma-add-process-drawable": [0, 77],
|
||||
"real-main-draw-hook": [120, 122],
|
||||
"display-frame-finish": [61],
|
||||
"display-loop-main": [130],
|
||||
"(method 63 collide-shape-moving)": [1, 2, 14, 49],
|
||||
"(method 67 collide-shape-moving)": [2, 3, 13],
|
||||
"(method 51 rigid-body-object)": [5],
|
||||
"(anon-function 2 rigid-body-queue)": [0, 2],
|
||||
"(method 15 rigid-body-queue)": [5, 6, 7, 9],
|
||||
"(method 13 rigid-body-queue)": [5, 6, 7, 9],
|
||||
"(method 11 rigid-body-queue)": [0, 6, 7, 9],
|
||||
"(method 10 rigid-body-queue)": [10, 34, 37],
|
||||
"(method 9 los-control)": [0, 43],
|
||||
"load-game-text-info": [19, 20, 21],
|
||||
"draw-actor-marks": [8],
|
||||
"find-nearest-entity": [7, 9],
|
||||
"(method 13 collide-cache)": [7, 9],
|
||||
"(method 11 collide-mesh)": [2, 4],
|
||||
"(method 12 collide-mesh-cache)": [0, 1, 2, 3, 4, 5],
|
||||
"(method 10 collide-mesh)": [2],
|
||||
"(method 42 collide-shape)": [0, 1, 2, 3, 4, 7],
|
||||
"(method 18 collide-shape-prim-mesh)": [2, 3, 4, 5, 6, 7],
|
||||
"(method 18 collide-shape-prim-sphere)": [2, 3, 4],
|
||||
"(method 15 collide-shape-prim-sphere)": [1, 2, 3, 4, 5, 6],
|
||||
"(method 16 collide-shape-prim-sphere)": [0, 1, 2, 3, 4],
|
||||
"(method 36 collide-shape)": [8, 9],
|
||||
"(method 45 collide-shape)": [33],
|
||||
"(method 40 collide-shape)": [
|
||||
0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
|
||||
22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32
|
||||
],
|
||||
"(method 12 collide-shape-prim-group)": [1, 2, 3, 4, 5, 6],
|
||||
"(method 13 collide-shape-prim)": [1, 2, 3, 4, 5, 6],
|
||||
"(method 12 collide-shape-prim-sphere)": [
|
||||
1, 2, 3, 4, 5, 8, 10, 11, 13, 14, 15
|
||||
],
|
||||
"(method 12 collide-shape-prim-mesh)": [
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 15, 16
|
||||
],
|
||||
"update-actor-hash": [0, 2, 4],
|
||||
"(method 24 grid-hash)": [39, 35, 22, 15],
|
||||
"(anon-function 4 gun-states)": [
|
||||
18, 128, 129, 131, 133, 135, 138, 139, 143
|
||||
],
|
||||
"(method 16 sparticle-launch-control)": [25, 35, 36, 48, 62, 65, 100, 102],
|
||||
"(anon-function 17 target-ladder)": [0, 1],
|
||||
"command-get-process": [46],
|
||||
"foreground-draw-hud": [0, 7, 8, 9, 16, 22],
|
||||
"target-flut-falling-anim-trans": [8, 9],
|
||||
"(method 12 nav-mesh)": [0, 1, 2, 9],
|
||||
"(method 20 nav-mesh)": [9],
|
||||
"(method 21 nav-mesh)": [7],
|
||||
"(method 29 nav-mesh)": [0, 1, 2, 4],
|
||||
"(method 33 nav-mesh)": [10, 11, 12, 13],
|
||||
"(method 34 nav-mesh)": [0, 1, 2, 4],
|
||||
"(method 35 nav-mesh)": [0, 1, 2, 4],
|
||||
"(method 36 nav-mesh)": [1, 2],
|
||||
"(method 37 nav-mesh)": [4],
|
||||
"(method 45 nav-mesh)": [1, 2],
|
||||
"(method 46 nav-mesh)": [1, 2, 19, 20],
|
||||
"(method 48 nav-mesh)": [4, 5, 6, 8],
|
||||
"(method 49 nav-mesh)": [0, 1, 2, 3, 5],
|
||||
"(method 18 nav-control)": [11, 12, 19, 20, 31, 34],
|
||||
"(method 19 nav-control)": [9, 10],
|
||||
"(method 40 nav-state)": [1, 2],
|
||||
"point-poly-distance-min": [0, 1, 2, 3, 4, 5, 6, 7, 10],
|
||||
"find-closest-circle-ray-intersection": [0, 4, 15, 16, 17, 18],
|
||||
"(method 39 vehicle)": [0, 10, 12, 15],
|
||||
"(anon-function 7 vehicle-states)": [0, 2],
|
||||
"(method 11 vehicle-hud-requests)": [0, 6, 7, 10],
|
||||
"(anon-function 12 neo-juicer)": [29, 30],
|
||||
"(method 160 neo-grenadier)": [1, 2, 3],
|
||||
"(method 82 spydroid-orig)": [13],
|
||||
"(method 118 vehicle)": [3, 4, 7, 8, 9, 10, 17, 26, 30, 31, 33],
|
||||
"(method 25 squad-control)": [0, 4, 5, 7],
|
||||
"target-pilot-post": [0, 29],
|
||||
"(method 36 was-squad-control)": [0, 8, 14, 16],
|
||||
"(anon-function 6 nst-tasks)": [4, 9, 10, 16, 23, 30],
|
||||
"(method 33 task-manager-nest-cocoons)": [3, 7, 13, 28],
|
||||
"(method 90 wvehicle)": [29, 37, 38, 44],
|
||||
"(anon-function 2 artifact-race)": [40, 55, 56, 57, 65, 66],
|
||||
"(anon-function 27 course-race)": [6],
|
||||
"(anon-function 65 temple-obs)": [5, 6],
|
||||
"(anon-function 5 target-turret)": [0, 1, 2, 3],
|
||||
"dp-bipedal-consider-attacks": [15, 19],
|
||||
"(anon-function 25 volcanox-obs)": [3, 5, 6],
|
||||
"(method 36 task-manager-arena-fight-base)": [11],
|
||||
"(method 28 hud-wasgun)": [0, 1, 2, 4],
|
||||
"(method 15 hud-wasgun)": [8, 28, 29, 30, 54],
|
||||
"(method 15 vehicle-controller)": [0, 3, 5, 6, 7, 10],
|
||||
"(method 51 hvehicle)": [5],
|
||||
"(method 159 hvehicle)": [0, 1, 10, 19, 21, 23, 26],
|
||||
"(method 18 vehicle-controller)": [0, 1, 74, 75],
|
||||
"glider-too-low?": [2, 19, 21],
|
||||
"(method 39 task-manager-desert-glide)": [0, 3, 4, 9],
|
||||
"(method 36 task-manager-desert-glide)": [20, 50, 60],
|
||||
"(method 37 task-manager-desert-glide)": [11, 12, 23, 29, 31],
|
||||
"(method 34 task-manager-desert-glide)": [3],
|
||||
"(anon-function 20 target-flut)": [0, 38, 39],
|
||||
"(anon-function 14 flut-racer)": [7, 17, 19],
|
||||
"(method 28 conveyor)": [22],
|
||||
"generic-merc-execute-all": [7, 15],
|
||||
"check-enemy": [0, 1],
|
||||
"(method 91 h-warf)": [0],
|
||||
"(method 51 h-warf)": [5],
|
||||
"(method 44 nav-graph)": [0, 7, 8, 26, 34],
|
||||
"(method 15 city-level-info)": [0, 1, 2, 6, 7, 9, 11, 13],
|
||||
"(method 10 traffic-suppressor)": [0, 1, 2, 4],
|
||||
"(method 18 traffic-tracker)": [5, 6, 7, 8],
|
||||
"(method 21 traffic-tracker)": [0],
|
||||
"(method 9 cty-faction-manager)": [8],
|
||||
"(method 46 traffic-engine)": [0, 1, 2, 4],
|
||||
"(method 42 traffic-engine)": [6],
|
||||
"(method 17 traffic-manager)": [7, 19, 27, 28, 29, 30, 41],
|
||||
"(anon-function 10 guard-rifle)": [9],
|
||||
"(method 261 crimson-guard)": [52, 64],
|
||||
"(anon-function 13 metalhead-predator)": [24, 25],
|
||||
"(anon-function 90 ctywide-obs)": [4],
|
||||
"(anon-function 10 cty-sniper-turret)": [44],
|
||||
"(method 33 rub-tower)": [9, 10],
|
||||
"(method 30 gungame-manager)": [0, 4, 5, 7],
|
||||
"closest-pt-in-triangle": [17],
|
||||
|
||||
"find-knot-span": [0, 1, 2, 3, 5, 6, 7, 8, 9],
|
||||
"curve-evaluate!": [0, 2, 5, 6, 7, 8, 9],
|
||||
"circle-circle-xz-intersect": [
|
||||
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14
|
||||
]
|
||||
},
|
||||
|
||||
// Sometimes the game might use format strings that are fetched dynamically,
|
||||
// for example using the game text lookup method
|
||||
// Add information about those format instructions here.
|
||||
// e.g. "function-name":[[op, argc], [op, argc], ...]
|
||||
// where "op" is the op number for the call to format.
|
||||
"dynamic_format_arg_counts": {
|
||||
"auto-save-post": [[182, 1]],
|
||||
"(method 10 menu-secret-option)": [[289, 1]],
|
||||
"(method 10 menu-create-game-option)": [[49, 1]],
|
||||
"(method 10 menu-format-card-option)": [[49, 1]],
|
||||
"(method 10 menu-card-removed-option)": [[49, 1]],
|
||||
"(method 10 menu-insert-card-option)": [[49, 1]],
|
||||
"(method 10 menu-hero-mode-message-option)": [[50, 1]],
|
||||
"(method 10 menu-secrets-insufficient-space-option)": [[51, 1]],
|
||||
"(method 10 menu-error-loading-option)": [
|
||||
[65, 1],
|
||||
[100, 1]
|
||||
],
|
||||
"(method 10 menu-insufficient-space-option)": [
|
||||
[72, 1],
|
||||
[112, 1]
|
||||
],
|
||||
"(method 10 menu-error-auto-saving-option)": [[73, 1]],
|
||||
"(method 10 menu-loading-option)": [[113, 1]],
|
||||
"(method 10 menu-icon-info-option)": [[150, 1]],
|
||||
"(method 17 hud-goal)": [[71, 0]],
|
||||
"(method 17 hud-miss)": [[71, 0]],
|
||||
"(method 16 resetter)": [
|
||||
[68, 1],
|
||||
[101, 1],
|
||||
[130, 1]
|
||||
],
|
||||
"(method 32 task-manager-desert-turtle-training)": [[59, 1]],
|
||||
"(method 24 race-manager)": [[97, 1]],
|
||||
"(method 25 race-manager)": [
|
||||
[97, 1],
|
||||
[126, 1]
|
||||
],
|
||||
"(method 15 hud-race-final-stats)": [[131, 0]],
|
||||
"(method 15 hud-wasbbv-goal-time)": [[74, 0]],
|
||||
"(method 32 task-manager-lightjak-training)": [[53, 0]],
|
||||
"(method 18 hover-training-manager)": [[69, 0]],
|
||||
"(method 37 task-manager-arena-training)": [[67, 1]],
|
||||
"(method 15 hud-arena-final-stats)": [
|
||||
[103, 0],
|
||||
[147, 0]
|
||||
],
|
||||
"(method 35 task-manager-arena-fight-base)": [[53, 0]],
|
||||
"(method 32 task-manager-arena-gun-training)": [[53, 0]],
|
||||
"(method 26 task-manager-arena-fight-2)": [
|
||||
[72, 0],
|
||||
[186, 0]
|
||||
],
|
||||
"(method 37 task-manager-wascity-gungame)": [
|
||||
[48, 0],
|
||||
[78, 0],
|
||||
[119, 0],
|
||||
[157, 0],
|
||||
[195, 0],
|
||||
[227, 0],
|
||||
[268, 0],
|
||||
[306, 0],
|
||||
[338, 0],
|
||||
[379, 0],
|
||||
[411, 0],
|
||||
[446, 0]
|
||||
],
|
||||
"(method 30 was-pre-game)": [
|
||||
[184, 0],
|
||||
[276, 0]
|
||||
],
|
||||
"(method 32 task-manager-throne-gun-training)": [[53, 0]],
|
||||
"(method 17 hud-spider-killed)": [[71, 0]],
|
||||
"(trans idle des-burning-bush)": [
|
||||
[226, 1],
|
||||
[257, 0]
|
||||
],
|
||||
"(method 37 des-burning-bush)": [
|
||||
[278, 0],
|
||||
[336, 0]
|
||||
],
|
||||
"(method 38 des-burning-bush)": [
|
||||
[109, 0],
|
||||
[153, 0],
|
||||
[196, 0]
|
||||
],
|
||||
"(method 15 freeze-time-hud)": [[108, 0]],
|
||||
"(method 17 freeze-time-hud)": [[97, 0]],
|
||||
"(method 15 hud-wasbbv-score)": [[61, 0]],
|
||||
"(method 15 hud-wasbbv-goal)": [[64, 0]],
|
||||
"(method 32 task-manager-dark-punch-training)": [[53, 0]],
|
||||
"(method 32 task-manager-lightjak-training-shield)": [[53, 0]],
|
||||
"(trans credits highres-viewer-manager)": [[185, 0]],
|
||||
"(trans idle hirez-viewer)": [[356, 0]],
|
||||
"(trans idle burning-bush)": [
|
||||
[171, 1],
|
||||
[202, 0]
|
||||
],
|
||||
"(method 33 task-manager-bbush-board)": [[86, 0]],
|
||||
"(method 17 board-score-hud)": [[71, 0]],
|
||||
"(method 23 gungame-manager)": [
|
||||
[52, 0],
|
||||
[90, 0],
|
||||
[128, 0],
|
||||
[164, 0],
|
||||
[194, 0],
|
||||
[235, 0],
|
||||
[273, 0],
|
||||
[305, 0],
|
||||
[346, 0],
|
||||
[378, 0],
|
||||
[413, 0]
|
||||
],
|
||||
"(trans carry precur-bomb)": [[60, 0]]
|
||||
},
|
||||
|
||||
"mips2c_functions_by_name": [
|
||||
"collide-do-primitives",
|
||||
"moving-sphere-triangle-intersect",
|
||||
"calc-animation-from-spr",
|
||||
"draw-string-asm",
|
||||
// "draw-string",
|
||||
// "get-string-length",
|
||||
"adgif-shader<-texture-with-update!",
|
||||
"init-boundary-regs",
|
||||
"draw-boundary-polygon",
|
||||
"render-boundary-quad",
|
||||
"render-boundary-tri",
|
||||
"clip-polygon-against-negative-hyperplane",
|
||||
"clip-polygon-against-positive-hyperplane",
|
||||
"sp-init-fields!",
|
||||
"particle-adgif",
|
||||
"sp-launch-particles-var",
|
||||
"sparticle-motion-blur",
|
||||
"sp-process-block-2d",
|
||||
"sp-process-block-3d",
|
||||
"set-tex-offset",
|
||||
"draw-large-polygon",
|
||||
"render-sky-quad",
|
||||
"render-sky-tri",
|
||||
"(method 17 sky-work)",
|
||||
"(method 18 sky-work)",
|
||||
"(method 32 sky-work)",
|
||||
"(method 31 sky-work)",
|
||||
"(method 29 sky-work)",
|
||||
"(method 30 sky-work)",
|
||||
// "(method 34 sky-work)",
|
||||
// "(method 35 sky-work)",
|
||||
"(method 11 collide-hash)",
|
||||
"(method 12 collide-hash)",
|
||||
"fill-bg-using-box-new",
|
||||
"fill-bg-using-line-sphere-new",
|
||||
"(method 12 collide-mesh)",
|
||||
"(method 14 collide-mesh)",
|
||||
"(method 15 collide-mesh)",
|
||||
"(method 10 collide-edge-hold-list)",
|
||||
"(method 19 collide-edge-work)",
|
||||
"(method 9 edge-grab-info)",
|
||||
"(method 16 collide-edge-work)",
|
||||
"(method 17 collide-edge-work)",
|
||||
"(method 18 collide-edge-work)",
|
||||
"draw-large-polygon-ocean",
|
||||
"render-ocean-quad",
|
||||
"init-ocean-far-regs",
|
||||
"(method 14 ocean)",
|
||||
"(method 15 ocean)",
|
||||
"(method 16 ocean)",
|
||||
"(method 18 grid-hash)",
|
||||
"(method 19 grid-hash)",
|
||||
"(method 20 grid-hash)",
|
||||
"(method 22 grid-hash)",
|
||||
"(method 28 sphere-hash)",
|
||||
"(method 33 sphere-hash)",
|
||||
"(method 29 sphere-hash)",
|
||||
"(method 30 sphere-hash)",
|
||||
"(method 31 sphere-hash)",
|
||||
"(method 32 sphere-hash)",
|
||||
"(method 32 spatial-hash)",
|
||||
"(method 34 spatial-hash)",
|
||||
"(method 35 spatial-hash)",
|
||||
"(method 36 spatial-hash)",
|
||||
"(method 38 spatial-hash)",
|
||||
"(method 10 collide-shape-prim-mesh)",
|
||||
"(method 10 collide-shape-prim-sphere)",
|
||||
"(method 10 collide-shape-prim-group)",
|
||||
"(method 11 collide-shape-prim-mesh)",
|
||||
"(method 11 collide-shape-prim-sphere)",
|
||||
"(method 11 collide-shape-prim-group)",
|
||||
"(method 9 collide-cache-prim)",
|
||||
"(method 10 collide-cache-prim)",
|
||||
"(method 17 collide-cache)",
|
||||
"(method 9 collide-puss-work)",
|
||||
"(method 10 collide-puss-work)",
|
||||
"bones-mtx-calc",
|
||||
"foreground-check-longest-edge-asm",
|
||||
"foreground-merc",
|
||||
"add-light-sphere-to-light-group",
|
||||
"light-hash-add-items",
|
||||
"light-hash-count-items",
|
||||
"light-hash-get-bucket-index",
|
||||
// nav-mesh / nav-control related
|
||||
// TODO - it would be nice to eventually figure out the asm blocks for the majority of these
|
||||
"nav-state-patch-pointers",
|
||||
"(method 20 nav-engine)",
|
||||
// "find-closest-circle-ray-intersection",
|
||||
// "(method 18 nav-control)",
|
||||
"nav-dma-send-to-spr-no-flush",
|
||||
"nav-dma-send-from-spr-no-flush",
|
||||
"(method 17 nav-engine)",
|
||||
"(method 18 nav-engine)",
|
||||
"(method 21 nav-engine)",
|
||||
"(method 39 nav-state)",
|
||||
"setup-blerc-chains-for-one-fragment",
|
||||
"blerc-execute",
|
||||
"ripple-create-wave-table",
|
||||
"ripple-execute-init",
|
||||
"ripple-apply-wave-table",
|
||||
"ripple-matrix-scale",
|
||||
"(method 53 squid)",
|
||||
"init-vortex-regs",
|
||||
"render-vortex-quad",
|
||||
"draw-large-polygon-vortex",
|
||||
"foreground-generic-merc",
|
||||
"generic-merc-init-asm",
|
||||
"mercneric-convert",
|
||||
"high-speed-reject",
|
||||
"generic-translucent",
|
||||
"generic-merc-query",
|
||||
"generic-merc-death",
|
||||
"generic-merc-execute-asm",
|
||||
"generic-merc-do-chain",
|
||||
"generic-light-proc",
|
||||
"generic-envmap-proc",
|
||||
"generic-prepare-dma-double",
|
||||
"generic-prepare-dma-single",
|
||||
"generic-warp-source-proc",
|
||||
"generic-warp-dest-proc",
|
||||
"generic-warp-dest",
|
||||
"generic-warp-envmap-dest",
|
||||
"generic-no-light-proc",
|
||||
"(method 21 cloth-system)",
|
||||
"debug-line-clip?",
|
||||
"(method 9 font-work)",
|
||||
"live-func-curve",
|
||||
"birth-func-curve",
|
||||
"sparticle-motion-blur-dirt",
|
||||
"foreground-draw-hud",
|
||||
"shadow-execute",
|
||||
"shadow-add-double-edges",
|
||||
"shadow-add-single-edges",
|
||||
"shadow-add-facing-single-tris",
|
||||
"shadow-add-double-tris",
|
||||
"shadow-xform-verts",
|
||||
"shadow-calc-dual-verts",
|
||||
"shadow-scissor-edges",
|
||||
"shadow-scissor-top",
|
||||
"shadow-init-vars",
|
||||
"shadow-find-facing-single-tris",
|
||||
"shadow-find-single-edges",
|
||||
"shadow-find-facing-double-tris",
|
||||
"shadow-find-double-edges",
|
||||
"shadow-add-verts",
|
||||
"shadow-add-single-tris"
|
||||
],
|
||||
|
||||
"mips2c_jump_table_functions": {},
|
||||
|
||||
// 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],
|
||||
["lfaccity", 0, 0],
|
||||
["ltowcity", 0, 0],
|
||||
["powergd", 0, 0],
|
||||
["lcitysml", 0, 0]
|
||||
],
|
||||
|
||||
// some object files have garbage pad data at the end which makes the decompiler
|
||||
// assume they must be different files, such as the art group for orb-cache-top.
|
||||
// this just suppresses a message.
|
||||
"expected_merged_objs": []
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
// This overrides the stack size for calls to stack-size-set! in given functions.
|
||||
{
|
||||
// NOTE: almost all of these were just copy pasted from jak2
|
||||
// so it's impossible to know which are actually needed for jakx...
|
||||
// commenting out incase there's something here actually needed
|
||||
|
||||
"(method 29 target)": 2048,
|
||||
"(method 11 part-spawner)": 64,
|
||||
"(method 11 elevator)": 1024,
|
||||
"scene-player-init": 1024,
|
||||
"task-manager-init-by-other": 2048,
|
||||
"race-manager-init-by-other": 1024,
|
||||
"neo-sat-shield-init-by-other": 64,
|
||||
"bt-gun-manager-init-by-other": 256
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+100
-47
@@ -100,57 +100,110 @@ void TextureDB::add_index_texture(u32 tpage,
|
||||
}
|
||||
|
||||
void TextureDB::merge_textures(const fs::path& base_path) {
|
||||
for (auto& tex : textures) {
|
||||
fs::path full_path = base_path / tpage_names.at(tex.second.page) / (tex.second.name + ".png");
|
||||
if (fs::exists(full_path)) {
|
||||
lg::info("Merging {}", full_path.string().c_str());
|
||||
int w, h;
|
||||
auto merge_data = stbi_load(full_path.string().c_str(), &w, &h, 0, 4); // rgba channels
|
||||
if (!merge_data) {
|
||||
lg::warn("failed to load PNG file: {}", full_path.string().c_str());
|
||||
continue;
|
||||
} else if (w != tex.second.w || h != tex.second.h) {
|
||||
lg::warn("merge texture does not match the same dimensions: {}, {} != {} || {} != {}",
|
||||
full_path.string().c_str(), w, tex.second.w, h, tex.second.h);
|
||||
stbi_image_free(merge_data);
|
||||
continue;
|
||||
}
|
||||
// Merge any non-transparent pixels into the existing texture
|
||||
for (int i = 0; i < w * h * 4; i += 4) {
|
||||
const auto merge_pixel_a = merge_data[i + 3];
|
||||
if (merge_pixel_a != 0) {
|
||||
u32 merge_pixel;
|
||||
memcpy(&merge_pixel, &merge_data[i], sizeof(u32));
|
||||
tex.second.rgba_bytes.at(i / 4) = merge_pixel;
|
||||
}
|
||||
}
|
||||
stbi_image_free(merge_data);
|
||||
}
|
||||
}
|
||||
merge_texture_dir = base_path;
|
||||
}
|
||||
|
||||
void TextureDB::replace_textures(const fs::path& path) {
|
||||
fs::path base_path(path);
|
||||
for (auto& tex : textures) {
|
||||
fs::path full_path = base_path / tpage_names.at(tex.second.page) / (tex.second.name + ".png");
|
||||
if (!fs::exists(full_path)) {
|
||||
full_path = base_path / "_all" / (tex.second.name + ".png");
|
||||
if (!fs::exists(full_path))
|
||||
continue;
|
||||
}
|
||||
lg::info("Replacing {}", tpage_names.at(tex.second.page) + "/" + (tex.second.name));
|
||||
int w, h;
|
||||
auto data = stbi_load(full_path.string().c_str(), &w, &h, 0, 4); // rgba channels
|
||||
if (!data) {
|
||||
lg::warn("failed to load PNG file: {}", full_path.string().c_str());
|
||||
continue;
|
||||
}
|
||||
tex.second.rgba_bytes.resize(w * h);
|
||||
memcpy(tex.second.rgba_bytes.data(), data, w * h * 4);
|
||||
tex.second.w = w;
|
||||
tex.second.h = h;
|
||||
stbi_image_free(data);
|
||||
replace_texture_dir = path;
|
||||
}
|
||||
|
||||
void TextureDB::merge_texture(u32 id, std::vector<u32>& rgba) const {
|
||||
if (!merge_texture_dir) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& tex = textures.at(id);
|
||||
fs::path full_path = *merge_texture_dir / tpage_names.at(tex.page) / (tex.name + ".png");
|
||||
|
||||
if (!fs::exists(full_path)) {
|
||||
return;
|
||||
}
|
||||
|
||||
lg::info("Merging {}", full_path.string().c_str());
|
||||
|
||||
int w, h;
|
||||
auto merge_data = stbi_load(full_path.string().c_str(), &w, &h, 0, 4);
|
||||
|
||||
if (!merge_data) {
|
||||
lg::warn("failed to load PNG file: {}", full_path.string().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
if (w != tex.w || h != tex.h) {
|
||||
lg::warn("merge texture does not match the same dimensions: {}, {} != {} || {} != {}",
|
||||
full_path.string().c_str(), w, tex.w, h, tex.h);
|
||||
stbi_image_free(merge_data);
|
||||
return;
|
||||
}
|
||||
// Merge any non-transparent pixels into the existing texture
|
||||
for (int i = 0; i < w * h * 4; i += 4) {
|
||||
const auto merge_pixel_a = merge_data[i + 3];
|
||||
if (merge_pixel_a != 0) {
|
||||
u32 merge_pixel;
|
||||
memcpy(&merge_pixel, &merge_data[i], sizeof(u32));
|
||||
rgba.at(i / 4) = merge_pixel;
|
||||
}
|
||||
}
|
||||
|
||||
stbi_image_free(merge_data);
|
||||
}
|
||||
|
||||
std::optional<ResolvedTextureData> TextureDB::replace_texture(u32 id) const {
|
||||
if (!replace_texture_dir) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
const auto& tex = textures.at(id);
|
||||
const auto& tpage_name = tpage_names.at(tex.page);
|
||||
|
||||
fs::path full_path = *replace_texture_dir / tpage_name / (tex.name + ".png");
|
||||
|
||||
if (!fs::exists(full_path)) {
|
||||
full_path = *replace_texture_dir / "_all" / (tex.name + ".png");
|
||||
|
||||
if (!fs::exists(full_path)) {
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
lg::info("Replacing {}", tpage_name + "/" + tex.name);
|
||||
|
||||
int w, h;
|
||||
auto data = stbi_load(full_path.string().c_str(), &w, &h, 0, 4);
|
||||
|
||||
if (!data) {
|
||||
lg::warn("failed to load PNG file: {}", full_path.string().c_str());
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
ResolvedTextureData result;
|
||||
result.w = static_cast<u16>(w);
|
||||
result.h = static_cast<u16>(h);
|
||||
result.rgba.resize(w * h);
|
||||
|
||||
memcpy(result.rgba.data(), data, w * h * 4);
|
||||
|
||||
stbi_image_free(data);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
ResolvedTextureData TextureDB::resolve_texture(u32 id) const {
|
||||
const auto& tex = textures.at(id);
|
||||
|
||||
ResolvedTextureData result{
|
||||
.w = tex.w,
|
||||
.h = tex.h,
|
||||
.rgba = tex.rgba_bytes,
|
||||
};
|
||||
|
||||
merge_texture(id, result.rgba);
|
||||
|
||||
if (auto replacement = replace_texture(id)) {
|
||||
result = std::move(*replacement);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*!
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <optional>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
@@ -11,6 +12,12 @@
|
||||
#include "common/util/FileUtil.h"
|
||||
|
||||
namespace decompiler {
|
||||
struct ResolvedTextureData {
|
||||
u16 w;
|
||||
u16 h;
|
||||
std::vector<u32> rgba;
|
||||
};
|
||||
|
||||
struct TextureDB {
|
||||
TextureDB();
|
||||
struct TextureData {
|
||||
@@ -25,12 +32,16 @@ struct TextureDB {
|
||||
std::map<u32, TextureData> textures;
|
||||
std::unordered_map<u32, std::string> tpage_names;
|
||||
std::unordered_map<std::string, std::set<u32>> texture_ids_per_level;
|
||||
std::optional<fs::path> merge_texture_dir;
|
||||
std::optional<fs::path> replace_texture_dir;
|
||||
|
||||
// special textures for animation.
|
||||
std::map<u32, tfrag3::IndexTexture> index_textures_by_combo_id;
|
||||
|
||||
std::unordered_map<std::string, u32> animated_tex_output_to_anim_slot;
|
||||
|
||||
ResolvedTextureData resolve_texture(u32 id) const;
|
||||
|
||||
static constexpr int kPlaceholderWhiteTexturePage = INT16_MAX;
|
||||
static constexpr int kPlaceholderWhiteTextureId = 0;
|
||||
|
||||
@@ -57,6 +68,8 @@ struct TextureDB {
|
||||
|
||||
void merge_textures(const fs::path& base_path);
|
||||
void replace_textures(const fs::path& path);
|
||||
void merge_texture(u32 id, std::vector<u32>& rgba) const;
|
||||
std::optional<ResolvedTextureData> replace_texture(u32 id) const;
|
||||
|
||||
std::string generate_texture_dest_adjustment_table() const;
|
||||
};
|
||||
|
||||
@@ -130,7 +130,7 @@ int run_decompilation_process(decompiler::Config config,
|
||||
// print disassembly
|
||||
if (config.disassemble_code || config.disassemble_data) {
|
||||
db.write_disassembly(out_folder, config.disassemble_data, config.disassemble_code,
|
||||
config.write_hex_near_instructions);
|
||||
config.write_hex_near_instructions, config.dump_function_metadata);
|
||||
}
|
||||
|
||||
if (config.process_art_groups) {
|
||||
@@ -180,7 +180,7 @@ int run_decompilation_process(decompiler::Config config,
|
||||
|
||||
if (config.generate_all_types) {
|
||||
ASSERT_MSG(config.decompile_code, "Must decompile code to generate all-types");
|
||||
db.ir2_analyze_all_types(out_folder / "new-all-types.gc", config.old_all_types_file,
|
||||
db.ir2_analyze_all_types(out_folder / "_new-all-types.gc", config.old_all_types_file,
|
||||
config.hacks.types_with_bad_inspect_methods);
|
||||
}
|
||||
|
||||
@@ -195,6 +195,12 @@ int run_decompilation_process(decompiler::Config config,
|
||||
}
|
||||
|
||||
if (config.dump_part_group_table) {
|
||||
if (!config.process_part_group_table || !config.decompile_code) {
|
||||
lg::error(
|
||||
"[DUMP] 'dump_part_group_table' set without setting 'process_part_group_table' or "
|
||||
"'decompile_code'");
|
||||
}
|
||||
lg::info("[DUMP] Dumping part group table");
|
||||
db.dump_part_group_table(out_folder, config.part_group_table);
|
||||
}
|
||||
|
||||
@@ -243,6 +249,11 @@ int run_decompilation_process(decompiler::Config config,
|
||||
lg::info("[Mem] After spool handling: {} MB", get_peak_rss() / (1024 * 1024));
|
||||
|
||||
TextureDB tex_db;
|
||||
if (config.dump_tex_info && (!config.process_tpages && config.levels_extract)) {
|
||||
lg::error(
|
||||
"[DUMP] 'dump_tex_info' set without also setting 'process_tpages' or 'levels_extract'");
|
||||
return 1;
|
||||
}
|
||||
if (config.process_tpages || config.levels_extract) {
|
||||
auto textures_out = out_folder / "textures";
|
||||
auto dump_out = out_folder / "import";
|
||||
@@ -254,6 +265,10 @@ int run_decompilation_process(decompiler::Config config,
|
||||
tex_db.generate_texture_dest_adjustment_table());
|
||||
}
|
||||
if (config.dump_tex_info) {
|
||||
if (!config.write_tpage_imports) {
|
||||
lg::error("[DUMP] 'dump_tex_info' set without setting 'write_tpage_imports'");
|
||||
return 1;
|
||||
}
|
||||
auto texture_file_name = out_folder / "dump" / "tex-info.min.json";
|
||||
nlohmann::json texture_json = db.dts.textures;
|
||||
file_util::create_dir_if_needed_for_file(texture_file_name);
|
||||
|
||||
@@ -16,6 +16,136 @@ struct Joint {
|
||||
math::Matrix4f bind_pose_T_w;
|
||||
};
|
||||
|
||||
struct UncompressedSingleJointAnim {
|
||||
std::vector<math::Vector3f> trans_frames;
|
||||
std::vector<math::Vector3f> scale_frames;
|
||||
std::vector<math::Vector4f> quat_frames;
|
||||
};
|
||||
|
||||
struct UncompressedJointAnim {
|
||||
std::string name;
|
||||
std::vector<UncompressedSingleJointAnim> joints;
|
||||
float framerate = 30;
|
||||
int frames = 0;
|
||||
};
|
||||
|
||||
struct CompressedMatrixMetadata {
|
||||
bool is_animated[2];
|
||||
};
|
||||
|
||||
struct CompressedFrame {
|
||||
std::vector<u16> data16;
|
||||
std::vector<u32> data32;
|
||||
std::vector<u64> data64;
|
||||
|
||||
int size_bytes() const { return data16.size() * 2 + data32.size() * 4 + data64.size() * 8; }
|
||||
};
|
||||
|
||||
struct CompressedJointMetadata {
|
||||
bool animated_trans = false;
|
||||
bool animated_quat = false;
|
||||
bool animated_scale = false;
|
||||
bool big_trans_mode = false;
|
||||
};
|
||||
|
||||
struct CompressedAnim {
|
||||
std::string name;
|
||||
CompressedFrame fixed;
|
||||
std::vector<CompressedFrame> frames;
|
||||
bool matrix_animated[2] = {false, false};
|
||||
std::vector<CompressedJointMetadata> joint_metadata;
|
||||
float framerate = 60;
|
||||
};
|
||||
|
||||
struct JointAnimCompressedHDR {
|
||||
u32 control_bits[14];
|
||||
u32 num_joints;
|
||||
u32 matrix_bits;
|
||||
|
||||
JointAnimCompressedHDR() {
|
||||
for (auto& bit : control_bits) {
|
||||
bit = 0;
|
||||
}
|
||||
num_joints = 1;
|
||||
matrix_bits = 0;
|
||||
}
|
||||
};
|
||||
|
||||
struct JointAnimCompressedFixed {
|
||||
JointAnimCompressedHDR hdr;
|
||||
u32 offset_64;
|
||||
u32 offset_32;
|
||||
u32 offset_16;
|
||||
u32 reserved;
|
||||
math::Vector4f data[133];
|
||||
int num_data_qw_used = 0;
|
||||
bool mat[2] = {false, false};
|
||||
math::Matrix4f mats[2] = {math::Matrix4f::zero(), math::Matrix4f::zero()};
|
||||
u64 data64_size;
|
||||
u32 data32_size;
|
||||
u16 data16_size;
|
||||
std::vector<u64> data64;
|
||||
std::vector<u32> data32;
|
||||
std::vector<u16> data16;
|
||||
|
||||
JointAnimCompressedFixed() {
|
||||
offset_64 = 0;
|
||||
offset_32 = 0;
|
||||
offset_16 = 0;
|
||||
reserved = 0;
|
||||
data[0] = math::Vector4f(1.0f, 0.0f, 0.0f, 0.0f);
|
||||
data[1] = math::Vector4f(0.0f, 1.0f, 0.0f, 0.0f);
|
||||
data[2] = math::Vector4f(0.0f, 0.0f, 1.0f, 0.0f);
|
||||
data[3] = math::Vector4f(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
data[4] = math::Vector4f(1.0f, 0.0f, 0.0f, 0.0f);
|
||||
data[5] = math::Vector4f(0.0f, 1.0f, 0.0f, 0.0f);
|
||||
data[6] = math::Vector4f(0.0f, 0.0f, 1.0f, 0.0f);
|
||||
data[7] = math::Vector4f(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
num_data_qw_used = 8;
|
||||
}
|
||||
};
|
||||
|
||||
struct JointAnimCompressedFrame {
|
||||
u32 offset_64;
|
||||
u32 offset_32;
|
||||
u32 offset_16;
|
||||
u32 reserved;
|
||||
// math::Vector4f data[133];
|
||||
u32 num_data_qw_used = 0;
|
||||
bool mat[2] = {false, false};
|
||||
math::Matrix4f mats[2] = {math::Matrix4f::zero(), math::Matrix4f::zero()};
|
||||
u64 data64_size;
|
||||
u32 data32_size;
|
||||
u16 data16_size;
|
||||
std::vector<u64> data64;
|
||||
std::vector<u32> data32;
|
||||
std::vector<u16> data16;
|
||||
|
||||
JointAnimCompressedFrame() {
|
||||
offset_64 = 0;
|
||||
offset_32 = 0;
|
||||
offset_16 = 0;
|
||||
reserved = 0;
|
||||
}
|
||||
};
|
||||
|
||||
struct JointAnimCompressedControl {
|
||||
u32 num_frames;
|
||||
u32 fixed_qwc;
|
||||
u32 frame_qwc;
|
||||
JointAnimCompressedFixed fixed;
|
||||
std::vector<JointAnimCompressedFrame> frame;
|
||||
};
|
||||
|
||||
struct ArtJointAnim {
|
||||
std::string name;
|
||||
float speed;
|
||||
float artist_base;
|
||||
float artist_step;
|
||||
s16 length;
|
||||
JointAnimCompressedControl frames;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Data extracted from art groups that is not needed for .FR3, but is potentially needed for other
|
||||
* stuff (skeleton export).
|
||||
@@ -24,6 +154,7 @@ struct ArtData {
|
||||
std::string art_group_name;
|
||||
std::string art_name;
|
||||
std::vector<Joint> joint_group;
|
||||
std::vector<ArtJointAnim> anims;
|
||||
};
|
||||
|
||||
} // namespace level_tools
|
||||
@@ -0,0 +1,299 @@
|
||||
#include "extract_anim.h"
|
||||
|
||||
#include "common_formats.h"
|
||||
|
||||
#include "decompiler/ObjectFile/LinkedObjectFile.h"
|
||||
#include "decompiler/util/goal_data_reader.h"
|
||||
|
||||
#include "third-party/lzokay/lzokay.hpp"
|
||||
|
||||
namespace decompiler {
|
||||
|
||||
static std::vector<u8> get_plain_data_bytes_up_to_label(const Ref& ref) {
|
||||
const auto& words = ref.data->words_by_seg.at(ref.seg);
|
||||
int start_word = ref.byte_offset / 4;
|
||||
std::vector<u8> result;
|
||||
for (int w = start_word; w < (int)words.size(); w++) {
|
||||
if (words[w].kind() != LinkedWord::PLAIN_DATA)
|
||||
break;
|
||||
for (int b = 0; b < 4; b++)
|
||||
result.push_back(words[w].get_byte(b));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static u32 read_u32(const u8* p) {
|
||||
u32 v;
|
||||
memcpy(&v, p, 4);
|
||||
return v;
|
||||
}
|
||||
|
||||
static void parse_fixed_from_buf(const u8* p,
|
||||
level_tools::JointAnimCompressedFixed& fixed,
|
||||
u32 fixed_qwc) {
|
||||
memcpy(fixed.hdr.control_bits, p, sizeof(u32) * 14);
|
||||
fixed.hdr.num_joints = read_u32(p + 56);
|
||||
fixed.hdr.matrix_bits = read_u32(p + 60);
|
||||
fixed.offset_64 = read_u32(p + 64);
|
||||
fixed.offset_32 = read_u32(p + 68);
|
||||
fixed.offset_16 = read_u32(p + 72);
|
||||
fixed.reserved = read_u32(p + 76);
|
||||
|
||||
fixed.data64_size = fixed.offset_32 - fixed.offset_64;
|
||||
fixed.data32_size = fixed.offset_16 - fixed.offset_32;
|
||||
int data16 = (int)((fixed_qwc - 5) * 16) - (int)fixed.data64_size - (int)fixed.data32_size;
|
||||
ASSERT(data16 >= 0);
|
||||
fixed.data16_size = (u16)data16;
|
||||
|
||||
fixed.mat[0] = (fixed.hdr.matrix_bits & 1) == 0;
|
||||
fixed.mat[1] = (fixed.hdr.matrix_bits & 2) == 0;
|
||||
|
||||
const u8* data = p + 80;
|
||||
int d64 = (int)fixed.data64_size;
|
||||
int d32 = (int)fixed.data32_size;
|
||||
int d16 = (int)fixed.data16_size;
|
||||
|
||||
fixed.data64.resize((d64 + 7) / 8);
|
||||
if (d64 > 0)
|
||||
memcpy(fixed.data64.data(), data + fixed.offset_64, d64);
|
||||
fixed.data32.resize((d32 + 3) / 4);
|
||||
if (d32 > 0)
|
||||
memcpy(fixed.data32.data(), data + fixed.offset_32, d32);
|
||||
fixed.data16.resize((d16 + 1) / 2);
|
||||
if (d16 > 0)
|
||||
memcpy(fixed.data16.data(), data + fixed.offset_16, d16);
|
||||
}
|
||||
|
||||
static void parse_frame_from_buf(const u8* p,
|
||||
level_tools::JointAnimCompressedFrame& frame,
|
||||
u32 frame_qwc) {
|
||||
frame.offset_64 = read_u32(p + 0);
|
||||
frame.offset_32 = read_u32(p + 4);
|
||||
frame.offset_16 = read_u32(p + 8);
|
||||
frame.reserved = read_u32(p + 12);
|
||||
|
||||
frame.data64_size = frame.offset_32 - frame.offset_64;
|
||||
frame.data32_size = frame.offset_16 - frame.offset_32;
|
||||
int data16 = (int)((frame_qwc - 1) * 16) - (int)frame.data64_size - (int)frame.data32_size;
|
||||
ASSERT(data16 >= 0);
|
||||
frame.data16_size = (u16)data16;
|
||||
|
||||
const u8* data = p + 16;
|
||||
int fd64 = (int)frame.data64_size;
|
||||
int fd32 = (int)frame.data32_size;
|
||||
int fd16 = (int)frame.data16_size;
|
||||
|
||||
frame.data64.resize((fd64 + 7) / 8);
|
||||
if (fd64 > 0)
|
||||
memcpy(frame.data64.data(), data + frame.offset_64, fd64);
|
||||
frame.data32.resize((fd32 + 3) / 4);
|
||||
if (fd32 > 0)
|
||||
memcpy(frame.data32.data(), data + frame.offset_32, fd32);
|
||||
frame.data16.resize((fd16 + 1) / 2);
|
||||
if (fd16 > 0)
|
||||
memcpy(frame.data16.data(), data + frame.offset_16, fd16);
|
||||
}
|
||||
|
||||
void extract_animations(const ObjectFileData& ag_data,
|
||||
const DecompilerTypeSystem& dts,
|
||||
GameVersion version,
|
||||
std::map<std::string, level_tools::ArtData>& out) {
|
||||
auto ja_locs = find_objects_with_type(ag_data.linked_data, "art-joint-anim");
|
||||
if (ja_locs.empty()) {
|
||||
lg::warn("extract_animations: art group {} has no anims, skipping", ag_data.name_in_dgo);
|
||||
return;
|
||||
}
|
||||
// jak 2/3 split the first word into num-frames + flags
|
||||
const bool has_flags = version != GameVersion::Jak1;
|
||||
for (auto loc : ja_locs) {
|
||||
TypedRef ref(Ref{&ag_data.linked_data, 0, loc * 4}, dts.ts.lookup_type("art-joint-anim"));
|
||||
auto master_art_name = read_string_field(ref, "master-art-group-name", dts, false);
|
||||
level_tools::ArtJointAnim ja;
|
||||
ja.name = read_string_field(ref, "name", dts, false);
|
||||
ja.speed = read_plain_data_field<float>(ref, "speed", dts);
|
||||
ja.artist_base = read_plain_data_field<float>(ref, "artist-base", dts);
|
||||
ja.artist_step = read_plain_data_field<float>(ref, "artist-step", dts);
|
||||
Ref jacc = deref_label(get_field_ref(ref, "frames", dts));
|
||||
int jacc_word_off = 0;
|
||||
u32 first_word = deref_u32(jacc, jacc_word_off++);
|
||||
ja.frames.num_frames = has_flags ? (first_word & 0xFFFF) : first_word;
|
||||
ja.frames.fixed_qwc = deref_u32(jacc, jacc_word_off++);
|
||||
ja.frames.frame_qwc = deref_u32(jacc, jacc_word_off++);
|
||||
|
||||
// jak 2/3 may lzo compress the animation, check the flag bit
|
||||
const bool lzo_compressed = has_flags && ((first_word >> 16) & 1) != 0;
|
||||
// lg::info("{}: extracting anim {} (compressed {})", ag_data.name_in_dgo, ja.name,
|
||||
// lzo_compressed);
|
||||
|
||||
Ref fixed_ptr = jacc;
|
||||
fixed_ptr.byte_offset += jacc_word_off * 4;
|
||||
Ref fixed_ref = deref_label(fixed_ptr);
|
||||
|
||||
if (lzo_compressed) {
|
||||
size_t decompressed_size =
|
||||
((size_t)ja.frames.fixed_qwc + (size_t)ja.frames.num_frames * ja.frames.frame_qwc) * 16;
|
||||
|
||||
auto compressed = get_plain_data_bytes_up_to_label(fixed_ref);
|
||||
ASSERT(!compressed.empty());
|
||||
|
||||
std::vector<u8> decompressed(decompressed_size);
|
||||
size_t out_size = 0;
|
||||
auto lzo_result = lzokay::decompress(compressed.data(), compressed.size(),
|
||||
decompressed.data(), decompressed.size(), out_size);
|
||||
ASSERT(lzo_result == lzokay::EResult::Success ||
|
||||
lzo_result == lzokay::EResult::InputNotConsumed);
|
||||
// if (out_size != decompressed_size) {
|
||||
// lg::warn("lzo decomp size mismatch for '{}' in '{}': got {} bytes, expected {}", ja.name,
|
||||
// ag_data.name_in_dgo, out_size, decompressed_size);
|
||||
// }
|
||||
|
||||
parse_fixed_from_buf(decompressed.data(), ja.frames.fixed, ja.frames.fixed_qwc);
|
||||
|
||||
size_t frame_base = (size_t)ja.frames.fixed_qwc * 16;
|
||||
for (int i = 0; i < (int)ja.frames.num_frames; i++) {
|
||||
auto& frame = ja.frames.frame.emplace_back();
|
||||
parse_frame_from_buf(
|
||||
decompressed.data() + frame_base + (size_t)i * ja.frames.frame_qwc * 16, frame,
|
||||
ja.frames.frame_qwc);
|
||||
}
|
||||
} else {
|
||||
int fixed_word_off = 0;
|
||||
|
||||
// fixed hdr
|
||||
memcpy_from_plain_data((u8*)ja.frames.fixed.hdr.control_bits, fixed_ref, 4 * 14);
|
||||
fixed_word_off += 14;
|
||||
ja.frames.fixed.hdr.num_joints = deref_u32(fixed_ref, fixed_word_off++);
|
||||
ja.frames.fixed.hdr.matrix_bits = deref_u32(fixed_ref, fixed_word_off++);
|
||||
ja.frames.fixed.offset_64 = deref_u32(fixed_ref, fixed_word_off++);
|
||||
ja.frames.fixed.offset_32 = deref_u32(fixed_ref, fixed_word_off++);
|
||||
ja.frames.fixed.offset_16 = deref_u32(fixed_ref, fixed_word_off++);
|
||||
ja.frames.fixed.reserved = deref_u32(fixed_ref, fixed_word_off++);
|
||||
|
||||
ja.frames.fixed.data64_size = ja.frames.fixed.offset_32 - ja.frames.fixed.offset_64;
|
||||
ja.frames.fixed.data32_size = ja.frames.fixed.offset_16 - ja.frames.fixed.offset_32;
|
||||
{
|
||||
int data16 = (int)((ja.frames.fixed_qwc - 5) * 16) - (int)ja.frames.fixed.data64_size -
|
||||
(int)ja.frames.fixed.data32_size;
|
||||
ASSERT(data16 >= 0);
|
||||
ja.frames.fixed.data16_size = (u16)data16;
|
||||
}
|
||||
|
||||
// matrix flags
|
||||
ja.frames.fixed.mat[0] = (ja.frames.fixed.hdr.matrix_bits & 1) == 0;
|
||||
ja.frames.fixed.mat[1] = (ja.frames.fixed.hdr.matrix_bits & 2) == 0;
|
||||
|
||||
fixed_ref.byte_offset += fixed_word_off * 4;
|
||||
|
||||
int d64_bytes = (int)ja.frames.fixed.data64_size;
|
||||
int d32_bytes = (int)ja.frames.fixed.data32_size;
|
||||
int d16_bytes = (int)ja.frames.fixed.data16_size;
|
||||
|
||||
ja.frames.fixed.data64.resize((d64_bytes + 7) / 8);
|
||||
if (d64_bytes > 0) {
|
||||
Ref d64 = fixed_ref;
|
||||
d64.byte_offset += ja.frames.fixed.offset_64;
|
||||
memcpy_from_plain_data((u8*)ja.frames.fixed.data64.data(), d64, d64_bytes);
|
||||
}
|
||||
ja.frames.fixed.data32.resize((d32_bytes + 3) / 4);
|
||||
if (d32_bytes > 0) {
|
||||
Ref d32 = fixed_ref;
|
||||
d32.byte_offset += ja.frames.fixed.offset_32;
|
||||
memcpy_from_plain_data((u8*)ja.frames.fixed.data32.data(), d32, d32_bytes);
|
||||
}
|
||||
ja.frames.fixed.data16.resize((d16_bytes + 1) / 2);
|
||||
if (d16_bytes > 0) {
|
||||
Ref d16 = fixed_ref;
|
||||
d16.byte_offset += ja.frames.fixed.offset_16;
|
||||
memcpy_from_plain_data((u8*)ja.frames.fixed.data16.data(), d16, d16_bytes);
|
||||
}
|
||||
|
||||
Ref frames_ref = jacc;
|
||||
frames_ref.byte_offset += 16;
|
||||
for (int i = 0; i < (int)ja.frames.num_frames; i++) {
|
||||
Ref frame_ref = deref_label(frames_ref);
|
||||
int frame_off = 0;
|
||||
auto& frame = ja.frames.frame.emplace_back();
|
||||
|
||||
frame.offset_64 = deref_u32(frame_ref, frame_off++);
|
||||
frame.offset_32 = deref_u32(frame_ref, frame_off++);
|
||||
frame.offset_16 = deref_u32(frame_ref, frame_off++);
|
||||
frame.reserved = deref_u32(frame_ref, frame_off++);
|
||||
|
||||
frame.data64_size = frame.offset_32 - frame.offset_64;
|
||||
frame.data32_size = frame.offset_16 - frame.offset_32;
|
||||
{
|
||||
int data16 = (int)((ja.frames.frame_qwc - 1) * 16) - (int)frame.data64_size -
|
||||
(int)frame.data32_size;
|
||||
ASSERT(data16 >= 0);
|
||||
frame.data16_size = (u16)data16;
|
||||
}
|
||||
|
||||
Ref frame_data = frame_ref;
|
||||
frame_data.byte_offset += frame_off * 4;
|
||||
|
||||
int fd64_bytes = (int)frame.data64_size;
|
||||
int fd32_bytes = (int)frame.data32_size;
|
||||
int fd16_bytes = (int)frame.data16_size;
|
||||
|
||||
frame.data64.resize((fd64_bytes + 7) / 8);
|
||||
if (fd64_bytes > 0) {
|
||||
Ref fd64 = frame_data;
|
||||
fd64.byte_offset += frame.offset_64;
|
||||
memcpy_from_plain_data((u8*)frame.data64.data(), fd64, fd64_bytes);
|
||||
}
|
||||
frame.data32.resize((fd32_bytes + 3) / 4);
|
||||
if (fd32_bytes > 0) {
|
||||
Ref fd32 = frame_data;
|
||||
fd32.byte_offset += frame.offset_32;
|
||||
memcpy_from_plain_data((u8*)frame.data32.data(), fd32, fd32_bytes);
|
||||
}
|
||||
frame.data16.resize((fd16_bytes + 1) / 2);
|
||||
if (fd16_bytes > 0) {
|
||||
Ref fd16 = frame_data;
|
||||
fd16.byte_offset += frame.offset_16;
|
||||
memcpy_from_plain_data((u8*)frame.data16.data(), fd16, fd16_bytes);
|
||||
}
|
||||
|
||||
frames_ref.byte_offset += 4;
|
||||
}
|
||||
}
|
||||
// some master art groups and model names do not match, this remaps the model name based on the
|
||||
// animation name prefix for these rare exceptions
|
||||
PerGameVersion<std::vector<std::string>> mdl_name_remap{
|
||||
{},
|
||||
{
|
||||
"collectables-bomb-blast",
|
||||
"collectables-health",
|
||||
"collectables-gem",
|
||||
"collectables-generic-blast",
|
||||
"collectables-generic-ripples",
|
||||
"collectables-skill",
|
||||
},
|
||||
{
|
||||
"collectables-bomb-blast",
|
||||
"collectables-health",
|
||||
"collectables-gem",
|
||||
"collectables-generic-blast",
|
||||
"collectables-generic-ripples",
|
||||
"collectables-skill",
|
||||
"collectables-warp-time",
|
||||
},
|
||||
{},
|
||||
};
|
||||
auto lst = mdl_name_remap[version];
|
||||
auto remap = std::ranges::find_if(lst.begin(), lst.end(), [&](const std::string& prefix) {
|
||||
return ja.name.find(prefix) != std::string::npos;
|
||||
});
|
||||
if (remap != lst.end()) {
|
||||
const auto& mdl_prefix = *remap;
|
||||
out[mdl_prefix + "-lod0"].anims.push_back(ja);
|
||||
// out[mdl_name + "-lod1"].anims.push_back(ja);
|
||||
// out[mdl_name + "-lod2"].anims.push_back(ja);
|
||||
} else {
|
||||
out[master_art_name + "-lod0"].anims.push_back(ja);
|
||||
// out[master_art_name + "-lod1"].anims.push_back(ja);
|
||||
// out[master_art_name + "-lod2"].anims.push_back(ja);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace decompiler
|
||||
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
#include "common/custom_data/Tfrag3Data.h"
|
||||
|
||||
#include "decompiler/ObjectFile/ObjectFileDB.h"
|
||||
#include "decompiler/level_extractor/common_formats.h"
|
||||
#include "goalc/build_actor/common/build_actor.h"
|
||||
|
||||
namespace decompiler {
|
||||
void extract_animations(const ObjectFileData& ag_data,
|
||||
const DecompilerTypeSystem& dts,
|
||||
GameVersion version,
|
||||
std::map<std::string, level_tools::ArtData>& out);
|
||||
} // namespace decompiler
|
||||
@@ -3,6 +3,8 @@
|
||||
#include <set>
|
||||
#include <thread>
|
||||
|
||||
#include "extract_anim.h"
|
||||
|
||||
#include "common/log/log.h"
|
||||
#include "common/util/FileUtil.h"
|
||||
#include "common/util/SimpleThreadGroup.h"
|
||||
@@ -59,18 +61,17 @@ bool is_valid_bsp(const decompiler::LinkedObjectFile& file) {
|
||||
return true;
|
||||
}
|
||||
|
||||
tfrag3::Texture make_texture(u32 id,
|
||||
const TextureDB::TextureData& tex,
|
||||
const std::string& tpage_name,
|
||||
bool pool_load) {
|
||||
tfrag3::Texture make_texture(u32 id, const TextureDB& tex_db, bool pool_load) {
|
||||
const auto& tex = tex_db.textures.at(id);
|
||||
auto resolved = tex_db.resolve_texture(id);
|
||||
|
||||
tfrag3::Texture new_tex;
|
||||
new_tex.combo_id = id;
|
||||
new_tex.w = tex.w;
|
||||
new_tex.h = tex.h;
|
||||
new_tex.debug_tpage_name = tpage_name;
|
||||
new_tex.w = resolved.w;
|
||||
new_tex.h = resolved.h;
|
||||
new_tex.debug_tpage_name = tex_db.tpage_names.at(tex.page);
|
||||
new_tex.debug_name = tex.name;
|
||||
new_tex.data = tex.rgba_bytes;
|
||||
new_tex.combo_id = id;
|
||||
new_tex.data = std::move(resolved.rgba);
|
||||
new_tex.load_to_pool = pool_load;
|
||||
return new_tex;
|
||||
}
|
||||
@@ -78,12 +79,13 @@ tfrag3::Texture make_texture(u32 id,
|
||||
void add_all_textures_from_level(tfrag3::Level& lev,
|
||||
const std::string& level_name,
|
||||
const TextureDB& tex_db) {
|
||||
const auto& level_it = tex_db.texture_ids_per_level.find(level_name);
|
||||
if (level_it != tex_db.texture_ids_per_level.end()) {
|
||||
for (auto id : level_it->second) {
|
||||
const auto& tex = tex_db.textures.at(id);
|
||||
lev.textures.push_back(make_texture(id, tex, tex_db.tpage_names.at(tex.page), true));
|
||||
}
|
||||
auto level_it = tex_db.texture_ids_per_level.find(level_name);
|
||||
if (level_it == tex_db.texture_ids_per_level.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto id : level_it->second) {
|
||||
lev.textures.push_back(make_texture(id, tex_db, true));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,6 +131,7 @@ void extract_art_groups_from_level(const ObjectFileDB& db,
|
||||
extract_merc(ag_file, tex_db, db.dts, tex_remap, level_data, false, db.version(),
|
||||
swapped_info);
|
||||
extract_joint_group(ag_file, db.dts, db.version(), art_group_data);
|
||||
extract_animations(ag_file, db.dts, db.version(), art_group_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -310,8 +313,7 @@ void extract_common(const ObjectFileDB& db,
|
||||
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));
|
||||
tfrag_level.textures.push_back(make_texture(id, tex_db, true));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -320,13 +322,16 @@ void extract_common(const ObjectFileDB& db,
|
||||
if (config.animated_textures.count(normal_texture.name) &&
|
||||
!textures_we_have.count(normal_texture.name)) {
|
||||
textures_we_have.insert(normal_texture.name);
|
||||
tfrag_level.textures.push_back(
|
||||
make_texture(id, normal_texture, tex_db.tpage_names.at(normal_texture.page), false));
|
||||
tfrag_level.textures.push_back(make_texture(id, tex_db, false));
|
||||
}
|
||||
}
|
||||
|
||||
Serializer ser;
|
||||
tfrag_level.serialize(ser);
|
||||
if (!config.rip_levels) {
|
||||
tfrag_level.textures.clear();
|
||||
tfrag_level.textures.shrink_to_fit();
|
||||
}
|
||||
auto compressed =
|
||||
compression::compress_zstd(ser.get_save_result().first, ser.get_save_result().second);
|
||||
|
||||
@@ -366,6 +371,10 @@ void extract_from_level(const ObjectFileDB& db,
|
||||
|
||||
Serializer ser;
|
||||
level_data.serialize(ser);
|
||||
if (!config.rip_levels) {
|
||||
level_data.textures.clear();
|
||||
level_data.textures.shrink_to_fit();
|
||||
}
|
||||
auto compressed =
|
||||
compression::compress_zstd(ser.get_save_result().first, ser.get_save_result().second);
|
||||
lg::info("stats for {}", level_data.level_name);
|
||||
@@ -405,12 +414,18 @@ void extract_all_levels(const ObjectFileDB& db,
|
||||
auto entities_dir = file_util::get_jak_project_dir() / "decompiler_out" /
|
||||
game_version_names[config.game_version] / "entities";
|
||||
file_util::create_dir_if_needed(entities_dir);
|
||||
|
||||
int num_workers = dgo_names.size();
|
||||
if (tex_db.replace_texture_dir) {
|
||||
num_workers = 1;
|
||||
}
|
||||
|
||||
SimpleThreadGroup threads;
|
||||
threads.run(
|
||||
[&](int idx) {
|
||||
extract_from_level(db, tex_db, dgo_names[idx], config, output_path, entities_dir);
|
||||
},
|
||||
dgo_names.size());
|
||||
dgo_names.size(), num_workers);
|
||||
threads.join();
|
||||
}
|
||||
|
||||
|
||||
@@ -61,10 +61,7 @@ void extract_all_levels(const ObjectFileDB& db,
|
||||
void add_all_textures_from_level(tfrag3::Level& lev,
|
||||
const std::string& level_name,
|
||||
const TextureDB& tex_db);
|
||||
tfrag3::Texture make_texture(u32 id,
|
||||
const TextureDB::TextureData& tex,
|
||||
const std::string& tpage_name,
|
||||
bool pool_load);
|
||||
tfrag3::Texture make_texture(u32 id, const TextureDB& tex_db, 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,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "fr3_to_gltf.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "common/custom_data/Tfrag3Data.h"
|
||||
@@ -879,6 +880,276 @@ int make_inv_matrix_bind_poses(const std::vector<level_tools::Joint>& joints,
|
||||
return accessor_idx;
|
||||
}
|
||||
|
||||
level_tools::UncompressedJointAnim decompress_anim(const level_tools::ArtJointAnim& art_anim) {
|
||||
constexpr float kQuatScale = 0.000030517578125f;
|
||||
constexpr float kScaleScale = 0.000244140625f;
|
||||
constexpr float kTransScale = 4.f / 4096.f;
|
||||
|
||||
auto read_f32 = [](const u8*& ptr) -> float {
|
||||
float v;
|
||||
memcpy(&v, ptr, 4);
|
||||
ptr += 4;
|
||||
return v;
|
||||
};
|
||||
auto read_s16 = [](const u8*& ptr) -> float {
|
||||
s16 v;
|
||||
memcpy(&v, ptr, 2);
|
||||
ptr += 2;
|
||||
return v;
|
||||
};
|
||||
|
||||
const auto& ctrl = art_anim.frames;
|
||||
const auto& fixed = ctrl.fixed;
|
||||
const auto& hdr = fixed.hdr;
|
||||
int num_joints = (int)hdr.num_joints;
|
||||
int total_frames = (int)ctrl.num_frames;
|
||||
|
||||
level_tools::UncompressedJointAnim out;
|
||||
out.name = art_anim.name;
|
||||
out.framerate = art_anim.speed > 0.f ? art_anim.speed * 60.f : 30.f;
|
||||
out.frames = total_frames;
|
||||
out.joints.resize(2 + num_joints);
|
||||
|
||||
auto d64 = (const u8*)fixed.data64.data();
|
||||
auto d32 = (const u8*)fixed.data32.data();
|
||||
auto d16 = (const u8*)fixed.data16.data();
|
||||
|
||||
if (fixed.mat[0])
|
||||
d64 += 64;
|
||||
if (fixed.mat[1])
|
||||
d64 += 64;
|
||||
|
||||
for (int tqi = 0; tqi < num_joints; tqi++) {
|
||||
int ctrl_idx = tqi / 8;
|
||||
int ctrl_shift = 4 * (tqi % 8);
|
||||
int c = 0xf & (hdr.control_bits[ctrl_idx] >> ctrl_shift);
|
||||
auto& joint = out.joints[2 + tqi];
|
||||
|
||||
if (!(c & 0b0001)) {
|
||||
math::Vector3f t;
|
||||
if (c & 0b1000) {
|
||||
t.x() = read_f32(d64) / 4096.f;
|
||||
t.y() = read_f32(d64) / 4096.f;
|
||||
t.z() = read_f32(d32) / 4096.f;
|
||||
} else {
|
||||
t.x() = read_s16(d32) * kTransScale;
|
||||
t.y() = read_s16(d32) * kTransScale;
|
||||
t.z() = read_s16(d16) * kTransScale;
|
||||
}
|
||||
joint.trans_frames.push_back(t);
|
||||
}
|
||||
|
||||
if (!(c & 0b0010)) {
|
||||
math::Vector4f q;
|
||||
q.x() = read_s16(d64) * kQuatScale;
|
||||
q.y() = read_s16(d64) * kQuatScale;
|
||||
q.z() = read_s16(d64) * kQuatScale;
|
||||
q.w() = read_s16(d64) * kQuatScale;
|
||||
joint.quat_frames.push_back(q);
|
||||
}
|
||||
|
||||
if (!(c & 0b0100)) {
|
||||
math::Vector3f s;
|
||||
s.x() = read_s16(d32) * kScaleScale;
|
||||
s.y() = read_s16(d32) * kScaleScale;
|
||||
s.z() = read_s16(d16) * kScaleScale;
|
||||
joint.scale_frames.push_back(s);
|
||||
}
|
||||
}
|
||||
|
||||
for (int fi = 0; fi < total_frames; fi++) {
|
||||
const auto& frame = ctrl.frame[fi];
|
||||
const u8* data64 = (const u8*)frame.data64.data();
|
||||
const u8* data32 = (const u8*)frame.data32.data();
|
||||
const u8* data16 = (const u8*)frame.data16.data();
|
||||
|
||||
if (!fixed.mat[0])
|
||||
data64 += sizeof(math::Matrix4f);
|
||||
if (!fixed.mat[1])
|
||||
data64 += sizeof(math::Matrix4f);
|
||||
|
||||
for (int tqi = 0; tqi < num_joints; tqi++) {
|
||||
int ctrl_idx = tqi / 8;
|
||||
int ctrl_shift = 4 * (tqi % 8);
|
||||
int c = 0xf & (hdr.control_bits[ctrl_idx] >> ctrl_shift);
|
||||
auto& joint = out.joints[2 + tqi];
|
||||
|
||||
if (c & 0b0001) {
|
||||
math::Vector3f t;
|
||||
if (c & 0b1000) {
|
||||
t.x() = read_f32(data64) / 4096.f;
|
||||
t.y() = read_f32(data64) / 4096.f;
|
||||
t.z() = read_f32(data32) / 4096.f;
|
||||
} else {
|
||||
t.x() = read_s16(data32) * kTransScale;
|
||||
t.y() = read_s16(data32) * kTransScale;
|
||||
t.z() = read_s16(data16) * kTransScale;
|
||||
}
|
||||
joint.trans_frames.push_back(t);
|
||||
}
|
||||
|
||||
if (c & 0b0010) {
|
||||
math::Vector4f q;
|
||||
q.x() = read_s16(data64) * kQuatScale;
|
||||
q.y() = read_s16(data64) * kQuatScale;
|
||||
q.z() = read_s16(data64) * kQuatScale;
|
||||
q.w() = read_s16(data64) * kQuatScale;
|
||||
joint.quat_frames.push_back(q);
|
||||
}
|
||||
|
||||
if (c & 0b0100) {
|
||||
math::Vector3f s;
|
||||
s.x() = read_s16(data32) * kScaleScale;
|
||||
s.y() = read_s16(data32) * kScaleScale;
|
||||
s.z() = read_s16(data16) * kScaleScale;
|
||||
joint.scale_frames.push_back(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int ji = 2; ji < (int)out.joints.size(); ji++) {
|
||||
auto& joint = out.joints[ji];
|
||||
while ((int)joint.trans_frames.size() < total_frames) {
|
||||
if (joint.trans_frames.empty())
|
||||
joint.trans_frames.emplace_back(0.f, 0.f, 0.f);
|
||||
else
|
||||
joint.trans_frames.push_back(joint.trans_frames[0]);
|
||||
}
|
||||
while ((int)joint.quat_frames.size() < total_frames) {
|
||||
if (joint.quat_frames.empty())
|
||||
joint.quat_frames.emplace_back(0.f, 0.f, 0.f, 1.f);
|
||||
else
|
||||
joint.quat_frames.push_back(joint.quat_frames[0]);
|
||||
}
|
||||
while ((int)joint.scale_frames.size() < total_frames) {
|
||||
if (joint.scale_frames.empty())
|
||||
joint.scale_frames.emplace_back(1.f, 1.f, 1.f);
|
||||
else
|
||||
joint.scale_frames.push_back(joint.scale_frames[0]);
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
int make_anim_float_accessor(const std::vector<float>& values, tinygltf::Model& model) {
|
||||
int buf_idx = (int)model.buffers.size();
|
||||
auto& buf = model.buffers.emplace_back();
|
||||
buf.data.resize(values.size() * sizeof(float));
|
||||
memcpy(buf.data.data(), values.data(), buf.data.size());
|
||||
|
||||
int bv_idx = (int)model.bufferViews.size();
|
||||
auto& bv = model.bufferViews.emplace_back();
|
||||
bv.buffer = buf_idx;
|
||||
bv.byteOffset = 0;
|
||||
bv.byteLength = buf.data.size();
|
||||
|
||||
int acc_idx = (int)model.accessors.size();
|
||||
auto& acc = model.accessors.emplace_back();
|
||||
acc.bufferView = bv_idx;
|
||||
acc.byteOffset = 0;
|
||||
acc.componentType = TINYGLTF_COMPONENT_TYPE_FLOAT;
|
||||
acc.count = (int)values.size();
|
||||
acc.type = TINYGLTF_TYPE_SCALAR;
|
||||
if (!values.empty()) {
|
||||
float mn = values[0], mx = values[0];
|
||||
for (float v : values) {
|
||||
mn = std::min(mn, v);
|
||||
mx = std::max(mx, v);
|
||||
}
|
||||
acc.minValues = {(double)mn};
|
||||
acc.maxValues = {(double)mx};
|
||||
}
|
||||
return acc_idx;
|
||||
}
|
||||
|
||||
int make_anim_vec3_accessor(const std::vector<math::Vector3f>& values, tinygltf::Model& model) {
|
||||
static_assert(sizeof(math::Vector3f) == 3 * sizeof(float));
|
||||
int buf_idx = (int)model.buffers.size();
|
||||
auto& buf = model.buffers.emplace_back();
|
||||
buf.data.resize(values.size() * sizeof(math::Vector3f));
|
||||
memcpy(buf.data.data(), values.data(), buf.data.size());
|
||||
|
||||
int bv_idx = (int)model.bufferViews.size();
|
||||
auto& bv = model.bufferViews.emplace_back();
|
||||
bv.buffer = buf_idx;
|
||||
bv.byteOffset = 0;
|
||||
bv.byteLength = buf.data.size();
|
||||
|
||||
int acc_idx = (int)model.accessors.size();
|
||||
auto& acc = model.accessors.emplace_back();
|
||||
acc.bufferView = bv_idx;
|
||||
acc.byteOffset = 0;
|
||||
acc.componentType = TINYGLTF_COMPONENT_TYPE_FLOAT;
|
||||
acc.count = (int)values.size();
|
||||
acc.type = TINYGLTF_TYPE_VEC3;
|
||||
return acc_idx;
|
||||
}
|
||||
|
||||
int make_anim_vec4_accessor(const std::vector<math::Vector4f>& values, tinygltf::Model& model) {
|
||||
static_assert(sizeof(math::Vector4f) == 4 * sizeof(float));
|
||||
int buf_idx = (int)model.buffers.size();
|
||||
auto& buf = model.buffers.emplace_back();
|
||||
buf.data.resize(values.size() * sizeof(math::Vector4f));
|
||||
memcpy(buf.data.data(), values.data(), buf.data.size());
|
||||
|
||||
int bv_idx = (int)model.bufferViews.size();
|
||||
auto& bv = model.bufferViews.emplace_back();
|
||||
bv.buffer = buf_idx;
|
||||
bv.byteOffset = 0;
|
||||
bv.byteLength = buf.data.size();
|
||||
|
||||
int acc_idx = (int)model.accessors.size();
|
||||
auto& acc = model.accessors.emplace_back();
|
||||
acc.bufferView = bv_idx;
|
||||
acc.byteOffset = 0;
|
||||
acc.componentType = TINYGLTF_COMPONENT_TYPE_FLOAT;
|
||||
acc.count = (int)values.size();
|
||||
acc.type = TINYGLTF_TYPE_VEC4;
|
||||
return acc_idx;
|
||||
}
|
||||
|
||||
void add_animation_to_gltf(const level_tools::UncompressedJointAnim& anim,
|
||||
const tinygltf::Skin& skin,
|
||||
tinygltf::Model& model) {
|
||||
if (anim.frames == 0 || anim.joints.size() <= 2)
|
||||
return;
|
||||
|
||||
auto& gltf_anim = model.animations.emplace_back();
|
||||
gltf_anim.name = anim.name;
|
||||
|
||||
std::vector<float> times(anim.frames);
|
||||
for (int i = 0; i < anim.frames; i++)
|
||||
times[i] = i / anim.framerate;
|
||||
int time_acc = make_anim_float_accessor(times, model);
|
||||
|
||||
int n_anim_joints = (int)anim.joints.size();
|
||||
int n_skin_joints = (int)skin.joints.size();
|
||||
for (int ji = 2; ji < n_anim_joints && ji < n_skin_joints; ji++) {
|
||||
const auto& joint = anim.joints[ji];
|
||||
int target_node = skin.joints[ji];
|
||||
|
||||
auto add_channel = [&](int val_acc, const std::string& path) {
|
||||
int si = (int)gltf_anim.samplers.size();
|
||||
auto& sampler = gltf_anim.samplers.emplace_back();
|
||||
sampler.input = time_acc;
|
||||
sampler.output = val_acc;
|
||||
sampler.interpolation = "LINEAR";
|
||||
auto& channel = gltf_anim.channels.emplace_back();
|
||||
channel.sampler = si;
|
||||
channel.target_node = target_node;
|
||||
channel.target_path = path;
|
||||
};
|
||||
|
||||
if ((int)joint.trans_frames.size() == anim.frames)
|
||||
add_channel(make_anim_vec3_accessor(joint.trans_frames, model), "translation");
|
||||
if ((int)joint.quat_frames.size() == anim.frames)
|
||||
add_channel(make_anim_vec4_accessor(joint.quat_frames, model), "rotation");
|
||||
if ((int)joint.scale_frames.size() == anim.frames)
|
||||
add_channel(make_anim_vec3_accessor(joint.scale_frames, model), "scale");
|
||||
}
|
||||
}
|
||||
|
||||
void add_merc(const tfrag3::Level& level,
|
||||
const std::map<std::string, level_tools::ArtData>& art_data,
|
||||
const tfrag3::MercModel& mmodel,
|
||||
@@ -956,6 +1227,15 @@ void add_merc(const tfrag3::Level& level,
|
||||
skin.inverseBindMatrices = make_inv_matrix_bind_poses(game_bones, model);
|
||||
}
|
||||
|
||||
if (art != art_data.end() && !art->second.anims.empty() && node.skin >= 0 &&
|
||||
node.skin < model.skins.size()) {
|
||||
const auto& skin = model.skins[node.skin];
|
||||
for (const auto& ja : art->second.anims) {
|
||||
auto uncompressed = decompress_anim(ja);
|
||||
add_animation_to_gltf(uncompressed, skin, 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++) {
|
||||
|
||||
@@ -1070,7 +1070,8 @@ const std::unordered_map<
|
||||
}},
|
||||
{GameVersion::JakX,
|
||||
{
|
||||
// TODO
|
||||
{"lightning-probe-vars",
|
||||
{{"probe-dirs", ArrayFieldDecompMeta(TypeSpec("vector"), 16)}}},
|
||||
}}};
|
||||
|
||||
goos::Object decompile_structure(const TypeSpec& type,
|
||||
|
||||
@@ -16,5 +16,5 @@ constexpr PerGameVersion<int> SYMBOL_TO_STRING_MEM_OFFSET_DECOMP = {
|
||||
8167 * 8, jak2::SYM_TO_STRING_OFFSET, -99999, -99999, // not supported this way!
|
||||
};
|
||||
|
||||
constexpr PerGameVersion<int> OFFSET_OF_NEXT_STATE_STORE = {72, 64, 68, 68};
|
||||
constexpr PerGameVersion<int> OFFSET_OF_NEXT_STATE_STORE = {72, 64, 68, 76};
|
||||
} // namespace decompiler
|
||||
|
||||
@@ -59,6 +59,7 @@ set(RUNTIME_SOURCE
|
||||
graphics/opengl_renderer/loader/Loader.cpp
|
||||
graphics/opengl_renderer/loader/LoaderStages.cpp
|
||||
graphics/opengl_renderer/ocean/CommonOceanRenderer.cpp
|
||||
graphics/opengl_renderer/ocean/OceanEnvmap.cpp
|
||||
graphics/opengl_renderer/ocean/OceanMid_PS2.cpp
|
||||
graphics/opengl_renderer/ocean/OceanMid.cpp
|
||||
graphics/opengl_renderer/ocean/OceanMidAndFar.cpp
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
"USANDO AS ESTAÇÕES DE TRANSPORTE QUE OS PRECURSORES ESPALHARAM POR TODO O MUNDO.",
|
||||
"IF YOU COME ACROSS ONE OF THESE PADS I CAN LOCK ON TO YOUR COMMUNICATOR'S LOCATION",
|
||||
"AND SEND YOU THE ZOOMER!",
|
||||
"KEEP AN EYE OUT FOR A TRANS-PAD WHEN YOU EXPLORE MISTY ISLAND, AND WHEREVER ELSE YOU GO!"
|
||||
"KEEP AN EYE OUT FOR A TRANS-PAD WHEN YOU EXPLORE ILHA NEBULOSA, AND WHEREVER ELSE YOU GO!"
|
||||
],
|
||||
"assistant-lavatube-end-resolution": [
|
||||
"EI! ONDE É QUE ANDA O PEQUENO, VERDE, E RUGOSO?",
|
||||
@@ -81,7 +81,7 @@
|
||||
],
|
||||
"assistant-reminder-1-race-bike": [
|
||||
"I'VE DEFINITELY FIGURED OUT HOW TO USE THE TRANS-PADS.",
|
||||
"NOW GO TO MISTY ISLAND AND I'LL SEND THE ZOOMER OVER TO YOU."
|
||||
"NOW GO TO ILHA NEBULOSA AND I'LL SEND THE ZOOMER OVER TO YOU."
|
||||
],
|
||||
"assistant-village2-introduction": [
|
||||
"WHOA!",
|
||||
@@ -373,7 +373,7 @@
|
||||
"I'LL GIVE YOU A POWER CELL",
|
||||
"IF YOU CAN CATCH 200 POUNDS OF THEM CRITTERS!",
|
||||
"AND I'LL LET YOU AND SHRIMP HERE",
|
||||
"USE MY SPEEDBOAT TO GET TO MISTY ISLAND.",
|
||||
"USE MY SPEEDBOAT TO GET TO ILHA NEBULOSA.",
|
||||
"YOU'S WANT TO TRY THE CHALLENGE?"
|
||||
],
|
||||
"fisher-reject": [
|
||||
@@ -786,55 +786,55 @@
|
||||
"HEI! UH, JAK? O VELHOTE VERDE DISSE-A-NOS PARA NÃO VIRMOS AQUI!"
|
||||
],
|
||||
"sage-intro-sequence-d1": [
|
||||
"WHAT IN GREEN TARNATION DO YOU TWO WANT?",
|
||||
"WE- WE- WE WAS- THEY WAS- I'M- I WAS-",
|
||||
"DON'T TELL ME! INSTEAD OF HEEDING MY WISDOM",
|
||||
"THE TWO OF YOU WENT MUCKING AROUND",
|
||||
"IN THE ONLY PLACE THAT I TOLD YOU NOT TO GO: MISTY ISLAND!",
|
||||
"THAT'S RIGHT! AND THEN-",
|
||||
"AND, DAXTER, YOU FINALLY TOOK A MUCH-NEEDED BATH",
|
||||
"BUT IN A BATHTUB FILLED WITH DARK ECO.",
|
||||
"LOOK, OLD MAN, ARE YOU GONNA KEEP YAPPIN'",
|
||||
"OR YOU GONNA HELP ME OUTTA THIS MESS!?",
|
||||
"I'M GONNA KEEP YAPPIN'! BECAUSE IN MY PROFESSIONAL OPINION",
|
||||
"THE CHANGE IS AN IMPROVEMENT.",
|
||||
"AND BESIDES... I COULDN'T HELP YOU IF I WANTED TO.",
|
||||
"WHAT!?",
|
||||
"THERE'S ONLY ONE PERSON WHO HAS STUDIED DARK ECO LONG ENOUGH",
|
||||
"TO HAVE A CHANCE AT RETURNING YOU TO YOUR PREVIOUS FORM:",
|
||||
"GOL ACHERON, THE SAGE.",
|
||||
"BUT HE LIVES FAR TO THE NORTH. FAR, FAR TO THE NORTH.",
|
||||
"NOBODY HAS SPOKEN TO HIM IN AGES.",
|
||||
"I WOULD TELEPORT YOU THERE, BUT I CAN'T DO THAT EITHER.",
|
||||
"NONE OF THE THREE SAGES THAT MAINTAIN THE OTHER TELEPORTER GATES",
|
||||
"HAVE SEEN FIT TO TURN THEIR ENDS ON FOR QUITE A WHILE!"
|
||||
"MAS QUE DIABOS VOCÊS DOIS QUEREM??",
|
||||
"NÓS- NÓS- NÓS ÉRAMOS- ELES ERAM- EU SOU- EU ERA -",
|
||||
"NÃO ME DIGAS! EM VEZ DE DARES OUVIDOS À MINHA SABEDORIA",
|
||||
"VOCÊS OS DOIS FORAM VAGUEAR POR AÍ",
|
||||
"NO ÚNICO LUGAR ONDE EU VOS DISSE PARA NÃO IR: ILHA NEBULOSA!",
|
||||
"É ISSO MESMO! E DEPOIS-",
|
||||
"E, DAXTER, FINALMENTE TOMASTE UM BANHO QUE JÁ ESTAVAS A PRECISAR",
|
||||
"MAS NUMA BANHEIRA CHEIA DE ECO NEGRO.",
|
||||
"OLHA VELHOTE, VAIS CONTINUAR O SERMÃO",
|
||||
"OU VAIS AJUDAR-ME A SAIR DESTA CONFUSÃO!?",
|
||||
"VOU CONTINUAR A FALAR! PORQUE, PORQUE NA MINHA OPINIÃO PROFISSIONAL",
|
||||
"A MUDANÇA É UMA MELHORIA.",
|
||||
"E APESAR DISSO... MESMO QUE EU QUISESSE, NÃO PODERIA TE AJUDAR.",
|
||||
"O QUÊ!?",
|
||||
"SÓ EXISTE UMA PESSOA QUE TENHA ESTUDADO O ECO NEGRO POR TEMPO SUFICIENTE",
|
||||
"PARA TER A OPORTUNIDADE DE TE TRAZER À TUA FORMA ORIGINAL:",
|
||||
"GOL ACHERON, O SÁBIO.",
|
||||
"MAS ELE VIVE PARA NORTE. NORTE, BEM LONGE DAQUI.",
|
||||
"NINGUÉM FALA COM ELE HÁ ANOS",
|
||||
"EU TELETRANSPORTAVA-TE PARA LÁ, MAS TAMBÉM NÃO CONSIGO FAZER ISSO.",
|
||||
"NENHUM DOS TRÊS SÁBIOS QUE MANTÉM OS OUTROS PORTAIS DE TELETRANSPORTE",
|
||||
"ACHOU POR BEM LIGÁ-LOS HÁ JÁ BASTANTE TEMPO!"
|
||||
],
|
||||
"sage-intro-sequence-d2": [
|
||||
"THE ONLY OTHER WAY NORTH IS BY FOOT THROUGH THE FIRE CANYON",
|
||||
"BUT ITS VOLCANIC SOIL IS HOT ENOUGH TO MELT PRECURSOR METAL.",
|
||||
"YOU CAN'T JUST WALK THROUGH IT.",
|
||||
"BUT YOU COULD FLY OVER IT",
|
||||
"IF YOU HAD A ZOOMER EQUIPPED WITH A HEAT SHIELD.",
|
||||
"I JUST HAPPEN TO BE WORKING ON SUCH A THING AT THIS VERY MOMENT.",
|
||||
"ALL I WOULD NEED IS TWENTY POWER CELLS TO GIVE IT ENOUGH ENERGY",
|
||||
"TO WITHSTAND THE CANYON'S HEAT. ISN'T THAT RIGHT, DADDY?",
|
||||
"YES, KEIRA, THAT MIGHT WORK. BUT WHERE ARE A BOY",
|
||||
"AND A HALF!",
|
||||
"GOING TO GET TWENTY POWER CELLS?",
|
||||
"FROM THE VILLAGERS! MOST OF THEM HAVE A POWER CELL OR TWO",
|
||||
"STASHED AWAY SOMEWHERE.",
|
||||
"AND EVEN IF THEY AREN'T WILLING TO JUST GIVE THEM AWAY",
|
||||
"GREASING THEIR PALMS WITH A FEW PRECURSOR ORBS SHOULD DO THE TRICK.",
|
||||
"AND I BET THERE ARE EVEN MORE OF THEM OUT IN THE WILDS JUST WAITING FOR SOME",
|
||||
"BRAVE ADVENTURER TO FIND.",
|
||||
"WELL WE'VE GOT THE BRAVE ADVENTURER, AT LEAST.",
|
||||
"BRAVE ADVENTURER?",
|
||||
"YOU TWO COULDN'T FIND YOUR WAY OUT OF THE VILLAGE WITHOUT TRAINING!",
|
||||
"BEFORE YOU DO ANYTHING ELSE, YOU BETTER GO THROUGH THE WARP GATE AND GET",
|
||||
"SOME PRACTICE ON GEYSER ROCK.",
|
||||
"UH, WE WON'T FIND ANY MORE OF THAT DARK GOOEY ECO STUFF, WILL WE?",
|
||||
"'CAUSE I'D HATE TO FALL IN AGAIN AND TURN INTO YOU!",
|
||||
"GET IN THERE! BEFORE I TURN YOU BOTH INTO FERNS!"
|
||||
"A ÚNICA OUTRA MANEIRA DE CHEGAR AO NORTE É A PÉ, ATRAVÉS DO DESFILADEIRO DO FOGO",
|
||||
"MAS O SEU SOLO VULCÂNICO É SUFICIENTEMENTE QUENTE PARA DERRETER O METAL PRECURSOR.",
|
||||
"NÃO PODES SIMPLESMENTE ATRAVESSÁ-LO A PÉ.",
|
||||
"MAS PODEM PASSAR POR CIMA A VOAR.",
|
||||
"SE TIVESSEM UM ZOOMER EQUIPADO COM UM PROTECTOR TÉRMICO.",
|
||||
"POR COINCIDÊNCIA, ESTOU A TRABALHAR NUM NESTE PRECISO MOMENTO.",
|
||||
"TUDO O QUE PRECISO SÃO VINTE CÈLULAS DE ENERGIA PARA TER CARGA SUFICIENTE",
|
||||
"PARA AGUENTAR O CALOR DO DESFILADEIRO. NÃO É VERDADE, PAPÁ?",
|
||||
"SIM, KEIRA, ISSO PODE FUNCIONAR. MAS COM UM RAPAZ?",
|
||||
"E MEIO!",
|
||||
"VÃO ARRANJAR VINTE CÉLULAS DE ENERGIA?",
|
||||
"DOS MORADORES DA ALDEIA! A MAIORIA DELES TEM UMA OU DUAS BATERIAS",
|
||||
"GUARDADAS EM ALGUM LUGAR.",
|
||||
"E MESMO QUE NÃO ESTEJAM DISPOSTOS A SIMPLESMENTE OFERECÊ-LAS",
|
||||
"DAR-LHES ALGUMAS ESFERAS PRECURSORAS DEVE AJUDAR A CONVENCÊ-LOS.",
|
||||
"E APOSTO QUE DEVEM HAVER ALGUMAS POR AÍ ESPALHADAS HÁ ESPERA QUE ALGUM",
|
||||
"AVENTUREIRO CORAJOSO AS ENCONTRE.",
|
||||
"BEM, PELO MENOS TEMOS O AVENTUREIRO CORAJOSO.",
|
||||
"AVENTUREIRO CORAJOSO?",
|
||||
"SEM TREINO VOCÊS DOIS NEM CONSEGUIAM SAIR DA ALDEIA",
|
||||
"ANTES DE FAZEREM QUALQUER COISA, É MELHOR ATRAVESSAREM O PORTAL E IREM",
|
||||
"PRATICAR NA ROCHA DO GEYSER.",
|
||||
"HUM, NÃO VAMOS ENCONTRAR MAIS DAQUELA PORCARIA ECO NEGRA E PEGAJOSA, POIS NÃO?",
|
||||
"PORQUE EU IA ODIAR CAIR NAQUELA LAMA DE NOVO E FICAR COMO TU!",
|
||||
"ENTREM AÍ! ANTES QUE EU VOS TRANSFORME OS DOIS EM FETOS!"
|
||||
],
|
||||
"sage-intro-sequence-e": [
|
||||
"GOOD TRAINING, BOYS, BUT THAT'S NOTHING COMPARED TO THE CHALLENGES THAT LIE AHEAD.",
|
||||
@@ -852,12 +852,12 @@
|
||||
"sage-introduction-misty-cannon": [
|
||||
"OH, IT'S THE CONQUERING HEROES.",
|
||||
"GOOD, I WANTED TO TALK WITH YOU TWO ABOUT SOMETHING SERIOUS.",
|
||||
"THERE APPEARS TO BE QUITE A BIT OF LURKER ACTIVITY ON MISTY ISLAND.",
|
||||
"THERE APPEARS TO BE QUITE A BIT OF LURKER ACTIVITY ON ILHA NEBULOSA.",
|
||||
"I CAN SEE THEM BOMBARDING THE PRECURSOR SILO FROM MY LOOKOUT TOWER.",
|
||||
"IF THE LURKERS OPEN IT UP AND RELEASE THE DARK ECO, WE COULD ALL END UP",
|
||||
"RUNNING AROUND LOOKING AS RIDICULOUS AS THIS ANNOYING LITTLE SPECIMEN.",
|
||||
"JAK, IT'S TIME FOR YOU TO PROVE YOUR WORTH.",
|
||||
"GET THE FISHERMAN TO LET YOU TAKE HIS BOAT BACK TO MISTY ISLAND",
|
||||
"GET THE FISHERMAN TO LET YOU TAKE HIS BOAT BACK TO ILHA NEBULOSA",
|
||||
"GET TO THE TOP OF THE PRECURSOR SILO AND TAKE OUT THAT CANNON.",
|
||||
"AND... WHAT ABOUT ME?",
|
||||
"YOU? WHY DON'T YOU MOP MY FLOORS? THEY SEEM TO HAVE LOST THEIR SHINE LATELY."
|
||||
@@ -876,7 +876,7 @@
|
||||
"sage-reminder-1-misty-cannon": [
|
||||
"THE BOMBARDMENT IS GETTING WORSE!",
|
||||
"FIND THE FISHERMAN IN THE JUNGLE, GET PERMISSION TO USE HIS BOAT",
|
||||
"AND GET OVER TO MISTY ISLAND TO STOP THE CANNON.",
|
||||
"AND GET OVER TO ILHA NEBULOSA TO STOP THE CANNON.",
|
||||
"AND YOU DAXTER, YOU NEED TO GET MOPPING. THIS PLACE IS A MESS!"
|
||||
],
|
||||
"sage-reminder-2-generic": [
|
||||
@@ -967,10 +967,10 @@
|
||||
"AS A MATTER OF FACT, WITHOUT MY MUSE, I JUST CAN'T SCULPT.",
|
||||
"BUT WITH HER AROUND... I SEE BEAUTY IN EVERYTHING, YOU KNOW?",
|
||||
"RIGHT NOW I COULDN'T CHISEL MY WAY OUT OF A BOX.",
|
||||
"I THINK SHE RAN AWAY TO THAT MISTY ISLAND.",
|
||||
"I THINK SHE RAN AWAY TO THAT ILHA NEBULOSA.",
|
||||
"AWW, I JUST HOPE SHE'S ALL RIGHT.",
|
||||
"IT'S WORTH A POWER CELL IF YOU BRING HER BACK TO ME!",
|
||||
"WAIT A MINUTE! WE ARE NOT GOING BACK TO MISTY ISLAND!",
|
||||
"WAIT A MINUTE! WE ARE NOT GOING BACK TO ILHA NEBULOSA!",
|
||||
"ARE WE?"
|
||||
],
|
||||
"sculptor-reminder-1": [
|
||||
@@ -981,25 +981,25 @@
|
||||
"HERE, TAKE THIS POWER CELL. I WON'T NEED IT NOW THAT I HAVE MY INSPIRATION BACK!"
|
||||
],
|
||||
"sidekick-human-intro-sequence-b": [
|
||||
"CONTINUE YOUR SEARCH FOR ARTIFACTS AND ECO.",
|
||||
"IF THE LOCALS POSSESS PRECURSOR ITEMS, YOU KNOW WHAT TO DO.",
|
||||
"DEAL HARSHLY WITH ANYBODY WHO STRAYS FROM THE VILLAGE.",
|
||||
"WE WILL ATTACK IT IN DUE TIME."
|
||||
"CONTINUEM A VOSSA PESQUISA POR ARTEFACTOS E ECO.",
|
||||
"SE OS ALDEÔES POSSUIREM ITENS PRECURSORES, VOCÊS SABEM O QUE FAZER.",
|
||||
"LIDEM COM DUREZA QUALQUER UM QUE SE AFASTAR DA ALDEIA.",
|
||||
"IREMOS ATACAR NA HORA CERTA."
|
||||
],
|
||||
"sidekick-human-intro-sequence-c": [
|
||||
"WHAT ARE WE DOING HERE ANYWAY, JAK? THIS PLACE GIVES ME THE CREEPS!",
|
||||
"HUH?",
|
||||
"(GROAN) STUPID PRECURSOR JUNK!",
|
||||
"EEK! WHAT IS THAT DARK OOZE? IT SURE DON'T LOOK FRIENDLY.",
|
||||
"O QUE É QUE ESTAMOS AQUI A FAZER, JAK? ESTE SÍTIO DA-ME ARREPIOS!",
|
||||
"HÃ?",
|
||||
"(SUSPIRO) LIXO ESTÚPIDO DE PRECURSORES!",
|
||||
"NHEC! O QUE É ESTA GOSMA ESCURA? NÃO PARECE NADA AMIGAVÉL.",
|
||||
"O SÁBIO FALA O TEMPO TODO SOBRE OS PRECURSORES QUE CONSTRUÍRAM ESTE LUGAR.",
|
||||
"\"WHERE DID THEY GO? WHY DID THEY BUILD THIS CRAP?\"",
|
||||
"NOW I LIKE PRECURSOR ORBS AND POWER CELLS AS MUCH AS THE NEXT GUY",
|
||||
"BUT IF YOU ASK ME, THEY MUST HAVE BEEN REAL LOSERS.",
|
||||
"WHOA! HOW DID YOU DO THAT?",
|
||||
"\"ONDE É QUE ELES FORAM? PORQUE É QUE CONSTRUIRAM ESTA PORCARIA?\"",
|
||||
"EU GOSTA DE ORBS PRECURSORAS E CÉLULAS DE ENERGIA TANTO COMO QUALQUER OUTRA PESSOA",
|
||||
"MAS SE QUERES A MINHA OPINIÃO, DEVEM TER SIDO UM BANDO DE FALHADOS",
|
||||
"UAU! COMO É QUE FIZESTE ISSO?",
|
||||
"JAK, EU ACHO QUE ESTAMOS EM SARILHOS!",
|
||||
"MAN, THAT STUNG.",
|
||||
"I TOLD YOU WE SHOULDN'T HAVE COME HERE, AND YOU LISTENED?",
|
||||
"O QUÊ?",
|
||||
"CARAMBA, ISSO DOEU.",
|
||||
"EU DISSE-TE QUE NÃO DEVIAMOS TER VINDO PARA CÁ, E TU OUVISTE-ME?",
|
||||
"O QUE FOI?",
|
||||
"WAAAAAAAAHHHHHHHH!!",
|
||||
"OKAY, OKAY. ESTOU BEM, ESTOU BEM...",
|
||||
"WAAAAAAAAHHHHHHHH!!"
|
||||
@@ -2077,7 +2077,7 @@
|
||||
],
|
||||
"sksp0011": [
|
||||
"WE SHOULD ASK THE FISHERMAN DOWN BY THE JUNGLE RIVER",
|
||||
"IF WE CAN BORROW HIS SPEEDBOAT TO ZOOM ON OVER TO MISTY ISLAND!"
|
||||
"IF WE CAN BORROW HIS SPEEDBOAT TO ZOOM ON OVER TO ILHA NEBULOSA!"
|
||||
],
|
||||
"sksp0013": [
|
||||
"DID YOU SEE THE SIZE OF THE BITE",
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
"Sig näyttää teille alkeet.",
|
||||
"Te nuorukaiset siis tahdotte aavikkolaisiksi?",
|
||||
"No, katsotaan mihin te pystytte, kun pääsemme toiminnan keskelle.",
|
||||
"Krew haluaa uusia saaliita houkuttamaan lisää asiakkaita,",
|
||||
"Krew tahtoo uusia saaliita houkuttamaan asiakkaita,",
|
||||
"joten aion napata viisi törkeää metallipäätä pumppaamolla.",
|
||||
"Älä suotta tutise, chilipippuri, koska rokkaamme Rauhantekijällä!",
|
||||
"Vauh, minulle kelpaisi tuollainen! Mistä sait sen?",
|
||||
@@ -57,7 +57,7 @@
|
||||
"atoll-3-intro": [
|
||||
"Eräs vanha vartiotoverini lähetettiin pumppaamolle.",
|
||||
"Partiosta ei ole kuulunut takaisin, ja koska mihin te siellä törmäsitte,",
|
||||
"pelkään, että nainen on avun tarpeessa.",
|
||||
"pelkään että nainen on avun tarpeessa.",
|
||||
"Sanoitko \"nainen\"?",
|
||||
"Älä edes kuvittelekaan!",
|
||||
"LOPETA! Tämä on vakavaa, senkin ääliö!",
|
||||
@@ -199,7 +199,7 @@
|
||||
"Pölhö! Etkö tajua?! Se on ohi, Jak!",
|
||||
"Kaikki sankarit kuolivat aikoja sitten! On vain selviytyminen...",
|
||||
"keinolla millä hyvänsä!",
|
||||
"Kaupunki on minun! Nämä elämät ovat minun! Tämä sota on minun!",
|
||||
"Kaupunki on minun! Nämä henget ovat minun! Tämä sota on minun!",
|
||||
"Ja sodassa... ihmisiä kuolee! Tappakaa hänet!",
|
||||
"Varokaa!",
|
||||
"Voitto on minun, Jak!",
|
||||
@@ -209,7 +209,7 @@
|
||||
"city-class-2-race-intro": [
|
||||
"Kappas, törmäämme jälleen, ecohirviö.",
|
||||
"Missä Keira on?",
|
||||
"Älä huoli, pidän häntä silmilläni.",
|
||||
"Älä huoli, pidän häntä silmälläni.",
|
||||
"Olet kaupungin puheenaihe, Jak!",
|
||||
"Annat kansalle toivoa... Miten säälittävää.",
|
||||
"Olisin nauttinut sinun tappamisesta vankilassa,",
|
||||
@@ -250,7 +250,7 @@
|
||||
"Epäilitkö taitojani? Olen Jakin apukuskina kaiken aikaa!",
|
||||
"Hei, milloin saan voittajan suukon?",
|
||||
"Ehkä myöhemmin... jos olet hyvä poika.",
|
||||
"Heippa. Näytimme niille kakkosluokan häviäjille paikkansa.",
|
||||
"Moikka. Näytimme niille kakkosluokan häviäjille paikkansa.",
|
||||
"Minä näin.",
|
||||
"Driftasit vähän korkealle parissa mutkassa, mutta pysyit pystyssä!",
|
||||
"Olen ylpeä sinusta, Dax.",
|
||||
@@ -307,7 +307,7 @@
|
||||
"Kaikkihan hänet tuntevat.",
|
||||
"Ja Keira on...",
|
||||
"Ystävä. Erittäin hyvä ystävä.",
|
||||
"Kiitos avustasi tankkerin kanssa, Jak. Säästit paljon henkiä.",
|
||||
"Kiitos avustasi tankkerin kanssa, Jak. Pelastit paljon henkiä.",
|
||||
"En ole kuin isäni.",
|
||||
"Pikkutytöstä asti olen katsellut kaduille sieltä typerästä tornista",
|
||||
"ja kuvitellut parempaa paikkaa.",
|
||||
@@ -370,7 +370,7 @@
|
||||
"Sanoisin, että tulet häviämään paljon rahaa.",
|
||||
"Koska minä aion kilpailla ja aion myös voittaa!",
|
||||
"Aagghh! Sinä senkin...",
|
||||
"Sinusta alkaa tulla enemmän hankaluuksia kuin hyötyä!",
|
||||
"Sinusta alkaa olla enemmän hankaluuksia kuin hyötyä!",
|
||||
"Sinuna en ottaisi liian rennosi. Jokainen on uhrattavissa!",
|
||||
"Onko kiire kuolemaan?!",
|
||||
"Meidän ei tarvitse odottaa suurkisaan asti!",
|
||||
@@ -460,7 +460,7 @@
|
||||
"Auttakaa minua nitistämään metallipäät!"
|
||||
],
|
||||
"city-intercept-tanker-res": [
|
||||
"Saimme ne kaikki!",
|
||||
"Se oli siinä!",
|
||||
"Metallipäät tulevat päivä päivältä röyhkeämmiksi.",
|
||||
"Ihan kuin ne koettelisivat puolustuksiamme hyökkäyksillään.",
|
||||
"Minulla on paha tunne tästä.",
|
||||
@@ -498,8 +498,8 @@
|
||||
"Olen kiireinen juuri nyt.",
|
||||
"Te taidatte olla Krewin uudet juoksupojat.",
|
||||
"Kuule, en tahdo olla töykeä, saavuitte kyllä nopeasti,",
|
||||
"mutta en ole kiinnostunut uusista ajajista juuri nyt,",
|
||||
"ja minulla on tekemistä...",
|
||||
"mutta en ole kiinnostunut uusista ajajista juuri nyt.",
|
||||
"Ja minulla on tekemistä...",
|
||||
"Voimmeko auttaa mitenkään?",
|
||||
"Ette! Työstän salaista... \"ajoneuvoprojektia\".",
|
||||
"Okei, pahoittelut...",
|
||||
@@ -510,7 +510,7 @@
|
||||
"city-keira-hover-challenge-res": [
|
||||
"Voitimme stadionhaasteen.",
|
||||
"Kiva. Teillä riittää tuuria.",
|
||||
"Eikö teillä ole ketään hakattavana tai jolta kerätä rahaa, tai jotain?",
|
||||
"Eikö teidän pitäisi olla kiristämässä tai hakkaamassa jotakuta?",
|
||||
"Et taida pitää meistä?",
|
||||
"Teette hommia sille limapallo Krewille. Miksi en pitäisi?",
|
||||
"Olet näköjään voittanut muutaman kisan.",
|
||||
@@ -537,19 +537,19 @@
|
||||
"Voi pojat, kelluuko tuossa oikeaa kultaa?",
|
||||
"Entäs tämä violetti litku?...",
|
||||
"Glug, glug, glug... HUH!",
|
||||
"Jak. Joudutte rottasi kanssa hoitaa noutoja puolestani.",
|
||||
"Jak. Saisitte rottasi kanssa hoitaa noutoja puolestani.",
|
||||
"Hellurei, leukaläjä... Mitäs rikoksille kuuluu?",
|
||||
"Mikäs häntä vaivaa?",
|
||||
"Mikä häntä vaivaa?",
|
||||
"Ei mikään... olen ihan kunnossa...",
|
||||
"huolehdi omista asioistasi...",
|
||||
"Minusta joskus tuntuu niin kovin...",
|
||||
"\"Minusta joskus tuntuu niin kovin...\"",
|
||||
"Kuuntele, minulla on kuusi \"asiakasta\" ympäri kaupunkia,",
|
||||
"jotka aikovat tehdä rahapudotuksia minulle.",
|
||||
"Sinun täytyy noutaa jokainen rahapussi mahdollisimman nopeasti",
|
||||
"ja \"hoidella\" jokainen utelias vartija nuuskimasta.",
|
||||
"Jos saavut rahapussille liian myöhään,",
|
||||
"joku jalankulkija voi napata sen.",
|
||||
"...OLO ON KUIVAA!...",
|
||||
"\"...OLO ON KUIVAA!...\"",
|
||||
"Tiedätkö mikä ongelmasi on, Krew? Sinulta puuttuu visio...",
|
||||
"Tämä paikka voisi olla oikea huippu mesta...",
|
||||
"Tarvitsemme lisää tanssia, lisää hauskaa, lisää naisia!",
|
||||
@@ -561,7 +561,7 @@
|
||||
"Mmm, rahankerääjäni palasivat.",
|
||||
"Tässä on asepäivitys.",
|
||||
"Nyt poistukaa! Tarvitsen kauneusuneni.",
|
||||
"Usko pois, veliseni. Päivässä ei tunnit riitä."
|
||||
"Usko pois, siihen ei päivässä tunnit riitä."
|
||||
],
|
||||
"city-krew-delivery-intro": [
|
||||
"\"Räjäytyskaksikko\" on palannut!",
|
||||
@@ -585,18 +585,18 @@
|
||||
],
|
||||
"city-meet-brutter-intro": [
|
||||
"Paroni lähetti kätyrinsä kiusamaan minua tuttuun tapaansa!",
|
||||
"Terveysrikkomuksia! Jälkiveroja!",
|
||||
"Terveysrikkomuksia! Jäännösveroja!",
|
||||
"Kaikki haluavat minusta palasen. Oi voi...",
|
||||
"Sinun onneksesi palasia kyllä riittää!",
|
||||
"Lastin tuhoaminen satamalla oli tärkeämpää kuin tiedättekään.",
|
||||
"Minulla on uusi projekti meneillään,",
|
||||
"enkä tahdo kenenkään nuuskivan toimituksiani.",
|
||||
"Sanotaanpa, että jos kaikki sujuu suunnitellusti,",
|
||||
"Sanotaanpa että jos kaikki sujuu suunnitellusti,",
|
||||
"tulen kuormittamaan markkinat metallipää-saaliilla. Hahaha...",
|
||||
"Kuitenkin, minulla on uusi tehtävä teille.",
|
||||
"Eräs virkaveljeni, Brutter, toimii kanssani pakkotyökaupassa.",
|
||||
"Tarkoitat kai orjakauppaa?",
|
||||
"Sanoisin \"vapaudesta vapautettu\".",
|
||||
"Sanoisin mieluummin \"vapaudesta vapautettu\".",
|
||||
"Vaanijat ovat kaupungin alemman luokan työvoimaa.",
|
||||
"Brutter maksaa minulle mainiosti avustani vapauttaa vaanijoita",
|
||||
"ja saada ne turvallisesti ulos kaupungista.",
|
||||
@@ -629,7 +629,7 @@
|
||||
"Palkkiona myönnän sinulle pimeän voiman."
|
||||
],
|
||||
"city-oracle-level-1": [
|
||||
"Metallipäät ovat pelänneet sinua ainiaan, vihaisa.",
|
||||
"Metallipäät ovat pelänneet sinua ainiaan.",
|
||||
"Jo nyt metallipäiden johtaja tietää sinun voivan tuhota hänet",
|
||||
"ja pelastaa rotumme viimeisen mahdollisuuden.",
|
||||
"Sinulla on nyt hallinnassasi toinen pimeä voima!"
|
||||
@@ -689,12 +689,12 @@
|
||||
"Ne puree ja satuttaa kylää pahalaatuisesti",
|
||||
"ja vaanijaveljet ovat ansassa kuin eläimet!",
|
||||
"Haloo? Ne ovat eläimiä.",
|
||||
"Emme enää pahoja, vaanivia ja luuttomia.",
|
||||
"Emme ole enää pahoja, vaanivia ja luuttomia.",
|
||||
"Me hyviä nyt. Metallipäiset on pahoja. Ne on vihollisia.",
|
||||
"Taidamme kaikki seilata samassa paatissa.",
|
||||
"Ja paatti uppoaa alta aikayksikön!",
|
||||
"Pyydän, pelastakaa kuusi vaanijaveljeä äkkiä,",
|
||||
"ja Brutter suukottaa teidän jalkoja!"
|
||||
"niin Brutter suukottaa teidän jalkoja!"
|
||||
],
|
||||
"city-shuttle-underground-intro": [
|
||||
"Kaupungissa on hälytystila.",
|
||||
@@ -819,7 +819,7 @@
|
||||
"Silti, jokaisella sisunsa arvoisella johtajalla",
|
||||
"on aina varasuunnitelma...",
|
||||
"Muista, ensimmäinen sääntö pommin rakentamisessa...",
|
||||
"on aina rakentaa kaksi!",
|
||||
"on aina rakentaa kaksi...",
|
||||
"Ääh, okei! Menen sisään!",
|
||||
"No onpas täällä sotkuista! Käämejä ja katkaisimia sikin sokin!",
|
||||
"Pitäisikö irrottaa sininen johto?",
|
||||
@@ -880,10 +880,10 @@
|
||||
"avataksesi Marin portin kanjonille."
|
||||
],
|
||||
"dig-find-totem-res": [
|
||||
"Hoidan! Hetkonen...",
|
||||
"Minä hoidan! Hetkinen...",
|
||||
"Ehkä tällä kertaa sinä voisit noutaa jutun!",
|
||||
"Näyttääpä siellä hurjalta! Älähän satuta itseäsi, Jak!",
|
||||
"Se on kirous, eikö vain?"
|
||||
"Hurjalta näyttää! Älä satuta itseäsi, Jak!",
|
||||
"Taidan olla kirottu, enkö?"
|
||||
],
|
||||
"dig-knock-down-scaffolding-intro": [
|
||||
"Samos pyysi meidät tuomaan lapsen luoksesi.",
|
||||
@@ -897,7 +897,7 @@
|
||||
"Mahtavia otuksia.",
|
||||
"Me näimme ison tulevan repeämäportista kerran.",
|
||||
"Hän oli ruma kuin mikä!",
|
||||
"Hmmmphh... Minulla on arvokasta tietoa teille.",
|
||||
"Hmph... Minulla on arvokasta tietoa teille.",
|
||||
"Paroni suorittaa kaivausta kaivannolla.",
|
||||
"Hän edelleen etsii sitä naurettavaa hautaa.",
|
||||
"Rehellisesti, en usko sen olevan olemassa,",
|
||||
@@ -913,14 +913,14 @@
|
||||
"Torn on pettänyt meidät!",
|
||||
"Torn tarkoitti hyvää. Hän vain suojeli yhtä joukostamme.",
|
||||
"Meidän täytyy saada se kivi takaisin!",
|
||||
"Se on työn alla!",
|
||||
"Se on työn alla.",
|
||||
"Niin, se on työmme alla!",
|
||||
"Olen aliarvioinut paronin,",
|
||||
"ja nyt hän on myös kaapannut pojan!",
|
||||
"ja nyt hän on myös kaapannut pojan.",
|
||||
"Mieti. Mikä voisi olla paronin seuraava siirto?",
|
||||
"No, jos Edeltäjäkivi olisi minulla kaikessa voimassaan,",
|
||||
"rakentaisin sillä valtavan palatsin.",
|
||||
"Palatsin, jossa on suurin joukkio naisia, mitä on ikinä nähty.",
|
||||
"Palatsin, jossa on suurin joukko naisia mitä on ikinä nähty.",
|
||||
"Ja siellä olisi uima-allas täytetty reunoja myöten suklaalla...",
|
||||
"hieman minttuista...",
|
||||
"Joo, joo, valtava allas täynnä tahmeaa suklaata!",
|
||||
@@ -1006,7 +1006,7 @@
|
||||
"Miksi se paikka raunioilla on niin tärkeä teille?",
|
||||
"Vanhassa talossa sijaitsee voimakas energialähde.",
|
||||
"Se vetää metallipäitä puoleensa.",
|
||||
"Ihan totta? Tunsimme henkilön, joka asui siellä!",
|
||||
"Ihan totta? Tunsimme henkilön, joka asui siellä.",
|
||||
"Te siis olette ne tulokkaat, jotka toistuvasti joutuvat pulaan.",
|
||||
"Voi ei, et sinä!",
|
||||
"Tervetuloa vaatimattomaan vastarintaliikkeeseemme.",
|
||||
@@ -1052,8 +1052,8 @@
|
||||
"Melkoinen tarina.",
|
||||
"Taidatkin olla tarvitsemani \"eläin\" yhteen vaaralliseen tehtävään.",
|
||||
"Taistelumetallipäitä on havaittu ympäri Havenin metsää!",
|
||||
"Näillä mokomilla on naamiopinta, joten niitä on vaikea nähdä,",
|
||||
"mutta etköhän sinä pärjää \"tappajavaistollasi\".",
|
||||
"Näillä mokomilla on naamiopinta, joten niitä on vaikea nähdä.",
|
||||
"Mutta etköhän sinä pärjää \"tappajavaistollasi\".",
|
||||
"Käy metsässä ja pistä ne nippuun!"
|
||||
],
|
||||
"forest-protect-samos-intro-a": [
|
||||
@@ -1098,7 +1098,7 @@
|
||||
"Paroni suunnittelee tuhota Edeltäjäkiven!",
|
||||
"Hän aikoo särkeä sen auki jotenkin!",
|
||||
"Jos hän onnistuu, siitä vapautuva energia on yli ymmärryksen!",
|
||||
"Se tuhoaisi maailman ja myös... kaiken elämän!",
|
||||
"Se tuhoaisi maailman ja kaiken elämän mukanaan!",
|
||||
"Kasvit anovat suojelua! Sinun täytyy pysäyttää paroni, Jak!",
|
||||
"Pysäytä hänet, keinolla millä hyvänsä!"
|
||||
],
|
||||
@@ -1115,7 +1115,7 @@
|
||||
"ja teidän täytyy räjäyttää kaikki ammukset sen sisältä.",
|
||||
"Kaiken kun saatte, niin me aiheutamme suuriskun paronille.",
|
||||
"Mehän tässä ne työt teemme.",
|
||||
"ME aiheutamme suuriskun!",
|
||||
"ME sen suuriskun aiheutamme!",
|
||||
"Sopii. Haluan paronin tietävän, että MINÄ satutan häntä."
|
||||
],
|
||||
"fortress-blow-up-ammo-res-a": [
|
||||
@@ -1149,12 +1149,12 @@
|
||||
],
|
||||
"fortress-save-friends-res": [
|
||||
"Mitä kuuluu, beibi?",
|
||||
"Metallipää-mäiskijä on pelastaa päivän!",
|
||||
"Niin ja annoin Jakin tulla mukaani myös!",
|
||||
"Metallipää-mäiskijä pelastaa päivän!",
|
||||
"Annoin myös Jakin tulla mukaani.",
|
||||
"Oih, pikku sankarini!",
|
||||
"Samos, oletko kunnossa?",
|
||||
"Mikä sinulla oikein kesti?!",
|
||||
"Sain halkooni kuusi ikärengasta odotellessani teidän apuanne!",
|
||||
"Sain halkooni kuusi ikärengasta teitä odotellessani!",
|
||||
"Hyvät hyssykät! Mitä sinulle on tapahtunut, Jak?",
|
||||
"Hetkonen! Se olet sinä! Siis se toinen sinä!",
|
||||
"Tai siis... no tiedätte kyllä.",
|
||||
@@ -1168,8 +1168,8 @@
|
||||
"Ai, joku luulee itäneensä.",
|
||||
"Jos sinulla olisi edes puolet viisaudestani,",
|
||||
"ymmärtäisit, että tärkein tehtävämme on löytää lapsi!",
|
||||
"Kuules, senkin kurttuinen käpy,",
|
||||
"minä päätän asiasta ja sanon, että sotkemme paronin varoja.",
|
||||
"Kuules, senkin kurttuinen käpy, minä päätän asiasta",
|
||||
"ja sanon että käymme paronin voimavarojen kimppuun.",
|
||||
"Pitääkö teidät kaksi erottaa?",
|
||||
"Vin aktivoi portaalin! Nyt on aika lähteä!"
|
||||
],
|
||||
@@ -1326,7 +1326,7 @@
|
||||
"Hmm, tuoksahtaa hieman...",
|
||||
"palaneelta saulumilta?",
|
||||
"Aaaaahhhh!!!",
|
||||
"Äää, huh, hah, poppaa, poppaa, kuumaa, polttaa, huhhahhaa...",
|
||||
"Äää, huh, hah, poppaa, kuumaa, polttaa, huhhahhaa...",
|
||||
"Ahhhhh..."
|
||||
],
|
||||
"mountain-shard-res": [
|
||||
@@ -1346,7 +1346,7 @@
|
||||
"HA HA HAA! Maista tätä!",
|
||||
"Tuo jos mikä herätti ne.",
|
||||
"Mennään hoitamaan homma.",
|
||||
"Mitä? Siis mennään tuonne? Tulen perässäsi..."
|
||||
"Mitä? Siis mennään tuonne? Tulen heti perässäsi..."
|
||||
],
|
||||
"nest-kor-boss-fight-intro-b": [
|
||||
"Viimein, päätitte liittyä seuraamme.",
|
||||
@@ -1355,7 +1355,7 @@
|
||||
"Ei tällä kertaa!",
|
||||
"Ah, mutta lapsi on niin suuri osa tätä. Suuri osa sinua.",
|
||||
"Etkö tunnista häntä? Poika on sinä, Jak!",
|
||||
"Ja tämä paikka... täällä sinä sait alkusi, tulevaisuudessa!",
|
||||
"Ja tämä paikka... täällä sinä sait alkusi. Tulevaisuudessa!",
|
||||
"Mutta miten...",
|
||||
"Sinut piilotettiin menneisyyteen sen toivossa,",
|
||||
"että keräisit taitosi kohdataksesi minut nyt.",
|
||||
@@ -1400,7 +1400,7 @@
|
||||
"Tiesin sen.",
|
||||
"Olet kunnossa?!",
|
||||
"Ettehän te kirsikat luulleet,",
|
||||
"että joku iso haiseva lisko estäisi minut kaupungin suurjuhlasta?",
|
||||
"että joku iso haiseva lisko estäisi minut kaupungin suurjuhlista?",
|
||||
"Tiesin, että olet liian kova pala purtavaksi!"
|
||||
],
|
||||
"outro-nest": [
|
||||
@@ -1449,7 +1449,7 @@
|
||||
"Voit aloittaa kaupungin korjaamisen huomenna.",
|
||||
"Tänä iltana juhlimme uusien ystäviemme kanssa.",
|
||||
"Sitä paitsi, tahdon niin nähdä sinun tanssivan.",
|
||||
"Ei onnistu."
|
||||
"Epätodennäköistä."
|
||||
],
|
||||
"outro-port": [
|
||||
"Pelastit kaupungin ja kaiken muunkin, poikani!",
|
||||
@@ -1479,7 +1479,7 @@
|
||||
"Ei, vaan sinä kerrot... TASAN NYT! AAHH!",
|
||||
"AAHH! Sinä senkin... UUH! AUH!",
|
||||
"Hei! Tuo on likaista tappelua!",
|
||||
"Jak, poikani. Tulevaisuus odottaa!"
|
||||
"Jak, poikani, tulevaisuus odottaa!"
|
||||
],
|
||||
"palace-boss-res": [
|
||||
"Antamani pimeät voimat eivät suojele sinua ikuisesti!",
|
||||
@@ -1513,11 +1513,11 @@
|
||||
"olisimme teljenneet hänet jo aikoja sitten!",
|
||||
"Kuten haluatte.",
|
||||
"Tarpeeksi kun suostuttelen, niin olen varma, että vakoojamme...",
|
||||
"Mikä tuo oli?!"
|
||||
"Mikä se oli?!"
|
||||
],
|
||||
"palace-outside-window-res-b": [
|
||||
"Seinissämme siis piileksii rotta!",
|
||||
"Rotta ja hänen toverinsa, näemmä.",
|
||||
"Rotta ja hänen toverinsa näemmä.",
|
||||
"Tuliko ikävä pimeän econ kokeitamme?",
|
||||
"No, saanen päästää teidät molemmat kärsimyksestä!"
|
||||
],
|
||||
@@ -1604,7 +1604,7 @@
|
||||
"Kuulemma haaveilet liittyä taisteluun kaupungin puolesta.",
|
||||
"Väärän puolen valitseminen voi koitua... epäterveelliseksi.",
|
||||
"Haluamme tavata Varjon.",
|
||||
"Ha ha ha. Ei onnistu.",
|
||||
"Ha ha ha. Epätodennäköistä.",
|
||||
"Jos tahdotte liittyä johonkin, sirkus voi ottaa teidät vastaan.",
|
||||
"Ellei teiltä löydy sisua todella hankalaan tehtävään.",
|
||||
"Varastakaa paronin lippu raunioituneen tornin huipulta",
|
||||
@@ -1629,7 +1629,7 @@
|
||||
"ja annan sinulle maukkaan asepäivityksen, jos onnistut.",
|
||||
"Annas kun arvaan... Likaista, sameaa vettä?",
|
||||
"Haisee pahemmalta kuin hönkäsi osterifestareilla?",
|
||||
"Täydempänä metallipäitä kuin lautasesi kertabuffetissa?",
|
||||
"Täynnempänä metallipäitä kuin lautasesi buffetissa?",
|
||||
"Ja tietenkin, tappavempia aseita kuin tiukat vaippasi kesäpäivänä?",
|
||||
"Kuules donitsinreikä, miksemme me leijuisi ympäriinsä laiskotellen",
|
||||
"ja sinä käyt hoitamassa putkityöt?",
|
||||
@@ -1724,7 +1724,7 @@
|
||||
],
|
||||
"sewer-drain-res": [
|
||||
"Huh... Koppi! Missä olisitkaan ilman minua, Dax?",
|
||||
"No, luultavasti en olisi puoli metriä pitkä, karvainen,",
|
||||
"No, luultavasti en olisi puoli metriä pitkä, karvainen",
|
||||
"ja hörhöilemässä viemäreissä ilman housuja...",
|
||||
"Kaipaan housuja."
|
||||
],
|
||||
@@ -1763,7 +1763,7 @@
|
||||
"Tämä on vääryys! Edeltäjäkivi ei ollut sinua varten!"
|
||||
],
|
||||
"tomb-boss-res": [
|
||||
"Hyvä yritys, mutta kivi yhä minun!",
|
||||
"Hyvä yritys, mutta kivi yhä minulla!",
|
||||
"Älä huoli... aion käyttää sitä sen täydellä potentiaalilla.",
|
||||
"Pian kaikki vastustajani tuhoutuvat sen voimasta!"
|
||||
],
|
||||
@@ -1776,8 +1776,7 @@
|
||||
"Miehuuden testit ovat taatusti täynnä vaaroja",
|
||||
"ja Marin perillisen tulee kohdata ne yksin.",
|
||||
"Kyllä se siitä. Sinä pystyt siihen!",
|
||||
"Se on vain syvä, sysipimeä,",
|
||||
"\"ääriään-myöten-täynnä-tuskallista-kuolemaa\", vanha hauta.",
|
||||
"Se on vain syvä, sysipimeä hauta täynnä tuskallista kuolemaa...",
|
||||
"Itse en menisi sinne.",
|
||||
"Tervetuloa, Marin perillinen.",
|
||||
"Viimein, valittu seisoo edessäni.",
|
||||
@@ -1826,7 +1825,7 @@
|
||||
"Mikään ei pysäytä meitä, koska olemme...",
|
||||
"AAAGGGHHH!",
|
||||
"SIG!",
|
||||
"Tuota... mikäs on varasuunnitelma?"
|
||||
"Tuota... olikos varasuunnitelmaa?"
|
||||
],
|
||||
"vin-rescue": [
|
||||
"Aaahhh! Pysykää kaukana!",
|
||||
@@ -8859,8 +8858,8 @@
|
||||
],
|
||||
"prop056": [
|
||||
"Täällä huipulla voi tulla niin yksinäistä.",
|
||||
"Täältä katsoen näen, kuinka mätä kaupunkimme on",
|
||||
"kuinka mätä kaupunkimme on toivottoman elvytyksen tarpeessa.",
|
||||
"Täältä katsoen näen, kuinka mätä kaupunkimme",
|
||||
"on toivottoman elvytyksen tarpeessa.",
|
||||
"Tämä mielessä, tulemme purkamaan useita alueita piakkoin!",
|
||||
"Kaikki valitukset tätä rakennusaloitetta vastaan",
|
||||
"tuodaan henkilökohtaisesti linnoituksen vankilaan,",
|
||||
@@ -8898,7 +8897,7 @@
|
||||
"ja piipahtaa vanhassa mökissäni.",
|
||||
"On aika noutaa jotain, mitä piilotin sinne kauan sitten.",
|
||||
"Onnea matkaan! Ja Daxter...",
|
||||
"siivoa paikkani, kun olette siellä!"
|
||||
"siivoat sitten joka nurkan!"
|
||||
],
|
||||
"sam002": [
|
||||
"Tämä on Samos. Nyt kun te pojat olette täällä,",
|
||||
@@ -8915,8 +8914,8 @@
|
||||
],
|
||||
"sam004": [
|
||||
"Pärjäsit hyvin, Jak.",
|
||||
"Onneksi Edeltäjäkivi ei ollut siinä pommissa, kun se räjähti,",
|
||||
"tai kukaan meistä ei olisi täällä juuri nyt.",
|
||||
"Onneksi Edeltäjäkivi ei ollut siinä pommissa kun se räjähti,",
|
||||
"tai muuten kukaan meistä ei hengittäisi juuri nyt.",
|
||||
"Tule takaisin kisatalliin niin pian kuin voit."
|
||||
],
|
||||
"sam005": [
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -16,13 +16,6 @@
|
||||
"010e": "Päällä",
|
||||
"010f": "Pois",
|
||||
"0110": "Käytä suuntanäppäimiä",
|
||||
"0111": "<FLAG_USA> English",
|
||||
"0112": "<FLAG_FRANCE> Fran,cais",
|
||||
"0113": "<FLAG_GERMAN> Deutsch",
|
||||
"0114": "<FLAG_SPAIN> Español",
|
||||
"0115": "<FLAG_ITALIAN> Italiano",
|
||||
"0116": "<FLAG_KOREA> ~Y~Z<K32e>~Z<K31a>~Z<K3c8>~Y~Z<K35e>~Z<K36b>~Z<K3de>~Y~Z<K30f>~Z<K31d>",
|
||||
"0117": "<FLAG_JAPAN> にほんご",
|
||||
"0118": "Kuvasuhde",
|
||||
"0119": "Peräkkäispyyhkäisy",
|
||||
"011a": "Videotila",
|
||||
@@ -504,7 +497,7 @@
|
||||
"02f6": "Kor ja lapsi",
|
||||
"02f7": "Pelasta lisää vaanijoita",
|
||||
"02f8": "Marin haudan legenda",
|
||||
"02f9": "Se on kirous, eikö vain?",
|
||||
"02f9": "Kirottu",
|
||||
"02fa": "Pora romahtaa",
|
||||
"02fb": "Valotorni nousee",
|
||||
"02fc": "Sinetti avaa portin",
|
||||
|
||||
@@ -236,20 +236,20 @@
|
||||
"1339": "Display",
|
||||
"133a": "<FLAG_FINLAND> Suomi",
|
||||
"133b": "Hint Subtitles",
|
||||
"133c": "Português",
|
||||
"133d": "Svenska ",
|
||||
"133e": "Dansk",
|
||||
"133f": "Norsk",
|
||||
"1340": "Nederlands",
|
||||
"1341": "Português (Brasil)",
|
||||
"1342": "Magyar",
|
||||
"1343": "Català",
|
||||
"1344": "Íslenska ",
|
||||
"1345": "Polski",
|
||||
"1346": "Lietuvių Kalba",
|
||||
"1347": "Čeština",
|
||||
"1348": "Hrvatski",
|
||||
"1349": "Galego",
|
||||
"133c": "<FLAG_PORTUGUAL> Português",
|
||||
"133d": "<FLAG_SWEDEN> Svenska",
|
||||
"133e": "<FLAG_DENMARK> Dansk",
|
||||
"133f": "<FLAG_NORWAY> Norsk",
|
||||
"1340": "<FLAG_DUTCH> Nederlands",
|
||||
"1341": "<FLAG_BRAZIL> Português (Brasil)",
|
||||
"1342": "<FLAG_HUNGARY> Magyar",
|
||||
"1343": "<FLAG_CATALAN> Català",
|
||||
"1344": "<FLAG_ICELAND> Íslenska",
|
||||
"1345": "<FLAG_POLAND> Polski",
|
||||
"1346": "<FLAG_LITHUANIA> Lietuvių Kalba",
|
||||
"1347": "<FLAG_CZECH> Čeština",
|
||||
"1348": "<FLAG_CROATIA> Hrvatski",
|
||||
"1349": "<FLAG_GALICIA> Galego",
|
||||
"134a": "Pressure Sensitivity",
|
||||
"134b": "Swap R1 and R2",
|
||||
"134c": "Trigger Effects"
|
||||
|
||||
@@ -236,20 +236,20 @@
|
||||
"1339": "Mostra",
|
||||
"133a": "<FLAG_FINLAND> Suomi",
|
||||
"133b": "Subtítols amb Suggeriments",
|
||||
"133c": "Português",
|
||||
"133d": "Svenska ",
|
||||
"133e": "Dansk",
|
||||
"133f": "Norsk",
|
||||
"1340": "Nederlands",
|
||||
"1341": "Português (Brasil)",
|
||||
"1342": "Magyar",
|
||||
"1343": "Català",
|
||||
"1344": "Íslenska ",
|
||||
"1345": "Polski",
|
||||
"1346": "Lietuvių Kalba",
|
||||
"1347": "Čeština",
|
||||
"1348": "Hrvatski",
|
||||
"1349": "Galego",
|
||||
"133c": "<FLAG_PORTUGUAL> Português",
|
||||
"133d": "<FLAG_SWEDEN> Svenska",
|
||||
"133e": "<FLAG_DENMARK> Dansk",
|
||||
"133f": "<FLAG_NORWAY> Norsk",
|
||||
"1340": "<FLAG_DUTCH> Nederlands",
|
||||
"1341": "<FLAG_BRAZIL> Português (Brasil)",
|
||||
"1342": "<FLAG_HUNGARY> Magyar",
|
||||
"1343": "<FLAG_CATALAN> Català",
|
||||
"1344": "<FLAG_ICELAND> Íslenska",
|
||||
"1345": "<FLAG_POLAND> Polski",
|
||||
"1346": "<FLAG_LITHUANIA> Lietuvių Kalba",
|
||||
"1347": "<FLAG_CZECH> Čeština",
|
||||
"1348": "<FLAG_CROATIA> Hrvatski",
|
||||
"1349": "<FLAG_GALICIA> Galego",
|
||||
"134a": "Sensibilitat a la pressió",
|
||||
"134b": "Intercanviar R1 i R2",
|
||||
"134c": "Efectes pels Gatells"
|
||||
|
||||
@@ -236,20 +236,20 @@
|
||||
"1339": "Obrazovka",
|
||||
"133a": "<FLAG_FINLAND> Suomi",
|
||||
"133b": "Titulky nápovědy",
|
||||
"133c": "Português",
|
||||
"133d": "Svenska ",
|
||||
"133e": "Dansk",
|
||||
"133f": "Norsk",
|
||||
"1340": "Nederlands",
|
||||
"1341": "Português (Brasil)",
|
||||
"1342": "Magyar",
|
||||
"1343": "Català",
|
||||
"1344": "Íslenska ",
|
||||
"1345": "Polski",
|
||||
"1346": "Lietuvių Kalba",
|
||||
"1347": "Čeština",
|
||||
"1348": "Hrvatski",
|
||||
"1349": "Galego",
|
||||
"133c": "<FLAG_PORTUGUAL> Português",
|
||||
"133d": "<FLAG_SWEDEN> Svenska",
|
||||
"133e": "<FLAG_DENMARK> Dansk",
|
||||
"133f": "<FLAG_NORWAY> Norsk",
|
||||
"1340": "<FLAG_DUTCH> Nederlands",
|
||||
"1341": "<FLAG_BRAZIL> Português (Brasil)",
|
||||
"1342": "<FLAG_HUNGARY> Magyar",
|
||||
"1343": "<FLAG_CATALAN> Català",
|
||||
"1344": "<FLAG_ICELAND> Íslenska",
|
||||
"1345": "<FLAG_POLAND> Polski",
|
||||
"1346": "<FLAG_LITHUANIA> Lietuvių Kalba",
|
||||
"1347": "<FLAG_CZECH> Čeština",
|
||||
"1348": "<FLAG_CROATIA> Hrvatski",
|
||||
"1349": "<FLAG_GALICIA> Galego",
|
||||
"134a": "Citlivost na tlak",
|
||||
"134b": "Prohodit R1 a R2",
|
||||
"134c": "Efekty spouští"
|
||||
|
||||
@@ -236,20 +236,20 @@
|
||||
"1339": "Skærm",
|
||||
"133a": "<FLAG_FINLAND> Suomi",
|
||||
"133b": "Hint Subtitles",
|
||||
"133c": "Português",
|
||||
"133d": "Svenska ",
|
||||
"133e": "Dansk",
|
||||
"133f": "Norsk",
|
||||
"1340": "Nederlands",
|
||||
"1341": "Português (Brasil)",
|
||||
"1342": "Magyar",
|
||||
"1343": "Català",
|
||||
"1344": "Íslenska ",
|
||||
"1345": "Polski",
|
||||
"1346": "Lietuvių Kalba",
|
||||
"1347": "Čeština",
|
||||
"1348": "Hrvatski",
|
||||
"1349": "Galego",
|
||||
"133c": "<FLAG_PORTUGUAL> Português",
|
||||
"133d": "<FLAG_SWEDEN> Svenska",
|
||||
"133e": "<FLAG_DENMARK> Dansk",
|
||||
"133f": "<FLAG_NORWAY> Norsk",
|
||||
"1340": "<FLAG_DUTCH> Nederlands",
|
||||
"1341": "<FLAG_BRAZIL> Português (Brasil)",
|
||||
"1342": "<FLAG_HUNGARY> Magyar",
|
||||
"1343": "<FLAG_CATALAN> Català",
|
||||
"1344": "<FLAG_ICELAND> Íslenska",
|
||||
"1345": "<FLAG_POLAND> Polski",
|
||||
"1346": "<FLAG_LITHUANIA> Lietuvių Kalba",
|
||||
"1347": "<FLAG_CZECH> Čeština",
|
||||
"1348": "<FLAG_CROATIA> Hrvatski",
|
||||
"1349": "<FLAG_GALICIA> Galego",
|
||||
"134a": "Pressure Sensitivity",
|
||||
"134b": "Swap R1 and R2",
|
||||
"134c": "Trigger Effects"
|
||||
|
||||
@@ -236,20 +236,20 @@
|
||||
"1339": "Anzeige",
|
||||
"133a": "<FLAG_FINLAND> Suomi",
|
||||
"133b": "Hinweis-Untertitel",
|
||||
"133c": "Português",
|
||||
"133d": "Svenska ",
|
||||
"133e": "Dansk",
|
||||
"133f": "Norsk",
|
||||
"1340": "Nederlands",
|
||||
"1341": "Português (Brasil)",
|
||||
"1342": "Magyar",
|
||||
"1343": "Català",
|
||||
"1344": "Íslenska ",
|
||||
"1345": "Polski",
|
||||
"1346": "Lietuvių Kalba",
|
||||
"1347": "Čeština",
|
||||
"1348": "Hrvatski",
|
||||
"1349": "Galego",
|
||||
"133c": "<FLAG_PORTUGUAL> Português",
|
||||
"133d": "<FLAG_SWEDEN> Svenska",
|
||||
"133e": "<FLAG_DENMARK> Dansk",
|
||||
"133f": "<FLAG_NORWAY> Norsk",
|
||||
"1340": "<FLAG_DUTCH> Nederlands",
|
||||
"1341": "<FLAG_BRAZIL> Português (Brasil)",
|
||||
"1342": "<FLAG_HUNGARY> Magyar",
|
||||
"1343": "<FLAG_CATALAN> Català",
|
||||
"1344": "<FLAG_ICELAND> Íslenska",
|
||||
"1345": "<FLAG_POLAND> Polski",
|
||||
"1346": "<FLAG_LITHUANIA> Lietuvių Kalba",
|
||||
"1347": "<FLAG_CZECH> Čeština",
|
||||
"1348": "<FLAG_CROATIA> Hrvatski",
|
||||
"1349": "<FLAG_GALICIA> Galego",
|
||||
"134a": "Druckempfindlichkeit",
|
||||
"134b": "R1 und R2 tauschen",
|
||||
"134c": "Trigger-Effekte"
|
||||
|
||||
@@ -236,20 +236,20 @@
|
||||
"1339": "Display",
|
||||
"133a": "<FLAG_FINLAND> Suomi",
|
||||
"133b": "Hint Subtitles",
|
||||
"133c": "Português",
|
||||
"133d": "Svenska ",
|
||||
"133e": "Dansk",
|
||||
"133f": "Norsk",
|
||||
"1340": "Nederlands",
|
||||
"1341": "Português (Brasil)",
|
||||
"1342": "Magyar",
|
||||
"1343": "Català",
|
||||
"1344": "Íslenska ",
|
||||
"1345": "Polski",
|
||||
"1346": "Lietuvių Kalba",
|
||||
"1347": "Čeština",
|
||||
"1348": "Hrvatski",
|
||||
"1349": "Galego",
|
||||
"133c": "<FLAG_PORTUGUAL> Português",
|
||||
"133d": "<FLAG_SWEDEN> Svenska",
|
||||
"133e": "<FLAG_DENMARK> Dansk",
|
||||
"133f": "<FLAG_NORWAY> Norsk",
|
||||
"1340": "<FLAG_DUTCH> Nederlands",
|
||||
"1341": "<FLAG_BRAZIL> Português (Brasil)",
|
||||
"1342": "<FLAG_HUNGARY> Magyar",
|
||||
"1343": "<FLAG_CATALAN> Català",
|
||||
"1344": "<FLAG_ICELAND> Íslenska",
|
||||
"1345": "<FLAG_POLAND> Polski",
|
||||
"1346": "<FLAG_LITHUANIA> Lietuvių Kalba",
|
||||
"1347": "<FLAG_CZECH> Čeština",
|
||||
"1348": "<FLAG_CROATIA> Hrvatski",
|
||||
"1349": "<FLAG_GALICIA> Galego",
|
||||
"134a": "Pressure Sensitivity",
|
||||
"134b": "Swap R1 and R2",
|
||||
"134c": "Trigger Effects"
|
||||
|
||||
@@ -236,20 +236,20 @@
|
||||
"1339": "Display",
|
||||
"133a": "<FLAG_FINLAND> Suomi",
|
||||
"133b": "Hint Subtitles",
|
||||
"133c": "Português",
|
||||
"133d": "Svenska ",
|
||||
"133e": "Dansk",
|
||||
"133f": "Norsk",
|
||||
"1340": "Nederlands",
|
||||
"1341": "Português (Brasil)",
|
||||
"1342": "Magyar",
|
||||
"1343": "Català",
|
||||
"1344": "Íslenska ",
|
||||
"1345": "Polski",
|
||||
"1346": "Lietuvių Kalba",
|
||||
"1347": "Čeština",
|
||||
"1348": "Hrvatski",
|
||||
"1349": "Galego",
|
||||
"133c": "<FLAG_PORTUGUAL> Português",
|
||||
"133d": "<FLAG_SWEDEN> Svenska",
|
||||
"133e": "<FLAG_DENMARK> Dansk",
|
||||
"133f": "<FLAG_NORWAY> Norsk",
|
||||
"1340": "<FLAG_DUTCH> Nederlands",
|
||||
"1341": "<FLAG_BRAZIL> Português (Brasil)",
|
||||
"1342": "<FLAG_HUNGARY> Magyar",
|
||||
"1343": "<FLAG_CATALAN> Català",
|
||||
"1344": "<FLAG_ICELAND> Íslenska",
|
||||
"1345": "<FLAG_POLAND> Polski",
|
||||
"1346": "<FLAG_LITHUANIA> Lietuvių Kalba",
|
||||
"1347": "<FLAG_CZECH> Čeština",
|
||||
"1348": "<FLAG_CROATIA> Hrvatski",
|
||||
"1349": "<FLAG_GALICIA> Galego",
|
||||
"134a": "Pressure Sensitivity",
|
||||
"134b": "Swap R1 and R2",
|
||||
"134c": "Trigger Effects"
|
||||
|
||||
@@ -236,20 +236,20 @@
|
||||
"1339": "Pantalla",
|
||||
"133a": "<FLAG_FINLAND> Suomi",
|
||||
"133b": "Subtítulos de sugerencia",
|
||||
"133c": "Português",
|
||||
"133d": "Svenska ",
|
||||
"133e": "Dansk",
|
||||
"133f": "Norsk",
|
||||
"1340": "Nederlands",
|
||||
"1341": "Português (Brasil)",
|
||||
"1342": "Magyar",
|
||||
"1343": "Català",
|
||||
"1344": "Íslenska ",
|
||||
"1345": "Polski",
|
||||
"1346": "Lietuvių Kalba",
|
||||
"1347": "Čeština",
|
||||
"1348": "Hrvatski",
|
||||
"1349": "Galego",
|
||||
"133c": "<FLAG_PORTUGUAL> Português",
|
||||
"133d": "<FLAG_SWEDEN> Svenska",
|
||||
"133e": "<FLAG_DENMARK> Dansk",
|
||||
"133f": "<FLAG_NORWAY> Norsk",
|
||||
"1340": "<FLAG_DUTCH> Nederlands",
|
||||
"1341": "<FLAG_BRAZIL> Português (Brasil)",
|
||||
"1342": "<FLAG_HUNGARY> Magyar",
|
||||
"1343": "<FLAG_CATALAN> Català",
|
||||
"1344": "<FLAG_ICELAND> Íslenska",
|
||||
"1345": "<FLAG_POLAND> Polski",
|
||||
"1346": "<FLAG_LITHUANIA> Lietuvių Kalba",
|
||||
"1347": "<FLAG_CZECH> Čeština",
|
||||
"1348": "<FLAG_CROATIA> Hrvatski",
|
||||
"1349": "<FLAG_GALICIA> Galego",
|
||||
"134a": "Sensibilidad a la presión",
|
||||
"134b": "Intercambiar R1 y R2",
|
||||
"134c": "Efectos de Gatillos"
|
||||
|
||||
@@ -136,7 +136,7 @@
|
||||
"1292": "Palauta oletukset",
|
||||
"1293": "Ohjainasetukset",
|
||||
"1294": "Valitse ohjain",
|
||||
"1295": "Analogisauvan katvealue",
|
||||
"1295": "Ohjaussauvan katvealue",
|
||||
"1296": "Älä huomioi ikkunan ulkopuolella",
|
||||
"1297": "LED-valo kunnolle",
|
||||
"1298": "LED-valo muille tiloille",
|
||||
@@ -207,7 +207,7 @@
|
||||
"1314": "Varoitus!",
|
||||
"1315": "Tämä asetus on erittäin kokeellinen. Kun peliä ei pelata 60 Hz:n kuvataajuudella, visuaalisia sekä pelattavuuden ongelmia voi ilmaantua sen seurauksena.",
|
||||
"1316": "Paikallinen tulos",
|
||||
"1317": "Analogisauvan herkkyys",
|
||||
"1317": "Ohjaussauvan herkkyys",
|
||||
"1320": "Ei mitään",
|
||||
"1321": "Pyörähdys",
|
||||
"1322": "Nopeuslisä",
|
||||
@@ -236,20 +236,20 @@
|
||||
"1339": "Näyttö",
|
||||
"133a": "<FLAG_FINLAND> Suomi",
|
||||
"133b": "Vinkkien tekstitys",
|
||||
"133c": "Português",
|
||||
"133d": "Svenska ",
|
||||
"133e": "Dansk",
|
||||
"133f": "Norsk",
|
||||
"1340": "Nederlands",
|
||||
"1341": "Português (Brasil)",
|
||||
"1342": "Magyar",
|
||||
"1343": "Català",
|
||||
"1344": "Íslenska ",
|
||||
"1345": "Polski",
|
||||
"1346": "Lietuvių Kalba",
|
||||
"1347": "Čeština",
|
||||
"1348": "Hrvatski",
|
||||
"1349": "Galego",
|
||||
"133c": "<FLAG_PORTUGUAL> Português",
|
||||
"133d": "<FLAG_SWEDEN> Svenska",
|
||||
"133e": "<FLAG_DENMARK> Dansk",
|
||||
"133f": "<FLAG_NORWAY> Norsk",
|
||||
"1340": "<FLAG_DUTCH> Nederlands",
|
||||
"1341": "<FLAG_BRAZIL> Português (Brasil)",
|
||||
"1342": "<FLAG_HUNGARY> Magyar",
|
||||
"1343": "<FLAG_CATALAN> Català",
|
||||
"1344": "<FLAG_ICELAND> Íslenska",
|
||||
"1345": "<FLAG_POLAND> Polski",
|
||||
"1346": "<FLAG_LITHUANIA> Lietuvių Kalba",
|
||||
"1347": "<FLAG_CZECH> Čeština",
|
||||
"1348": "<FLAG_CROATIA> Hrvatski",
|
||||
"1349": "<FLAG_GALICIA> Galego",
|
||||
"134a": "Näppäinten paineherkkyys",
|
||||
"134b": "Vaihda R1- ja R2-toiminnot",
|
||||
"134c": "Ohjaimen liipaisintehosteet"
|
||||
|
||||
@@ -236,20 +236,20 @@
|
||||
"1339": "Écran",
|
||||
"133a": "<FLAG_FINLAND> Suomi",
|
||||
"133b": "Sous-titres d'indices.",
|
||||
"133c": "Português",
|
||||
"133d": "Svenska ",
|
||||
"133e": "Dansk",
|
||||
"133f": "Norsk",
|
||||
"1340": "Nederlands",
|
||||
"1341": "Português (Brasil)",
|
||||
"1342": "Magyar",
|
||||
"1343": "Català",
|
||||
"1344": "Íslenska ",
|
||||
"1345": "Polski",
|
||||
"1346": "Lietuvių Kalba",
|
||||
"1347": "Čeština",
|
||||
"1348": "Hrvatski",
|
||||
"1349": "Galego",
|
||||
"133c": "<FLAG_PORTUGUAL> Português",
|
||||
"133d": "<FLAG_SWEDEN> Svenska",
|
||||
"133e": "<FLAG_DENMARK> Dansk",
|
||||
"133f": "<FLAG_NORWAY> Norsk",
|
||||
"1340": "<FLAG_DUTCH> Nederlands",
|
||||
"1341": "<FLAG_BRAZIL> Português (Brasil)",
|
||||
"1342": "<FLAG_HUNGARY> Magyar",
|
||||
"1343": "<FLAG_CATALAN> Català",
|
||||
"1344": "<FLAG_ICELAND> Íslenska",
|
||||
"1345": "<FLAG_POLAND> Polski",
|
||||
"1346": "<FLAG_LITHUANIA> Lietuvių Kalba",
|
||||
"1347": "<FLAG_CZECH> Čeština",
|
||||
"1348": "<FLAG_CROATIA> Hrvatski",
|
||||
"1349": "<FLAG_GALICIA> Galego",
|
||||
"134a": "Sensibilité à la pression.",
|
||||
"134b": "Inversez R1 et R2.",
|
||||
"134c": "Déclencher des effets."
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user