Compare commits

..
11 Commits
Author SHA1 Message Date
Tyler Wilding 1e307c8a9e i18n: add finnish to menus 2024-07-31 22:34:55 -04:00
Tyler Wilding 3a67f40098 i18n: remove meta line 2024-07-31 22:21:04 -04:00
Aloqas cbfa65c78a Update text-id-h.gc 2024-07-31 23:43:55 +03:00
Aloqas 681c419f17 Update subtitle_meta_fi-FI.json 2024-07-31 23:43:42 +03:00
Aloqas a4e108cca6 city-save-lurkers-intro 2024-07-31 23:41:08 +03:00
Aloqas f1ee25c640 Merge branch 'master' into test2 2024-07-31 18:55:20 +03:00
Aloqas 495a8bc26f rewording stuff 2024-06-20 18:26:15 +03:00
Aloqas c2cccc48cd another change 2024-05-24 15:35:17 +03:00
Aloqas c5effb2395 small change 2024-05-24 12:14:29 +03:00
Aloqas 5f3671b8a3 small fixes 2024-05-24 11:02:02 +03:00
Aloqas 26bfac8555 Jak 2: Finnish subtitles and game text 2024-05-23 22:54:42 +03:00
1818 changed files with 24621 additions and 435810 deletions

No files matched your search

+1 -2
View File
@@ -1,7 +1,6 @@
name: "\U0001F41B Jak 1 Bug Report"
description: Create a bug report for Jak 1.
labels: ["jak1"]
type: 'bug'
labels: ["bug", "jak1"]
body:
- type: checkboxes
attributes:
+1 -2
View File
@@ -1,7 +1,6 @@
name: "\U0001F41B Jak 2 Bug Report"
description: Create a bug report for Jak 2.
labels: ["jak2"]
type: 'bug'
labels: ["bug", "jak2"]
body:
- type: checkboxes
attributes:
@@ -1,10 +1,4 @@
{
"3990": {
"msg": "Provided invalid or missing arguments"
},
"3991": {
"msg": "Input path(s) do not exist"
},
"4000": {
"msg": "Validation Failed: Cannot locate ELF"
},
+9 -7
View File
@@ -49,12 +49,14 @@ jobs:
name: "🍎 MacOS"
uses: ./.github/workflows/macos-build.yaml
with:
cmakePreset: "Release-macos-x86_64-clang"
cmakePreset: "Release-macos-clang"
cachePrefix: ""
build_macos_arm:
name: "🍎 MacOS"
uses: ./.github/workflows/macos-build-arm.yaml
with:
cmakePreset: "Release-macos-x86_64-clang"
cachePrefix: ""
# Q4 2023 there will hopefully be native arm64 runners
# https://github.com/github/roadmap/issues/528
# build_macos_arm:
# name: "🍎 MacOS"
# uses: ./.github/workflows/macos-build-arm.yaml
# with:
# cmakePreset: "Release-macos-clang"
# cachePrefix: ""
@@ -1,98 +0,0 @@
name: Compilation Check
on:
pull_request:
branches:
- master
jobs:
build:
name: Compare
runs-on: ubuntu-20.04
timeout-minutes: 60
steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
ref: master
- name: Install Package Dependencies
run: |
sudo apt update
sudo apt install build-essential cmake \
clang gcc g++ lcov make nasm libxrandr-dev \
libxinerama-dev libxcursor-dev libpulse-dev \
libxi-dev zip ninja-build libgl1-mesa-dev libssl-dev
- name: Setup sccache
uses: hendrikmuhs/[email protected]
with:
variant: sccache
key: linux-ubuntu-20.04--Release-linux-clang-static-${{ github.sha }}
restore-keys: linux-ubuntu-20.04--Release-linux-clang-static
max-size: 1000M
- name: CMake Generation (master)
env:
CC: clang
CXX: clang++
run: |
cmake -B build --preset=Release-linux-clang-static \
-DCMAKE_C_COMPILER_LAUNCHER=sccache \
-DCMAKE_CXX_COMPILER_LAUNCHER=sccache
- name: Build goalc (master)
run: |
cmake --build build --parallel $((`nproc`)) --target goalc
mv ./build ./build.master
- name: Checkout PR
uses: actions/checkout@v4
with:
clean: "false"
- name: CMake Generation (PR)
env:
CC: clang
CXX: clang++
run: |
cmake -B build --preset=Release-linux-clang-static \
-DCMAKE_C_COMPILER_LAUNCHER=sccache \
-DCMAKE_CXX_COMPILER_LAUNCHER=sccache
- name: Build goalc (PR)
run: cmake --build build --parallel $((`nproc`)) --target goalc
- name: Compile and preserve (master)
run: |
./build.master/goalc/goalc --game jak1 --cmd "(make-group \"all-code\")"
./build.master/goalc/goalc --game jak2 --cmd "(make-group \"all-code\")"
./build.master/goalc/goalc --game jak3 --cmd "(make-group \"all-code\")"
mv ./out/jak1/obj ./out/jak1/obj.master
mv ./out/jak2/obj ./out/jak2/obj.master
mv ./out/jak3/obj ./out/jak3/obj.master
- name: Compile and preserve (PR)
run: |
./build/goalc/goalc --game jak1 --cmd "(make-group \"all-code\")"
./build/goalc/goalc --game jak2 --cmd "(make-group \"all-code\")"
./build/goalc/goalc --game jak3 --cmd "(make-group \"all-code\")"
mv ./out/jak1/obj ./out/jak1/obj.pr
mv ./out/jak2/obj ./out/jak2/obj.pr
mv ./out/jak3/obj ./out/jak3/obj.pr
- name: Compare Results and Produce Report
run: |
ls -l ./out/jak1
ls -l ./out/jak2
ls -l ./out/jak3
set +e
python ./scripts/gsrc/compare-compilation-outputs.py --base "./out/jak1/obj.master,./out/jak2/obj.master,./out/jak3/obj.master" --compare "./out/jak1/obj.pr,./out/jak2/obj.pr,./out/jak3/obj.pr" --markdown
SCRIPT_EXIT_CODE=$?
cat ./comp-diff-report.md >> $GITHUB_STEP_SUMMARY
if [ "$SCRIPT_EXIT_CODE" -ne 0 ]; then
exit 1
fi
+35
View File
@@ -0,0 +1,35 @@
name: 🏭 Draft Release
on:
workflow_dispatch:
inputs:
bump:
description: 'Semver Bump Type'
required: true
default: 'patch'
type: choice
options:
- patch
- minor
- major
jobs:
cut-release:
runs-on: ubuntu-latest
steps:
# Docs - https://github.com/mathieudutour/github-tag-action
# Workflows cannot trigger other workflows implicitly
# - https://github.community/t/github-actions-workflow-not-triggering-with-tag-push/17053/7
- name: Bump Version and Push Tag
if: github.repository == 'open-goal/jak-project'
id: tag_version
uses: mathieudutour/[email protected]
with:
github_token: ${{ secrets.BOT_PAT }}
tag_prefix: v
default_bump: ${{ github.event.inputs.bump }}
- name: Create Release
env:
GITHUB_TOKEN: ${{ secrets.BOT_PAT }}
run: gh release create ${{ steps.tag_version.outputs.new_tag }} --generate-notes --draft --repo open-goal/jak-project
+1 -11
View File
@@ -21,19 +21,9 @@ jobs:
timeout-minutes: 60
steps:
# minimal checkout if we're NOT uploading artifacts
- name: Checkout Repository
if: ${{ ! inputs.uploadArtifacts }}
uses: actions/checkout@v4
# full checkout with tags if we ARE uploading artifacts
- name: Checkout Repository with Tags
if: ${{ inputs.uploadArtifacts }}
uses: actions/checkout@v4
with:
fetch-depth: 0
fetch-tags: true
- name: Install Package Dependencies
run: |
sudo apt update
@@ -43,7 +33,7 @@ jobs:
libxi-dev zip ninja-build libgl1-mesa-dev libssl-dev
- name: Setup sccache
uses: hendrikmuhs/[email protected]4
uses: hendrikmuhs/[email protected]3
with:
variant: sccache
key: linux-ubuntu-20.04-${{ inputs.cachePrefix }}-${{ inputs.cmakePreset }}-${{ github.sha }}
+1 -1
View File
@@ -34,7 +34,7 @@ jobs:
sudo update-alternatives --set g++ /usr/bin/g++-10
- name: Setup sccache
uses: hendrikmuhs/[email protected]4
uses: hendrikmuhs/[email protected]3
with:
variant: sccache
key: linux-ubuntu-20.04-${{ inputs.cachePrefix }}-${{ inputs.cmakePreset }}-${{ github.sha }}
+9 -6
View File
@@ -13,22 +13,25 @@ on:
jobs:
build:
name: ARM
runs-on: macos-15
runs-on: macos-12
timeout-minutes: 120
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Set up ARM64 environment
run: sudo softwareupdate --install-rosetta --agree-to-license
- name: Install Package Dependencies
run: brew install cmake ninja nasm
run: arch -arm64 brew install cmake ninja
- name: Setup sccache
uses: hendrikmuhs/[email protected]4
uses: hendrikmuhs/[email protected]3
with:
variant: sccache
key: macos-15-${{ inputs.cachePrefix }}-${{ inputs.cmakePreset }}-${{ github.sha }}
restore-keys: macos-15-${{ inputs.cachePrefix }}-${{ inputs.cmakePreset }}
key: macos-12-${{ inputs.cachePrefix }}-${{ inputs.cmakePreset }}-${{ github.sha }}
restore-keys: macos-12-${{ inputs.cachePrefix }}-${{ inputs.cmakePreset }}
max-size: 1000M
- name: CMake Generation
@@ -49,7 +52,7 @@ jobs:
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: opengoal-macos-arm-${{ inputs.cachePrefix }}
name: opengoal-macos-${{ inputs.cachePrefix }}
if-no-files-found: error
path: |
./build/goalc/goalc
+4 -14
View File
@@ -17,32 +17,22 @@ on:
jobs:
build:
name: Intel
runs-on: macos-13
runs-on: macos-12
timeout-minutes: 120
steps:
# minimal checkout if we're NOT uploading artifacts
- name: Checkout Repository
if: ${{ ! inputs.uploadArtifacts }}
uses: actions/checkout@v4
# full checkout with tags if we ARE uploading artifacts
- name: Checkout Repository with Tags
if: ${{ inputs.uploadArtifacts }}
uses: actions/checkout@v4
with:
fetch-depth: 0
fetch-tags: true
- name: Install Package Dependencies
run: brew install cmake nasm ninja
- name: Setup sccache
uses: hendrikmuhs/[email protected]4
uses: hendrikmuhs/[email protected]3
with:
variant: sccache
key: macos-13-${{ inputs.cachePrefix }}-${{ inputs.cmakePreset }}-${{ github.sha }}
restore-keys: macos-13-${{ inputs.cachePrefix }}-${{ inputs.cmakePreset }}
key: macos-12-${{ inputs.cachePrefix }}-${{ inputs.cmakePreset }}-${{ github.sha }}
restore-keys: macos-12-${{ inputs.cachePrefix }}-${{ inputs.cmakePreset }}
max-size: 1000M
- name: CMake Generation
+12 -81
View File
@@ -1,52 +1,13 @@
name: 🏭 Draft Release
name: 🏭 Release Pipeline
on:
workflow_dispatch:
inputs:
bump:
description: 'Semver Bump Type'
required: true
default: 'patch'
type: choice
options:
- patch
- minor
- major
permissions:
contents: write
push:
tags:
- v*
jobs:
cut_release:
name: Cut Release
runs-on: ubuntu-latest
outputs:
new_tag: ${{ steps.set_tag.outputs.new_tag }}
steps:
# Docs - https://github.com/mathieudutour/github-tag-action
- name: Bump Version and Push Tag
if: github.repository == 'open-goal/jak-project'
id: tag_version
uses: mathieudutour/[email protected]
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
tag_prefix: v
default_bump: ${{ github.event.inputs.bump }}
- name: Create Release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: gh release create ${{ steps.tag_version.outputs.new_tag }} --generate-notes --draft --repo ${{ github.repository }}
- name: Output new tag
id: set_tag
run: |
echo "new_tag=${{ steps.tag_version.outputs.new_tag }}" >> $GITHUB_OUTPUT
# Windows
build_windows_clang:
needs:
- cut_release
name: "🖥️ Windows"
uses: ./.github/workflows/windows-build-clang.yaml
with:
@@ -57,8 +18,6 @@ jobs:
# Linux
build_linux_clang:
needs:
- cut_release
name: "🐧 Linux"
uses: ./.github/workflows/linux-build-clang.yaml
with:
@@ -69,23 +28,10 @@ jobs:
# macOS
build_macos_intel:
needs:
- cut_release
name: "🍎 MacOS"
uses: ./.github/workflows/macos-build.yaml
with:
cmakePreset: "Release-macos-x86_64-clang-static"
cachePrefix: "static"
uploadArtifacts: true
secrets: inherit
build_macos_arm:
needs:
- cut_release
name: "🍎 MacOS"
uses: ./.github/workflows/macos-build.yaml
with:
cmakePreset: "Release-macos-x86_64-clang-static"
cmakePreset: "Release-macos-clang-static"
cachePrefix: "static"
uploadArtifacts: true
secrets: inherit
@@ -94,17 +40,13 @@ jobs:
upload_artifacts:
if: github.repository == 'open-goal/jak-project'
needs:
- cut_release
- build_windows_clang
- build_linux_clang
- build_macos_intel
- build_macos_arm
name: "Upload Artifacts"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: ${{ needs.cut_release.outputs.new_tag }}
- name: Prepare Artifact Folder
run: mkdir -p ./ci-artifacts/final
@@ -122,7 +64,7 @@ jobs:
mkdir -p ./ci-artifacts/linux
./.github/scripts/releases/extract_build_unix.sh ./ci-artifacts/linux ./ci-artifacts/opengoal-linux-static ./
pushd ci-artifacts/linux
TAG_VAL=${{ needs.cut_release.outputs.new_tag }}
TAG_VAL=$(echo ${{ github.REF }} | awk -F'refs/tags/' '{print $2}')
tar czf ../final/opengoal-linux-${TAG_VAL}.tar.gz .
popd
chmod +x ./ci-artifacts/opengoal-linux-static/lsp/lsp
@@ -132,42 +74,31 @@ jobs:
run: |
mkdir -p ./ci-artifacts/windows
./.github/scripts/releases/extract_build_windows.sh ./ci-artifacts/windows ./ci-artifacts/opengoal-windows-static ./
TAG_VAL=${{ needs.cut_release.outputs.new_tag }}
TAG_VAL=$(echo ${{ github.REF }} | awk -F'refs/tags/' '{print $2}')
7z a -tzip ./ci-artifacts/final/opengoal-windows-${TAG_VAL}.zip ./ci-artifacts/windows/*
cp ./ci-artifacts/opengoal-windows-static/lsp.exe ./ci-artifacts/final/opengoal-lsp-windows-${TAG_VAL}.exe
- name: Prepare Intel macOS Build Assets
- name: Prepare macOS Build Assets
run: |
mkdir -p ./ci-artifacts/macos
./.github/scripts/releases/extract_build_unix.sh ./ci-artifacts/macos ./ci-artifacts/opengoal-macos-static ./
pushd ci-artifacts/macos
TAG_VAL=${{ needs.cut_release.outputs.new_tag }}
TAG_VAL=$(echo ${{ github.REF }} | awk -F'refs/tags/' '{print $2}')
tar czf ../final/opengoal-macos-intel-${TAG_VAL}.tar.gz .
popd
chmod +x ./ci-artifacts/opengoal-macos-static/lsp/lsp
cp ./ci-artifacts/opengoal-macos-static/lsp/lsp ./ci-artifacts/final/opengoal-lsp-macos-intel-${TAG_VAL}.bin
- name: Prepare ARM macOS Build Assets
run: |
mkdir -p ./ci-artifacts/macos-arm
./.github/scripts/releases/extract_build_unix.sh ./ci-artifacts/macos-arm ./ci-artifacts/opengoal-macos-arm-static ./
pushd ci-artifacts/macos-arm
TAG_VAL=${{ needs.cut_release.outputs.new_tag }}
tar czf ../final/opengoal-macos-arm-${TAG_VAL}.tar.gz .
popd
chmod +x ./ci-artifacts/opengoal-macos-arm-static/lsp/lsp
cp ./ci-artifacts/opengoal-macos-arm-static/lsp/lsp ./ci-artifacts/final/opengoal-lsp-macos-arm-${TAG_VAL}.bin
- name: Upload Assets
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
TAG_VAL=${{ needs.cut_release.outputs.new_tag }}
TAG_VAL=$(echo ${{ github.REF }} | awk -F'refs/tags/' '{print $2}')
gh release upload "${TAG_VAL}" ${{ github.WORKSPACE }}/ci-artifacts/final/* --repo open-goal/jak-project --clobber
- name: Publish Release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_TOKEN: ${{ secrets.BOT_PAT }}
run: |
TAG_VAL=${{ needs.cut_release.outputs.new_tag }}
TAG_VAL=$(echo ${{ github.REF }} | awk -F'refs/tags/' '{print $2}')
gh release edit ${TAG_VAL} --draft=false --repo open-goal/jak-project
+1 -1
View File
@@ -19,7 +19,7 @@ jobs:
wget -O ./game/assets/sdl_controller_db.txt https://raw.githubusercontent.com/gabomdq/SDL_GameControllerDB/master/gamecontrollerdb.txt
- name: Create Pull Request
uses: peter-evans/create-pull-request@v7
uses: peter-evans/create-pull-request@v6
with:
token: ${{ secrets.BOT_PAT }}
author: 'OpenGOALBot <[email protected]>'
+1 -11
View File
@@ -22,19 +22,9 @@ jobs:
timeout-minutes: 60
steps:
# minimal checkout if we're NOT uploading artifacts
- name: Checkout Repository
if: ${{ ! inputs.uploadArtifacts }}
uses: actions/checkout@v4
# full checkout with tags if we ARE uploading artifacts
- name: Checkout Repository with Tags
if: ${{ inputs.uploadArtifacts }}
uses: actions/checkout@v4
with:
fetch-depth: 0
fetch-tags: true
- name: Install NASM
# TODO - Simplify this with just the first command once choco 2.0 rolls out everywhere
run: |
@@ -46,7 +36,7 @@ jobs:
}
- name: Setup sccache
uses: hendrikmuhs/[email protected]4
uses: hendrikmuhs/[email protected]3
with:
variant: sccache
key: windows-2022-${{ inputs.cachePrefix }}-${{ inputs.cmakePreset }}-${{ github.sha }}
+1 -1
View File
@@ -31,7 +31,7 @@ jobs:
}
- name: Setup sccache
uses: hendrikmuhs/[email protected]4
uses: hendrikmuhs/[email protected]3
with:
variant: sccache
key: windows-2022-${{ inputs.cachePrefix }}-${{ inputs.cmakePreset }}-${{ github.sha }}
+2 -5
View File
@@ -1,7 +1,6 @@
# logs
/log
prof.json
/gpu-test.json
# for CMake
/Testing
@@ -10,8 +9,7 @@ prof.json
cmake-build-debug/*
cmake-build-debug--o0/*
.idea/*
build/
build.master/
build/*
/decompiler_out*
logs/*
profile_data/*
@@ -34,7 +32,6 @@ linux-default/
*.bin
*.log
*.p2s
out/
savestate-out/
savestate_out/
failures/
@@ -42,7 +39,6 @@ ee-results*.json
search-results.json
.env
/search-results.json
comp-diff-report.md
# graphics debug
debug_out/
@@ -71,6 +67,7 @@ custom_assets/jak3/merc_replacements/*
svnrev.h
common/versions/revision.h
ci-artifacts/
out/build/
__pycache__/
# sqlite stuff
-13
View File
@@ -138,19 +138,6 @@
"-debug"
]
},
{
"type": "default",
"project": "CMakeLists.txt",
"projectTarget": "gk.exe (bin\\gk.exe)",
"name": "Game - GPU Test",
"args": [
"-v",
"--gpu-test",
"opengl",
"--gpu-test-out-path",
"./gpu-test.json"
]
},
{
"type": "default",
"project": "CMakeLists.txt",
+1 -10
View File
@@ -2,7 +2,6 @@
cmake_minimum_required(VERSION 3.10)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
project(jak)
include(CTest)
@@ -44,10 +43,6 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
-Wall \
-Wno-c++11-narrowing \
-Wno-c++98-compat \
-Wno-deprecated-this-capture \
-Wno-missing-field-initializers \
-Wno-sign-compare \
-Wno-ignored-qualifiers \
-O3 \
-D_CRT_SECURE_NO_WARNINGS")
@@ -57,7 +52,7 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
# Note: this is only _reserved_ memory, not necessarily _committed_ memory
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${LDFLAGS} -Xlinker /STACK:16000000")
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ggdb -g")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ggdb -g -Wextra")
endif()
# additional c++ and linker flags for release mode for our projects
@@ -288,10 +283,6 @@ include(test/CMakeLists.txt)
build_third_party_lib(lzokay lzokay)
build_third_party_lib(stb_image stb_image)
# build draco library for tinygltf compression support
include_directories(third-party/draco/src)
add_subdirectory(third-party/draco)
add_compile_definitions(TINYGLTF_ENABLE_DRACO)
build_third_party_lib(tiny_gltf tiny_gltf)
build_third_party_lib(xdelta3 xdelta3)
+8 -40
View File
@@ -78,22 +78,6 @@
"CMAKE_INSTALL_PREFIX": "${sourceDir}/build/install/${presetName}"
}
},
{
"name": "base-macos-arm64",
"hidden": true,
"cacheVariables": {
"CMAKE_APPLE_SILICON_PROCESSOR": "arm64",
"CMAKE_OSX_ARCHITECTURES": "arm64"
}
},
{
"name": "base-macos-x86_64",
"hidden": true,
"cacheVariables": {
"CMAKE_APPLE_SILICON_PROCESSOR": "x86_64",
"CMAKE_OSX_ARCHITECTURES": "x86_64"
}
},
{
"name": "base-clang",
"hidden": true,
@@ -175,32 +159,16 @@
"inherits": ["base-linux-release", "base-clang"]
},
{
"name": "Release-macos-arm64-clang",
"displayName": "MacOS ARM64 Release (clang)",
"description": "Build for ARM64 with Clang as Release without Debug Symbols",
"inherits": ["base-macos-release", "base-macos-arm64", "base-clang"]
"name": "Release-macos-clang",
"displayName": "MacOS Release (clang)",
"description": "Build with Clang as Release without Debug Symbols",
"inherits": ["base-macos-release", "base-clang"]
},
{
"name": "Release-macos-x86_64-clang",
"displayName": "MacOS x86_64 Release (clang)",
"description": "Build for x86_64 with Clang as Release without Debug Symbols",
"inherits": ["base-macos-release", "base-macos-x86_64", "base-clang"]
},
{
"name": "Release-macos-arm64-clang-static",
"displayName": "MacOS ARM64 Static Release (clang)",
"description": "Build for ARM64 with Clang as Release without Debug Symbols but statically linked",
"inherits": ["base-macos-release", "base-macos-arm64", "base-clang"],
"cacheVariables": {
"STATICALLY_LINK": "true",
"ZYDIS_BUILD_SHARED_LIB": "OFF"
}
},
{
"name": "Release-macos-x86_64-clang-static",
"displayName": "MacOS x86_64 Static Release (clang)",
"description": "Build for x86_64 with Clang as Release without Debug Symbols but statically linked, requires MacOS Sequoia",
"inherits": ["base-macos-release", "base-macos-x86_64", "base-clang"],
"name": "Release-macos-clang-static",
"displayName": "MacOS Static Release (clang)",
"description": "Build with Clang as Release without Debug Symbols but statically linked",
"inherits": ["base-macos-release", "base-clang"],
"cacheVariables": {
"STATICALLY_LINK": "true",
"ZYDIS_BUILD_SHARED_LIB": "OFF"
+1 -1
View File
@@ -1,6 +1,6 @@
ISC License
Copyright (c) 2020-2025 OpenGOAL Team
Copyright (c) 2020-2022 OpenGOAL Team
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
+11 -13
View File
@@ -72,7 +72,7 @@ Our objectives are:
We support both Linux and Windows on x86-64.
> We do not support, or plan to support the ARM architecture. This means that this will not run on devices such as a mobile device.
> We do not support, or plan to support the ARM architecture. This means that this will not run on devices such as an M1 Mac or a mobile device.
### Current Status
@@ -127,7 +127,7 @@ Unfortunately you'll still need task runner on your local machine to run the gam
Install packages and init repository:
```sh
sudo apt install gcc make cmake ninja-build build-essential g++ nasm clang-format libxrandr-dev libxinerama-dev libxcursor-dev libpulse-dev libxi-dev python libgl1-mesa-dev libssl-dev
sudo apt install gcc make cmake build-essential g++ nasm clang-format libxrandr-dev libxinerama-dev libxcursor-dev libpulse-dev libxi-dev python libgl1-mesa-dev libssl-dev
sudo sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b /usr/local/bin
```
@@ -235,7 +235,7 @@ Then build the entire project as `Windows Release (clang)`. You can also press C
### MacOS
> NOTE: Running the game requires an Apple Silicon Mac running macOS Sequoia, or an Intel Mac.
> NOTE: At this time you can only run the game on macOS if you have an Intel processor.
Ensure that you have Xcode command line tools installed (this installs things like Apple Clang). If you don't, you can run the following command:
@@ -243,25 +243,23 @@ Ensure that you have Xcode command line tools installed (this installs things li
xcode-select --install
```
On Apple Silicon, Rosetta 2 also must be installed:
```bash
softwareupdate --install-rosetta
```
#### Building for x86_64
#### Intel Based
```bash
brew install go-task/tap/go-task
brew install cmake nasm ninja go-task clang-format
cmake -B build --preset=Release-macos-x86_64-clang
cmake -B build --preset=Release-macos-clang
cmake --build build --parallel $((`sysctl -n hw.logicalcpu`))
```
#### Building for ARM64 (experimental, unsupported)
#### Apple Silicon
**Not Supported at This Time**
```bash
brew install go-task/tap/go-task
brew install cmake ninja go-task clang-format
cmake -B build --preset=Release-macos-arm64-clang
cmake -B build --preset=Release-macos-clang
cmake --build build --parallel $((`sysctl -n hw.logicalcpu`))
```
-15
View File
@@ -67,14 +67,6 @@ tasks:
cmds:
- "{{.GK_BIN_RELEASE_DIR}}/gk -v --game {{.GAME}} -- -fakeiso -debug"
# DEVELOPMENT
gen-cmake:
desc: "Generate the CMake"
cmds:
- "cmake -B build --preset={{.CMAKE_PRESET}}"
build:
desc: "Build the project using the generated CMake"
cmds:
- "cmake --build build --parallel {{.CMAKE_NUM_THREADS}}"
repl:
desc: "Start the REPL"
preconditions:
@@ -172,13 +164,6 @@ tasks:
lint:
cmds:
- python ./scripts/ci/lint-trailing-whitespace.py
run-gpu-test:
desc: "Runs the game's built in GPU test"
preconditions:
- sh: test -f {{.GK_BIN_RELEASE_DIR}}/gk{{.EXE_FILE_EXTENSION}}
msg: "Couldn't locate runtime executable in '{{.GK_BIN_RELEASE_DIR}}/gk'"
cmds:
- "{{.GK_BIN_RELEASE_DIR}}/gk -v --gpu-test opengl --gpu-test-out-path ./gpu-test.json"
# TESTS
offline-tests: # ran by jenkins
cmds:
-8
View File
@@ -15,13 +15,6 @@ function(write_revision_h)
OUTPUT_VARIABLE GIT_TAG
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET)
# To support being on a commit with mutiple tags
if(${GIT_TAG} MATCHES "\n")
string(REPLACE "\n" ";" GIT_TAG_LIST "${GIT_TAG}")
list(LENGTH GIT_TAG_LIST GIT_TAG_LIST_LENGTH)
math(EXPR GIT_TAG_LAST_INDEX "${GIT_TAG_LIST_LENGTH} - 1")
list(GET GIT_TAG_LIST ${GIT_TAG_LAST_INDEX} GIT_TAG)
endif()
endif()
file(WRITE ${CMAKE_CURRENT_SOURCE_DIR}/versions/revision.h "#define BUILT_TAG \"${GIT_TAG}\"\n#define BUILT_SHA \"${GIT_SHORT_SHA}\"\n")
endfunction()
@@ -95,7 +88,6 @@ add_library(common
util/Timer.cpp
util/unicode_util.cpp
util/gltf_util.cpp
util/image_resize.cpp
versions/versions.cpp
)
+1 -12
View File
@@ -304,15 +304,13 @@ void TieTree::unpack() {
for (auto& draw : static_draws) {
draw.unpacked.idx_of_first_idx_in_full_buffer = unpacked.indices.size();
// indices can come from either runs or already in plain indices.
ASSERT(draw.plain_indices.empty());
for (auto& run : draw.runs) {
for (u32 ri = 0; ri < run.length; ri++) {
unpacked.indices.push_back(run.vertex0 + ri);
}
unpacked.indices.push_back(UINT32_MAX);
}
unpacked.indices.insert(unpacked.indices.end(), draw.plain_indices.begin(),
draw.plain_indices.end());
}
}
@@ -408,8 +406,6 @@ void TieTree::serialize(Serializer& ser) {
colors.serialize(ser);
bvh.serialize(ser);
ser.from_ptr(&use_strips);
ser.from_ptr(&has_per_proto_visibility_toggle);
ser.from_string_vector(&proto_names);
}
@@ -854,11 +850,4 @@ std::size_t PreloadedVertex::hash::operator()(const PreloadedVertex& v) const {
std::hash<float>()(v.s) ^ std::hash<float>()(v.t) ^ std::hash<u16>()(v.color_index);
}
std::size_t PackedTieVertices::Vertex::hash::operator()(const Vertex& v) const {
return std::hash<float>()(v.x) ^ std::hash<float>()(v.y) ^ std::hash<float>()(v.z) ^
std::hash<float>()(v.r) ^ std::hash<float>()(v.g) ^ std::hash<float>()(v.b) ^
std::hash<float>()(v.a) ^ std::hash<float>()(v.s) ^ std::hash<float>()(v.t) ^
std::hash<float>()(v.nx) ^ std::hash<float>()(v.ny) ^ std::hash<float>()(v.nz);
}
} // namespace tfrag3
+2 -14
View File
@@ -18,7 +18,7 @@ namespace tfrag3 {
// - if changing any large things (vertices, vis, bvh, colors, textures) update get_memory_usage
// - if adding a new category to the memory usage, update extract_level to print it.
constexpr int TFRAG3_VERSION = 43;
constexpr int TFRAG3_VERSION = 41;
enum MemoryUsageCategory {
TEXTURE,
@@ -116,16 +116,6 @@ struct PackedTieVertices {
float s, t;
s8 nx, ny, nz;
u8 r, g, b, a;
struct hash {
std::size_t operator()(const Vertex& x) const;
};
bool operator==(const Vertex& other) const {
return x == other.x && y == other.y && z == other.z && s == other.s && t == other.t &&
nx == other.nx && ny == other.ny && nz == other.nz && r == other.r && g == other.g &&
b == other.b && a == other.a;
}
};
struct MatrixGroup {
@@ -241,7 +231,7 @@ struct ShrubDraw {
struct InstancedStripDraw {
DrawMode mode; // the OpenGL draw settings.
s32 tree_tex_id = 0; // the texture that should be bound for the draw
u32 tree_tex_id = 0; // the texture that should be bound for the draw
// the list of vertices in the draw. This includes the restart code of UINT32_MAX that OpenGL
// will use to start a new strip.
@@ -430,8 +420,6 @@ struct TieTree {
bool has_per_proto_visibility_toggle = false;
std::vector<std::string> proto_names;
bool use_strips = true;
struct {
std::vector<PreloadedVertex> vertices; // mesh vertices
std::vector<u32> indices;
+1 -1
View File
@@ -37,7 +37,7 @@ struct DmaTag {
DmaTag(u64 value) {
spr = (value >> 63);
addr = (value >> 32) & 0x7fffffff;
qwc = value & 0xffff;
qwc = value & 0xfff;
kind = Kind((value >> 28) & 0b111);
}
+1 -1
View File
@@ -143,7 +143,7 @@ void FormatterTree::construct_formatter_tree_recursive(const std::string& source
}
for (size_t i = 0; i < ts_node_child_count(curr_node); i++) {
const auto child_node = ts_node_child(curr_node, i);
[[maybe_unused]] auto debug_child = ts_node_string(child_node);
auto debug_child = ts_node_string(child_node);
const auto contents = get_source_code(source, child_node);
bool skip_node = false;
for (const auto& skippable_content : skippable_nodes) {
-38
View File
@@ -168,39 +168,6 @@ static FormFormattingConfig new_deftype_rule(
return cfg;
}
static FormFormattingConfig new_defproc_rule(
int start_index,
int num_columns_to_compute_widths,
const std::vector<int>& inlining_preventation_indices) {
FormFormattingConfig cfg;
cfg.has_constant_pairs = true;
cfg.config_set = true;
cfg.hang_forms = false;
cfg.inline_until_index = [start_index](std::vector<std::string> curr_lines) {
// if (curr_lines.size() >= 4 && curr_lines.at(3) == "()") {
// return 4;
// }
return start_index;
};
for (const auto& index : inlining_preventation_indices) {
auto temp_config = std::make_shared<FormFormattingConfig>();
temp_config->config_set = true;
temp_config->prevent_inlining = true;
temp_config->hang_forms = false;
temp_config->indentation_width = 1;
auto temp_list_config = std::make_shared<FormFormattingConfig>();
temp_list_config->force_inline = false;
temp_list_config->hang_forms = false;
temp_config->default_index_config = temp_list_config;
if (index == 3) {
temp_config->determine_column_widths_for_list_elements = true;
temp_config->num_columns_to_compute_widths = num_columns_to_compute_widths;
}
cfg.index_configs.emplace(index, temp_config);
}
return cfg;
}
static FormFormattingConfig new_binding_rule(int form_head_width) {
FormFormattingConfig cfg;
cfg.config_set = true;
@@ -286,9 +253,6 @@ const std::unordered_map<std::string, FormFormattingConfig> opengoal_form_config
{"defmethod", new_defmethod_rule(3)},
{"lambda", new_lambda_rule(2)},
{"deftype", new_deftype_rule(3, 1, {3, 4, 5, 6})},
{"defproc", new_defproc_rule(3, 1, {3, 4, 5, 6})},
{"suspend-for", new_flow_rule(2)},
{"spawn-proc", new_flow_rule(2)},
{"defun", new_flow_rule(3)},
{"defun-recursive", new_flow_rule(4)},
{"defun-debug-recursive", new_flow_rule(4)},
@@ -317,14 +281,12 @@ const std::unordered_map<std::string, FormFormattingConfig> opengoal_form_config
{"protect", new_binding_rule(4)},
{"let*", new_binding_rule(5)},
{"rlet", new_binding_rule(5)},
{"mlet", new_binding_rule(5)},
{"when", new_flow_rule(2)},
{"unless", new_flow_rule(2)},
{"with-profiler", new_flow_rule(2)},
{"with-pc", new_flow_rule(0)},
{"#unless", new_flow_rule(2)},
{"#when", new_flow_rule(2)},
{"#when-game", new_flow_rule(2)},
{"countdown", new_flow_rule(2)},
{"until", new_flow_rule(2)},
{"loop", new_flow_rule(0)},
+4 -4
View File
@@ -295,7 +295,7 @@ void break_list(Node* node) {
}
} else if (name == "until" || name == "while" || name == "dotimes" || name == "countdown" ||
name == "when" || name == "behavior" || name == "lambda" || name == "defpart" ||
name == "define" || name == "suspend-for") {
name == "define") {
node->top_line_count = 2;
} else if (name == "let" || name == "let*" || name == "rlet" ||
name == "with-dma-buffer-add-bucket") {
@@ -341,9 +341,9 @@ void break_list(Node* node) {
void insert_required_breaks(const std::vector<Node*>& bfs_order) {
const std::unordered_set<std::string> always_break = {
"when", "defun-debug", "countdown", "case", "defun", "defmethod", "let", "until",
"while", "if", "dotimes", "cond", "else", "defbehavior", "with-pp", "rlet",
"defstate", "behavior", "defpart", "loop", "let*", "suspend-for"};
"when", "defun-debug", "countdown", "case", "defun", "defmethod", "let",
"until", "while", "if", "dotimes", "cond", "else", "defbehavior",
"with-pp", "rlet", "defstate", "behavior", "defpart", "loop", "let*"};
for (auto node : bfs_order) {
if (!node->break_list && node->kind == Node::Kind::LIST &&
node->child_nodes.at(0).kind == Node::Kind::ATOM) {
-11
View File
@@ -369,17 +369,6 @@ struct Matrix {
return result;
}
Matrix<T, Rows, Cols> transposed() const {
static_assert(Rows == Cols);
Matrix<T, Rows, Cols> ret;
for (int i = 0; i < Rows; i++) {
for (int j = 0; j < Cols; j++) {
ret(i, j) = operator()(j, i);
}
}
return ret;
}
template <int OtherCols>
Matrix<T, Rows, OtherCols> operator*(const Matrix<T, Cols, OtherCols>& y) const {
Matrix<T, Rows, OtherCols> result;
-1
View File
@@ -49,7 +49,6 @@ struct Config {
{KeyBind::Modifier::CTRL, "N", "Full build of the game", "(mi)"}};
bool per_game_history = true;
bool permissive_redefinitions = false;
std::string iso_path;
int get_nrepl_port() {
if (temp_nrepl_port != -1) {
+8 -16
View File
@@ -43,15 +43,6 @@ void Wrapper::print_welcome_message(const std::vector<std::string>& loaded_proje
fmt::format(" Project Path: {}\n",
fmt::format(fg(fmt::color::gray), file_util::get_jak_project_dir().string()));
message += fmt::format(fmt::emphasis::bold | fg(fmt::color::orange), " - :===: -");
std::string effective_iso_path;
if (repl_config.iso_path.empty()) {
effective_iso_path = file_util::get_file_path({"iso_data"});
} else {
effective_iso_path = repl_config.iso_path;
}
message +=
fmt::format(" ISO Data Path: {}\n", fmt::format(fg(fmt::color::gray), effective_iso_path));
message += fmt::format(fmt::emphasis::bold | fg(fmt::color::orange), " --. .--: :--. .--");
message += " nREPL:";
if (!nrepl_alive) {
message += fmt::format(fg(fmt::color::red), "DISABLED\n");
@@ -59,21 +50,22 @@ void Wrapper::print_welcome_message(const std::vector<std::string>& loaded_proje
message += fmt::format(fg(fmt::color::light_green), " Listening on {}\n",
repl_config.get_nrepl_port());
}
message += fmt::format(fmt::emphasis::bold | fg(fmt::color::orange), " .=======. =======.");
message += fmt::format(fmt::emphasis::bold | fg(fmt::color::orange), " --. .--: :--. .--");
message += " Source File Search Dirs: ";
const auto search_dir_string =
fmt::format("{}", fmt::join(repl_config.asm_file_search_dirs, ","));
message += fmt::format("[{}]\n", fmt::format(fg(fmt::color::gray), search_dir_string));
message += fmt::format(fmt::emphasis::bold | fg(fmt::color::orange), " .-=====-. .-=====-");
message += fmt::format(" {} or {} for basic help and usage\n",
message += fmt::format(fmt::emphasis::bold | fg(fmt::color::orange), " .=======. =======.");
message += fmt::format(" {} or {} for basic help and usage\n",
fmt::format(fg(fmt::color::cyan), "(repl-help)"),
fmt::format(fg(fmt::color::cyan), "(repl-keybinds)"));
message += fmt::format(fmt::emphasis::bold | fg(fmt::color::orange), " .-===========-.");
message += fmt::format(fmt::emphasis::bold | fg(fmt::color::orange), " .-=====-. .-=====-");
message +=
fmt::format(" {} to connect to the game\n", fmt::format(fg(fmt::color::cyan), "(lt)"));
message += fmt::format(fmt::emphasis::bold | fg(fmt::color::orange), " .-===-.");
message += fmt::format(" {} to recompile the active project.\n",
fmt::format(" {} to connect to the game\n", fmt::format(fg(fmt::color::cyan), "(lt)"));
message += fmt::format(fmt::emphasis::bold | fg(fmt::color::orange), " .-===========-.");
message += fmt::format(" {} to recompile the active project.\n",
fmt::format(fg(fmt::color::cyan), "(mi)"));
message += fmt::format(fmt::emphasis::bold | fg(fmt::color::orange), " .-===-.\n");
message += fmt::format(fmt::emphasis::bold | fg(fmt::color::orange), " .\n");
fmt::print("{}", message);
}
+2 -6
View File
@@ -61,10 +61,7 @@ const std::unordered_map<GameVersion, std::vector<std::string>> locale_lookup =
{GameVersion::Jak1,
{"en-US", "fr-FR", "de-DE", "es-ES", "it-IT", "jp-JP", "en-GB", "pt-PT", "fi-FI", "sv-SE",
"da-DK", "no-NO", "nl-NL", "pt-BR", "hu-HU", "ca-ES", "is-IS"}},
{GameVersion::Jak2, {"en-US", "fr-FR", "de-DE", "es-ES", "it-IT", "jp-JP", "ko-KR", "en-GB"}},
{GameVersion::Jak3,
{"en-US", "fr-FR", "de-DE", "es-ES", "it-IT", "cm-CM", "jp-JP", "ko-KR", "ru-RU", "pt-PT",
"nl-NL", "en-GB"}}};
{GameVersion::Jak2, {"en-US", "fr-FR", "de-DE", "es-ES", "it-IT", "jp-JP", "ko-KR", "en-GB"}}};
std::string lookup_locale_code(const GameVersion game_version, const int language_id) {
if (locale_lookup.find(game_version) == locale_lookup.end() ||
@@ -76,8 +73,7 @@ std::string lookup_locale_code(const GameVersion game_version, const int languag
const std::unordered_map<GameVersion, std::vector<int>> language_ids_with_audio = {
{GameVersion::Jak1, {0, 1, 2, 3, 4, 5, 6}},
{GameVersion::Jak2, {0, 1, 2, 3, 4, 5, 6, 7}},
{GameVersion::Jak3, {0, 1, 2, 3, 4, 5, 11}}};
{GameVersion::Jak2, {0, 1, 2, 3, 4, 5, 6, 7}}};
bool dump_language_with_duplicates_from_base(const GameVersion game_version,
const int language_id) {
@@ -93,55 +93,6 @@ const std::unordered_map<std::string, u16> jak2_speaker_name_to_enum_val = {
{"metalkor-before-consite", 35},
{"metalkor-intro", 36}};
// matches enum in `subtitle3-h.gc` with "none" (first) and "max" (last and removed)
const std::unordered_map<std::string, u16> jak3_speaker_name_to_enum_val = {
{"none", 0},
{"jak", 1},
{"darkjak", 2},
{"daxter", 3},
{"pecker", 4},
{"ashelin", 5},
{"veger", 6},
{"samos", 7},
{"damas", 8},
{"kleiver", 9},
{"seem", 10},
{"errol", 11},
{"errol-hologram", 12},
{"sig", 13},
{"torn", 14},
{"tess", 15},
{"guard", 16},
{"guard-a", 17},
{"guard-b", 18},
{"keira", 19},
{"vin", 20},
{"onin", 21},
{"jinx", 22},
{"wastelander-male", 23},
{"wastelander-female", 24},
{"citizen-male", 25},
{"citizen-female", 26},
{"marauder", 27},
{"oracle", 28},
{"precursor", 29},
{"ottsel-leader", 30},
{"ottsel-surfer", 31},
{"ottsel-dummy", 32},
{"ottsel-veger", 33},
{"ottsel-tess", 34},
{"computer", 35},
{"krew", 36},
{"baron", 37},
{"scherr", 38},
{"arey", 39},
{"baldwin", 40},
{"schimpf", 41},
{"martinsen", 42},
{"phillips", 43},
{"yates", 44},
};
GameSubtitlePackage read_json_files_v2(const GameSubtitleDefinitionFile& file_info) {
GameSubtitlePackage package;
SubtitleFile lang_lines;
@@ -305,21 +256,11 @@ void GameSubtitleBank::add_scenes_from_files(const GameSubtitlePackage& package)
}
}
// TODO - for jak 3+, this needs some game version context info (could infer from text version)
std::vector<std::string> GameSubtitleBank::speaker_names_ordered_by_enum_value() {
// Create a temporary vector of pairs (key, value)
std::vector<std::pair<std::string, u16>> temp_vec;
switch (m_text_version) {
case GameTextVersion::JAK2:
temp_vec = {jak2_speaker_name_to_enum_val.begin(), jak2_speaker_name_to_enum_val.end()};
break;
case GameTextVersion::JAK3:
temp_vec = {jak3_speaker_name_to_enum_val.begin(), jak3_speaker_name_to_enum_val.end()};
break;
default:
throw std::runtime_error(fmt::format("GameSubtitleBank: invalid game text version {} ({})",
(int)m_text_version,
get_text_version_name(m_text_version)));
}
std::vector<std::pair<std::string, u16>> temp_vec(jak2_speaker_name_to_enum_val.begin(),
jak2_speaker_name_to_enum_val.end());
// Sort the temporary vector based on the enum value in ascending order
std::sort(temp_vec.begin(), temp_vec.end(),
[](const auto& a, const auto& b) { return a.second < b.second; });
@@ -338,25 +279,13 @@ std::vector<std::string> GameSubtitleBank::speaker_names_ordered_by_enum_value()
}
u16 GameSubtitleBank::speaker_enum_value_from_name(const std::string& speaker_id) {
std::unordered_map<std::string, u16> enum_map;
switch (m_text_version) {
case GameTextVersion::JAK2:
enum_map = jak2_speaker_name_to_enum_val;
break;
case GameTextVersion::JAK3:
enum_map = jak3_speaker_name_to_enum_val;
break;
default:
throw std::runtime_error(fmt::format("GameSubtitleBank: invalid game text version {}",
get_text_version_name(m_text_version)));
}
if (enum_map.find(speaker_id) == enum_map.end()) {
if (jak2_speaker_name_to_enum_val.find(speaker_id) == jak2_speaker_name_to_enum_val.end()) {
throw std::runtime_error(
fmt::format("'{}' speaker could not be found in the enum value mapping, update it or fix "
"the invalid speaker!",
speaker_id));
}
return u16(enum_map.at(speaker_id));
return u16(jak2_speaker_name_to_enum_val.at(speaker_id));
}
SubtitleMetadataFile dump_bank_meta_v2(const GameVersion game_version,
+4 -15
View File
@@ -8,8 +8,6 @@
#include "BinaryWriter.h"
#include "FileUtil.h"
#include "common/log/log.h"
void build_dgo(const DgoDescription& description, const std::string& output_prefix) {
BinaryWriter writer;
// dgo header
@@ -17,14 +15,8 @@ void build_dgo(const DgoDescription& description, const std::string& output_pref
writer.add_cstr_len(description.dgo_name.c_str(), 60);
for (auto& obj : description.entries) {
// Ensure the directory exists
const auto file_path =
file_util::get_jak_project_dir() / "out" / output_prefix / "obj" / obj.file_name;
if (!file_util::file_exists(file_path.string())) {
lg::warn("tried to build a DGO with a file that doesn't exist: {}", file_path.string());
continue;
}
auto obj_data = file_util::read_binary_file(file_path);
auto obj_data = file_util::read_binary_file(file_util::get_jak_project_dir() / "out" /
output_prefix / "obj" / obj.file_name);
// size
writer.add<uint32_t>(obj_data.size());
// name
@@ -37,9 +29,6 @@ void build_dgo(const DgoDescription& description, const std::string& output_pref
}
}
// Ensure the output directory exists
const auto dgo_path =
file_util::get_jak_project_dir() / "out" / output_prefix / "iso" / description.dgo_name;
file_util::create_dir_if_needed_for_file(dgo_path);
writer.write_to_file(dgo_path);
writer.write_to_file(file_util::get_jak_project_dir() / "out" / output_prefix / "iso" /
description.dgo_name);
}
-19
View File
@@ -1156,25 +1156,6 @@ static std::vector<ReplaceInfo> s_replace_info_jak2 = {
"<FLAG_KOREA>"},
{"~Y~1L<FLAG_PART_FILL>~]~-1H~Y~1L<FLAG_PART_FILL>~Z~-11H~3L<FLAG_PART_JAPAN_SUN>~Z~+26H",
"<FLAG_JAPAN>"},
{"~Y~1L<FLAG_PART_FILL>~Z~7L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~7L<FLAG_PART_VERT_STRIPE_RIGHT>~]"
"~-1H~Y~1L<FLAG_PART_FILL>~Z~7L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~+26H",
"<FLAG_FINLAND>"},
{"~Y~7L<FLAG_PART_FILL>~Z~5L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~5L<FLAG_PART_VERT_STRIPE_RIGHT>~]"
"~-1H~Y~7L<FLAG_PART_FILL>~Z~5L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~+26H",
"<FLAG_SWEDEN>"},
{"~Y~3L<FLAG_PART_FILL>~Z~1L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~1L<FLAG_PART_VERT_STRIPE_RIGHT>~]"
"~-1H~Y~3L<FLAG_PART_FILL>~Z~1L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~+26H",
"<FLAG_DENMARK>"},
{"~Y~1L<FLAG_PART_FILL>~Z~3L<FLAG_PART_TOP_BOTTOM_STRIPE>~]~-1H~Y~1L<FLAG_PART_FILL>~Z~3L<FLAG_"
"PART_TOP_BOTTOM_STRIPE>~Z~-19H~1L<FLAG_PART_VERT_STRIPE_MIDDLE>~Z~-23H~7L<FLAG_PART_VERT_"
"STRIPE_RIGHT>~Z~-23H~7L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~7L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~"
"+26H",
"<FLAG_NORWAY>"},
{"~Y~1L<FLAG_PART_FILL>~Z~7L<FLAG_PART_TOP_BOTTOM_STRIPE>~]~-1H~Y~1L<FLAG_PART_FILL>~Z~7L<FLAG_"
"PART_TOP_BOTTOM_STRIPE>~Z~-19H~1L<FLAG_PART_VERT_STRIPE_MIDDLE>~Z~-23H~3L<FLAG_PART_VERT_"
"STRIPE_RIGHT>~Z~-23H~3L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~3L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~"
"+26H",
"<FLAG_ICELAND>"},
// weird stuff
// - descenders
+21 -293
View File
@@ -1,7 +1,5 @@
#include "gltf_util.h"
#include "image_resize.h"
#include "common/log/log.h"
namespace gltf_util {
@@ -46,20 +44,6 @@ std::vector<math::Vector<u8, 4>> extract_color_from_vec4_float(const u8* data,
return result;
}
std::vector<math::Vector<u8, 4>> extract_color_from_vec3_float(const u8* data,
u32 count,
u32 stride) {
std::vector<math::Vector<u8, 4>> result;
result.reserve(count);
for (u32 i = 0; i < count; i++) {
math::Vector<float, 3> temp;
memcpy(&temp, data, sizeof(math::Vector<float, 3>));
data += stride;
result.emplace_back(temp.x() * 255, temp.y() * 255, temp.z() * 255, 255);
}
return result;
}
/*!
* Convert a GLTF color buffer (u16 format) to u8 colors.
*/
@@ -77,16 +61,6 @@ std::vector<math::Vector<u8, 4>> extract_color_from_vec4_u16(const u8* data,
return result;
}
std::vector<math::Vector<u8, 4>> extract_color_from_vec4_u8(const u8* data, u32 count, u32 stride) {
std::vector<math::Vector<u8, 4>> result;
result.reserve(count);
for (u32 i = 0; i < count; i++) {
result.push_back(math::Vector<u8, 4>(data[0], data[1], data[2], data[3]));
data += stride;
}
return result;
}
/*!
* Convert a GLTF index buffer
*/
@@ -118,74 +92,6 @@ std::vector<u32> gltf_index_buffer(const tinygltf::Model& model,
}
}
std::vector<math::Matrix4f> extract_mat4(const tinygltf::Model& model, int accessor_idx) {
const auto& accessor = model.accessors[accessor_idx];
const auto& buffer_view = model.bufferViews[accessor.bufferView];
const auto& buffer = model.buffers[buffer_view.buffer];
const u8* data_ptr = buffer.data.data() + buffer_view.byteOffset + accessor.byteOffset;
const auto stride = accessor.ByteStride(buffer_view);
const auto count = accessor.count;
// ASSERT(buffer_view.target == TINYGLTF_TARGET_ARRAY_BUFFER); // ??
ASSERT(accessor.componentType == TINYGLTF_COMPONENT_TYPE_FLOAT);
ASSERT(accessor.type == TINYGLTF_TYPE_MAT4);
std::vector<math::Matrix4f> result(accessor.count);
for (size_t x = 0; x < count; x++) {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
memcpy(&result[x](j, i), data_ptr + sizeof(float) * (i * 4 + j), sizeof(float));
}
}
data_ptr += stride;
}
return result;
}
JointsAndWeights convert_per_vertex_data(const math::Vector4f& weights,
const math::Vector<u8, 4>& joints) {
int discard_idx = -1;
float discard_weight = 100;
for (int i = 0; i < 4; i++) {
if (weights[i] < discard_weight) {
discard_idx = i;
discard_weight = weights[i];
}
}
JointsAndWeights ret;
int dst = 0;
float sum = 0;
for (int src = 0; src < 4; src++) {
if (src == discard_idx) {
continue;
}
// this +1 is to account for align not existing in the gltf.
ret.joints[dst] = joints[src] + 2;
ret.weights[dst] = weights[src];
sum += ret.weights[dst];
dst++;
}
ret.weights /= sum;
return ret;
}
std::vector<JointsAndWeights> extract_and_flatten_joints_and_weights(
const tinygltf::Model& model,
const tinygltf::Primitive& prim) {
auto weights =
extract_vec<float, 4>(model, prim.attributes.at("WEIGHTS_0"), TINYGLTF_COMPONENT_TYPE_FLOAT);
auto joints = extract_vec<u8, 4>(model, prim.attributes.at("JOINTS_0"),
TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE);
std::vector<JointsAndWeights> ret;
ASSERT(weights.size() == joints.size());
for (size_t i = 0; i < weights.size(); i++) {
ret.push_back(convert_per_vertex_data(weights[i], joints[i]));
}
return ret;
}
/*!
* Extract positions, colors, and normals from a mesh.
*/
@@ -242,37 +148,19 @@ ExtractedVertices gltf_vertices(const tinygltf::Model& model,
buffer.data.data() + buffer_view.byteOffset + attrib_accessor.byteOffset;
const auto byte_stride = attrib_accessor.ByteStride(buffer_view);
const auto count = attrib_accessor.count;
std::vector<math::Vector<u8, 4>> colors;
switch (attrib_accessor.type) {
case TINYGLTF_TYPE_VEC4:
switch (attrib_accessor.componentType) {
case TINYGLTF_COMPONENT_TYPE_FLOAT:
colors = extract_color_from_vec4_float(data_ptr, count, byte_stride);
break;
case TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT:
colors = extract_color_from_vec4_u16(data_ptr, count, byte_stride);
break;
case TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE:
colors = extract_color_from_vec4_u8(data_ptr, count, byte_stride);
break;
default:
lg::die("Unknown type for COLOR_0: {}", attrib_accessor.componentType);
}
ASSERT_MSG(attrib_accessor.type == TINYGLTF_TYPE_VEC4, "COLOR_0 wasn't vec4");
std::vector<math::Vector<u8, 4>> colors;
switch (attrib_accessor.componentType) {
case TINYGLTF_COMPONENT_TYPE_FLOAT:
colors = extract_color_from_vec4_float(data_ptr, count, byte_stride);
break;
case TINYGLTF_TYPE_VEC3:
switch (attrib_accessor.componentType) {
case TINYGLTF_COMPONENT_TYPE_FLOAT:
colors = extract_color_from_vec3_float(data_ptr, count, byte_stride);
break;
default:
lg::die("unkonwn component type for vec3 color {}", attrib_accessor.componentType);
}
case TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT:
colors = extract_color_from_vec4_u16(data_ptr, count, byte_stride);
break;
default:
lg::die("unknown attribute type for color {}", attrib_accessor.type);
lg::die("Unknown component type for COLOR_0: {}", attrib_accessor.componentType);
}
vtx_colors.insert(vtx_colors.end(), colors.begin(), colors.end());
}
}
@@ -325,8 +213,7 @@ ExtractedVertices gltf_vertices(const tinygltf::Model& model,
normals = extract_vec3f(data_ptr, count, byte_stride);
for (auto& nrm : normals) {
math::Vector4f nrm4(nrm.x(), nrm.y(), nrm.z(), 0.f);
// we found that normals aren't normalized if an object is scaled in blender.
nrm = (w_T_local * nrm4).xyz().normalized();
nrm = (w_T_local * nrm4).xyz();
}
ASSERT(normals.size() == result.size());
} else {
@@ -390,7 +277,7 @@ int texture_pool_debug_checker(TexturePool* pool) {
}
}
int texture_pool_add_texture(TexturePool* pool, const tinygltf::Image& tex, int alpha_shift) {
int texture_pool_add_texture(TexturePool* pool, const tinygltf::Image& tex) {
const auto& existing = pool->textures_by_name.find(tex.name);
if (existing != pool->textures_by_name.end()) {
lg::info("Reusing image: {}", tex.name);
@@ -415,72 +302,6 @@ int texture_pool_add_texture(TexturePool* pool, const tinygltf::Image& tex, int
tt.data.resize(tt.w * tt.h);
ASSERT(tex.image.size() >= tt.data.size());
memcpy(tt.data.data(), tex.image.data(), tt.data.size() * 4);
// adjust alpha colors for PS2/PC difference
for (auto& color : tt.data) {
u32 alpha = color >> 24;
alpha >>= alpha_shift;
color &= 0xff'ff'ff;
color |= (alpha << 24);
}
return idx;
}
int texture_pool_add_envmap_control_texture(TexturePool* pool,
const tinygltf::Model& model,
int rgb_image_id,
int mr_image_id,
bool wrap_w,
bool wrap_h) {
const auto& existing = pool->envmap_textures_by_gltf_id.find({rgb_image_id, mr_image_id});
if (existing != pool->envmap_textures_by_gltf_id.end()) {
lg::info("Reusing envmap textures");
return existing->second;
}
const auto& rgb_tex = model.images.at(rgb_image_id);
const auto& mr_tex = model.images.at(mr_image_id);
lg::info("new envmap texture {} {}", rgb_tex.name, mr_tex.name);
ASSERT(rgb_tex.bits == 8);
ASSERT(rgb_tex.component == 4);
ASSERT(rgb_tex.pixel_type == TINYGLTF_TEXTURE_TYPE_UNSIGNED_BYTE);
ASSERT(mr_tex.bits == 8);
ASSERT(mr_tex.pixel_type == TINYGLTF_TEXTURE_TYPE_UNSIGNED_BYTE);
ASSERT(mr_tex.component == 4);
std::vector<u8> resized_mr_tex;
const u8* mr_src;
if (rgb_tex.width == mr_tex.width && rgb_tex.height == mr_tex.height) {
mr_src = mr_tex.image.data();
} else {
resized_mr_tex.resize(rgb_tex.width * rgb_tex.height * 4);
resize_rgba_image(resized_mr_tex.data(), rgb_tex.width, rgb_tex.height, mr_tex.image.data(),
mr_tex.width, mr_tex.height, wrap_w, wrap_h);
mr_src = resized_mr_tex.data();
}
size_t idx = pool->textures_by_idx.size();
pool->envmap_textures_by_gltf_id[{rgb_image_id, mr_image_id}] = idx;
auto& tt = pool->textures_by_idx.emplace_back();
tt.w = rgb_tex.width;
tt.h = rgb_tex.height;
tt.debug_name = rgb_tex.name;
tt.debug_tpage_name = "custom-level";
tt.load_to_pool = false;
tt.combo_id = 0; // doesn't matter, not a pool tex
tt.data.resize(tt.w * tt.h);
ASSERT(rgb_tex.image.size() >= tt.data.size());
memcpy(tt.data.data(), rgb_tex.image.data(), tt.data.size() * 4);
// adjust alpha from metallic channel
for (size_t i = 0; i < tt.data.size(); i++) {
u32 rgb = tt.data[i];
u32 metal = mr_src[4 * i + 2] / 4;
rgb &= 0xff'ff'ff;
rgb |= (metal << 24);
tt.data[i] = rgb;
}
return idx;
}
@@ -527,15 +348,6 @@ math::Vector4f vector4f_from_gltf(const std::vector<double>& in) {
return math::Vector4f{in[0], in[1], in[2], in[3]};
}
math::Matrix4f matrix_from_trs(const math::Vector3f& trans,
const math::Vector4f& quat,
const math::Vector3f& scale) {
math::Matrix4f t = affine_translation(trans);
math::Matrix4f r = affine_rot_qxyzw(quat);
math::Matrix4f s = affine_scale(scale);
return t * r * s;
}
math::Matrix4f matrix_from_node(const tinygltf::Node& node) {
if (!node.matrix.empty()) {
math::Matrix4f result;
@@ -618,38 +430,22 @@ void dedup_vertices(const std::vector<tfrag3::PreloadedVertex>& vertices_in,
}
}
void setup_alpha_from_material(const tinygltf::Material& material, DrawMode* mode) {
if (material.alphaMode == "OPAQUE") {
mode->disable_ab();
} else if (material.alphaMode == "MASK") {
mode->enable_at();
mode->set_alpha_test(DrawMode::AlphaTest::GEQUAL);
mode->set_alpha_fail(GsTest::AlphaFail::KEEP);
mode->set_aref(material.alphaCutoff * 127);
} else if (material.alphaMode == "BLEND") {
mode->enable_ab();
mode->set_alpha_blend(DrawMode::AlphaBlend::SRC_DST_SRC_DST);
mode->set_depth_write_enable(false);
} else {
lg::die("Unknown GLTF alphaMode {}", material.alphaMode);
}
}
void setup_draw_mode_from_sampler(const tinygltf::Sampler& sampler, DrawMode* mode) {
DrawMode draw_mode_from_sampler(const tinygltf::Sampler& sampler) {
DrawMode mode = make_default_draw_mode();
if (sampler.magFilter == TINYGLTF_TEXTURE_FILTER_NEAREST) {
ASSERT(sampler.minFilter == TINYGLTF_TEXTURE_FILTER_NEAREST_MIPMAP_NEAREST);
mode->set_filt_enable(false);
ASSERT(sampler.minFilter == TINYGLTF_TEXTURE_FILTER_NEAREST);
mode.set_filt_enable(false);
} else {
ASSERT(sampler.minFilter != TINYGLTF_TEXTURE_FILTER_NEAREST);
mode->set_filt_enable(true);
mode.set_filt_enable(true);
}
switch (sampler.wrapS) {
case TINYGLTF_TEXTURE_WRAP_CLAMP_TO_EDGE:
mode->set_clamp_s_enable(true);
mode.set_clamp_s_enable(true);
break;
case TINYGLTF_TEXTURE_WRAP_REPEAT:
mode->set_clamp_s_enable(false);
mode.set_clamp_s_enable(false);
break;
default:
ASSERT(false);
@@ -657,83 +453,15 @@ void setup_draw_mode_from_sampler(const tinygltf::Sampler& sampler, DrawMode* mo
switch (sampler.wrapT) {
case TINYGLTF_TEXTURE_WRAP_CLAMP_TO_EDGE:
mode->set_clamp_t_enable(true);
mode.set_clamp_t_enable(true);
break;
case TINYGLTF_TEXTURE_WRAP_REPEAT:
mode->set_clamp_t_enable(false);
mode.set_clamp_t_enable(false);
break;
default:
ASSERT(false);
}
return mode;
}
EnvmapSettings envmap_settings_from_gltf(const tinygltf::Material& mat) {
EnvmapSettings settings;
ASSERT(mat.extensions.contains("KHR_materials_specular"));
const auto& specular_extension = mat.extensions.at("KHR_materials_specular");
ASSERT(specular_extension.Has("specularColorTexture"));
auto& texture = specular_extension.Get("specularColorTexture");
ASSERT(texture.Has("index"));
settings.texture_idx = texture.Get("index").Get<int>();
return settings;
}
std::optional<int> find_single_skin(const tinygltf::Model& model,
const std::vector<NodeWithTransform>& all_nodes) {
std::optional<int> skin_index;
for (const auto& n : all_nodes) {
const auto& node = model.nodes.at(n.node_idx);
if (node.skin >= 0) {
if (skin_index && *skin_index != node.skin) {
lg::die("GLTF contains multiple skins, but only one skin per actor is supported.");
}
skin_index = node.skin;
}
}
return skin_index;
}
std::vector<float> extract_floats(const tinygltf::Model& model, int accessor_idx) {
const auto& accessor = model.accessors[accessor_idx];
const auto& buffer_view = model.bufferViews[accessor.bufferView];
const auto& buffer = model.buffers[buffer_view.buffer];
const u8* data_ptr = buffer.data.data() + buffer_view.byteOffset + accessor.byteOffset;
const auto stride = accessor.ByteStride(buffer_view);
const auto count = accessor.count;
// ASSERT(buffer_view.target == TINYGLTF_TARGET_ARRAY_BUFFER); // ??
if (accessor.componentType != TINYGLTF_COMPONENT_TYPE_FLOAT) {
lg::die("mismatched format, wanted {} but got {}", TINYGLTF_COMPONENT_TYPE_FLOAT,
accessor.componentType);
}
ASSERT(accessor.type == TINYGLTF_TYPE_SCALAR);
std::vector<float> result(accessor.count);
for (size_t x = 0; x < count; x++) {
memcpy(&result[x], data_ptr, sizeof(float));
data_ptr += stride;
}
return result;
}
std::size_t TieFullVertex::hash::operator()(const TieFullVertex& x) const {
return tfrag3::PackedTieVertices::Vertex::hash()(x.vertex) ^ std::hash<u16>()(x.color_index);
}
tfrag3::PackedTimeOfDay pack_time_of_day(const std::vector<math::Vector<u8, 4>>& color_palette) {
tfrag3::PackedTimeOfDay colors;
colors.color_count = (color_palette.size() + 3) & (~3);
colors.data.resize(colors.color_count * 8 * 4);
for (u32 color_index = 0; color_index < color_palette.size(); color_index++) {
for (u32 palette = 0; palette < 8; palette++) {
for (u32 channel = 0; channel < 4; channel++) {
colors.read(color_index, palette, channel) = color_palette[color_index][channel];
}
}
}
return colors;
}
} // namespace gltf_util
+5 -114
View File
@@ -1,13 +1,11 @@
#pragma once
#include <optional>
#include <string>
#include <unordered_map>
#include <vector>
#include "common/common_types.h"
#include "common/custom_data/Tfrag3Data.h"
#include "common/log/log.h"
#include "common/math/Vector.h"
#include "third-party/tiny_gltf/tiny_gltf.h"
@@ -30,19 +28,10 @@ std::vector<u32> index_list_to_u32(const u8* data, u32 num_verts, u32 offset, u3
return result;
}
struct JointsAndWeights {
math::Vector<u8, 3> joints = math::Vector<u8, 3>::zero();
math::Vector<float, 3> weights = math::Vector<float, 3>::zero();
};
std::vector<math::Vector3f> extract_vec3f(const u8* data, u32 count, u32 stride);
std::vector<math::Vector2f> extract_vec2f(const u8* data, u32 count, u32 stride);
std::vector<math::Vector<u8, 4>> extract_color_from_vec4_u16(const u8* data, u32 count, u32 stride);
std::vector<u32> gltf_index_buffer(const tinygltf::Model& model, int indices_idx, u32 index_offset);
std::vector<math::Matrix4f> extract_mat4(const tinygltf::Model& model, int accessor_idx);
std::vector<JointsAndWeights> extract_and_flatten_joints_and_weights(
const tinygltf::Model& model,
const tinygltf::Primitive& prim);
struct ExtractedVertices {
std::vector<tfrag3::PreloadedVertex> vtx;
@@ -61,16 +50,9 @@ DrawMode make_default_draw_mode();
struct TexturePool {
std::unordered_map<std::string, int> textures_by_name;
std::vector<tfrag3::Texture> textures_by_idx;
std::map<std::pair<int, int>, int> envmap_textures_by_gltf_id;
};
int texture_pool_add_texture(TexturePool* pool, const tinygltf::Image& tex, int alpha_shift = 1);
int texture_pool_add_envmap_control_texture(TexturePool* pool,
const tinygltf::Model& model,
int rgb_image_id,
int mr_image_id,
bool wrap_w,
bool wrap_h);
int texture_pool_add_texture(TexturePool* pool, const tinygltf::Image& tex);
int texture_pool_debug_checker(TexturePool* pool);
struct NodeWithTransform {
@@ -78,103 +60,12 @@ struct NodeWithTransform {
math::Matrix4f w_T_node;
};
struct TieFullVertex {
tfrag3::PackedTieVertices::Vertex vertex;
u16 color_index = 0;
struct hash {
std::size_t operator()(const TieFullVertex& x) const;
};
bool operator==(const TieFullVertex& other) const {
return vertex == other.vertex && color_index == other.color_index;
}
};
template <typename T>
void dedup_vertices(const std::vector<T>& vertices_in,
std::vector<T>& vertices_out,
std::vector<u32>& old_to_new_out) {
ASSERT(vertices_out.empty());
ASSERT(old_to_new_out.empty());
old_to_new_out.resize(vertices_in.size(), -1);
std::unordered_map<T, u32, typename T::hash> vtx_to_new;
for (size_t in_idx = 0; in_idx < vertices_in.size(); in_idx++) {
auto& vtx = vertices_in[in_idx];
const auto& lookup = vtx_to_new.find(vtx);
if (lookup == vtx_to_new.end()) {
// first time seeing this one
size_t new_idx = vertices_out.size();
vertices_out.push_back(vtx);
old_to_new_out[in_idx] = new_idx;
vtx_to_new[vtx] = new_idx;
} else {
old_to_new_out[in_idx] = lookup->second;
}
}
}
void dedup_vertices(const std::vector<tfrag3::PreloadedVertex>& vertices_in,
std::vector<tfrag3::PreloadedVertex>& vertices_out,
std::vector<u32>& old_to_new_out);
std::vector<NodeWithTransform> flatten_nodes_from_all_scenes(const tinygltf::Model& model);
void setup_alpha_from_material(const tinygltf::Material& material, DrawMode* mode);
void setup_draw_mode_from_sampler(const tinygltf::Sampler& sampler, DrawMode* mode);
struct EnvmapSettings {
int texture_idx = -1;
};
EnvmapSettings envmap_settings_from_gltf(const tinygltf::Material& mat);
/*!
* Find the index of the skin for this model. Returns nullopt if there is no skin, the index of the
* skin if there is a single skin used, or fatal error if there are multiple skins.
*/
std::optional<int> find_single_skin(const tinygltf::Model& model,
const std::vector<NodeWithTransform>& all_nodes);
template <typename T, int n>
std::vector<math::Vector<T, n>> extract_vec(const tinygltf::Model& model,
int accessor_idx,
int format) {
const auto& accessor = model.accessors[accessor_idx];
const auto& buffer_view = model.bufferViews[accessor.bufferView];
const auto& buffer = model.buffers[buffer_view.buffer];
const u8* data_ptr = buffer.data.data() + buffer_view.byteOffset + accessor.byteOffset;
const auto stride = accessor.ByteStride(buffer_view);
const auto count = accessor.count;
// ASSERT(buffer_view.target == TINYGLTF_TARGET_ARRAY_BUFFER); // ??
if (accessor.componentType != format) {
lg::die("mismatched format, wanted {} but got {}", format, accessor.componentType);
}
ASSERT(accessor.componentType == format);
switch (n) {
case 3:
ASSERT(accessor.type == TINYGLTF_TYPE_VEC3);
break;
case 4:
ASSERT(accessor.type == TINYGLTF_TYPE_VEC4);
break;
default:
ASSERT_NOT_REACHED();
}
std::vector<math::Vector<T, n>> result(accessor.count);
for (size_t x = 0; x < count; x++) {
for (int i = 0; i < n; i++) {
memcpy(&result[x][i], data_ptr + sizeof(T) * i, sizeof(T));
}
data_ptr += stride;
}
return result;
}
std::vector<float> extract_floats(const tinygltf::Model& model, int accessor_idx);
math::Matrix4f matrix_from_trs(const math::Vector3f& trans,
const math::Vector4f& quat,
const math::Vector3f& scale);
tfrag3::PackedTimeOfDay pack_time_of_day(const std::vector<math::Vector<u8, 4>>& color_palette);
DrawMode draw_mode_from_sampler(const tinygltf::Sampler& sampler);
} // namespace gltf_util
-101
View File
@@ -1,101 +0,0 @@
#include "image_resize.h"
#include <cmath>
#include "common/math/Vector.h"
namespace {
struct BilinearSample {
int i0, i1;
double w0, w1;
};
BilinearSample bilinear(int src_i, double sample, bool wrap) {
BilinearSample result;
const double px_size = 1. / double(src_i);
const double px_center_f = (sample - 0.5 * px_size) / px_size;
const int px_floor = std::floor(px_center_f);
const double frac = px_center_f - double(px_floor);
if (px_center_f < 0) { // off the bottom
if (wrap) {
// wrap around!
result.i0 = 0;
result.i1 = src_i - 1;
result.w1 = -px_center_f;
result.w0 = 1. - result.w1;
} else {
// clamp to edge
result.i0 = 0;
result.i1 = 0;
result.w0 = 1;
result.w1 = 0;
}
} else if (px_floor >= (src_i - 1)) { // off the top
if (wrap) {
result.i0 = src_i - 1;
result.i1 = 0;
result.w0 = 1. - frac;
result.w1 = frac;
} else {
// clamp
result.i0 = src_i - 1;
result.i1 = src_i - 1;
result.w0 = 1;
result.w1 = 0;
}
} else {
result.i0 = px_floor;
result.i1 = px_floor + 1;
result.w0 = 1. - frac;
result.w1 = frac;
}
return result;
}
math::Vector4<u8> sample1(const u8* src, int w, int h, int x, int y) {
(void)h;
int offset = 4 * (y * w + x);
return math::Vector4<u8>(src[offset], src[offset + 1], src[offset + 2], src[offset + 3]);
}
math::Vector4<u8> sample_bilinear(const u8* src,
int w,
int h,
const BilinearSample& x,
const BilinearSample& y) {
auto p00 = sample1(src, w, h, x.i0, y.i0).cast<double>();
auto p01 = sample1(src, w, h, x.i0, y.i1).cast<double>();
auto p10 = sample1(src, w, h, x.i1, y.i0).cast<double>();
auto p11 = sample1(src, w, h, x.i1, y.i1).cast<double>();
auto p_interp = (p00 * x.w0 * y.w0 + p01 * x.w0 * y.w1 + p10 * x.w1 * y.w0 + p11 * x.w1 * y.w1);
return p_interp.cast<u8>();
}
} // namespace
void resize_rgba_image(u8* dst,
int dst_w,
int dst_h,
const u8* src,
int src_w,
int src_h,
bool wrap_w,
bool wrap_h) {
const double dst_px_h = 1. / dst_h;
const double dst_px_w = 1. / dst_w;
for (int h = 0; h < dst_h; h++) {
const float h_pos = (double(h) + 0.5) * dst_px_h;
const auto h_sample = bilinear(src_h, h_pos, wrap_h);
for (int w = 0; w < dst_w; w++) {
const float w_pos = (double(w) + 0.5) * dst_px_w;
const auto w_sample = bilinear(src_w, w_pos, wrap_w);
auto result = sample_bilinear(src, src_w, src_h, w_sample, h_sample);
for (int i = 0; i < 4; i++) {
*dst = result[i];
dst++;
}
}
}
}
-12
View File
@@ -1,12 +0,0 @@
#pragma once
#include "common/common_types.h"
void resize_rgba_image(u8* dst,
int dst_w,
int dst_h,
const u8* src,
int src_w,
int src_h,
bool wrap_w,
bool wrap_h);
-27
View File
@@ -3,13 +3,6 @@
#include "common/common_types.h"
#include "common/log/log.h"
#ifdef __APPLE__
#include <stdio.h>
#include <sys/sysctl.h>
#include <sys/types.h>
#endif
#ifdef _WIN32
// clang-format off
#define NOMINMAX
@@ -111,23 +104,3 @@ void setup_cpu_info() {
CpuInfo& get_cpu_info() {
return gCpuInfo;
}
std::optional<double> get_macos_version() {
#ifndef __APPLE__
return {};
#else
char buffer[128];
size_t bufferlen = 128;
auto ok = sysctlbyname("kern.osproductversion", &buffer, &bufferlen, NULL, 0);
if (ok != 0) {
lg::warn("Unable to check for `kern.osproductversion` to determine macOS version");
return {};
}
try {
return std::stod(buffer);
} catch (std::exception& e) {
lg::error("Error occured when attempting to convert sysctl value {} to number", buffer);
return {};
}
#endif
}
-3
View File
@@ -1,7 +1,6 @@
#pragma once
#include <cstddef>
#include <optional>
#include <string>
size_t get_peak_rss();
@@ -17,5 +16,3 @@ struct CpuInfo {
};
CpuInfo& get_cpu_info();
std::optional<double> get_macos_version();
@@ -90,7 +90,6 @@ def draw_func_ob(self, context):
layout = self.layout
ob = context.object
layout.prop(ob, "set_invisible")
layout.prop(ob, "enable_custom_weights")
layout.prop(ob, "set_collision")
if (ob.set_collision):
layout.prop(ob, "ignore")
@@ -117,7 +116,6 @@ def register():
bpy.types.Object.set_invisible = bpy.props.BoolProperty(name="Invisible")
bpy.types.Object.set_collision = bpy.props.BoolProperty(name="Apply Collision Properties")
bpy.types.Object.enable_custom_weights = bpy.props.BoolProperty(name="Use Custom Bone Weights")
bpy.types.Object.ignore = bpy.props.BoolProperty(name="ignore")
bpy.types.Object.noedge = bpy.props.BoolProperty(name="No-Edge")
bpy.types.Object.noentity = bpy.props.BoolProperty(name="No-Entity")
@@ -67,60 +67,21 @@
"custom_models": ["test-actor"],
// Any textures you want to include in your custom level. This is mainly useful for things such as the zoomer HUD,
// sky textures and cases where you want to use objects drawn with the generic renderer,
// which also requires you to set a texture remap table and a list of tpages.
// which is not in the common level files and has no art group associated with it.
// To get a list of all the textures, you can extract all of the game's textures
// by setting "save_texture_pngs" to true in the decompiler config.
// The format is ["tpage-name", "texture-name1", "texture-name2", ...].
// If you want all textures from a tpage, you can just do ["tpage-name"].
"textures": [
// Zoomer HUD textures
// ["zoomerhud"],
// Sandover sky textures
["village1-vis-alpha"]
// all textures required for the zoomer HUD
// "zoomerhud",
// "zoomerhud-dial",
// "zoomerhud-main-02",
// "zoomerhud-main-03",
// "zoomerhud-pieslice",
// "zoomerhud-heatbg-01",
// "zoomerhud-main-03arrow",
// "zoomerhud-main-03knob"
],
// Which vanilla level's texture remap table to use.
// This is needed if you want to have proper textures for objects that are drawn using generic, such as
// dark eco pools or dying enemies. If you choose to use this,
// the order of art groups and tpages in your level's .gd MUST match the vanilla level's for the textures to work.
"tex_remap": "village1",
// Which sky to use for your custom level. This needs to be the name of a vanilla level with sky textures.
// Your level's mood update needs to be set up to copy the sky texture (update-mood-default already handles this as an example).
// You also need to add a specific tpage to your level .gd depending on the level you chose:
// training: tpage-1308.go
// village1: tpage-401.go
// beach: tpage-215.go
// jungle: tpage-388.go
// misty: tpage-520.go
// firecanyon: tpage-1123.go
// village2: tpage-921.go
// rolling: tpage-925.go
// sunkenb: tpage-162.go
// swamp: tpage-630.go
// ogre: tpage-1117.go
// village3: tpage-1194.go
// snow: tpage-712.go
// finalboss: tpage-1418.go
// The tpage you choose also has to be in the alpha (4th) slot in the "tpages" list below.
"sky": "village1",
// Any texture pages that are added to the level's "texture-ids" array.
// These will be logged in and linked as part of level loading.
// There are five tpage categories, in this order:
// - tfrag
// - pris
// - shrub
// - alpha
// - water
// This is also (with the exception of levels that use the zoomer) the order that the tpages are listed in in the vanilla .gd files.
// You need to also add these to your level .gd as well.
// Sky textures use the alpha slot.
// If this is empty and "tex_remap" and "sky" are the same level, this will be auto-filled with the tpages from the
// corresponding level (check its .gd file for the art group/tpage order to copy over).
"tpages": [],
// Ambients you want to use in your custom level. Ambients can be used for various things like changing the music variation (flava),
// adding ambient sounds, level name hints, etc.
"ambients": [
@@ -136,10 +97,10 @@
}
],
"actors": [
"actors" : [
{
"trans": [-21.6238, 20.0496, 17.1191], // translation
"etype": "fuel-cell", // actor type
"etype": "fuel-cell", // actor type
"game_task": "(game-task none)", // associated game task (for powercells, etc)
"quat": [0, 0, 0, 1], // quaternion
"bsphere": [-21.6238, 19.3496, 17.1191, 10], // bounding sphere
@@ -150,11 +111,11 @@
},
{
"trans": [-15.2818, 15.2461, 17.136], // translation
"etype": "crate", // actor type
"trans": [-15.2818, 15.2461, 17.1360], // translation
"etype": "crate", // actor type
"game_task": "(game-task none)", // associated game task (for powercells, etc)
"quat": [0, 0, 0, 1], // quaternion
"bsphere": [-15.2818, 15.2461, 17.136, 10], // bounding sphere
"bsphere": [-15.2818, 15.2461, 17.1360, 10], // bounding sphere
"lump": {
"name": "test-crate",
"crate-type": "'steel",
@@ -163,18 +124,18 @@
},
{
"trans": [-5.463, 17.4553, 1.6169], // translation
"etype": "eco-yellow", // actor type
"trans": [-5.4630, 17.4553, 1.6169], // translation
"etype": "eco-yellow", // actor type
"game_task": "(game-task none)", // associated game task (for powercells, etc)
"quat": [0, 0, 0, 1], // quaternion
"bsphere": [-5.463, 17.4553, 1.6169, 10], // bounding sphere
"bsphere": [-5.4630, 17.4553, 1.6169, 10], // bounding sphere
"lump": {
"name": "test-eco"
}
},
{
"trans": [-5.41, 3.5, 28.42], // translation
"etype": "test-actor", // actor type
"etype": "test-actor", // actor type
"game_task": 0, // associated game task (for powercells, etc)
"quat": [0, 0, 0, 1], // quaternion
"bsphere": [-7.41, 3.5, 28.42, 10], // bounding sphere
@@ -193,4 +154,4 @@
// }
// }
]
}
}
@@ -3,14 +3,9 @@
;; the actual file name still needs to be 8.3
("TSZ.DGO"
("test-zone-obs.o"
"tpage-398.go"
"tpage-400.go"
"tpage-399.go"
"tpage-401.go"
"tpage-1470.go"
("static-screen.o"
"test-zone-obs.o"
"plat-ag.go"
"test-actor-ag.go"
"test-zone.go"
)
)
))
@@ -49,29 +49,27 @@
// adds a 'type' tag (using the "symbol" and "string" lump types works the same way):
// "spawn-types": ["type", "spyder", "juicer"]
// The base actor id for your custom level. If you have multiple levels, this should be unique!
"base_id": 100,
// The base actor id for your custom level. If you have multiple levels, this should be unique!
"base_id": 100,
// All art groups you want to use in your custom level. Will add their models and corresponding textures to the FR3 file.
// Removed so that the release builds don't have to double-decompile the game
// "art_groups": ["prsn-torture-ag"],
// Any textures you want to include in your custom level.
// This is mainly useful for textures which are not in the common level files and have no art group associated with them.
// To get a list of all the textures, you can extract all of the game's textures
// by setting "save_texture_pngs" to true in the decompiler config.
// The format is ["tpage-name", "texture-name1", "texture-name2", ...].
// If you want all textures from a tpage, you can just do ["tpage-name"].
"textures": [],
// Any textures you want to include in your custom level.
// This is mainly useful for textures which are not in the common level files and have no art group associated with them.
// To get a list of all the textures, you can extract all of the game's textures
// by setting "save_texture_pngs" to true in the decompiler config.
"textures": [],
"actors": [
"actors" : [
{
"trans": [-15.2818, 15.2461, 17.136], // translation
"etype": "crate", // actor type
"trans": [-15.2818, 15.2461, 17.1360], // translation
"etype": "crate", // actor type
"game_task": 0, // associated game task (for powercells, etc)
"kill_mask": 0,
"quat": [0, 0, 0, 1], // quaternion
"bsphere": [-15.2818, 15.2461, 17.136, 10], // bounding sphere
"bsphere": [-15.2818, 15.2461, 17.1360, 10], // bounding sphere
"lump": {
"name": "test-crate",
"eco-info": ["eco-info", "(pickup-type health)", 2]
@@ -79,12 +77,12 @@
},
{
"trans": [-5.463, 17.4553, 1.6169], // translation
"etype": "eco-yellow", // actor type
"trans": [-5.4630, 17.4553, 1.6169], // translation
"etype": "eco-yellow", // actor type
"game_task": "(game-task none)", // associated game task (for powercells, etc)
"kill_mask": 0,
"quat": [0, 0, 0, 1], // quaternion
"bsphere": [-5.463, 17.4553, 1.6169, 10], // bounding sphere
"bsphere": [-5.4630, 17.4553, 1.6169, 10], // bounding sphere
"lump": {
"name": "test-eco"
}
@@ -92,7 +90,7 @@
{
"trans": [-7.41, 13.5, 28.42], // translation
"etype": "prsn-torture", // actor type
"etype": "prsn-torture", // actor type
"game_task": "(game-task none)", // associated game task (for powercells, etc)
"quat": [0, 0, 0, 1], // quaternion
"bsphere": [-7.41, 13.5, 28.42, 10], // bounding sphere
@@ -101,4 +99,4 @@
}
}
]
}
}
@@ -49,28 +49,26 @@
// adds a 'type' tag (using the "symbol" and "string" lump types works the same way):
// "spawn-types": ["type", "spyder", "juicer"]
// The base actor id for your custom level. If you have multiple levels, this should be unique!
"base_id": 100,
// The base actor id for your custom level. If you have multiple levels, this should be unique!
"base_id": 100,
// All art groups you want to use in your custom level. Will add their models and corresponding textures to the FR3 file.
// "art_groups": [],
// Any textures you want to include in your custom level.
// This is mainly useful for textures which are not in the common level files and have no art group associated with them.
// To get a list of all the textures, you can extract all of the game's textures
// by setting "save_texture_pngs" to true in the decompiler config.
// The format is ["tpage-name", "texture-name1", "texture-name2", ...].
// If you want all textures from a tpage, you can just do ["tpage-name"].
"textures": [],
// Any textures you want to include in your custom level.
// This is mainly useful for textures which are not in the common level files and have no art group associated with them.
// To get a list of all the textures, you can extract all of the game's textures
// by setting "save_texture_pngs" to true in the decompiler config.
// "textures": [],
"actors": [
"actors" : [
{
"trans": [-15.2818, 15.2461, 17.136], // translation
"etype": "crate", // actor type
"trans": [-15.2818, 15.2461, 17.1360], // translation
"etype": "crate", // actor type
"game_task": "(game-task none)", // associated game task (for powercells, etc)
"kill_mask": 0,
"quat": [0, 0, 0, 1], // quaternion
"bsphere": [-15.2818, 15.2461, 17.136, 10], // bounding sphere
"bsphere": [-15.2818, 15.2461, 17.1360, 10], // bounding sphere
"lump": {
"name": "test-crate",
"eco-info": ["eco-info", "(pickup-type gem)", 1]
@@ -78,15 +76,15 @@
},
{
"trans": [-5.463, 17.4553, 1.6169], // translation
"etype": "eco-yellow", // actor type
"trans": [-5.4630, 17.4553, 1.6169], // translation
"etype": "eco-yellow", // actor type
"game_task": "(game-task none)", // associated game task (for powercells, etc)
"kill_mask": 0,
"quat": [0, 0, 0, 1], // quaternion
"bsphere": [-5.463, 17.4553, 1.6169, 10], // bounding sphere
"bsphere": [-5.4630, 17.4553, 1.6169, 10], // bounding sphere
"lump": {
"name": "test-eco"
}
}
]
}
}
+1 -1
View File
@@ -3175,7 +3175,7 @@ goos::Object DefskelgroupElement::ClothParams::to_list(const std::string& ag_nam
pretty_print::to_symbol(std::to_string(timestep_freq))}));
}
if (secret != 0) {
auto bits = decompile_bitfield_enum_from_int(TypeSpec("game-secrets"), env.dts->ts, secret);
auto bits = decompile_bitfield_enum_from_int(TypeSpec("game-secrets"), env.dts->ts, flags);
result.push_back(pretty_print::build_list(
{pretty_print::to_symbol("secret-disable"),
pretty_print::to_symbol(fmt::format("(game-secrets {})", fmt::join(bits, " ")))}));
-23
View File
@@ -211,13 +211,6 @@ Matcher Matcher::while_loop(const Matcher& condition, const Matcher& body) {
return m;
}
Matcher Matcher::until_loop(const Matcher& condition, const Matcher& body) {
Matcher m;
m.m_kind = Kind::UNTIL_LOOP;
m.m_sub_matchers = {condition, body};
return m;
}
Matcher Matcher::any_constant_token(int match_id) {
Matcher m;
m.m_kind = Kind::ANY_CONSTANT_TOKEN;
@@ -678,22 +671,6 @@ bool Matcher::do_match(Form* input, MatchResult::Maps* maps_out, const Env* cons
return true;
} break;
case Kind::UNTIL_LOOP: {
auto as_until = dynamic_cast<UntilElement*>(input->try_as_single_active_element());
if (!as_until) {
return false;
}
if (!m_sub_matchers.at(0).do_match(as_until->condition, maps_out, env)) {
return false;
}
if (!m_sub_matchers.at(1).do_match(as_until->body, maps_out, env)) {
return false;
}
return true;
} break;
case Kind::BEGIN: {
if ((int)m_sub_matchers.size() != input->size()) {
return false;
-2
View File
@@ -69,7 +69,6 @@ class Matcher {
const Matcher& false_case);
static Matcher if_no_else(const Matcher& condition, const Matcher& true_case);
static Matcher while_loop(const Matcher& condition, const Matcher& body);
static Matcher until_loop(const Matcher& condition, const Matcher& body);
static Matcher any_constant_token(int match_id = -1);
static Matcher constant_token(const std::string& name);
static Matcher or_expression(const std::vector<Matcher>& elts);
@@ -101,7 +100,6 @@ class Matcher {
IF_WITH_ELSE,
IF_NO_ELSE,
WHILE_LOOP,
UNTIL_LOOP,
ANY_CONSTANT_TOKEN,
CONSTANT_TOKEN,
SC_OR,
+4 -5
View File
@@ -231,11 +231,10 @@ ObjectFileDB::ObjectFileDB(const std::vector<fs::path>& _dgos,
StrFileReader reader(obj, version());
// name from the file name
std::string base_name = obj_filename_to_name(obj.string());
for (int i = 0; i < reader.chunk_count(); i++) {
auto name = reader.get_chunk_texture_name(i);
add_obj_from_dgo(name, name, reader.get_chunk(i).data(), reader.get_chunk(i).size(),
"TEXSPOOL", config, name);
}
ASSERT(reader.chunk_count() == 1);
auto name = reader.get_texture_name();
add_obj_from_dgo(name, name, reader.get_chunk(0).data(), reader.get_chunk(0).size(),
"TEXSPOOL", config, name);
}
}
+1 -9
View File
@@ -79,14 +79,12 @@ struct LetRewriteStats {
int with_dma_buf_add_bucket = 0;
int dma_buffer_add_gs_set = 0;
int launch_particles = 0;
int call_parent_state_handler = 0;
int suspend_for = 0;
int total() const {
return dotimes + countdown + abs + abs2 + unused + ja + case_no_else + case_with_else +
set_vector + set_vector2 + send_event + font_context_meth + proc_new + attack_info +
vector_dot + rand_float_gen + set_let + with_dma_buf_add_bucket + dma_buffer_add_gs_set +
launch_particles + call_parent_state_handler + suspend_for;
launch_particles;
}
std::string print() const {
@@ -113,8 +111,6 @@ struct LetRewriteStats {
out += fmt::format(" with_dma_buf_add_bucket: {}\n", with_dma_buf_add_bucket);
out += fmt::format(" dma_buffer_add_gs_set: {}\n", dma_buffer_add_gs_set);
out += fmt::format(" launch_particles: {}\n", launch_particles);
out += fmt::format(" call_parent_state_handler: {}\n", call_parent_state_handler);
out += fmt::format(" suspend_for: {}\n", suspend_for);
return out;
}
@@ -139,8 +135,6 @@ struct LetRewriteStats {
result.set_let = rand_float_gen + other.set_let;
result.with_dma_buf_add_bucket = rand_float_gen + other.with_dma_buf_add_bucket;
result.launch_particles = launch_particles + other.launch_particles;
result.call_parent_state_handler = call_parent_state_handler + other.call_parent_state_handler;
result.suspend_for = suspend_for + other.suspend_for;
return result;
}
@@ -164,8 +158,6 @@ struct LetRewriteStats {
set_let += other.set_let;
with_dma_buf_add_bucket += other.with_dma_buf_add_bucket;
launch_particles += other.launch_particles;
call_parent_state_handler += other.call_parent_state_handler;
suspend_for += other.suspend_for;
return *this;
}
};
-105
View File
@@ -1673,99 +1673,6 @@ FormElement* rewrite_part_tracker_new(const std::string& type,
->try_as_single_element();
}
FormElement* rewrite_call_parent_state_handler(LetElement* in, const Env& env, FormPool& pool) {
// (let ((t9-3 (-> (find-parent-state) code)))
// (if t9-3
// ((the-as (function none) t9-3))
// )
// )
auto mr =
Matcher::let(false,
{LetEntryMatcher::any(Matcher::deref(Matcher::func("find-parent-state", {}),
false, {DerefTokenMatcher::any_string(1)}),
0)},
{Matcher::if_no_else(Matcher::any(), Matcher::any(2))});
auto let_mr = match(mr, in);
if (!let_mr.matched) {
return nullptr;
}
auto handler = let_mr.maps.strings.at(1);
auto valid_handlers = {"enter", "trans", "code", "post"};
if (std::find(valid_handlers.begin(), valid_handlers.end(), handler) != valid_handlers.end()) {
std::vector<Form*> macro_args;
macro_args.push_back(pool.form<ConstantTokenElement>(handler));
// there are no examples of this being used with args, so that is not handled for now...
// auto func = let_mr.maps.forms.at(2);
return pool
.form<GenericElement>(GenericOperator::make_function(
pool.form<ConstantTokenElement>("call-parent-state-handler")),
macro_args)
->try_as_single_element();
}
return nullptr;
}
FormElement* rewrite_suspend_for(LetElement* in, const Env& env, FormPool& pool) {
// (let ((gp-1 (current-time)))
// (until (time-elapsed? gp-1 (seconds 0.5))
// (suspend)
// )
// )
// ->
// (suspend-for (seconds 0.5))
auto until = dynamic_cast<UntilElement*>(in->body()->at(0));
if (!until) {
return nullptr;
}
auto mr = Matcher::let(
false, {LetEntryMatcher::any(Matcher::func("current-time", {}), 0)},
{Matcher::until_loop(Matcher::func("time-elapsed?", {Matcher::any_reg(1), Matcher::any(2)}),
Matcher::any(3))});
auto let_mr = match(mr, in);
if (!let_mr.matched) {
return nullptr;
}
auto var = let_mr.maps.regs.at(1);
auto time = let_mr.maps.forms.at(2);
auto body = let_mr.maps.forms.at(3);
std::vector<Form*> macro_args;
std::vector<FormElement*> macro_elts;
macro_args.push_back(time);
for (auto& elt : body->elts()) {
auto op = dynamic_cast<AtomicOpElement*>(elt);
auto suspend = op && op->op() && dynamic_cast<SpecialOp*>(op->op()) &&
dynamic_cast<SpecialOp*>(op->op())->kind() == SpecialOp::Kind::SUSPEND;
if (!suspend || elt != body->elts().back()) {
elt->apply_form([&](Form* form) {
for (auto& e : form->elts()) {
auto as_expr = dynamic_cast<SimpleExpressionElement*>(e);
if (as_expr) {
RegAccessSet regs;
as_expr->collect_vars(regs, false);
for (auto reg : regs) {
if (reg.to_string(env, RegisterAccess::Print::AS_VARIABLE) ==
var.value().to_string(env, RegisterAccess::Print::AS_VARIABLE)) {
e = pool.alloc_element<ConstantTokenElement>("time");
}
}
}
}
});
macro_elts.push_back(elt);
}
}
if (!macro_elts.empty()) {
for (auto elt : macro_elts) {
macro_args.push_back(pool.alloc_single_form(nullptr, elt));
}
}
return pool
.form<GenericElement>(
GenericOperator::make_function(pool.form<ConstantTokenElement>("suspend-for")),
macro_args)
->try_as_single_element();
}
FormElement* rewrite_proc_new(LetElement* in, const Env& env, FormPool& pool) {
// this function checks for the process-spawn macros.
// it uses recursive form scanning to wrap the macro inside a potential "shell"
@@ -2278,12 +2185,6 @@ FormElement* rewrite_let(LetElement* in, const Env& env, FormPool& pool, LetRewr
return as_set_vector3;
}
auto suspend_for = rewrite_suspend_for(in, env, pool);
if (suspend_for) {
stats.suspend_for++;
return suspend_for;
}
auto as_abs_2 = fix_up_abs_2(in, env, pool);
if (as_abs_2) {
stats.abs2++;
@@ -2314,12 +2215,6 @@ FormElement* rewrite_let(LetElement* in, const Env& env, FormPool& pool, LetRewr
return as_attack_info;
}
auto as_call_parent_state = rewrite_call_parent_state_handler(in, env, pool);
if (as_call_parent_state) {
stats.call_parent_state_handler++;
return as_call_parent_state;
}
// nothing matched.
return nullptr;
}
+19 -86
View File
@@ -287,41 +287,25 @@
)
(defenum pad-buttons
:bitfield #t
:type uint32
(select 0)
(l3 1)
(r3 2)
(start 3)
(up 4)
(right 5)
(down 6)
(left 7)
(l2 8)
(r2 9)
(l1 10)
(r1 11)
(triangle 12)
(circle 13)
(x 14)
(square 15)
)
(defenum abutton-idx
:type uint8
(right 0)
(left 1)
(up 2)
(down 3)
(triangle 4)
(circle 5)
(x 6)
(square 7)
(l1 8)
(r1 9)
(l2 10)
(r2 11)
)
:bitfield #t
:type uint32
(select 0)
(l3 1)
(r3 2)
(start 3)
(up 4)
(right 5)
(down 6)
(left 7)
(l2 8)
(r2 9)
(l1 10)
(r1 11)
(triangle 12)
(circle 13)
(x 14)
(square 15)
)
(defenum gs-psm
:bitfield #f
@@ -19628,57 +19612,6 @@
(wt31)
)
(defenum water-look
(water-anim-sunken-big-room 0)
(water-anim-sunken-first-room-from-entrance 1)
(water-anim-sunken-qbert-room 2)
(water-anim-sunken-first-right-branch 3)
(water-anim-sunken-circular-with-bullys 4)
(water-anim-sunken-hall-with-one-whirlpool 5)
(water-anim-sunken-hall-with-three-whirlpools 6)
(water-anim-sunken-start-of-helix-slide 7)
(water-anim-sunken-room-above-exit-chamber 8)
(water-anim-sunken-hall-before-big-room 9)
(water-anim-sunken-dark-eco-qbert 10)
(water-anim-sunken-short-piece 11)
(water-anim-sunken-big-room-upper-water 12)
(water-anim-sunken-dark-eco-platform-room 13)
(water-anim-maincave-water-with-crystal 14)
(water-anim-maincave-center-pool 15)
(water-anim-maincave-lower-right-pool 16)
(water-anim-maincave-mid-right-pool 17)
(water-anim-maincave-lower-left-pool 18)
(water-anim-maincave-mid-left-pool 19)
(water-anim-robocave-main-pool 20)
(water-anim-misty-mud-by-arena 21)
(water-anim-misty-mud-above-skeleton 22)
(water-anim-misty-mud-behind-skeleton 23)
(water-anim-misty-mud-above-skull-back 24)
(water-anim-misty-mud-above-skull-front 25)
(water-anim-misty-mud-other-near-skull 26)
(water-anim-misty-mud-near-skull 27)
(water-anim-misty-mud-under-spine 28)
(water-anim-misty-mud-by-dock 29)
(water-anim-misty-mud-island-near-dock 30)
(water-anim-misty-mud-lonely-island 31)
(water-anim-misty-dark-eco-pool 32)
(water-anim-ogre-lava 33)
(water-anim-jungle-river 34)
(water-anim-village3-lava 35)
(water-anim-training-lake 36)
(water-anim-darkcave-water-with-crystal 37)
(water-anim-rolling-water-back 38)
(water-anim-rolling-water-front 39)
(water-anim-sunken-dark-eco-helix-room 40)
(water-anim-finalboss-dark-eco-pool 41)
(water-anim-lavatube-energy-lava 42)
(water-anim-village1-rice-paddy 43)
(water-anim-village1-fountain 44)
(water-anim-village1-rice-paddy-mid 45)
(water-anim-village1-rice-paddy-top 46)
(water-anim-village2-bucket 47)
)
(deftype water-control (basic)
((flags water-flags :offset-assert 4)
(process process-drawable :offset-assert 8)
+20 -39
View File
@@ -52,28 +52,14 @@
(defenum language-enum
:type int64
(english 0)
(french 1)
(german 2)
(spanish 3)
(italian 4)
(japanese 5)
(korean 6)
(uk-english 7)
;; custom
(portuguese 8)
(finnish 9)
(swedish 10)
(danish 11)
(norwegian 12)
(dutch 13)
(br-portuguese 14)
(hungarian 15)
(catalan 16)
(icelandic 17)
(russian 18)
(polish 19)
(lithuanian 20)
(english)
(french)
(german)
(spanish)
(italian)
(japanese)
(korean)
(uk-english)
)
(defenum runtime-exit-status
@@ -4202,22 +4188,6 @@ and the state of the VU memory buffers at the end of the bucket."
(confirm 24)
)
(defenum abutton-idx
:type uint8
(right 0)
(left 1)
(up 2)
(down 3)
(triangle 4)
(circle 5)
(x 6)
(square 7)
(l1 8)
(r1 9)
(l2 10)
(r2 11)
)
(defenum mouse-buttons
:bitfield #t
:type uint32
@@ -8818,7 +8788,6 @@ Unlike [[engine]], users can use [[engine-pers]] as a parent class."
(progress-graphics-msaa-off #x1338)
(progress-graphics-display #x1339)
(language-name-finnish #x133a)
(progress-hint-subtitles #x133b)
)
;; ---text-id-h:text-id
@@ -9465,6 +9434,18 @@ Unlike [[engine]], users can use [[engine-pers]] as a parent class."
;; settings-h ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defenum language-enum
:type int64
(english)
(french)
(german)
(spanish)
(italian)
(japanese)
(korean)
(uk-english)
)
(defenum game-feature
:type uint64
:bitfield #t
+51 -114
View File
@@ -4603,24 +4603,6 @@
)
;; ---pad:pad-buttons
;; +++pad:abutton-idx
(defenum abutton-idx
:type uint8
(right 0)
(left 1)
(up 2)
(down 3)
(triangle 4)
(circle 5)
(x 6)
(square 7)
(l1 8)
(r1 9)
(l2 10)
(r2 11)
)
;; ---pad:abutton-idx
;; +++pad:mouse-buttons
(defenum mouse-buttons
:bitfield #t
@@ -7541,27 +7523,27 @@
;; +++level-h:bigmap-id
(defenum bigmap-id
:type uint32
(city 0)
(comb 1)
(bigmap-id-0 0)
(bigmap-id-1 1)
(desert 2)
(factory 3)
(forest 4)
(mhcity 5)
(mine 6)
(nest 7)
(nest2 8)
(none 9)
(precursor1 10)
(precursor2 11)
(bigmap-id-8 8)
(no-map 9)
(precursor 10)
(bigmap-id-11 11)
(rubble 12)
(sewer-hum-kg 13)
(sewer-kg-met 14)
(sewer-met-hum 15)
(sewer0 13)
(sewer1 14)
(sewer2 15)
(stadium 16)
(temple1 17)
(temple2 18)
(temple3 19)
(temple4 20)
(temple 17)
(bigmap-id-18 18)
(bigmap-id-19 19)
(bigmap-id-20 20)
(tower 21)
(volcano 22)
(wascity 23)
@@ -8306,7 +8288,7 @@
(define-extern *font-default-matrix* matrix)
(define-extern *font-work* font-work)
(define-extern font-set-tex0 (function (pointer gs-tex0) texture int int int none))
(define-extern set-font-color (function font-color rgba rgba rgba rgba int))
(define-extern set-font-color (function font-color int rgba rgba rgba int))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; decomp-h ;;
@@ -10742,55 +10724,16 @@
:flag-assert #x900000180
)
;; +++bigmap-h:bigmap-flag
(defenum bigmap-flag
:type uint32
:bitfield #t
(bf00 0)
(bf01 1)
(bf02 2)
(bf03 3)
(bf04 4)
(bf05 5)
(bf06 6)
(bf07 7)
(bf08 8)
(bf09 9)
(bf10 10)
(bf11 11)
(bf12 12)
(bf13 13)
(bf14 14)
(bf15 15)
(bf16 16)
(bf17 17)
(ctywide 18)
(waswide 19)
(wasall 20)
(desert 21)
(bf22 22)
(bf23 23)
(bf24 24)
(bf25 25)
(bf26 26)
(bf27 27)
(bf28 28)
(bf29 29)
(bf30 30)
(bf31 31)
)
;; ---bigmap-h:bigmap-flag
(deftype bigmap (basic)
((drawing-flag symbol :offset-assert 4) ;; guessed by decompiler
(loading-flag symbol :offset-assert 8) ;; guessed by decompiler
(bigmap-index bigmap-id :offset-assert 12)
(bigmap-index uint32 :offset-assert 12)
(bigmap-image external-art-buffer :offset-assert 16) ;; guessed by decompiler
(tpage external-art-buffer :offset-assert 20) ;; guessed by decompiler
(tpage2 external-art-buffer :offset-assert 24)
(tpage2 basic :offset-assert 24)
(progress-minimap texture-page :offset-assert 28) ;; guessed by decompiler
(progress-minimap2 texture-page :offset-assert 32)
(load-index bigmap-id :offset-assert 36)
(load-index uint32 :offset-assert 36)
(x0 int32 :offset-assert 40)
(y0 int32 :offset-assert 44)
(x1 int32 :offset-assert 48)
@@ -10805,29 +10748,29 @@
(scroll vector :inline :offset-assert 176)
(pos vector4w :inline :offset-assert 192)
(color vector4w :inline :offset-assert 208)
(corner vector 4 :inline :offset-assert 224) ;; guessed by decompiler
(corner vector 4 :inline :offset-assert 224) ;; guessed by decompiler
(auto-save-icon-flag symbol :offset-assert 288) ;; guessed by decompiler
(global-flags bigmap-flag :offset-assert 292)
(global-flags uint32 :offset-assert 292)
)
:method-count-assert 23
:size-assert #x128
:flag-assert #x1700000128
(:methods
(new (symbol type) _type_) ;; 0
(initialize (_type_) none) ;; 9
(new (symbol type) _type_) ;; 0 ;; (new (symbol type) _type_)
(bigmap-method-9 () none) ;; 9 ;; (initialize (_type_) none)
(update (_type_) none) ;; 10
(loaded? (_type_) symbol) ;; 11
(draw! (_type_ int int int int) none) ;; 12 ;; (handle-cpad-inputs (_type_) int)
(handle-cpad-input (_type_) none) ;; 13 ;; (compress-all (_type_) int)
(bigmap-method-11 (_type_) symbol) ;; 11
(bigmap-method-12 () none) ;; 12 ;; (handle-cpad-inputs (_type_) int)
(bigmap-method-13 () none) ;; 13 ;; (compress-all (_type_) int)
(enable-drawing (_type_) none) ;; 14
(disable-drawing (_type_) int) ;; 15
(set-map-indices! (_type_) none) ;; 16 ;; (dump-to-file (_type_) file-stream)
(set-pos! (_type_ vector) none) ;; 17
(bigmap-method-18 (_type_ (pointer int32)) none) ;; 18 ;; (decompress-current-masks! (_type_) int)
(texture-upload-dma (_type_ dma-buffer (pointer uint32) int int int gs-psm) none) ;; 19 ;; (compress-current-masks! (_type_) int)
(bigmap-method-20 (_type_ dma-buffer) symbol) ;; 20 ;; (set-enable-from-position! (_type_) int)
(sprite-dma (_type_ dma-buffer int int int int int int) object) ;; 21 ;; (maybe-fill-for-position (_type_ int int) int)
(draw-from-minimap (_type_ dma-buffer connection-minimap) none) ;; 22
(bigmap-method-16 (_type_) none) ;; 16 ;; (dump-to-file (_type_) file-stream)
(bigmap-method-17 () none) ;; 17 ;; (set-pos! (_type_ vector) int)
(bigmap-method-18 () none) ;; 18 ;; (decompress-current-masks! (_type_) int)
(bigmap-method-19 () none) ;; 19 ;; (compress-current-masks! (_type_) int)
(bigmap-method-20 () none) ;; 20 ;; (set-enable-from-position! (_type_) int)
(bigmap-method-21 () none) ;; 21 ;; (maybe-fill-for-position (_type_ int int) int)
(bigmap-method-22 () none) ;; 22 ;; (texture-upload-dma (_type_ dma-buffer (pointer uint32) int int int gs-psm) none)
)
)
@@ -11542,13 +11485,13 @@
(scan-tmpl dma-gif-packet :inline :offset-assert 192)
(color vector4w :inline :offset-assert 224)
(line-color uint64 :offset-assert 240)
(scan-colors vector4w 15 :inline :offset-assert 256) ;; guessed by decompiler
(scan-colors vector4w 15 :inline :offset-assert 256) ;; guessed by decompiler
(zoom-blur-pos vector :inline :offset-assert 496)
(zoom-blur-count int32 :offset-assert 512)
(zoom-blur-texels int32 :offset-assert 516)
(zoom-blur-alpha-target float :offset-assert 520)
(zoom-blur-alpha-current float :offset-assert 524)
(zoom-blur-2d symbol :offset-assert 528)
(zoom-blur-2d basic :offset-assert 528)
(menu-mode symbol :offset-assert 532) ;; guessed by decompiler
(screen-copied symbol :offset-assert 536) ;; guessed by decompiler
(vu1-enable-user-menu vu1-renderer-mask :offset-assert 544)
@@ -11566,18 +11509,18 @@
:size-assert #x24c
:flag-assert #x1b0000024c
(:methods
(blit-displays-work-method-9 (_type_ dma-buffer int int int) none) ;; 9
(blit-displays-work-method-10 (_type_ dma-buffer int int int) none) ;; 10
(blit-displays-work-method-11 (_type_ dma-buffer int) none) ;; 11
(draw-letterbox (_type_ dma-buffer float int float) none) ;; 12
(blit-displays-work-method-13 (_type_ dma-buffer int int int) none) ;; 13
(blit-displays-work-method-14 (_type_ dma-buffer vector) none) ;; 14
(blit-displays-work-method-15 (_type_ dma-buffer) none) ;; 15
(draw-zoom-blur (_type_ dma-buffer int) none) ;; 16
(setup-zoom-blur-2d (_type_ vector int float symbol) none) ;; 17
(setup-brightness-and-contrast (_type_ dma-buffer float float) none) ;; 18
(do-blit-displays (_type_) none) ;; 19 (called from main.gc)
(draw-sky (_type_ dma-buffer) none) ;; 20
(blit-displays-work-method-9 () none) ;; 9
(blit-displays-work-method-10 () none) ;; 10
(blit-displays-work-method-11 () none) ;; 11
(blit-displays-work-method-12 () none) ;; 12
(blit-displays-work-method-13 () none) ;; 13
(blit-displays-work-method-14 () none) ;; 14
(blit-displays-work-method-15 () none) ;; 15
(blit-displays-work-method-16 () none) ;; 16
(blit-displays-work-method-17 (_type_ vector int float symbol) none) ;; 17
(blit-displays-work-method-18 () none) ;; 18
(blit-displays-work-method-19 (_type_) none) ;; 19 (called from main.gc)
(blit-displays-work-method-20 (_type_) none) ;; 20
(get-menu-mode (_type_) symbol) ;; 21
(get-screen-copied (_type_) symbol) ;; 22
(get-horizontal-flip-flag (_type_) symbol) ;; 23
@@ -23125,7 +23068,7 @@
(disable-for-duration (_type_ time-frame) none) ;; 16
(ragdoll-proc-method-17 (_type_ ragdoll-edit-info) none) ;; 17
(ragdoll-proc-method-18 (_type_ ragdoll-edit-info) none) ;; 18
(ragdoll-proc-method-19 (_type_) symbol) ;; 19
(ragdoll-proc-method-19 (_type_) none) ;; 19
)
)
@@ -31121,7 +31064,7 @@
(define-extern *blit-displays-work* blit-displays-work)
(define-extern draw-color-bars (function blit-displays-work none))
(define-extern draw-raw-image (function blit-displays-work bucket-id art-group vector vector level int none))
(define-extern draw-raw-image (function bucket-id art-group int vector vector level int none))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; font-data ;;
@@ -39286,7 +39229,7 @@
;; bigmap ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define-extern *bigmap-info-array* bigmap-info-array)
;; (define-extern *bigmap-info-array* object) ;; bigmap-info-array
(define-extern *bigmap* bigmap)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -42180,12 +42123,6 @@
;; rigid-body ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(deftype rigid-body-stack (structure)
((vec vector :inline)
(mat matrix :inline)
)
)
(deftype rigid-body-work (structure)
((max-ang-momentum float :offset-assert 0)
(max-ang-velocity float :offset-assert 4)
@@ -44457,9 +44394,9 @@
(within-outer-ring symbol :offset-assert 136)
(within-inner-ring symbol :offset-assert 140)
(ouched symbol :offset-assert 144)
(bound-cam string :offset-assert 148)
(bound-cam basic :offset-assert 148)
(trans vector :inline :offset-assert 160)
(state-time time-frame :offset-assert 176)
(state-time uint64 :offset-assert 176)
(jak-in-hint-region symbol :offset-assert 184)
(watchers-vulnerable symbol :offset-assert 188)
)
@@ -44492,7 +44429,7 @@
standing-down ;; 31
)
(:methods
(init-collision! (_type_) none) ;; 32
(tpl-watcher-method-32 (_type_) none) ;; 32
)
)
+1 -1
View File
@@ -73,7 +73,7 @@
"write_hex_near_instructions": false,
// to write out "scripts", which are currently just all the linked lists found. mostly a jak 2/3 thing
"write_scripts": false,
"write_scripts": true,
// hex dump of code/data files.
"hexdump_code": false,
@@ -1000,10 +1000,5 @@
[12, "(function none :behavior scene-player)"],
[13, "(function none :behavior scene-player)"],
[14, "(function none :behavior scene-player)"]
],
"bigmap": [
[15, "(function external-art-buffer object)"],
[16, "(function external-art-buffer object)"],
[17, "(function external-art-buffer object)"]
]
}
@@ -735,6 +735,10 @@
// 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],
+5 -248
View File
@@ -186,18 +186,18 @@
"DGO/PRECA.DGO",
"DGO/PRECB.DGO",
"DGO/PRECC.DGO",
"DGO/PRECD.DGO",
// title/intro
// "DGO/PRECD.DGO",
// // title/intro
"DGO/WIN.DGO", // wasintro
"DGO/TITLE.DGO",
"DGO/INTTITLE.DGO",
"DGO/INTPALRF.DGO", // intro-palace-roof
"DGO/IPF.DGO", // intro-palace-fall
"DGO/INTROCST.DGO",
// outro
// // outro
"DGO/OUTCAST3.DGO",
"DGO/OUTROCST.DGO",
// museum
// // museum
"DGO/MUSEUM.DGO",
"DGO/MUSEUM2.DGO",
"DGO/MUSEUM3.DGO",
@@ -311,245 +311,8 @@
"DGO/LWSTDPCK.DGO"
],
// STR files containing a texture that should be used by
// FR3 creation.
"str_texture_file_names": ["STR/PRMINIMA.STR"],
// some objects are part of STR files (streaming data).
"str_file_names": [
"STR/ARF1INTR.STR",
"STR/ARF1RES.STR",
"STR/ARF2INTR.STR",
"STR/ARF2RES.STR",
"STR/ARF3INTR.STR",
"STR/ARF3RES.STR",
"STR/AROUTRO.STR",
"STR/ART1INTR.STR",
"STR/CAGSHIEL.STR",
"STR/CATRES.STR",
"STR/CAWRRES.STR",
"STR/CIATIDES.STR",
"STR/CIATOUT.STR",
"STR/CIBBINTR.STR",
"STR/CIBBRES.STR",
"STR/CIBTINTR.STR",
"STR/CIDGRES.STR",
"STR/CIFCEINT.STR",
"STR/CIGC1RES.STR",
"STR/CIGC2INT.STR",
"STR/CIGC2RES.STR",
"STR/CIGCINTR.STR",
"STR/CIGDPUNC.STR",
"STR/CIGTCINT.STR",
"STR/CIHVRES.STR",
"STR/CIPAIB.STR",
"STR/CIPAINTR.STR",
"STR/CIPARES.STR",
"STR/CIPFINTR.STR",
"STR/CIPGINTR.STR",
"STR/CIPGRES.STR",
"STR/CIPHINTR.STR",
"STR/CIPHRES.STR",
"STR/CISFINTR.STR",
"STR/COETEMPL.STR",
"STR/COEXIT.STR",
"STR/DAD06.STR",
"STR/DAD07.STR",
"STR/DAD10.STR",
"STR/DAD12.STR",
"STR/DAD13.STR",
"STR/DAD14.STR",
"STR/DAD16.STR",
"STR/DAD17.STR",
"STR/DAD18.STR",
"STR/DAD20.STR",
"STR/DAD21.STR",
"STR/DAD24.STR",
"STR/DAD31.STR",
"STR/DAD35.STR",
"STR/DAD38.STR",
"STR/DAD57.STR",
"STR/DAD58.STR",
"STR/DAD61.STR",
"STR/DAMOLE.STR",
"STR/DEAR1INT.STR",
"STR/DEAR1RES.STR",
"STR/DEAR2INT.STR",
"STR/DEATIN.STR",
"STR/DEATOUT.STR",
"STR/DEBBINTR.STR",
"STR/DECLINTR.STR",
"STR/DECRINTR.STR",
"STR/DECWIN.STR",
"STR/DEFBIA.STR",
"STR/DEFBINTR.STR",
"STR/DEFBRB.STR",
"STR/DEFBRES.STR",
"STR/DEGRES.STR",
"STR/DEHINTRO.STR",
"STR/DEHRES.STR",
"STR/DEJGOTA.STR",
"STR/DEJGOTB.STR",
"STR/DEJGOTC.STR",
"STR/DEJMINTR.STR",
"STR/DELC2.STR",
"STR/DELC3.STR",
"STR/DELCATCH.STR",
"STR/DEODRB.STR",
"STR/DEODRES.STR",
"STR/DERINTRO.STR",
"STR/DERRA.STR",
// "STR/DESCREEN.STR",
"STR/DPBTURRE.STR",
"STR/FABINTRO.STR",
"STR/FABRES.STR",
"STR/FAI1INTR.STR",
"STR/FAI2INTR.STR",
"STR/FAI3INTR.STR",
"STR/FAI4INTR.STR",
"STR/FASBIB.STR",
"STR/FASBINTR.STR",
"STR/FASBRES.STR",
"STR/FORB.STR",
"STR/FORCRES.STR",
"STR/FOTOMRES.STR",
"STR/FOTOWER.STR",
"STR/GRMANIMS.STR",
"STR/INDROP.STR",
"STR/INFFHQ.STR",
"STR/INLOST.STR",
"STR/INPALACE.STR",
"STR/INRESCUE.STR",
"STR/INTIRED.STR",
"STR/INTRAINI.STR",
"STR/JAA1.STR",
"STR/JAA2.STR",
"STR/JAA3.STR",
"STR/JAA4.STR",
"STR/JAA5.STR",
"STR/JAA6.STR",
"STR/JAA7.STR",
"STR/JABOARD.STR",
"STR/JACARRY.STR",
"STR/JAD1.STR",
"STR/JAD2.STR",
"STR/JAD3.STR",
"STR/JAD4.STR",
"STR/JAD5.STR",
"STR/JADARK.STR",
"STR/JADON.STR",
"STR/JADUMMY.STR",
"STR/JAEBOARD.STR",
"STR/JAEDARK.STR",
"STR/JAEGC.STR",
"STR/JAEGNORM.STR",
"STR/JAEGOLD.STR",
"STR/JAELIGHT.STR",
"STR/JAENORMA.STR",
// "STR/JAEXTERN.STR",
"STR/JAFLDAX.STR",
"STR/JAFLUT.STR",
"STR/JAGUN.STR",
"STR/JAICE.STR",
"STR/JAINDAX.STR",
"STR/JAKANGA.STR",
"STR/JALADDER.STR",
"STR/JALIGHT.STR",
"STR/JAMECH.STR",
"STR/JAPEGASU.STR",
"STR/JAPGLIDE.STR",
"STR/JAPGUN.STR",
"STR/JAPHCAR.STR",
"STR/JAPIDAX.STR",
"STR/JAPILOT.STR",
"STR/JAPOLE.STR",
"STR/JAPWCAR.STR",
"STR/JARACER.STR",
"STR/JASWIM.STR",
"STR/JATENTAC.STR",
"STR/JATUBE.STR",
"STR/JATURRET.STR",
"STR/KRWB1.STR",
"STR/KRWB2.STR",
"STR/KRWB3.STR",
"STR/MIBINTRO.STR",
"STR/MIBRES.STR",
"STR/MIERES.STR",
"STR/MIGEXIT.STR",
"STR/MITINTRO.STR",
"STR/MITRES.STR",
"STR/MU2ANIMS.STR",
"STR/MU3ANIMS.STR",
"STR/MU4ANIMS.STR",
"STR/MUANIMS.STR",
"STR/NEDBARRI.STR",
"STR/NEEINTRO.STR",
"STR/NEHINTRO.STR",
"STR/NEHRES.STR",
"STR/NSB1BREA.STR",
"STR/NSB2BREA.STR",
"STR/PARAINTR.STR",
"STR/PARARA.STR",
"STR/PARARES.STR",
"STR/PARPINTR.STR",
"STR/PEFLY.STR",
"STR/POAINTRO.STR",
"STR/PRDSERES.STR",
"STR/PRDSLOSE.STR",
"STR/PRDSRES.STR",
"STR/PRHA.STR",
"STR/PRHB.STR",
"STR/PRHC.STR",
"STR/PRHFINAL.STR",
// "STR/PRMINIMA.STR",
"STR/PRTRES.STR",
"STR/RATA1INT.STR",
"STR/RATA2INT.STR",
// "STR/SCBOOK.STR",
"STR/SEEINTRO.STR",
"STR/SEGENTRA.STR",
"STR/SEHKENTR.STR",
"STR/SEHKRES.STR",
"STR/SEKENTRA.STR",
"STR/SEKEXIT.STR",
"STR/SEKMINTR.STR",
"STR/SEMEXIT.STR",
"STR/SEMHINTR.STR",
"STR/SEPEXIT.STR",
"STR/SESGRUNT.STR",
"STR/SEWATERS.STR",
"STR/TECINTRO.STR",
"STR/TECRES.STR",
"STR/TEDINTRO.STR",
"STR/TEDRES.STR",
"STR/TEEANIMS.STR",
"STR/TEELAANI.STR",
"STR/TEELODS.STR",
"STR/TEJGLGLI.STR",
"STR/TEOINTRO.STR",
"STR/TEORES.STR",
"STR/TETINTRO.STR",
"STR/TETRA.STR",
"STR/TETRB.STR",
"STR/TEWDESER.STR",
"STR/TODINTRO.STR",
"STR/TODRB.STR",
"STR/TODRES.STR",
"STR/VODRES.STR",
"STR/VOI1INTR.STR",
"STR/VOI1RES.STR",
"STR/VOI2INTR.STR",
"STR/VOI2RES.STR",
"STR/WACINTRO.STR",
"STR/WADRES.STR",
"STR/WAGINTRO.STR",
"STR/WAGRES.STR",
"STR/WALRINTR.STR",
"STR/WALRRES.STR",
"STR/WAPGINTR.STR",
"STR/WAPGRES.STR"
// "STR/WOMAP.STR"
],
"str_file_names": [],
// streaming "art" that should be added to GAME.FR3.
"str_art_file_names": ["STR/JAEXTERN.STR"],
@@ -580,12 +343,6 @@
"VAGWAD.INT"
],
// tpages that should always be possible to access.
"common_tpages": [
17, // PRMINIMA progress-minimap
3349 // PRMINIMA progress-minimap2
],
"animated_textures": [
// dark jak
"jakc-arm",
@@ -1046,7 +1046,7 @@
"desertf-obs": [["L99", "(inline-array vector)", 2]],
"desert-dust-storm": [["L89", "vector"]],
"artifact-race": [
["L162", "(inline-array talker-speech-class)", 32],
["L162", "(inline-array talker-speech-class)", 16],
["L160", "vector"],
["L159", "vector"],
["L158", "vector"],
@@ -429,7 +429,7 @@
"(method 22 rigid-body-control)": [[16, ["inline-array", "vector", 2]]],
"(method 23 rigid-body-control)": [[16, ["inline-array", "vector", 2]]],
"(method 24 rigid-body-control)": [[16, ["inline-array", "vector", 2]]],
"(method 28 rigid-body-control)": [[16, "rigid-body-stack"]],
"(method 28 rigid-body-control)": [[16, "rigid-body-impact"]],
"(method 50 rigid-body-object)": [[16, "rigid-body-impact"]],
"(method 51 rigid-body-object)": [[16, "rigid-body-impact"]],
"ptest": [[16, "vector"]],
@@ -1067,7 +1067,7 @@
[208, ["array", "uint32", 1]]
],
"(method 35 was-squad-control)": [
[16, ["inline-array", "matrix", 4]],
[16, ["inline-array", "matrix", 2]],
[240, "cquery-with-5vec"]
],
"(method 39 vehicle-wheel)": [[16, "rigid-body-move-work"]],
@@ -2513,12 +2513,5 @@
[80, "matrix"],
[144, "matrix"],
[208, "matrix"]
],
"(method 12 bigmap)": [[32, "matrix"]],
"(method 22 bigmap)": [
[16, "vector4w"],
[32, "vector"],
[48, "vector"],
[64, "vector"]
]
}
@@ -10857,6 +10857,7 @@
["_stack_", 76, "float"],
["_stack_", 100, "float"]
],
"real-wang-texture-anim-func": [[[3, 31], "v1", "mood-context"]],
"(method 24 sky-work)": [
[256, "s4", "(pointer int32)"],
[261, "s4", "(pointer int32)"]
@@ -11265,80 +11266,5 @@
[[191, 249], "gp", "shadow-dcache"],
[96, "v1", "shadow-dcache"]
],
"real-fog-texture-anim-func": [[[6, 160], "s2", "(pointer uint32)"]],
"(method 22 bigmap)": [
[22, "s3", "process-drawable"],
[[46, 49], "v1", "entity-actor"],
[58, "a0", "process-drawable"],
[65, "a0", "entity-actor"],
[42, "v1", "entity-actor"],
[55, "s3", "process-drawable"],
[[201, 243], "a1", "(inline-array vector4w)"]
],
"(method 20 bigmap)": [
[[3, 95], "s4", "(pointer uint32)"],
[99, "a2", "(pointer uint32)"],
[54, "a2", "(pointer uint32)"]
],
"(method 12 bigmap)": [
[85, "v1", "(pointer uint32)"],
[100, "v1", "(pointer uint32)"],
[[142, 145], "s0", "(pointer uint128)"],
["_stack_", 96, "(inline-array vector4w)"]
],
"(method 21 bigmap)": [[[10, 38], "v1", "(inline-array vector4w)"]],
"(method 19 blit-displays-work)": [
[764, "v1", "float"],
[759, "v1", "float"],
[[935, 954], "a1", "(inline-array vector4w)"],
[[857, 875], "a1", "(inline-array vector4w)"],
[[844, 847], "a0", "dma-gif-packet"],
[[921, 924], "v1", "dma-gif-packet"]
],
"(method 9 blit-displays-work)": [[[2, 36], "v1", "(inline-array vector4w)"]],
"(method 10 blit-displays-work)": [
[[2, 141], "v1", "(inline-array vector4w)"]
],
"(method 11 blit-displays-work)": [
[[2, 30], "v1", "(inline-array vector4w)"]
],
"(method 12 blit-displays-work)": [
[[4, 41], "v1", "(inline-array vector4w)"],
[[60, 112], "v1", "(inline-array vector4w)"]
],
"(method 13 blit-displays-work)": [
[[41, 44], "v1", "(inline-array vector4w)"],
[[53, 71], "a0", "(inline-array vector4w)"]
],
"(method 18 blit-displays-work)": [
[[28, 33], "v1", "dma-gif-packet"],
[[174, 177], "v1", "dma-gif-packet"],
[[186, 202], "a0", "(inline-array vector4w)"]
],
"draw-raw-image": [[[104, 154], "v1", "(inline-array vector4w)"]],
"draw-color-bars": [
[[11, 16], "v1", "dma-gif-packet"],
[[28, 54], "v1", "(inline-array vector4w)"]
],
"(method 20 blit-displays-work)": [
[[57, 89], "a3", "(inline-array vector4w)"],
[[102, 134], "t1", "(inline-array vector4w)"],
[[176, 209], "t1", "(inline-array vector4w)"],
[[310, 338], "t2", "(inline-array vector4w)"],
[[385, 422], "v1", "(inline-array vector4w)"]
],
"(method 14 blit-displays-work)": [
[[88, 91], "v1", "dma-gif-packet"],
[[100, 120], "a0", "(inline-array vector4w)"]
],
"(method 16 blit-displays-work)": [
[[35, 79], "s2", "(inline-array vector4w)"],
[[134, 178], "s2", "(inline-array vector4w)"]
],
"(method 15 blit-displays-work)": [
[[60, 63], "v1", "dma-gif-packet"],
[[81, 99], "a0", "(inline-array vector4w)"],
[[165, 190], "a0", "(inline-array vector4w)"]
],
"(event idle progress)": [[[10, 80], "v1", "mc-status-code"]]
"real-fog-texture-anim-func": [[[6, 160], "s2", "(pointer uint32)"]]
}
@@ -2135,14 +2135,5 @@
"vars": {
"v0-0": ["type", "assault-target-type"]
}
},
"(method 22 bigmap)": {
"vars": {
"a2-1": ["a2-1", "uint"],
"a3-0": ["a3-0", "uint"]
}
},
"set-font-color": {
"args": ["idx", "clr0", "clr1", "clr2", "clr3"]
}
}
+4 -3
View File
@@ -166,7 +166,7 @@ FullName extract_name(const std::string& file_info_name) {
name.name = name.name.substr(0, name.name.length() - 6);
int chunk_id = 0;
int place = 0;
for (int i = 3; i-- > 0;) {
for (int i = 2; i-- > 0;) {
char c = name.name.back();
if (c >= '0' && c <= '9') {
int val = (c - '0');
@@ -258,8 +258,9 @@ std::string StrFileReader::get_full_name(const std::string& short_name) const {
return result;
}
std::string StrFileReader::get_chunk_texture_name(int idx) const {
const auto& chunk = m_chunks[idx];
std::string StrFileReader::get_texture_name() const {
ASSERT(m_chunks.size() == 1);
const auto& chunk = m_chunks[0];
auto find_string = get_texture_page_file_info_string();
int offset;
if (find_string_in_data(chunk.data(), int(chunk.size()), find_string, &offset)) {
+2 -3
View File
@@ -22,7 +22,7 @@ class StrFileReader {
std::string get_chunk_art_name(int idx) const;
std::string get_full_name(const std::string& short_name) const;
std::string get_chunk_texture_name(int idx) const;
std::string get_texture_name() const;
private:
void init_jak1(const fs::path& file_path);
@@ -46,9 +46,8 @@ class StrFileReader {
std::string get_texture_page_file_info_string() const {
switch (m_version) {
case GameVersion::Jak2:
return "/src/jak2/final/texture-page8/";
case GameVersion::Jak3:
return "/src/jak3/final/texture-page8/";
return "/src/jak2/final/texture-page8/";
default:
ASSERT_MSG(false, "NYI get_file_info_string version");
break;
+6 -6
View File
@@ -454,7 +454,7 @@ std::string write_spool_subtitles(
bool has_spools = false;
for (auto& [spool_name, subs] : data) {
result += " \"" + spool_name + "\": {\n";
// result += " \"scene\": true,\n";
result += " \"scene\": true,\n";
result += " \"lines\": [\n";
bool has_subs = false;
for (auto& sub : subs) {
@@ -463,20 +463,20 @@ std::string write_spool_subtitles(
continue;
}
result += " {\n";
result += " \"frame_end\": " + float_to_string(sub.end_frame) + ",\n";
result += " \"frame_start\": " + float_to_string(sub.start_frame) + ",\n";
result += " \"end\": " + float_to_string(sub.end_frame) + ",\n";
if (dump_text) {
result += " \"merge\": false,\n";
} else {
result += " \"merge\": true,\n";
}
result += " \"offscreen\": false,\n";
result += " \"speaker\": \"none\",\n";
result += " \"start\": " + float_to_string(sub.start_frame) + ",\n";
if (dump_text) {
result += " \"text\": \"" + msg.text + "\",\n";
result += " \"text\": \"" + msg.text + "\"\n";
} else {
// result += " \"text\": \"\",\n";
result += " \"text\": \"\"\n";
}
result += " \"speaker\": \"none\"\n";
result += " },\n";
has_subs = true;
}
+3 -6
View File
@@ -164,16 +164,13 @@ AudioDir read_audio_dir(const decompiler::Config& config, const fs::path& path)
u64 data;
struct {
u64 name : 42;
u64 stereo : 1;
u64 international : 1;
u64 param : 4;
bool stereo : 1;
bool international : 1;
u8 param : 4;
u64 offset : 16;
};
};
};
static_assert(sizeof(DirEntryJak3) == sizeof(u64));
dir = reader.read<VagDirJak3>();
ASSERT(dir.id[0] == 0x41574756);
ASSERT(dir.id[1] == 0x52494444);
-1
View File
@@ -12,7 +12,6 @@
enum class ExtractorErrorCode {
SUCCESS = 0,
INVALID_CLI_INPUT = 3990,
INVALID_CLI_INPUT_MISSING_FOLDER = 3991,
VALIDATION_CANT_LOCATE_ELF = 4000,
VALIDATION_SERIAL_MISSING_FROM_DB = 4001,
VALIDATION_ELF_MISSING_FROM_DB = 4002,
+3 -3
View File
@@ -225,7 +225,7 @@ int main(int argc, char** argv) {
if (!project_path_override.empty()) {
if (!fs::exists(project_path_override)) {
lg::error("Error: project path override '{}' does not exist", project_path_override.string());
return static_cast<int>(ExtractorErrorCode::INVALID_CLI_INPUT_MISSING_FOLDER);
return static_cast<int>(ExtractorErrorCode::INVALID_CLI_INPUT);
}
auto ok = file_util::setup_project_path(project_path_override);
if (!ok) {
@@ -255,7 +255,7 @@ int main(int argc, char** argv) {
// - INPUT VALIDATION
if (!fs::exists(input_file_path)) {
lg::error("Error: input game file path '{}' does not exist", input_file_path.string());
return static_cast<int>(ExtractorErrorCode::INVALID_CLI_INPUT_MISSING_FOLDER);
return static_cast<int>(ExtractorErrorCode::INVALID_CLI_INPUT);
}
if (data_subfolders.count(game_name) == 0) {
lg::error("Error: input game name '{}' is not valid", game_name);
@@ -325,7 +325,7 @@ int main(int argc, char** argv) {
} else if (fs::is_directory(input_file_path)) {
if (!flag_folder) {
// if we didn't request a folder explicitly, but we got one, assume something went wrong.
lg::error("got a folder, but didn't provide the folder flag");
lg::error("got a folder, but didn't get folder flag");
return static_cast<int>(ExtractorErrorCode::INVALID_CLI_INPUT);
}
iso_data_path = input_file_path;
+1 -22
View File
@@ -1017,8 +1017,7 @@ void PrototypeBucketTie::read_from_file(TypedRef ref,
for (int i = 0; i < 4; i++) {
u32 start = index_start[i];
u32 end = start + frag_count[i];
// precd tie has a bug where geo 3's
// ASSERT(num_color_qwcs <= end);
ASSERT(num_color_qwcs <= end);
num_color_qwcs = std::max(end, num_color_qwcs);
}
@@ -1988,13 +1987,6 @@ void HFragment::read_from_file(TypedRef ref, const decompiler::DecompilerTypeSys
size = read_plain_data_field<u32>(ref, "size", dts);
}
void AdgifShaderArray::read_from_file(TypedRef ref, const decompiler::DecompilerTypeSystem& dts) {
auto length = read_plain_data_field<s32>(ref, "length", dts);
adgifs.resize(length);
memcpy_plain_data((u8*)adgifs.data(), get_field_ref(ref, "data", dts),
sizeof(AdGifData) * length);
}
void BspHeader::read_from_file(const decompiler::LinkedObjectFile& file,
const decompiler::DecompilerTypeSystem& dts,
GameVersion version,
@@ -2009,19 +2001,6 @@ void BspHeader::read_from_file(const decompiler::LinkedObjectFile& file,
bsphere.read_from_file(get_field_ref(ref, "bsphere", dts));
name = read_symbol_field(ref, "name", dts);
if (version == GameVersion::Jak1) {
adgifs.read_from_file(get_and_check_ref_to_basic(ref, "adgifs", "adgif-shader-array", dts),
dts);
}
texture_page_count = read_plain_data_field<s32>(ref, "texture-page-count", dts);
if (texture_page_count > 0) {
auto tex_id_ptr = deref_label(get_field_ref(ref, "texture-ids", dts));
for (int i = 0; i < texture_page_count; i++) {
texture_ids.push_back(deref_u32(tex_id_ptr, i));
}
}
texture_remap_table.clear();
s32 tex_remap_len = read_plain_data_field<s32>(ref, "texture-remap-table-len", dts);
if (tex_remap_len > 0) {
-9
View File
@@ -840,12 +840,6 @@ struct DrawableTreeArray {
std::vector<std::unique_ptr<DrawableTree>> trees;
};
struct AdgifShaderArray {
std::vector<AdGifData> adgifs;
void read_from_file(TypedRef ref, const decompiler::DecompilerTypeSystem& dts);
};
// The "file info"
struct FileInfo {
std::string file_type;
@@ -890,9 +884,7 @@ struct BspHeader {
u16 texture_flags[kNumTextureFlags]; // jak 2 only
//
// (texture-ids (pointer texture-id) :offset-assert 60)
std::vector<u32> texture_ids;
// (texture-page-count int32 :offset-assert 64)
s32 texture_page_count;
//
// (unk-zero-0 basic :offset-assert 68)
//
@@ -915,7 +907,6 @@ struct BspHeader {
// (unk-data-4 float :offset-assert 160)
// (unk-data-5 float :offset-assert 164)
// (adgifs adgif-shader-array :offset-assert 168)
AdgifShaderArray adgifs;
// (actor-birth-order (pointer uint32) :offset-assert 172)
// (split-box-indices (pointer uint16) :offset-assert 176)
// (unk-data-8 uint32 55 :offset-assert 180)
@@ -19,5 +19,4 @@ void extract_collide_frags(const level_tools::CollideHash& chash,
const decompiler::DecompilerTypeSystem& dts,
tfrag3::Level& out);
void set_vertices_for_tri(tfrag3::CollisionMesh::Vertex* out, const math::Vector4f* in);
} // namespace decompiler
+8 -10
View File
@@ -279,25 +279,20 @@ void extract_common(const ObjectFileDB& db,
extract_art_groups_from_level(db, tex_db, {}, "ARTSPOOL", tfrag_level, art_group_data);
std::set<std::string> textures_we_have;
std::set<u32> textures_we_have_id;
// put _all_ index textures in common.
for (const auto& [id, tex] : tex_db.index_textures_by_combo_id) {
tfrag_level.index_textures.push_back(tex);
}
// remember which textures we already added.
// textures with the same name or the same ID always have the same data.
for (const auto& t : tfrag_level.textures) {
textures_we_have.insert(t.debug_name);
textures_we_have_id.insert(t.combo_id);
}
// for common textures, add if the ID isn't there - common textures are looked up by ID.
for (const auto& [id, normal_texture] : tex_db.textures) {
if (config.common_tpages.count(normal_texture.page) && !textures_we_have_id.count(id)) {
if (config.common_tpages.count(normal_texture.page) &&
!textures_we_have.count(normal_texture.name)) {
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));
}
@@ -328,7 +323,8 @@ void extract_common(const ObjectFileDB& db,
if (config.rip_levels) {
auto file_path = file_util::get_jak_project_dir() / "glb_out" /
game_version_names[config.game_version] / "common";
game_version_names[config.game_version] / "common.glb";
file_util::create_dir_if_needed_for_file(file_path);
save_level_foreground_as_gltf(tfrag_level, art_group_data, file_path);
}
}
@@ -365,12 +361,14 @@ void extract_from_level(const ObjectFileDB& db,
if (config.rip_levels) {
auto back_file_path = file_util::get_jak_project_dir() / "glb_out" /
game_version_names[config.game_version] / level_data.level_name /
game_version_names[config.game_version] /
fmt::format("{}-background.glb", level_data.level_name);
file_util::create_dir_if_needed_for_file(back_file_path);
save_level_background_as_gltf(level_data, back_file_path);
auto fore_file_path = file_util::get_jak_project_dir() / "glb_out" /
game_version_names[config.game_version] / level_data.level_name;
game_version_names[config.game_version] /
fmt::format("{}-foreground.glb", level_data.level_name);
file_util::create_dir_if_needed_for_file(fore_file_path);
save_level_foreground_as_gltf(level_data, art_group_data, fore_file_path);
}
file_util::write_text_file(entities_folder / fmt::format("{}-actors.json", level_data.level_name),
@@ -26,7 +26,4 @@ tfrag3::Texture make_texture(u32 id,
bool pool_load);
std::vector<level_tools::TextureRemap> extract_tex_remap(const ObjectFileDB& db,
const std::string& dgo_name);
std::optional<ObjectFileRecord> get_bsp_file(const std::vector<ObjectFileRecord>& records,
const std::string& dgo_name);
bool is_valid_bsp(const LinkedObjectFile& file);
} // namespace decompiler
+2 -9
View File
@@ -853,19 +853,12 @@ ConvertedMercEffect convert_merc_effect(const MercEffect& input_effect,
u32 tidx = (env >> 8) & 0b1111'1111'1111;
tex_combo = (((u32)tpage) << 16) | tidx;
} break;
case GameVersion::Jak2: {
case GameVersion::Jak2:
case GameVersion::Jak3: {
u32 tpage = 0x1f;
u32 tidx = 2;
tex_combo = (((u32)tpage) << 16) | tidx;
} break;
case GameVersion::Jak3: {
// (define *generic-envmap-texture* (get-texture pal-environment-front environment-generic))
// (defconstant environment-generic 2) tpage
// (def-tex pal-environment-front environment-generic 1) texture
u32 tpage = 2;
u32 tidx = 1;
tex_combo = (((u32)tpage) << 16) | tidx;
} break;
default:
ASSERT_NOT_REACHED();
}
@@ -2032,20 +2032,6 @@ s32 find_or_add_texture_to_level(u32 combo_tex_id,
if (ok_to_miss) {
// we're missing a texture, just use the first one.
tex_it = tdb.textures.begin();
// some tfrags in jak 3 are missing textures, so we use some suitable
// replacements instead of the default eye texture
static std::map<std::string, std::string> per_level_tex_hacks = {
{"wasintro", "des-rock-01"},
{"intpfall", "common-black"},
{"powergd", "common-black"},
};
auto it = std::find_if(tdb.textures.begin(), tdb.textures.end(),
[&](const std::pair<u32, TextureDB::TextureData> val) {
return val.second.name == per_level_tex_hacks[level_name];
});
if (it != tdb.textures.end()) {
tex_it = it;
}
} else {
ASSERT_MSG(
false,
+10 -20
View File
@@ -2339,7 +2339,7 @@ TieCategoryInfo get_jak1_tie_category(u32 flags) {
return result;
}
s32 get_or_add_texture(u32 combo_tex, tfrag3::Level& lev, const TextureDB& tdb) {
u32 get_or_add_texture(u32 combo_tex, tfrag3::Level& lev, const TextureDB& tdb) {
if (combo_tex == 0) {
// untextured
combo_tex = (((u32)TextureDB::kPlaceholderWhiteTexturePage) << 16) |
@@ -2348,7 +2348,7 @@ s32 get_or_add_texture(u32 combo_tex, tfrag3::Level& lev, const TextureDB& tdb)
// try looking it up in the existing textures that we have in the C++ renderer data.
// (this is shared with tfrag)
s32 idx_in_lev_data = INT32_MAX;
u32 idx_in_lev_data = UINT32_MAX;
for (u32 i = 0; i < lev.textures.size(); i++) {
if (lev.textures[i].combo_id == combo_tex) {
idx_in_lev_data = i;
@@ -2356,7 +2356,7 @@ s32 get_or_add_texture(u32 combo_tex, tfrag3::Level& lev, const TextureDB& tdb)
}
}
if (idx_in_lev_data == INT32_MAX) {
if (idx_in_lev_data == UINT32_MAX) {
// didn't find it, have to add a new one texture.
auto tex_it = tdb.textures.find(combo_tex);
if (tex_it == tdb.textures.end()) {
@@ -2378,20 +2378,14 @@ s32 get_or_add_texture(u32 combo_tex, tfrag3::Level& lev, const TextureDB& tdb)
new_tex.debug_tpage_name = tdb.tpage_names.at(tex_it->second.page);
new_tex.data = tex_it->second.rgba_bytes;
}
const auto& level_tex = lev.textures.at(idx_in_lev_data);
const auto& it = tdb.animated_tex_output_to_anim_slot.find(level_tex.debug_name);
if (it != tdb.animated_tex_output_to_anim_slot.end()) {
// lg::warn("TIE animated texture: {}", level_tex.debug_name);
return -int(it->second) - 1;
}
return idx_in_lev_data;
}
void handle_wind_draw_for_strip(
tfrag3::TieTree& tree,
std::unordered_map<s32, std::vector<u32>>& wind_draws_by_tex,
std::unordered_map<u32, std::vector<u32>>& wind_draws_by_tex,
const std::vector<std::vector<std::pair<int, int>>>& packed_vert_indices,
s32 idx_in_lev_data,
u32 idx_in_lev_data,
DrawMode mode,
const TieStrip& strip,
const TieInstanceInfo& inst,
@@ -2458,7 +2452,7 @@ void handle_wind_draw_for_strip(
}
void handle_draw_for_strip(tfrag3::TieTree& tree,
std::unordered_map<s32, std::vector<u32>>& static_draws_by_tex,
std::unordered_map<u32, std::vector<u32>>& static_draws_by_tex,
std::vector<tfrag3::StripDraw>& category_draws,
const std::vector<std::vector<std::pair<int, int>>>& packed_vert_indices,
DrawMode mode,
@@ -2548,8 +2542,8 @@ void add_vertices_and_static_draw(tfrag3::TieTree& tree,
GameVersion version) {
// our current approach for static draws is just to flatten to giant mesh, except for wind stuff.
// this map sorts these two types of draws by texture.
std::unordered_map<s32, std::vector<u32>> static_draws_by_tex;
std::unordered_map<s32, std::vector<u32>> wind_draws_by_tex;
std::unordered_map<u32, std::vector<u32>> static_draws_by_tex;
std::unordered_map<u32, std::vector<u32>> wind_draws_by_tex;
std::array<std::vector<tfrag3::StripDraw>, tfrag3::kNumTieCategories> draws_by_category;
@@ -2638,7 +2632,7 @@ void add_vertices_and_static_draw(tfrag3::TieTree& tree,
for (size_t strip_idx = 0; strip_idx < frag.strips.size(); strip_idx++) {
auto& strip = frag.strips[strip_idx];
s32 idx_in_lev_data = get_or_add_texture(strip.adgif.combo_tex, lev, tdb);
u32 idx_in_lev_data = get_or_add_texture(strip.adgif.combo_tex, lev, tdb);
// determine the draw mode
DrawMode mode = process_draw_mode(strip.adgif, frag.prog_info.misc_x == 0,
frag.has_magic_tex0_bit, version, info.category);
@@ -2655,7 +2649,7 @@ void add_vertices_and_static_draw(tfrag3::TieTree& tree,
draws_by_category.at((int)info.category), packed_vert_indices,
mode, idx_in_lev_data, strip, inst, ifrag, proto_idx, frag_idx,
strip_idx, matrix_idx);
s32 envmap_tex_idx =
u32 envmap_tex_idx =
get_or_add_texture(proto.envmap_adgif.value().combo_tex, lev, tdb);
// second pass envmap draw mode, in envmap bucket, envmap-specific draw list
@@ -2753,10 +2747,6 @@ void extract_tie(const level_tools::DrawableTreeInstanceTie* tree,
bool dump_level,
GameVersion version) {
for (int geo = 0; geo < GEOM_MAX; ++geo) {
// as far as I can tell, this one has bad colors
if (debug_name == "PRECD.DGO-2-tie" && geo == 3) {
continue;
}
tfrag3::TieTree this_tree;
// sanity check the vis tree (not a perfect check, but this is used in game and should be right)
+118 -121
View File
@@ -93,33 +93,36 @@ void unstrip_tie_wind(std::vector<u32>& unstripped,
}
/*!
* Convert merc strips. Doesn't assume anything about strips. Output is [effect][draw] format (done
* for each model)
* Convert merc strips. Doesn't assume anything about strips. Output is [model][effect][draw] format
*/
void unstrip_merc_draws(const std::vector<u32>& stripped_indices,
const tfrag3::MercModel& model,
const std::vector<tfrag3::MercModel>& models,
std::vector<u32>& unstripped,
std::vector<std::vector<u32>>& draw_to_start,
std::vector<std::vector<u32>>& draw_to_count) {
for (auto& effect : model.effects) {
auto& effect_dts = draw_to_start.emplace_back();
auto& effect_dtc = draw_to_count.emplace_back();
for (auto& draw : effect.all_draws) {
effect_dts.push_back(unstripped.size());
std::vector<std::vector<std::vector<u32>>>& draw_to_start,
std::vector<std::vector<std::vector<u32>>>& draw_to_count) {
for (auto& model : models) {
auto& model_dts = draw_to_start.emplace_back();
auto& model_dtc = draw_to_count.emplace_back();
for (auto& effect : model.effects) {
auto& effect_dts = model_dts.emplace_back();
auto& effect_dtc = model_dtc.emplace_back();
for (auto& draw : effect.all_draws) {
effect_dts.push_back(unstripped.size());
for (size_t i = 2; i < draw.index_count; i++) {
int idx = i + draw.first_index;
u32 a = stripped_indices[idx];
u32 b = stripped_indices[idx - 1];
u32 c = stripped_indices[idx - 2];
if (a == UINT32_MAX || b == UINT32_MAX || c == UINT32_MAX) {
continue;
for (size_t i = 2; i < draw.index_count; i++) {
int idx = i + draw.first_index;
u32 a = stripped_indices[idx];
u32 b = stripped_indices[idx - 1];
u32 c = stripped_indices[idx - 2];
if (a == UINT32_MAX || b == UINT32_MAX || c == UINT32_MAX) {
continue;
}
unstripped.push_back(a);
unstripped.push_back(b);
unstripped.push_back(c);
}
unstripped.push_back(a);
unstripped.push_back(b);
unstripped.push_back(c);
effect_dtc.push_back(unstripped.size() - effect_dts.back());
}
effect_dtc.push_back(unstripped.size() - effect_dts.back());
}
}
}
@@ -482,12 +485,12 @@ int make_shrub_index_buffer_view(const std::vector<u32>& indices,
}
int make_merc_index_buffer_view(const std::vector<u32>& indices,
const tfrag3::MercModel& mmodel,
const std::vector<tfrag3::MercModel>& models,
tinygltf::Model& model,
std::vector<std::vector<u32>>& draw_to_start,
std::vector<std::vector<u32>>& draw_to_count) {
std::vector<std::vector<std::vector<u32>>>& draw_to_start,
std::vector<std::vector<std::vector<u32>>>& draw_to_count) {
std::vector<u32> unstripped;
unstrip_merc_draws(indices, mmodel, unstripped, draw_to_start, draw_to_count);
unstrip_merc_draws(indices, models, unstripped, draw_to_start, draw_to_count);
// first create a buffer:
int buffer_idx = (int)model.buffers.size();
@@ -881,7 +884,6 @@ int make_inv_matrix_bind_poses(const std::vector<level_tools::Joint>& joints,
void add_merc(const tfrag3::Level& level,
const std::map<std::string, level_tools::ArtData>& art_data,
const tfrag3::MercModel& mmodel,
tinygltf::Model& model,
std::unordered_map<int, int>& tex_image_map) {
const auto& mverts = level.merc_data.vertices;
@@ -890,88 +892,91 @@ void add_merc(const tfrag3::Level& level,
int position_buffer_accessor = make_position_buffer_accessor(mverts, model);
int texture_buffer_accessor = make_tex_buffer_accessor(mverts, model, 1.f);
std::vector<std::vector<u32>> draw_to_start, draw_to_count;
int index_buffer_view = make_merc_index_buffer_view(level.merc_data.indices, mmodel, model,
draw_to_start, draw_to_count);
std::vector<std::vector<std::vector<u32>>> draw_to_start, draw_to_count;
int index_buffer_view = make_merc_index_buffer_view(
level.merc_data.indices, level.merc_data.models, model, draw_to_start, draw_to_count);
int colors = make_color_buffer_accessor(mverts, model);
auto joints_accessor = make_bones_accessor(mverts, model);
auto weights_accessor = make_weights_accessor(mverts, model);
const auto& art = art_data.find(mmodel.name);
int node_idx = (int)model.nodes.size();
auto& node = model.nodes.emplace_back();
model.scenes.at(0).nodes.push_back(node_idx);
node.name = mmodel.name;
int mesh_idx = (int)model.meshes.size();
auto& mesh = model.meshes.emplace_back();
mesh.name = node.name;
node.mesh = mesh_idx;
for (size_t model_idx = 0; model_idx < level.merc_data.models.size(); model_idx++) {
const auto& mmodel = level.merc_data.models[model_idx];
const auto& art = art_data.find(mmodel.name);
int node_idx = (int)model.nodes.size();
auto& node = model.nodes.emplace_back();
model.scenes.at(0).nodes.push_back(node_idx);
node.name = mmodel.name;
int mesh_idx = (int)model.meshes.size();
auto& mesh = model.meshes.emplace_back();
mesh.name = node.name;
node.mesh = mesh_idx;
if (art != art_data.end() && !art->second.joint_group.empty()) {
node.skin = model.skins.size();
auto& skin = model.skins.emplace_back();
const auto& game_bones = art->second.joint_group;
int n_bones = game_bones.size();
std::vector<std::vector<int>> children(n_bones);
for (size_t i = 0; i < game_bones.size(); i++) {
if (game_bones[i].parent_idx >= 0) {
children.at(game_bones[i].parent_idx).push_back(i);
if (art != art_data.end() && !art->second.joint_group.empty()) {
node.skin = model.skins.size();
auto& skin = model.skins.emplace_back();
const auto& game_bones = art->second.joint_group;
int n_bones = game_bones.size();
std::vector<std::vector<int>> children(n_bones);
for (size_t i = 0; i < game_bones.size(); i++) {
if (game_bones[i].parent_idx >= 0) {
children.at(game_bones[i].parent_idx).push_back(i);
}
}
}
skin.skeleton = model.nodes.size();
for (int i = 0; i < n_bones; i++) {
const auto& gbone = game_bones[i];
skin.joints.push_back(skin.skeleton + i);
auto& snode = model.nodes.emplace_back();
snode.name = gbone.name;
skin.skeleton = model.nodes.size();
for (int i = 0; i < n_bones; i++) {
const auto& gbone = game_bones[i];
skin.joints.push_back(skin.skeleton + i);
auto& snode = model.nodes.emplace_back();
snode.name = gbone.name;
// bind pose is bind_T_w
// for glb we want bind_parent_T_bind_child
// so bindp_T_w * inverse(bindc_T_w)
math::Matrix4f matrix;
if (gbone.parent_idx >= 0) {
matrix = unscale_translation(game_bones.at(gbone.parent_idx).bind_pose_T_w) *
inverse(unscale_translation(gbone.bind_pose_T_w));
// bind pose is bind_T_w
// for glb we want bind_parent_T_bind_child
// so bindp_T_w * inverse(bindc_T_w)
math::Matrix4f matrix;
if (gbone.parent_idx >= 0) {
matrix = unscale_translation(game_bones.at(gbone.parent_idx).bind_pose_T_w) *
inverse(unscale_translation(gbone.bind_pose_T_w));
} else {
// I think this value is ignored anyway.
for (int r = 0; r < 4; r++) {
for (int c = 0; c < 4; c++) {
matrix(r, c) = (r == c) ? 1 : 0;
} else {
// I think this value is ignored anyway.
for (int r = 0; r < 4; r++) {
for (int c = 0; c < 4; c++) {
matrix(r, c) = (r == c) ? 1 : 0;
}
}
}
}
for (int r = 0; r < 4; r++) {
for (int c = 0; c < 4; c++) {
snode.matrix.push_back(matrix(c, r));
for (int r = 0; r < 4; r++) {
for (int c = 0; c < 4; c++) {
snode.matrix.push_back(matrix(c, r));
}
}
for (auto child : children.at(i)) {
snode.children.push_back(skin.skeleton + child);
}
}
for (auto child : children.at(i)) {
snode.children.push_back(skin.skeleton + child);
}
ASSERT(skin.skeleton + n_bones == (int)model.nodes.size());
skin.inverseBindMatrices = make_inv_matrix_bind_poses(game_bones, model);
}
ASSERT(skin.skeleton + n_bones == (int)model.nodes.size());
skin.inverseBindMatrices = make_inv_matrix_bind_poses(game_bones, model);
}
for (size_t effect_idx = 0; effect_idx < mmodel.effects.size(); effect_idx++) {
const auto& effect = mmodel.effects[effect_idx];
for (size_t draw_idx = 0; draw_idx < effect.all_draws.size(); draw_idx++) {
const auto& draw = effect.all_draws[draw_idx];
auto& prim = mesh.primitives.emplace_back();
prim.material =
add_material_for_tex(level, model, draw.tree_tex_id, tex_image_map, draw.mode);
prim.indices =
make_index_buffer_accessor(model, draw_to_start[effect_idx][draw_idx],
draw_to_count[effect_idx][draw_idx], index_buffer_view);
prim.attributes["POSITION"] = position_buffer_accessor;
prim.attributes["TEXCOORD_0"] = texture_buffer_accessor;
prim.attributes["COLOR_0"] = colors;
prim.attributes["JOINTS_0"] = joints_accessor;
prim.attributes["WEIGHTS_0"] = weights_accessor;
prim.mode = TINYGLTF_MODE_TRIANGLES;
for (size_t effect_idx = 0; effect_idx < mmodel.effects.size(); effect_idx++) {
const auto& effect = mmodel.effects[effect_idx];
for (size_t draw_idx = 0; draw_idx < effect.all_draws.size(); draw_idx++) {
const auto& draw = effect.all_draws[draw_idx];
auto& prim = mesh.primitives.emplace_back();
prim.material =
add_material_for_tex(level, model, draw.tree_tex_id, tex_image_map, draw.mode);
prim.indices = make_index_buffer_accessor(
model, draw_to_start[model_idx][effect_idx][draw_idx],
draw_to_count[model_idx][effect_idx][draw_idx], index_buffer_view);
prim.attributes["POSITION"] = position_buffer_accessor;
prim.attributes["TEXCOORD_0"] = texture_buffer_accessor;
prim.attributes["COLOR_0"] = colors;
prim.attributes["JOINTS_0"] = joints_accessor;
prim.attributes["WEIGHTS_0"] = weights_accessor;
prim.mode = TINYGLTF_MODE_TRIANGLES;
}
}
}
}
@@ -1021,38 +1026,30 @@ void save_level_background_as_gltf(const tfrag3::Level& level, const fs::path& g
void save_level_foreground_as_gltf(const tfrag3::Level& level,
const std::map<std::string, level_tools::ArtData>& art_data,
const fs::path& glb_path) {
for (size_t model_idx = 0; model_idx < level.merc_data.models.size(); model_idx++) {
const auto& mmodel = level.merc_data.models[model_idx];
const fs::path& glb_file) {
// the top level container for everything is the model.
tinygltf::Model model;
// the top level container for everything is the model.
tinygltf::Model model;
// a "scene" is a traditional scene graph, made up of Nodes.
// sadly, attempting to nest stuff makes the blender importer unhappy, so we just dump
// everything into the top level.
model.scenes.emplace_back();
// a "scene" is a traditional scene graph, made up of Nodes.
// sadly, attempting to nest stuff makes the blender importer unhappy, so we just dump
// everything into the top level.
model.scenes.emplace_back();
// hack, add a default material.
tinygltf::Material mat;
mat.pbrMetallicRoughness.baseColorFactor = {1.0f, 0.9f, 0.9f, 1.0f};
mat.doubleSided = true;
model.materials.push_back(mat);
// hack, add a default material.
tinygltf::Material mat;
mat.pbrMetallicRoughness.baseColorFactor = {1.0f, 0.9f, 0.9f, 1.0f};
mat.doubleSided = true;
model.materials.push_back(mat);
std::unordered_map<int, int> tex_image_map;
std::unordered_map<int, int> tex_image_map;
add_merc(level, art_data, model, tex_image_map);
add_merc(level, art_data, mmodel, model, tex_image_map);
model.asset.generator = "opengoal";
auto glb_file = glb_path / fmt::format("{}.glb", mmodel.name);
file_util::create_dir_if_needed_for_file(glb_file);
tinygltf::TinyGLTF gltf;
gltf.WriteGltfSceneToFile(&model, glb_file.string(),
true, // embedImages
true, // embedBuffers
true, // pretty print
true); // write binary
}
model.asset.generator = "opengoal";
tinygltf::TinyGLTF gltf;
gltf.WriteGltfSceneToFile(&model, glb_file.string(),
true, // embedImages
true, // embedBuffers
true, // pretty print
true); // write binary
}
+1 -1
View File
@@ -13,4 +13,4 @@
void save_level_background_as_gltf(const tfrag3::Level& level, const fs::path& glb_file);
void save_level_foreground_as_gltf(const tfrag3::Level& level,
const std::map<std::string, level_tools::ArtData>& art_data,
const fs::path& glb_path);
const fs::path& glb_file);
+36 -139
View File
@@ -3,25 +3,18 @@
using namespace gltf_util;
namespace decompiler {
bool material_has_envmap(const tinygltf::Material& mat) {
return mat.extensions.contains("KHR_materials_specular");
}
void extract(const std::string& name,
MercExtractData& out,
const tinygltf::Model& model,
const std::vector<NodeWithTransform>& all_nodes,
u32 index_offset,
u32 vertex_offset,
u32 tex_offset,
bool& has_custom_weights) {
u32 tex_offset) {
ASSERT(out.new_vertices.empty());
std::map<int, tfrag3::MercDraw> draw_by_material;
int mesh_count = 0;
int prim_count = 0;
bool has_envmaps = false;
for (const auto& n : all_nodes) {
const auto& node = model.nodes[n.node_idx];
@@ -31,8 +24,6 @@ void extract(const std::string& name,
if (node.mesh >= 0) {
const auto& mesh = model.meshes[node.mesh];
mesh_count++;
has_custom_weights = node.extras.Has("enable_custom_weights") &&
node.extras.Get("enable_custom_weights").Get<int>();
for (const auto& prim : mesh.primitives) {
prim_count++;
// extract index buffer
@@ -48,21 +39,6 @@ void extract(const std::string& name,
out.normals.insert(out.normals.end(), verts.normals.begin(), verts.normals.end());
ASSERT(out.new_colors.size() == out.new_vertices.size());
if (prim.attributes.count("JOINTS_0") && prim.attributes.count("WEIGHTS_0")) {
auto joints_and_weights = gltf_util::extract_and_flatten_joints_and_weights(model, prim);
ASSERT(joints_and_weights.size() == verts.vtx.size());
out.joints_and_weights.insert(out.joints_and_weights.end(), joints_and_weights.begin(),
joints_and_weights.end());
} else {
// add fake data for vertices without this data
gltf_util::JointsAndWeights dummy;
dummy.joints[0] = 3;
dummy.weights[0] = 1.f;
for (size_t i = 0; i < out.new_vertices.size(); i++) {
out.joints_and_weights.push_back(dummy);
}
}
// TODO: just putting it all in one material
auto& draw = draw_by_material[prim.material];
draw.mode = gltf_util::make_default_draw_mode(); // todo rm
@@ -78,108 +54,41 @@ void extract(const std::string& name,
}
tfrag3::MercEffect e;
tfrag3::MercEffect envmap_eff;
out.new_model.name = name;
out.new_model.max_bones = 100; // idk
out.new_model.max_bones = 120;
out.new_model.max_draws = 200;
auto process_normal_draw = [&](tfrag3::MercEffect& eff, int mat_idx, const tfrag3::MercDraw& d_) {
const auto& mat = model.materials[mat_idx];
eff.all_draws.push_back(d_);
auto& draw = eff.all_draws.back();
draw.mode = gltf_util::make_default_draw_mode();
for (const auto& [mat_idx, d_] : draw_by_material) {
e.all_draws.push_back(d_);
auto& draw = e.all_draws.back();
draw.mode = make_default_draw_mode();
if (mat_idx == -1) {
lg::warn("Draw had a material index of -1, using default texture.");
draw.tree_tex_id = 0;
return;
continue;
}
const auto& mat = model.materials[mat_idx];
int tex_idx = mat.pbrMetallicRoughness.baseColorTexture.index;
if (tex_idx == -1) {
lg::warn("Material {} has no texture, using default texture.", mat.name);
draw.tree_tex_id = 0;
return;
continue;
}
const auto& tex = model.textures[tex_idx];
ASSERT(tex.sampler >= 0);
ASSERT(tex.source >= 0);
gltf_util::setup_draw_mode_from_sampler(model.samplers.at(tex.sampler), &draw.mode);
gltf_util::setup_alpha_from_material(mat, &draw.mode);
draw.mode = draw_mode_from_sampler(model.samplers.at(tex.sampler));
const auto& img = model.images[tex.source];
draw.tree_tex_id = tex_offset + texture_pool_add_texture(&out.tex_pool, img);
};
auto process_envmap_draw = [&](tfrag3::MercEffect& eff, int mat_idx, const tfrag3::MercDraw& d_) {
const auto& mat = model.materials[mat_idx];
eff.all_draws.push_back(d_);
auto& draw = eff.all_draws.back();
draw.mode = gltf_util::make_default_draw_mode();
if (mat_idx == -1) {
lg::warn("Envmap draw had a material index of -1, using default texture.");
draw.tree_tex_id = texture_pool_debug_checker(&out.tex_pool);
return;
}
int base_tex_idx = mat.pbrMetallicRoughness.baseColorTexture.index;
if (base_tex_idx == -1) {
lg::warn("Envmap material {} has no texture, using default texture.", mat.name);
draw.tree_tex_id = texture_pool_debug_checker(&out.tex_pool);
return;
}
int roughness_tex_idx = mat.pbrMetallicRoughness.metallicRoughnessTexture.index;
ASSERT(roughness_tex_idx >= 0);
const auto& base_tex = model.textures[base_tex_idx];
ASSERT(base_tex.sampler >= 0);
ASSERT(base_tex.source >= 0);
gltf_util::setup_draw_mode_from_sampler(model.samplers.at(base_tex.sampler), &draw.mode);
gltf_util::setup_alpha_from_material(mat, &draw.mode);
const auto& roughness_tex = model.textures.at(roughness_tex_idx);
ASSERT(roughness_tex.sampler >= 0);
ASSERT(roughness_tex.source >= 0);
draw.tree_tex_id =
tex_offset + gltf_util::texture_pool_add_envmap_control_texture(
&out.tex_pool, model, base_tex.source, roughness_tex.source,
!draw.mode.get_clamp_s_enable(), !draw.mode.get_clamp_t_enable());
// now, setup envmap draw:
auto envmap_settings = gltf_util::envmap_settings_from_gltf(mat);
const auto& envmap_tex = model.textures[envmap_settings.texture_idx];
ASSERT(envmap_tex.sampler >= 0);
ASSERT(envmap_tex.source >= 0);
auto env_mode = gltf_util::make_default_draw_mode();
gltf_util::setup_draw_mode_from_sampler(model.samplers.at(envmap_tex.sampler), &env_mode);
eff.envmap_texture = tex_offset + gltf_util::texture_pool_add_texture(
&out.tex_pool, model.images[envmap_tex.source]);
env_mode.set_alpha_blend(DrawMode::AlphaBlend::SRC_0_DST_DST);
env_mode.enable_ab();
eff.envmap_mode = env_mode;
};
for (const auto& [mat_idx, d_] : draw_by_material) {
const auto& mat = model.materials[mat_idx];
if (!material_has_envmap(mat)) {
process_normal_draw(e, mat_idx, d_);
} else {
has_envmaps = true;
envmap_eff.has_envmap = true;
process_envmap_draw(envmap_eff, mat_idx, d_);
}
}
lg::info("total of {} unique materials ({} normal, {} envmap)",
e.all_draws.size() + envmap_eff.all_draws.size(), e.all_draws.size(),
envmap_eff.all_draws.size());
// in case a model only has envmap draws, we don't push the normal merc effect
if (!e.all_draws.empty()) {
out.new_model.effects.push_back(e);
}
if (has_envmaps) {
out.new_model.effects.push_back(envmap_eff);
}
lg::info("total of {} unique materials", e.all_draws.size());
e.has_mod_draw = false;
out.new_model.effects.push_back(e);
out.new_model.effects.push_back(e);
out.new_model.effects.push_back(e);
out.new_model.effects.push_back(e);
lg::info("Merged {} meshes and {} prims into {} vertices", mesh_count, prim_count,
out.new_vertices.size());
@@ -190,9 +99,9 @@ const tfrag3::MercVertex& find_closest(const std::vector<tfrag3::MercVertex>& ol
float y,
float z) {
float best_dist = 1e10;
size_t best_idx = 0;
int best_idx = 0;
for (size_t i = 0; i < old.size(); i++) {
for (int i = 0; i < old.size(); i++) {
auto& v = old[i];
float dx = v.pos[0] - x;
float dy = v.pos[1] - y;
@@ -209,8 +118,7 @@ const tfrag3::MercVertex& find_closest(const std::vector<tfrag3::MercVertex>& ol
void merc_convert_replacement(MercSwapData& out,
const MercExtractData& in,
const std::vector<tfrag3::MercVertex>& old_verts,
bool use_custom_weights) {
const std::vector<tfrag3::MercVertex>& old_verts) {
out.new_model = in.new_model;
out.new_indices = in.new_indices;
out.new_textures = in.tex_pool.textures_by_idx;
@@ -218,36 +126,26 @@ void merc_convert_replacement(MercSwapData& out,
// convert vertices
for (size_t i = 0; i < in.new_vertices.size(); i++) {
const auto& y = in.new_vertices[i];
const auto& copy_from = find_closest(old_verts, y.x, y.y, y.z);
auto& x = out.new_vertices.emplace_back();
x.pos[0] = y.x;
x.pos[1] = y.y;
x.pos[2] = y.z;
x.normal[0] = in.normals.at(i).x();
x.normal[1] = in.normals.at(i).y();
x.normal[2] = in.normals.at(i).z();
if (use_custom_weights) {
x.weights[0] = in.joints_and_weights.at(i).weights[0];
x.weights[1] = in.joints_and_weights.at(i).weights[1];
x.weights[2] = in.joints_and_weights.at(i).weights[2];
x.mats[0] = in.joints_and_weights.at(i).joints[0];
x.mats[1] = in.joints_and_weights.at(i).joints[1];
x.mats[2] = in.joints_and_weights.at(i).joints[2];
} else {
x.weights[0] = copy_from.weights[0];
x.weights[1] = copy_from.weights[1];
x.weights[2] = copy_from.weights[2];
x.mats[0] = copy_from.mats[0];
x.mats[1] = copy_from.mats[1];
x.mats[2] = copy_from.mats[2];
}
x.normal[0] = copy_from.normal[0];
x.normal[1] = copy_from.normal[1];
x.normal[2] = copy_from.normal[2];
x.weights[0] = copy_from.weights[0];
x.weights[1] = copy_from.weights[1];
x.weights[2] = copy_from.weights[2];
x.st[0] = y.s;
x.st[1] = y.t;
x.rgba[0] = in.new_colors[i][0];
x.rgba[1] = in.new_colors[i][1];
x.rgba[2] = in.new_colors[i][2];
x.rgba[3] = in.new_colors[i][3];
x.mats[0] = copy_from.mats[0];
x.mats[1] = copy_from.mats[1];
x.mats[2] = copy_from.mats[2];
}
}
@@ -266,18 +164,18 @@ void merc_convert_custom(MercSwapData& out, const MercExtractData& in) {
x.normal[0] = in.normals.at(i).x();
x.normal[1] = in.normals.at(i).y();
x.normal[2] = in.normals.at(i).z();
x.weights[0] = in.joints_and_weights.at(i).weights[0];
x.weights[1] = in.joints_and_weights.at(i).weights[1];
x.weights[2] = in.joints_and_weights.at(i).weights[2];
x.weights[0] = 1.0f;
x.weights[1] = 0.0f;
x.weights[2] = 0.0f;
x.st[0] = y.s;
x.st[1] = y.t;
x.rgba[0] = in.new_colors[i][0];
x.rgba[1] = in.new_colors[i][1];
x.rgba[2] = in.new_colors[i][2];
x.rgba[3] = in.new_colors[i][3];
x.mats[0] = in.joints_and_weights.at(i).joints[0];
x.mats[1] = in.joints_and_weights.at(i).joints[1];
x.mats[2] = in.joints_and_weights.at(i).joints[2];
x.mats[0] = 3;
x.mats[1] = 0;
x.mats[2] = 0;
}
}
@@ -300,13 +198,12 @@ MercSwapData load_replacement_merc_model(const std::string& name,
auto all_nodes = flatten_nodes_from_all_scenes(model);
MercExtractData extract_data;
auto has_custom_weights = false;
extract(name, extract_data, model, all_nodes, current_idx_count, current_vtx_count,
current_tex_count, has_custom_weights);
current_tex_count);
if (custom_mdl) {
merc_convert_custom(result, extract_data);
} else {
merc_convert_replacement(result, extract_data, old_verts, has_custom_weights);
merc_convert_replacement(result, extract_data, old_verts);
}
return result;
@@ -10,7 +10,7 @@ struct MercExtractData {
std::vector<tfrag3::PreloadedVertex> new_vertices;
std::vector<math::Vector<u8, 4>> new_colors;
std::vector<math::Vector3f> normals;
std::vector<gltf_util::JointsAndWeights> joints_and_weights;
tfrag3::MercModel new_model;
};
+2 -2
View File
@@ -2,7 +2,7 @@ FROM ubuntu:20.04
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update
RUN apt-get install -y gcc make cmake build-essential g++ nasm clang-format libxrandr-dev libxinerama-dev libxcursor-dev libpulse-dev libxi-dev python lld clang curl libssl-dev libstdc++-10-dev
RUN apt-get install -y gcc make cmake build-essential g++ nasm clang-format libxrandr-dev libxinerama-dev libxcursor-dev libpulse-dev libxi-dev python lld clang curl
RUN sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b /usr/local/bin
@@ -21,4 +21,4 @@ WORKDIR /home/$user/jak-project/build
RUN cmake -DCMAKE_SHARED_LINKER_FLAGS="-fuse-ld=lld" -DCMAKE_EXE_LINKER_FLAGS="-fuse-ld=lld" -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ ..
WORKDIR /home/$user/jak-project
RUN cmake -B build && cmake --build build -j 8
RUN cmake -B build && cmake --build build -j 8
-3
View File
@@ -322,6 +322,3 @@ endif()
add_executable(gk main.cpp)
target_link_libraries(gk runtime)
if(WIN32)
set_target_properties(gk PROPERTIES VS_DPI_AWARE "PerMonitor")
endif()
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

File diff suppressed because it is too large. Load diff
@@ -6,7 +6,7 @@
"TOT HET 500 GRADEN BEREIKT, DUS PROBEER HAAR KOEL TE HOUDEN.",
"VLIEGEN OVER OPEN LAVA ZAL JE ZEKER SNEL OPWARMEN.",
"ALS HET 500 GRADEN WORDT, IS HET VOORBIJ.",
"VOORBIJ?! ALS IN BRANDEND GESMOLTEN METAAL VOORBIJ?!",
"OVER?! ALS IN BRANDEND GESMOLTEN METAAL OVER?!",
"DE VUURVALLEI WORDT BEHOORLIJK HEET, DUS KIJK UIT VOOR SCHANSEN",
"OM JE VAN DE HETE GROND TE HOUDEN.",
"IK HEB OOK EEN AANTAL BLAUWE KOELBALLONNEN UITGEBRACHT DIE JE KUNT GEBRUIKEN OM",
@@ -1164,7 +1164,7 @@
"OVER DAAR!"
],
"BIL-TA04": [
"AW, PRUTS."
"AW, DANG."
],
"BIL-TA05": [
"RAT HEEFT EEN SNACK."
@@ -1191,7 +1191,7 @@
"OVER DAAR."
],
"BIL-TA4A": [
"VERDOMME!"
"DANG!"
],
"BIL-TA4B": [
"VERDOMME!"
@@ -1748,7 +1748,7 @@
"(SNIKKEN)"
],
"WAR-LO1B": [
"(JANKT)"
"(SOBS)"
],
"WAR-LO1C": [
"(BLAAST NEUS EN SPUTTERT)",
@@ -46,7 +46,7 @@
"VISMÄNNEN HAR BLIVIT KIDNAPPADE,",
"GOL OCH MAIA HAR SAMLAT IHOP TILLRÄCKLIGT MED ECO",
"FÖR ATT KUNNA GENOMFÖRA SIN HEMSKA PLAN,",
"OCH FÖR ATT KUNNA STOPPA DOM, SÅ MÅSTE NI",
"OCH FÖR ATT KUNNA STOPPA DEM, SÅ MÅSTE NI",
"SLÅ ER FRAM HELA VÄGEN GENOM DERAS CITADELL!",
"EH... JA. SÅ KAN MAN, EH... NOG SAMMANFATTA DET HELA.",
"NI MÅSTE RÄDDA MIN FAR INNAN DET ÄR FÖR SENT!",
@@ -323,7 +323,7 @@
],
"explorer-resolution": [
"JAG SER ATT NI TVÅ ÄR TILLBAKA FÖR ATT GENOMFÖRA BYTET. BRA, BRA, MYCKET BRA!",
"ÄH, NI HAR MED ER ÖH, DOM PRECURSOR-KULOR VI KOM ÖVERENS OM?",
"ÄH, DU HAR MED DIG ÖH, DOM PRECURSOR-KULOR VI KOM ÖVERENS OM?",
"JAG HOPPAS ATT DU FÅR ANVÄNDNING AV DEN HÄR SURT FÖRVÄRVADE KRAFTCELLEN.",
"TACK SÅ MYCKET, GODDAG, ADJÖ!"
],
@@ -2242,7 +2242,7 @@
],
"sksp0079": [
"AH! JAG KOMMER ATT DÖ! JAG KOMMER, FARFAR!",
"NI MÅSTE FÅ DEN HÄR SAKEN ÖVER TILL ANDRA SIDAN INNAN DEN BLIR ÖVERHETTAD!"
"DU MÅSTE FÅ DEN HÄR SAKEN ÖVER TILL ANDRA SIDAN INNAN DEN BLIR ÖVERHETTAD!"
],
"sksp0080": [
"ANVÄND KURVAN FÖR ATT KUNNA STYRA BÄTTRE!"
File diff suppressed because it is too large. Load diff
+38 -38
View File
@@ -6,16 +6,16 @@
"0107": "HALUATKO PELATA UUDELLEEN?",
"0108": "LOPETA",
"0109": "TAUKO",
"010a": "ÄÄNITEHOSTEET",
"010b": "MUSIIKKI",
"010c": "PUHE",
"010a": "EFEKTIEN VOIMAKKUUS",
"010b": "MUSIIKIN VOIMAKKUUS",
"010c": "PUHEEN VOIMAKKUUS",
"010d": "KIELI",
"010e": "VÄRINÄTOIMINTO",
"010e": "VÄRÄHTELYT",
"010f": "VINKIT",
"0110": "KESKITÄ RUUTU",
"0111": "PÄÄLLÄ",
"0112": "POIS",
"0113": "KÄYTÄ SUUNTANÄPPÄIMIÄ",
"0113": "KÄYTÄ D-PAD:IA",
"0114": "ENGLISH",
"0115": "FRANÇAIS",
"0116": "DEUTSCH",
@@ -24,36 +24,36 @@
"0119": "にほんご",
"011a": "PAINA <PAD_CIRCLE> VAIHTAAKSESI 90 HELMEÄ VOIMAKENNOON.",
"011b": "PAINA <PAD_CIRCLE> VAIHTAAKSESI 120 HELMEÄ VOIMAKENNOON.",
"011c": "MATKUSTA PAINAMALLA <PAD_CIRCLE>.",
"011d": "PERU PAINAMALLA <PAD_TRIANGLE>.",
"011c": "PAINA <PAD_CIRCLE> MENNÄKSESI.",
"011d": "PAINA <PAD_TRIANGLE> PERUAKSESI.",
"011e": "GEYSIRSAARI",
"011f": "VIHREÄN TIETÄJÄN MÖKKI",
"0120": "SINISEN TIETÄJÄN MÖKKI",
"0121": "PUNAISEN TIETÄJÄN MÖKKI",
"0122": "GOLIN AND MAIAN LINNOITUS",
"0123": "PAINA <PAD_CIRCLE> PUHUAKSESI SAMOSILLE.",
"0124": "PAINA <PAD_CIRCLE> PUHUAKSESI KEIRALLE.",
"0123": "PAINA <PAD_CIRCLE> PUHUAKSESI SAMOSILLE",
"0124": "PAINA <PAD_CIRCLE> PUHUAKSESI KEIRALLE",
"0125": "KUVASUHDE",
"0126": "VIDEOTILA",
"0126": "VIDEON TILA",
"0127": "PELIASETUKSET",
"0128": "GRAFIIKKA-ASETUKSET",
"0129": "ÄÄNIASETUKSET",
"012a": "4X3",
"012b": "16X9",
"012c": "60 HZ",
"012d": "50 HZ",
"012c": "60HZ",
"012d": "50HZ",
"012e": "JAK AND DAXTER",
"012f": "LÖYDÄ KÄTKETTY VOIMAKENNO",
"0130": "EI TARPEEKSI TILAA MUISTIKORTILLA MEMORY_CARD_(PS2) PAIKASSA MEMORY_CARD_SLOT_~D",
"0131": "EI MEMORY_CARD_(PS2) LIITETTYNÄ PAIKASSA MEMORY_CARD_SLOT_~D",
"0132": "MEMORY_CARD_(PS2) PAIKASSA MEMORY_CARD_SLOT_~D ON ALUSTAMATON",
"0133": "JAK AND DAXTER VAATII ~D KT VAPAATA TILAA",
"0134": "SYÖTÄ MEMORY_CARD_(PS2), JOSSA ON TARPEEKSI TILAA, MUUTEN PELITIETOJASI EI VOIDA TALLENTAA",
"0130": "LIIAN VÄHÄN TILAA MUISTIKORTILLA MEMORY_CARD_(PS2, INSERTED IN MEMORY_CARD_SLOT_~D",
"0131": "EI MEMORY_CARD_(PS2, LIITETTYNÄ IN MEMORY_CARD_SLOT_~D",
"0132": "MEMORY_CARD_(PS2, PAIKASSA MEMORY_CARD_SLOT_~D ON ALUSTAMATON",
"0133": "JAK AND DAXTER VAATII ~DKB VAPAATA TILAA",
"0134": "KIINNITÄ MEMORY_CARD_(PS2, JOSSA ON TARPEEKSI TILAA, MUUTEN PELITIETOJA EI VOIDA TALLENTAA",
"0135": "ILMAN ALUSTAMISTA PELITIETOJA EI VOIDA TALLENTAA",
"0136": "TALLENNETAAN TIETOJA",
"0137": "LADATAAN TIETOJA",
"0138": "ÄLÄ POISTA MEMORY_CARD_(PS2) PAIKASSA MEMORY_CARD_SLOT_~D TAI SAMMUTA LAITETTASI",
"0139": "HALUATKO KORVATA SEN?",
"0138": "ÄLÄ POISTA MEMORY_CARD_(PS2, IN MEMORY_CARD_SLOT_~D TAI SAMMUTA LAITETTASI",
"0139": "HALUATKO PÄÄLLEKIRJOITTAA TÄMÄN?",
"013a": "ALUSTA?",
"013c": "KYLLÄ",
"013d": "EI",
@@ -62,7 +62,7 @@
"0140": "VALITSE TALLENNUSPAIKKA",
"0141": "VALITSE LADATTAVA TALLENNUS",
"0142": "JAK AND DAXTER -TALLENNUS ON JO OLEMASSA VALITSEMASSASI TIEDOSTOSSA",
"0143": "SYÖTÄ JAK AND DAXTER -PELITIETOJA SISÄLTÄVÄ MEMORY_CARD_(PS2) PAIKKAAN MEMORY_CARD_SLOT_~D",
"0143": "SYÖTÄ MEMORY_CARD_(PS2, JOKA SISÄLTÄÄ JAK AND DAXTER -TALLENNUSTIETOJA PAIKKAAN MEMORY_CARD_SLOT_~D",
"0144": "JATKA?",
"014b": "LATAA PELI",
"014c": "TALLENNA PELI",
@@ -72,29 +72,29 @@
"0150": "ASETUKSET",
"0151": "VIRHE LADATTAESSA",
"0152": "VIRHE TALLENTAESSA",
"0153": "VIRHE ALUSTAESSA",
"0153": "VIRHE ALUSTAMISESSA",
"0154": "VIRHE LUODESSA TALLENNUSTIEDOSTOA",
"0156": "MEMORY_CARD_(PS2) PAIKASTA MEMORY_CARD_SLOT_~D POISTETTIIN",
"0157": "AUTOMAATTINEN TALLENNUS ON POISTETTU KÄYTÖSTÄ",
"0158": "TALLENNA PELISI MANUAALISESTI, NIIN AUTOMAATTINEN TALLENNUS PALAUTETAAN KÄYTTÖÖN",
"0159": "JAK AND DAXTER -TALLENNUSTIETOJA EI LÖYTYNYT KORITLTA MEMORY_CARD_(PS2) PAIKASSA MEMORY_CARD_SLOT_~D",
"0156": "MEMORY_CARD_(PS2, PAIKASTA MEMORY_CARD_SLOT_~D POISTETTIIN",
"0157": "AUTOMAATTITALLENNUS ON POISTETTU KÄYTÖSTÄ",
"0158": "KÄYTÄ TALLENNA PELI -ASETUSTA TALLENTAAKSESI PELIN MANUAALISESTI JA UUDELLEENKÄYNNISTÄÄKSESI AUTOMAATTITALLENNUKSEN",
"0159": "JAK AND DAXTER -TALLENNUSTIETOJA EI LÖYTYNYT MEMORY_CARD_(PS2, PAIKASSA MEMORY_CARD_SLOT_~D",
"015a": "HALUATKO LUODA UUDEN JAK AND DAXTER -TALLENNUKSEN?",
"015b": "TARKISTA MEMORY_CARD_(PS2) PAIKASSA MEMORY_CARD_SLOT_~D",
"015b": "TARKISTA MEMORY_CARD_(PS2, PAIKASSA MEMORY_CARD_SLOT_~D",
"015c": "UUSI PELI",
"015d": "TAKAISIN?",
"015e": "OK",
"015f": "POISTU DEMOSTA",
"0160": "KUN OHEINEN KUVAKE ILMESTYY, EDISTYKSESI TALLENNETAAN",
"0161": "KUN TÄMÄ KUVAKE ON RUUDULLA, ÄLÄ IRROTA MEMORY_CARD_(PS2) TAI SAMMUTA LAITETTASI",
"0161": "KUN TÄMÄ KUVAKE ON RUUDULLA, ÄLÄ POISTA THE MEMORY_CARD_(PS2, TAI SAMMUTA LAITETTASI",
"0162": "TEHTÄVÄ SUORITETTU",
"0163": "TARKISTA MEMORY_CARD_(PS2) PAIKASSA MEMORY_CARD_SLOT_~D JA YRITÄ UUDELLEEN",
"0163": "TARKISTA MEMORY_CARD_(PS2, IN MEMORY_CARD_SLOT_~D JA YRITÄ UUDELLEEN",
"0164": "RUUTU OTTAA NYT KÄYTTÖÖN 60HZ-TILAN",
"0165": "JOS KUVA NÄKYY VIRHEELLISENÄ, TELEVISIOSI EI TUE TÄTÄ TILAA",
"0166": "JOS NIIN KÄY, ODOTA 10 SEKUNTIA, NIIN RUUTU PALAUTUU TAKAISIN",
"0166": "JOS NÄIN KÄY, ODOTA 10 SEKUNTIA NIIN RUUTU PALAUTETAAN TAKAISIN",
"0167": "RUUTU ON NYT 60HZ-TILASSA",
"0168": "HALUATKO PITÄÄ TÄMÄN TILAN KÄYTÖSSÄ?",
"0169": "VALITSE TASO SUUNTANÄPPÄIMILLÄ",
"016a": "LEVY POISTETTIIN",
"0169": "KÄYTÄ D-PAD:IA VALITAKSESI TASON",
"016a": "LEVY ON POISTETTU",
"016b": "SYÖTÄ JAK AND DAXTER -LEVY SISÄÄN, JOTTA VOIT JATKAA PELAAMISTA",
"016c": "VIRHE TIETOJEN LUKEMISESSA",
"016d": "TARKISTA JAK AND DAXTER -LEVYSI JA YRITÄ UUDELLEEN",
@@ -104,7 +104,7 @@
"0171": "YHTEENSÄ KERÄTTY:",
"0200": "TUO 90 HELMEÄ PORMESTARILLE",
"0201": "TUO 90 HELMEÄ ENOLLESI",
"0202": "PAIMENNA NAUKIT TAKAISIN AITAUKSEEN",
"0202": "PAIMENNA NAUKIT TAKAISIN AITAUKSEENSA",
"0203": "PALAA VILJELIJÄN LUO",
"0204": "TUO 120 HELMEÄ ORAAKKELILLE",
"0205": "AVAA ECO-KERÄIMIEN TUKOKSET",
@@ -117,9 +117,9 @@
"020c": "YHDISTÄ ECO-SÄTEET",
"020d": "KIIPEÄ TEMPPELIN HUIPULLE",
"020e": "ETSI SINISEN ECON KATKAISIN",
"020f": "PÄIHITÄ PIMEÄ ECO-KASVI",
"020f": "PÄIHITÄ PIMEÄN ECON KASVI",
"0210": "NAPPAA 200 KILOA KALAA",
"0211": "NAPPAA KIINNI VEISTÄJÄN MUUSA",
"0211": "OTA KIINNI VEISTÄJÄN MUUSA",
"0212": "VIE MUUSA TAKAISIN VEISTÄJÄLLE",
"0213": "KIIPEÄ VAANIJAPAATTIIN",
"0214": "PYSÄYTÄ KANUUNA",
@@ -135,7 +135,7 @@
"021e": "VIHREÄN TIETÄJÄN MÖKKI",
"021f": "KEIRAN TALLI",
"0220": "SANDOVERIN KYLÄ",
"0221": "VAHTIRANTA",
"0221": "VARTIJARANTA",
"0222": "KIELLETTY VIIDAKKO",
"0223": "USVASAARI",
"0224": "TULIKANJONI",
@@ -145,14 +145,14 @@
"0228": "FLUT FLUT",
"0229": "HELMIORAAKKELI",
"022a": "TRANS-ALUSTA",
"022b": "VIHREÄT ECO-KERÄIMET",
"022b": "VIHREÄN ECON KERÄIMET",
"022c": "EDELTÄJÄHELMI",
"022d": "VOIMAKENNO",
"022e": "NAPPAA PUDONNUT VOIMAKENNO",
"022f": "KORJAA ECO-SÄDE",
"0230": "PALAA PORMESTARIN LUO",
"0262": "TUTKI RANNIKKOA",
"0263": "KIIPEÄ VAHDIN PÄÄLLE",
"0263": "KIIPEÄ VARTIJAN PÄÄLLE",
"0264": "SEURAA ROTKOA MERENRANNALLE",
"0265": "AVAA LUKITTU TEMPPELIN OVI",
"0266": "YLLÄ VOIMAKENNOLLE ZOOMERILLA",
@@ -223,7 +223,7 @@
"040e": "KIIPEÄ VALTAVAA ROBOTTIA",
"040f": "TUTKI PIMEÄÄ LUOLAA",
"0410": "AMMU JAUHAVAT VAANIJAT KIIKARIESI AVULLA",
"0411": "TUHOA PIMEÄT ECO-KRISTALLIT",
"0411": "TUHOA PIMEÄN ECON KRISTALLIT",
"0412": "PÄIHITÄ LUOLAN LEPAKOT",
"0413": "VAPAUTA 7 PARTIOKÄRPÄSTÄ",
"0414": "PUNAISEN TIETÄJÄN LABRA",
@@ -204,7 +204,7 @@
"1601": "CONTROLLER AUSWÄHLEN",
"1602": "STICK DEADZONE",
"1603": "IGNORIERE WENN UNFOKUSIERT",
"1604": "CONTROLLER LED FÜR HP",
"1604": "CONTROLLER LED FÜR LEBEN",
"1605": "CONTROLLER LED FÜR ECO",
"1606": "KAMERA VERFOLGEN",
"1607": "HORIZONTALE SENSITIVITÄT",
@@ -2,15 +2,15 @@
"1000": "KUVAKULMA-ASETUKSET",
"1001": "NORMAALI",
"1002": "KÄÄNTEINEN",
"1003": "VAAKAOHJAUS (1. PERSOONA)",
"1004": "PYSTYOHJAUS (1. PERSOONA)",
"1005": "VAAKAOHJAUS (3. PERSOONA)",
"1006": "PYSTYOHJAUS (3. PERSOONA)",
"1003": "ENSIMMÄISEN PERSOONAN VAAKAKAMERA",
"1004": "ENSIMMÄISEN PERSOONAN PYSTYKAMERA",
"1005": "KOLMANNEN PERSOONAN VAAKAKAMERA",
"1006": "KOLMANNEN PERSOONAN PYSTYKAMERA",
"1007": "PALAUTA OLETUKSET",
"1010": "HELPPOKÄYTTÖISYYS",
"1011": "EDELTÄJÄHELMIEN HEHKU",
"1020": "PS2-ASETUKSET",
"1021": "PS2-LATAUSNOPEUS",
"1021": "PS2 LATAUSNOPEUS",
"1022": "PARTIKKELEIDEN VÄHENNYS",
"1023": "MUSIIKIN ULOS HÄIVYTYS",
"1024": "MUSIIKIN SISÄÄN HÄIVYTYS",
@@ -24,11 +24,11 @@
"1034": "KOKORUUTU",
"1035": "RESOLUUTIO",
"1036": "~D X ~D",
"1037": "PS2-KUVASUHDE",
"1038": "KUN PS2-KUVASUHDE ON KÄYTÖSSÄ, VAIN KUVASUHTEET 4X3 JA 16X9 OVAT VALITTAVISSA. JATKA?",
"1037": "PS2 KUVASUHDE",
"1038": "KUN PS2 KUVASUHDE ON KÄYTÖSSÄ, VAIN KUVASUHTEET 4X3 JA 16X9 OVAT VALITTAVISSA. JATKA?",
"1039": "KUVASUHDE (PS2)",
"1040": "TEKSTITYS KÄYTÖSSÄ",
"1041": "TEKSTITYS EI KÄYTÖSSÄ",
"1040": "TEKSTITYKSET KÄYTÖSSÄ",
"1041": "TEKSTITYKSET EI KÄYTÖSSÄ",
"1042": "TEKSTIN KIELI",
"1043": "NÄYTTÖ",
"1044": "NÄYTTÖ ~D",
@@ -50,8 +50,8 @@
"1075": "ALHAINEN",
"1076": "MINIMI",
"1077": "PS2",
"1078": "TEKSTITYS",
"1079": "VINKKIEN TEKSTITYS",
"1078": "TEKSTITYKSET",
"1079": "VINKKITEKSTITYKSET",
"1080": "HUIJAUKSET",
"1081": "SALAISUUDET",
"1082": "VALITSE KAPPALE",
@@ -68,8 +68,8 @@
"1093": "LOPUTON KELTAINEN ECO",
"1094": "VAIHTOEHTOINEN DAXTER",
"1095": "HAAVOITTUMATTOMUUS",
"1096": "KAIKKI MUSIIKKITYYLIT",
"1097": "TODELLINEN VUOROKAUDENAIKA",
"1096": "KAIKKI MUSIIKKIKAPPALEET",
"1097": "TODELLINEN VUOROKAUDEN AIKA",
"1098": "LÄPÄISE PELI 100%",
"1099": "LÄPÄISE PELI",
"1100": "KELTAINEN TIETÄJÄ",
@@ -96,17 +96,17 @@
"1500": "SPEEDRUN-TILA",
"138": "ÄLÄ LISÄÄ TAI POISTA MITÄÄN OHEISLAITTEITA, SAMMUTA LAITETTASI TAI SAMMUTA PELIÄ",
"161": "KUN TÄMÄ KUVAKE ON RUUDULLA, ÄLÄ LISÄÄ TAI POISTA MITÄÄN OHEISLAITTEITA, SAMMUTA LAITETTASI TAI SAMMUTA PELIÄ",
"100c": "AUTOM. TALLENNUS POIS",
"100d": "HALUATKO VARMASTI LOPETTAA AUTOMAATTISEN TALLENNUKSEN?",
"100e": "LOPETA AUTOM. TALLENNUS",
"100c": "AUTO-TALLENNUS POIS PÄÄLTÄ",
"100d": "HALUATKO VARMASTI LOPETTAA AUTO-TALLENTAMISEN?",
"100e": "LOPETA AUTO-TALLENNUS",
"100f": "SEKALAISET",
"103a": "SOVITA RUUTUUN",
"103b": "PYSTYTAHDISTUS",
"103c": "4X3 (PS2)",
"103d": "16X9 (PS2)",
"103e": "~DX~D",
"103f": "OTA TEKSTITYS KÄYTTÖÖN PAINAMALLA <PAD_SQUARE>",
"107a": "TEKSTITYKSEN KIELI",
"103f": "OTA TEKSTITYKSET KÄYTTÖÖN PAINAMALLA <PAD_SQUARE>",
"107a": "TEKSTITYSTEN KIELI",
"107b": "NÄYTÄ PUHUJA TEKSTITYKSISSÄ",
"107c": "AINA",
"107d": "EI KOSKAAN",
@@ -120,7 +120,7 @@
"109f": "KÄÄNTEINEN MAAILMA",
"10a0": "SUURIPÄINEN JAK",
"10c0": "MUSIIKKISOITIN",
"10c1": "VÄLINÄYTÖSSSOITIN",
"10c1": "VÄLIANIMAATIO-SOITIN",
"10c2": "TOISTA LOPPUTEKSTIT",
"10c3": "LEIKEKIRJA",
"10d0": "OLETUS",
@@ -160,7 +160,7 @@
"10f2": "SOLAN LOPPUOSA",
"10f3": "HÄMÄHÄKKILUOLAAN",
"10f4": "LUMIVUORILLE",
"10f5": "MAINARIT",
"10f5": "KAIVOSMIEHET",
"10f6": "ROBOTTILUOLAN TELINEET",
"10f7": "EDELTÄJÄROBOTIN HUIPPU",
"10f8": "PÄÄLUOLA",
@@ -171,10 +171,10 @@
"10fd": "LUMIPALLOT",
"10fe": "TUNNELIN KESKIOSA",
"10ff": "TUNNELIN LOPPU",
"1501": "VÄLINÄYTÖSTEN OHITUKSET",
"1501": "OHITA VÄLIANIMAATIOT",
"1502": "VALITSE TARKISTUSPISTE",
"1503": "SPEEDRUN-ASETUKSET",
"1504": "VAROITUS: NÄMÄ ASETUKSET TALLENTAVAT AUTOMAATTISESTI ENSIMMÄISEEN TALLENNUSPAIKKAAN!",
"1504": "VAROITUS: NÄMÄ ASETUKSET AUTOMAATTITALLENTAVAT ENSIMMÄISEEN TALLENNUSPAIKKAAN!",
"1505": "ALOITA SPEEDRUN UUDELLEEN",
"1506": "UUSI TÄYDEN PELIN SPEEDRUN",
"150e": "UUSI YKSITTÄISEN TASON SPEEDRUN",
@@ -199,16 +199,16 @@
"1521": "HUBI 1 100%",
"1522": "HUBI 2 100%",
"1523": "HUBI 3 100%",
"1524": "KAIKKI VÄLINÄYTÖKSET",
"1524": "KAIKKI VÄLIANIMAATIOT",
"1600": "OHJAUSSYÖTTEEN ASETUKSET",
"1601": "VALITSE OHJAIN",
"1602": "ANALOGISAUVAN KATVEALUE",
"1603": "ÄLÄ HUOMIOI TYÖPÖYDÄLLÄ",
"1603": "ÄLÄ HUOMIOI, JOS IKKUNA EI AKTIIVINEN",
"1604": "OHJAIMEN LED TERVEYDELLE",
"1605": "OHJAIMEN LED ECO-VOIMILLE",
"1606": "KAMERAN OHJAUS HIIRELLÄ",
"1607": "HERKKYYS (VAAKASUUNTA)",
"1608": "HERKKYYS (PYSTYSUUNTA)",
"1607": "VAAKASUUNTAINEN HERKKYYS",
"1608": "PYSTYSUUNTAINEN HERKKYYS",
"1609": "PELAAJAN OHJAUS HIIRELLÄ",
"160a": "PELIOHJAIMEN KYTKENNÄT",
"160b": "NÄPPÄIMISTÖN KYTKENNÄT",
@@ -220,8 +220,8 @@
"1611": "MUUTA KYTKENTÖJÄ",
"1612": "OHJAIN ~D",
"1613": "PIILOTA OSOITIN AUTOMAATTISESTI",
"1614": "TYHJÄ",
"1614": "MÄÄRITTÄMÄTÖN",
"1615": "TUNTEMATON",
"1616": "MUITA KUVASUHTEITA EI OLE SAATAVILLA",
"1616": "MUITA ASETUKSIA RUUDUN KOOLLE EI SAATAVISSA",
"1617": "OHJAIMEN LED LÄMPÖMITTARILLE"
}
@@ -16,7 +16,7 @@
"1024": "ミュージック ゲイン",
"1025": "アクター カリング",
"1026": "バックグラウンド カリング",
"1027": "かんきょうマッピングをきょうせいてきにじっこう",
"1027": "かんきょう マッピングを きょうせいする",
"1030": "DISCORDリッチプレゼンス",
"1031": "スクリーンモード",
"1032": "ウィンドウ",
@@ -25,13 +25,13 @@
"1035": "かいぞうど",
"1036": "~D X ~D",
"1037": "PS2 アスペクト ひ",
"1038": "PS2アスペクトひがゆうこうになると、4X3と16X9しかのアスペクトひがせんたくできません.つづきますか?",
"1038": "PS2アスペクトひが ゆうこうになると、4X3と16X9しか せんたくできません ぞっこうしますか?",
"1039": "アスペクト ひ (PS2)",
"1040": "じまくあり",
"1041": "じまくなし",
"1042": "テキストのげんご",
"1043": "ディスプレイ",
"1044": "ディスプレイ ~D",
"1042": "テキストのことば",
"1043": "ディスプレー",
"1044": "ディスプレー ~D",
"1050": "MSAA",
"1051": "~DX",
"1052": "2X",
@@ -66,18 +66,18 @@
"1091": "むげんの赤のエコ",
"1092": "むげんの緑のエコ",
"1093": "むげんの黄のエコ",
"1094": "かわりのダクスター",
"1094": "へんかのダクスター",
"1095": "むてき",
"1096": "ぜんおんがくトラック",
"1096": "すべてBGMのへんか",
"1097": "リアルタイムオブデイ",
"1098": "100%クリア",
"1099": "ゲームクリア",
"1100": "黄の賢者",
"1101": "赤の賢者",
"1102": "青の賢者",
"1103": "城エリア",
"1104": "プリカーソルロボットの中?",
"1105": "プリカーソルロボットのおわり",
"1103": "城のハブ",
"1104": "プリカーソルロボットの中かん",
"1105": "プリカーソルロボットのけつまつ",
"1106": "スタイル 1",
"1107": "スタイル 2",
"1110": "ENGLISH (UK)",
@@ -97,30 +97,30 @@
"138": "しゅうへんききをぬいたり, さしたり, でんげんを きったりは しないでください",
"161": "このアイコンが あらわれているあいだ、しゅうへんききをぬいたり, さしたり, でんげんを きったりは しないでください",
"100c": "オートセーブ オフ",
"100d": "オートセーブを?っても よろしいでしょうか?",
"100e": "オートセーブをむこうにする",
"100d": "オートセーブをきっても よろしいでしょうか?",
"100e": "DISABLE AUTO-SAVE",
"100f": "そのほか",
"103a": "スクリーンに合わせる",
"103a": "FIT TO SCREEN",
"103b": "すいちょくどうき",
"103c": "4X3 (PS2)",
"103d": "16X9 (PS2)",
"103e": "~DX~D",
"103f": "<PAD_SQUARE> をおすとじまくをトグルする",
"103f": "<PAD_SQUARE> で じまくのきりかえ",
"107a": "じまくのことば",
"107b": "じまくではなしてをひょうじする",
"107c": "いつも",
"107c": "イツモ",
"107d": "いつもしなく",
"107e": "オフ スクリーン",
"107f": "ヒントログ",
"107e": "OFF-SCREEN",
"107f": "ヒントロッグ",
"109a": "ビッグヘッド ジャック",
"109b": "スモールヘッド ジャック",
"109c": "ビッグハンドジャック",
"109d": "ビッグヘッドキャラクター",
"109d": "あたまがおおきいキャラクター",
"109e": "テクスチャなしモード",
"109f": "ミラー・モード",
"10a0": "ビッグヘッド ジャック",
"10c0": "ミュージックプレイヤー",
"10c1": "シーンプレイヤー",
"109f": "かがみ世界",
"10a0": "でかいヘッド ジャック",
"10c0": "BGM プレイヤー",
"10c1": "SCENE PLAYER",
"10c2": "スタッフロール",
"10c3": "スクラップブック",
"10d0": "デフォルト",
@@ -133,11 +133,11 @@
"10d7": "メイヨル",
"10d8": "ほりものし",
"10d9": "たんけん家のブロオラ",
"10da": "ドック",
"10db": "キンダン寺の出口",
"10da": "DOCK",
"10db": "FORBIDDEN TEMPLE EXIT",
"10dc": "ラーカーのマシン",
"10dd": "TOP OF THE TOWER",
"10de": "青エコのふきだしぐちスイッチ",
"10de": "BLUE VENT SWITCH",
"10df": "みしよう",
"10e0": "SENTINELS",
"10e1": "LURKER CANNON",
@@ -145,19 +145,19 @@
"10e3": "みしよう1",
"10e4": "LURKER BOAT",
"10e5": "みしよう2",
"10e6": "ズーマー",
"10e6": "ZOOMER",
"10e7": "フラフラ鳥",
"10e8": "みしよう",
"10e9": "せんしヴォリア",
"10ea": "がくしゃロジィ",
"10eb": "ギャンブラーのタルパン",
"10e9": "WARRIOR",
"10ea": "GEOLOGIST",
"10eb": "GAMBLER",
"10ec": "LEVITATOR MACHINE",
"10ed": "みしよう1",
"10ee": "LAUNCHER TRAPS",
"10ef": "みしよう2",
"10f0": "DEAD MAN'S GORGE",
"10f1": "谷のちゅうかん",
"10f2": "谷のおわり",
"10f1": "MIDDLE OF THE PASS",
"10f2": "END OF THE PASS",
"10f3": "ヤミノ洞くつへ",
"10f4": "ガイセツ山へ",
"10f5": "宝石ほりたち",
@@ -195,33 +195,33 @@
"151d": "LAVA TUBE IL",
"151e": "GOL AND MAIA'S CITADEL IL",
"151f": "NEW CATEGORY EXTENSION RUN",
"1520": "つよくてニューゲーム",
"1521": "エリア 1 100%",
"1522": "エリア 2 100%",
"1523": "エリア 3 100%",
"1520": "?しいゲーム+",
"1521": "ハブ 1 100%",
"1522": "ハブ 2 100%",
"1523": "ハブ 3 100%",
"1524": "すべてのシーン",
"1600": "にゅうりょくせってい",
"1600": "INPUT OPTIONS",
"1601": "コントローラをせんたくする",
"1602": "ANALOG DEADZONE",
"1603": "IGNORE IF WINDOW UNFOCUSED",
"1604": "コントローラのLEDでたい力をひょうじする",
"1605": "コントローラのLEDでエコをひょうじする",
"1606": "TRACK CAMERA",
"1607": "よこかんど",
"1608": "たてかんど",
"1607": "HORIZONTAL SENSITIVITY",
"1608": "VERTICAL SENSITIVITY",
"1609": "PLAYER MOVEMENT",
"160a": "コントローラのバインド",
"160b": "キーボードのバインド",
"160c": "マウスのバインド",
"160d": "コントローラオプション",
"160e": "キーボードゆうこう",
"160f": "マウスゆうこう",
"160e": "ENABLE KEYBOARD",
"160f": "ENABLE MOUSE",
"1610": "マウスオプション",
"1611": "REASSIGN BINDS",
"1612": "CONTROLLER ~D",
"1613": "AUTO HIDE CURSOR",
"1614": "みけってい",
"1615": "ふめい",
"1615": "?られていない",
"1616": "アスペクトひのほかのせんたくしはありません",
"1617": "コントローラのLEDでズーマーのおんどをひょうじする"
}
@@ -202,7 +202,7 @@
"1524": "ALLA SCENER",
"1600": "INMATNINGSINSTÄLLNINGAR",
"1601": "VÄLJ HANDKONTROLL",
"1602": "ANALOG NEUTRAL ZON",
"1602": "ANALOG DEADZONE",
"1603": "IGNORERA OM FÖNSTRET INTE HAR FOKUS",
"1604": "LED REFLEKTERAR HP",
"1605": "LED REFLEKTERAR ECO",
Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

@@ -713,8 +713,7 @@
],
"bb06int": [
"Jak, necessitem que treus un altre grup de Bomb Bots.",
"These mobile weapons keep showing up in the city,",
"we gotta take them out as soon as possible."
"Aquestes armes mòbils continuen apareixent a la ciutat, les hem de treure el més aviat possible."
],
"bb06win": [
"Un altre munt de ferralla de bombes per al KG",
@@ -725,10 +724,8 @@
"Has perdut un agent! No és gens bo, Jak! Missió fallida!"
],
"bb07int": [
"Torn here, I need you to go out and move more of our Agents",
"to new locations in the city.",
"KG spies are watching our every move,",
"so look out for trouble. Good luck."
"Esquinçat aquí, necessito que surtis i traslladis més dels nostres agents a nous llocs de la ciutat.",
"Els espies de KG estan vigilant tots els nostres moviments, així que vigileu els problemes. Bona sort."
],
"bb07win": [
"Bona feina de llançadora! Estàs mantenint la gent viva allà fora."
@@ -740,8 +737,7 @@
"bb08int": [
"Jak, alguns dels nostres agents s'han vist compromesos de nou.",
"Trobeu-los i porteu-los a amagatalls especials de la ciutat.",
"The guard patrols are on high alert,",
"so this is going to be a tough one. Keep your head down!"
"Les patrulles de guàrdia estan en alerta màxima, així que serà difícil. Mantingueu el cap avall!"
],
"bb08win": [
"Va ser una bona conducció, Jak.",
@@ -4915,10 +4911,10 @@
"Activació de defenses de seguretat."
],
"kg121": [
"Please advise, suspect's description."
"Si us plau, aviseu, descripció del tema."
],
"kg121a": [
"Please advise, suspect's description."
"Si us plau, aviseu, descripció del tema."
],
"kg122": [
"Tinc civismes a la vista."
@@ -5693,11 +5689,11 @@
"lluitant per l'Underground."
],
"kg233b": [
"I'm worried about this new guy",
"Estic preocupat perquè aquest nou noi lluita per l'Underground.",
"lluitant per l'Underground."
],
"kg234": [
"Yeah, they say he can change into some kind of monster."
"Sí, diuen que es pot convertir en una mena de... monstre."
],
"kg234a": [
"Sí, diuen que es pot convertir en una mena de monstre."
@@ -6943,7 +6939,7 @@
],
"prop049": [
"Estic decebut amb la manca d'aquesta ciutat",
"commitment and sacrifice. Work harder! Eat less!",
"compromís i sacrifici. Treballar més dur! Menja menys!",
"Beu només quan et digui! Dormir és opcional.",
"Estem en guerra amb una amenaça externa,",
"no em feu declarar-vos la guerra també!"
@@ -6951,14 +6947,13 @@
"prop050": [
"Salutacions, gent d'aquesta meravellosa utopia. La d'enguany",
"la cursa del campionat començarà en breu. Tots els ciutadans",
"not under house arrest are invited to come down",
"to the Stadium and watch your favorite son Erol",
"no estan sota arrest domiciliari estan convidats a baixar",
"l'Estadi i mira el teu fill preferit Erol",
"mostrar una vegada més com la Guàrdia Krimzon és l'elit",
"warriors of this city. Bring the whole family!",
"The first one thousand children will get",
"a mandatory Krimzon Guard recruitment package",
"and be \"asked\" to join the Guard for life!",
"What a treat!"
"guerrers d'aquesta ciutat. Porta tota la família! El primer",
"mil nens tindran una obligatòria",
"Paquet de contractació de Krimzon Guard i be",
"\"demanat\" unir-se a la Guàrdia de per vida, quina delícia!"
],
"prop051": [
"Aquest és el teu baró, encara tinc el control!",
@@ -6989,24 +6984,22 @@
"seria si els Metal Heads estiguessin al capdavant!"
],
"prop054": [
"We've had a few incidents with our lower class",
"labor force lately. If your Lurker is acting up,",
"call Krimzon Animal Control. Is your Lurker in a tree?",
"Stuck in a sewer grate? Foaming at the mouth?",
"Call the friendly officers of the K.A.C.",
"and they will deal with your furry slave",
"with all the love and care it deserves...",
"then haul it away for reconditioning.",
"Remember, Lurkers can be dangerous!"
"Hem tingut alguns incidents amb els nostres treballadors de classe baixa",
"força últimament. Si el vostre Lurker està actuant, truqueu a Krimzon",
"Control d'animals. El teu Lurker està en un arbre? Encallat en un",
"reixa de clavegueram? Escuma a la boca? Anomenada",
"els oficials amics de la K.A.C. i tractaran",
"amb el teu esclau pelut. amb tot l'amor i cura",
"es mereix... després traieu-lo per a un reacondicionament.",
"Recordeu que els lurkers poden ser perillosos!"
],
"prop055": [
"Si us plau, doneu generosament al fons ecològic Baron.",
"Your munificent donation will be used for",
"a variety of humanitarian needs:",
"bombs, guns, armor, genetic alteration research,",
"all in the name of preserving this",
"wonderful city of ours. Give often, give freely...",
"or it will be taken from you!"
"La teva donació s'utilitzarà per a una varietat",
"de necessitats humanitàries: bombes, pistoles, blindatges, genètica",
"investigació sobre alteracions, tot en nom de preservar-ho",
"meravellosa ciutat nostra. Donar sovint, donar lliurement...",
"o t'ho prendran!"
],
"prop056": [
"Pot estar tan sol a dalt i mirant cap avall",
@@ -7556,17 +7549,15 @@
"Fes un petó al teu cul brillant adéu!"
],
"sigt112": [
"Born to kill, baby!"
"Nascut per matar un nadó!"
],
"sigt113": [
"Dos al pit, un al cap."
],
"spot004": [
"Come out and cheer for me",
"as I destroy the competition once again on the track.",
"This year's racing final will be to die for,",
"I guarantee more thrills and more spills.",
"This time I want blood! Bring the kids."
"Veniu a animar-me mentre destrueixo la competició una vegada més a la pista.",
"La final de curses d'enguany serà per morir-se, us garanteixo més emocions i més vessars.",
"Aquesta vegada vull sang!...Porteu els nens."
],
"tess001": [
"Hola nois! Aquesta és la Tess. Abans que en Krew marxés, el vaig veure amagar-se",
@@ -7575,32 +7566,23 @@
"Potser vols venir a comprovar-ho."
],
"tor001": [
"The operation was a success.",
"All Underground members are safe.",
"Come back to the hideout, I have a new mission for you",
"while we wait for this alert to blow over."
"L'operació va ser un èxit. Tots els membres de Underground estan segurs.",
"Torna a l'amagatall, tinc una nova missió per a tu mentre esperem que passi aquesta alerta."
],
"tor002": [
"That should take some heat off the streets.",
"Good work, I couldn't have done it better myself."
"Això hauria de treure una mica de calor als carrers. Bona feina, jo mateix no ho hauria pogut fer millor."
],
"tor003": [
"That's it, Jak, you're up! Try not to trigger any alarms,",
"the garrison guards will be tough.",
"Get to the prison cell block and find the prisoners.",
"Once there, we'll turn on the Warp Gate inside",
"to get you all back out. Good luck."
"Això és tot, Jak, estàs aixecat! Intenta no activar cap alarma, els guàrdies de la guarnició seran durs.",
"Arriba al bloc de cel·les de la presó i troba els presoners. Un cop allà, encendrem la Warp Gate per dins per tornar-vos a sortir. Bona sort."
],
"tor004": [
"Okay, my old access codes should help Vin turn off",
"the magnetic seal for the Fortress door."
"D'acord, els meus codis d'accés antics haurien d'ajudar a Vin a apagar el segell magnètic de la porta de la fortalesa."
],
"tor005": [
"Jak, this is Torn, the city is under Metal Head attack!",
"There's a large force moving toward the city wall",
"from the ocean. We need people manning the tower gunpods",
"to stop that assault. Meet me at the seaside ocean wall",
"in the Port. Hurry, we need every man we can get!"
"Jak, aquest és Torn, la ciutat està sota atac de Metal Head. Hi ha una gran força que es mou cap a la muralla de la ciutat des de l'oceà.",
"Necessitem gent que s'encarrega de les pistoles de la torre per aturar aquest assalt. Trobeu-me a la paret marítima del Port, afanyeu-vos!",
"Necessitem tots els homes que puguem aconseguir!"
],
"tor007": [
"Jak, és un bloqueig de guàrdia, surt d'allà!"
@@ -7825,8 +7807,8 @@
"Massa d'ells!! Jak!!! AHHHH!!!"
],
"ys001": [
"Excellent work, boys! Come on back",
"to the Hideout, I have another task for you."
"Excel·lent feina, nois! Torna a l'amagatall,",
"Tinc una altra tasca per a tu."
],
"ys002": [
"Bonic tiroteig, fill meu!",
@@ -713,8 +713,7 @@
],
"bb06int": [
"Jak, vi har brug for dig til at fjerne endnu en gruppe Bombe-botter.",
"These mobile weapons keep showing up in the city,",
"we gotta take them out as soon as possible."
"Disse mobile våben bliver ved med at dukke op i byen, vi må fjerne dem hurtigst muligt."
],
"bb06win": [
"Endnu en bunke Bombe-bot skrot for KG'ernes",
@@ -725,10 +724,8 @@
"Du mistede en agent! IKKE godt overhovedet, Jak! Missionen fejlet!"
],
"bb07int": [
"Torn here, I need you to go out and move more of our Agents",
"to new locations in the city.",
"KG spies are watching our every move,",
"so look out for trouble. Good luck."
"Torn her, Jeg skal bruge jer til at tage ud og flytte flere af vores Agenter til nye steder i byen.",
"KG-spioner holder øje med alle vores bevægelser, så hold øje efter problemer. Held og lykke."
],
"bb07win": [
"Fint flytte-arbejde! I holder folk i live derude."
@@ -740,8 +737,7 @@
"bb08int": [
"Jak, nogle af vores agenter er blevet kompromitteret igen.",
"Find hver enkelt og tag dem til specielle skjulesteder i byen.",
"The guard patrols are on high alert,",
"so this is going to be a tough one. Keep your head down!"
"Vagtpatruljerne er i høj beredskab, så den her bliver svær. Hold hovedet nede!"
],
"bb08win": [
"Det var god kørsel, Jak.",
@@ -4915,10 +4911,10 @@
"Aktivering af sikkerhedsforsvar."
],
"kg121": [
"Please advise, suspect's description."
"Giv venligst besked, emnebeskrivelse."
],
"kg121a": [
"Please advise, suspect's description."
"Giv venligst besked, emnebeskrivelse."
],
"kg122": [
"Jeg har civvies i sigte."
@@ -5693,11 +5689,11 @@
"kæmper for undergrunden."
],
"kg233b": [
"I'm worried about this new guy",
"Jeg er bekymret for denne nye fyr, der kæmper for undergrunden.",
"kæmper for undergrunden."
],
"kg234": [
"Yeah, they say he can change into some kind of monster."
"Ja, de siger, at han kan ændre sig til en slags... monster."
],
"kg234a": [
"Ja, de siger, at han kan ændre sig til en slags monster."
@@ -6943,7 +6939,7 @@
],
"prop049": [
"Jeg er skuffet over denne bys mangel på",
"commitment and sacrifice. Work harder! Eat less!",
"engagement og opofrelse. Arbejd hårdere! Spis mindre!",
"Drik kun når jeg fortæller dig! Søvn er valgfrit.",
"Vi er i krig med en trussel udefra,",
"lad mig heller ikke erklære krig mod dig!"
@@ -6951,14 +6947,13 @@
"prop050": [
"Hilsen folk i denne vidunderlige utopi. Årets",
"mesterskabsløbet begynder snart. Alle borgere",
"not under house arrest are invited to come down",
"to the Stadium and watch your favorite son Erol",
"ikke i husarrest inviteres til at komme ned til",
"Stadion og se din yndlingssøn Erol",
"endnu en gang vise, hvordan Krimzon-garden er eliten",
"warriors of this city. Bring the whole family!",
"The first one thousand children will get",
"a mandatory Krimzon Guard recruitment package",
"and be \"asked\" to join the Guard for life!",
"What a treat!"
"krigere i denne by. Tag hele familien med! Den første",
"tusinde børn vil få en obligatorisk",
"Krimzon Guard rekrutteringspakke og være",
"\"bad\" om at slutte sig til vagten for livet, sikke en godbid!"
],
"prop051": [
"Dette er din baron, jeg har stadig kontrol!",
@@ -6989,24 +6984,22 @@
"det ville være, hvis Metal Heads havde ansvaret!"
],
"prop054": [
"We've had a few incidents with our lower class",
"labor force lately. If your Lurker is acting up,",
"call Krimzon Animal Control. Is your Lurker in a tree?",
"Stuck in a sewer grate? Foaming at the mouth?",
"Call the friendly officers of the K.A.C.",
"and they will deal with your furry slave",
"with all the love and care it deserves...",
"then haul it away for reconditioning.",
"Remember, Lurkers can be dangerous!"
"Vi har haft et par hændelser med vores lavere klasses arbejdskraft",
"kraft på det seneste. Hvis din Lurker optræder, så ring til Krimzon",
"Dyrekontrol. Er din Lurker i et træ? Sidder fast i en",
"kloakrist? Skummer om munden? Opkald",
"de venlige officerer i K.A.C. og de vil handle",
"med din lodne slave. med al den kærlighed og omsorg det",
"fortjener... så slæb den væk til renovering.",
"Husk, Lurkers kan være farlige!"
],
"prop055": [
"Giv venligst generøst til Baron økofond.",
"Your munificent donation will be used for",
"a variety of humanitarian needs:",
"bombs, guns, armor, genetic alteration research,",
"all in the name of preserving this",
"wonderful city of ours. Give often, give freely...",
"or it will be taken from you!"
"Din overdådige donation vil blive brugt til en række forskellige",
"af humanitære behov: bomber, våben, rustninger, genetiske",
"ændringsforskning, alt sammen for at bevare dette",
"vores vidunderlige by. Giv ofte, giv frit...",
"eller det bliver taget fra dig!"
],
"prop056": [
"Det kan være så ensomt på toppen og kigge ned fra",
@@ -7556,17 +7549,15 @@
"Kys din skinnende røv farvel!"
],
"sigt112": [
"Born to kill, baby!"
"Født til at dræbe baby!"
],
"sigt113": [
"To til brystet, en til hovedet."
],
"spot004": [
"Come out and cheer for me",
"as I destroy the competition once again on the track.",
"This year's racing final will be to die for,",
"I guarantee more thrills and more spills.",
"This time I want blood! Bring the kids."
"Kom ud og hep på mig, mens jeg ødelægger konkurrencen igen på banen.",
"Dette års løbsfinale bliver til at dø for, jeg garanterer mere spænding og mere spild.",
"Denne gang vil jeg have blod!...Tag børnene med."
],
"tess001": [
"Hej gutter! Det her er Tess. Før Krew gik, så jeg ham gemme sig",
@@ -7575,32 +7566,23 @@
"Du vil måske komme og tjekke det ud."
],
"tor001": [
"The operation was a success.",
"All Underground members are safe.",
"Come back to the hideout, I have a new mission for you",
"while we wait for this alert to blow over."
"Operationen var en succes. Alle underjordiske medlemmer er i sikkerhed.",
"Kom tilbage til gemmestedet, jeg har en ny mission til dig, mens vi venter på, at denne alarm blæser over."
],
"tor002": [
"That should take some heat off the streets.",
"Good work, I couldn't have done it better myself."
"Det burde tage lidt varme fra gaderne. Godt arbejde, jeg kunne ikke have gjort det bedre selv."
],
"tor003": [
"That's it, Jak, you're up! Try not to trigger any alarms,",
"the garrison guards will be tough.",
"Get to the prison cell block and find the prisoners.",
"Once there, we'll turn on the Warp Gate inside",
"to get you all back out. Good luck."
"Det var det, Jak, du er oppe! Prøv ikke at udløse nogen alarmer, garnisonens vagter vil være hårde.",
"Gå til fængselscelleblokken og find fangerne. Når vi er der, tænder vi Warp Gate inde for at få jer alle ud igen. Held og lykke."
],
"tor004": [
"Okay, my old access codes should help Vin turn off",
"the magnetic seal for the Fortress door."
"Ok, mine gamle adgangskoder skulle hjælpe Vin med at slukke for den magnetiske forsegling til fæstningsdøren."
],
"tor005": [
"Jak, this is Torn, the city is under Metal Head attack!",
"There's a large force moving toward the city wall",
"from the ocean. We need people manning the tower gunpods",
"to stop that assault. Meet me at the seaside ocean wall",
"in the Port. Hurry, we need every man we can get!"
"Jak, det er Torn, byen er under Metal Head-angreb. Der er en stor styrke, der bevæger sig mod bymuren fra havet.",
"Vi har brug for folk, der bemander tårnets geværbøjler for at stoppe det overfald. Mød mig ved havets havvæg i havnen, skynd dig!",
"Vi har brug for hver mand, vi kan få!"
],
"tor007": [
"Jak, det er en vagtspærring, kom ud derfra!"
@@ -7825,8 +7807,8 @@
"For mange af dem!! Jak!!! ARHHH!!!"
],
"ys001": [
"Excellent work, boys! Come on back",
"to the Hideout, I have another task for you."
"Fremragende arbejde, drenge! Kom tilbage til skjulestedet,",
"Jeg har endnu en opgave til jer."
],
"ys002": [
"Godt skudt, min dreng!",
Loaded 100 of 1818 files, more files were not shown because too many files have changed in this diff. Show more