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
8909 changed files with 746871 additions and 1802884 deletions

No files matched your search

-8
View File
@@ -1,8 +0,0 @@
.cache/
.git/
build/
decompiler_out/
failures/
iso_data/
out/
log/
+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,75 +0,0 @@
name: "\U0001F41B Jak 3 Bug Report"
description: Create a bug report for Jak 3.
labels: ["jak3"]
type: 'bug'
body:
- type: checkboxes
attributes:
label: Acknowledgements
description: Take a couple minutes to help our maintainers work faster.
options:
- label: I have [searched](https://github.com/open-goal/jak-project/issues?q=is%3Aissue+is%3Aopen+label%3Abug+label%3Ajak3+sort%3Aupdated-desc+) for duplicate or closed bug reports
required: true
- label: I understand that I am supposed to provide my own legitimately obtained copy of the game
required: true
- type: textarea
attributes:
label: Describe the Bug
description: A clear and concise description of what the bug is. You may post screenshots or videos of the bug here.
validations:
required: true
- type: textarea
attributes:
label: How To Reproduce
description: Steps to reproduce the behavior. You can also post a video of it here.
validations:
required: true
- type: dropdown
attributes:
label: Does this problem occur on original hardware or PCSX2?
description: Some things that may seem like bugs are actually exactly how the original game behaved.
options:
- Yes, it's unique to OpenGOAL
- Didn't check
- Not needed, bug is obvious
validations:
required: true
- type: textarea
attributes:
label: Expected Behavior
description: A clear and concise description of the expected behavior.
placeholder: When I do X, Y should happen.
validations:
required: true
- type: textarea
attributes:
label: Environment Information
description: "You can upload the [Support Package](https://github.com/open-goal/launcher#asking-for-help) provided by the Launcher here, or you can provide the following information: CPU, GPU, OS Version, OpenGOAL Version (found in the window's title bar)"
validations:
required: true
- type: dropdown
attributes:
label: Game Version
options:
- NTSC 1.0 (black label)
- NTSC Greatest Hits version (red label)
- PAL
- KO
validations:
required: true
- type: dropdown
attributes:
label: Have you set the game to something other than `60fps`?
options:
- "No"
- "Yes"
validations:
required: true
@@ -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 -9
View File
@@ -49,14 +49,14 @@ jobs:
name: "🍎 MacOS"
uses: ./.github/workflows/macos-build.yaml
with:
cmakePreset: "Release-macos-x86_64-clang"
cmakePreset: "Release-macos-clang"
cachePrefix: ""
secrets: inherit
build_macos_arm:
name: "🍎 MacOS"
uses: ./.github/workflows/macos-build-arm.yaml
with:
cmakePreset: "Release-macos-arm64-clang"
cachePrefix: ""
secrets: inherit
# 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,96 +0,0 @@
name: Compilation Check
on:
pull_request:
branches:
- master
jobs:
build:
name: Compare
runs-on: ubuntu-22.04
timeout-minutes: 60
steps:
- name: Checkout Repository
uses: actions/checkout@v6
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-22.04--Release-linux-clang-static-${{ github.sha }}
restore-keys: linux-ubuntu-22.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@v6
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
+5 -6
View File
@@ -12,7 +12,7 @@ jobs:
gen-docs:
name: Generate Documentation
if: github.repository == 'open-goal/jak-project'
runs-on: ubuntu-22.04
runs-on: ubuntu-20.04
timeout-minutes: 45
env: # overrides: https://github.com/mbitsnbites/buildcache/blob/master/doc/configuration.md
BUILDCACHE_MAX_CACHE_SIZE: 1000000000 # 1gb
@@ -22,7 +22,7 @@ jobs:
BUILDCACHE_LOG_FILE: ${{ github.workspace }}/buildcache.log
steps:
- name: Checkout Repository
uses: actions/checkout@v6
uses: actions/checkout@v4
- name: Install Package Dependencies
run: |
@@ -35,7 +35,7 @@ jobs:
- name: Setup Buildcache
uses: mikehardy/[email protected]
with:
cache_key: linux-ubuntu-22.04--Release-linux-clang
cache_key: linux-ubuntu-20.04--Release-linux-clang
buildcache_tag: v0.28.1
- name: CMake Generation
@@ -67,20 +67,19 @@ jobs:
python ./scripts/ci/docs/append-file-docs.py
- name: Upload Docs Artifact
uses: actions/upload-artifact@v7
uses: actions/upload-artifact@v4
with:
name: opengoal-docs
if-no-files-found: error
path: |
./jak1*.json
./jak2*.json
./jak3*.json
- name: Log Run ID
run: echo ${{ github.run_id }}
- name: Send Dispatch
uses: peter-evans/repository-dispatch@v4
uses: peter-evans/repository-dispatch@v3
with:
token: ${{ secrets.BOT_PAT }}
repository: 'open-goal/open-goal.github.io'
+13 -13
View File
@@ -12,24 +12,26 @@ on:
jobs:
formatting:
name: 📝 Formatting
runs-on: ubuntu-22.04
runs-on: ubuntu-20.04
timeout-minutes: 10
steps:
- name: Checkout Repository
uses: actions/checkout@v6
uses: actions/checkout@v4
# wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
# sudo add-apt-repository 'deb http://apt.llvm.org/focal/ llvm-toolchain-focal-15 main'
# sudo apt install clang-format-15
# --clang-format-executable $(which clang-format-15)
- name: Get Package Dependencies
run: |
sudo apt update
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
sudo add-apt-repository 'deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-18 main'
sudo apt install clang-format-18
clang-format-18 -version
sudo apt install clang-format
clang-format -version
- name: Check Clang-Formatting
run: |
chmod +x ./third-party/run-clang-format/run-clang-format.py
./third-party/run-clang-format/run-clang-format.py -r common decompiler game goalc test tools lsp --color always --clang-format-executable $(which clang-format-18)
./third-party/run-clang-format/run-clang-format.py -r common decompiler game goalc test tools lsp --color always
required-checks:
name: 📝 Required Checks
@@ -37,7 +39,7 @@ jobs:
timeout-minutes: 10
steps:
- name: Checkout Repository
uses: actions/checkout@v6
uses: actions/checkout@v4
- name: Check for Trailing Whitespace in goal_src
run: python ./scripts/ci/lint-trailing-whitespace.py
@@ -49,9 +51,7 @@ jobs:
run: python ./scripts/ci/check-for-asserts.py
- name: Check for Invalid Translation Characters
run: |
python ./scripts/ci/lint-characters.py
python ./scripts/ci/lint-autoglottonyms.py
run: python ./scripts/ci/lint-characters.py
optional-checks:
name: 📝 Optional Checks
@@ -59,7 +59,7 @@ jobs:
timeout-minutes: 10
steps:
- name: Checkout Repository
uses: actions/checkout@v6
uses: actions/checkout@v4
- name: Install Python Dependencies
run: pip install unidiff colorama
@@ -67,6 +67,6 @@ jobs:
- name: Check for Removed goal_src/ Code
# FYI - if you run this `git diff` on windows, it creates a utf-16 LE file
run: |
git fetch origin master
git fetch origin
git diff origin/master > lint-changes.diff
python ./scripts/ci/lint-gsrc-removals.py
+6 -16
View File
@@ -17,22 +17,12 @@ on:
jobs:
build:
name: Clang
runs-on: ubuntu-22.04
runs-on: ubuntu-20.04
timeout-minutes: 60
steps:
# minimal checkout if we're NOT uploading artifacts
- name: Checkout Repository
if: ${{ ! inputs.uploadArtifacts }}
uses: actions/checkout@v6
# full checkout with tags if we ARE uploading artifacts
- name: Checkout Repository with Tags
if: ${{ inputs.uploadArtifacts }}
uses: actions/checkout@v6
with:
fetch-depth: 0
fetch-tags: true
uses: actions/checkout@v4
- name: Install Package Dependencies
run: |
@@ -43,11 +33,11 @@ jobs:
libxi-dev zip ninja-build libgl1-mesa-dev libssl-dev
- name: Setup sccache
uses: hendrikmuhs/[email protected].23
uses: hendrikmuhs/[email protected].13
with:
variant: sccache
key: linux-ubuntu-22.04-${{ inputs.cachePrefix }}-${{ inputs.cmakePreset }}-${{ github.sha }}
restore-keys: linux-ubuntu-22.04-${{ inputs.cachePrefix }}-${{ inputs.cmakePreset }}
key: linux-ubuntu-20.04-${{ inputs.cachePrefix }}-${{ inputs.cmakePreset }}-${{ github.sha }}
restore-keys: linux-ubuntu-20.04-${{ inputs.cachePrefix }}-${{ inputs.cmakePreset }}
max-size: 1000M
- name: CMake Generation
@@ -76,7 +66,7 @@ jobs:
strip ./build/lsp/lsp
- name: Upload artifact
uses: actions/upload-artifact@v7
uses: actions/upload-artifact@v4
if: ${{ inputs.uploadArtifacts }}
with:
name: opengoal-linux-${{ inputs.cachePrefix }}
+6 -6
View File
@@ -13,12 +13,12 @@ on:
jobs:
build:
name: GCC
runs-on: ubuntu-22.04
runs-on: ubuntu-20.04
timeout-minutes: 60
steps:
- name: Checkout Repository
uses: actions/checkout@v6
uses: actions/checkout@v4
- name: Install Package Dependencies
run: |
@@ -34,11 +34,11 @@ jobs:
sudo update-alternatives --set g++ /usr/bin/g++-10
- name: Setup sccache
uses: hendrikmuhs/[email protected].23
uses: hendrikmuhs/[email protected].13
with:
variant: sccache
key: linux-ubuntu-22.04-${{ inputs.cachePrefix }}-${{ inputs.cmakePreset }}-${{ github.sha }}
restore-keys: linux-ubuntu-22.04-${{ inputs.cachePrefix }}-${{ inputs.cmakePreset }}
key: linux-ubuntu-20.04-${{ inputs.cachePrefix }}-${{ inputs.cmakePreset }}-${{ github.sha }}
restore-keys: linux-ubuntu-20.04-${{ inputs.cachePrefix }}-${{ inputs.cmakePreset }}
max-size: 1000M
- name: CMake Generation
@@ -52,7 +52,7 @@ jobs:
-DCMAKE_CXX_COMPILER_LAUNCHER=sccache
- name: Build Project
run: cmake --build build --parallel $((`nproc`))
run: cmake --build build --parallel $((`nproc`)) -- -w dupbuild=warn
- name: Run Tests
run: ./test.sh
+11 -31
View File
@@ -9,37 +9,29 @@ on:
cachePrefix:
required: true
type: string
uploadArtifacts:
required: false
type: boolean
default: false
jobs:
build:
name: ARM
runs-on: macos-15
runs-on: macos-12
timeout-minutes: 120
steps:
- name: Checkout Repository
uses: actions/checkout@v6
uses: actions/checkout@v4
- name: Set up ARM64 environment
run: sudo softwareupdate --install-rosetta --agree-to-license
- name: Install Package Dependencies
env:
HOMEBREW_NO_INSTALL_CLEANUP: 1
HOMEBREW_NO_ANALYTICS: 1
run: |
if ! brew install ninja nasm; then
brew update
brew install ninja nasm
fi
run: arch -arm64 brew install cmake ninja
- name: Setup sccache
uses: hendrikmuhs/[email protected].23
uses: hendrikmuhs/[email protected].13
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
@@ -54,25 +46,13 @@ jobs:
- name: Build Project
run: cmake --build build --parallel $((`sysctl -n hw.logicalcpu`))
- name: List libraries of gk
run: otool -L ./build/game/gk
- name: Run Tests
run: ./test.sh
- name: Prepare artifacts
if: ${{ inputs.uploadArtifacts }}
run: |
strip ./build/goalc/goalc
strip ./build/decompiler/extractor
strip ./build/game/gk
strip ./build/lsp/lsp
- name: Upload artifact
uses: actions/upload-artifact@v7
if: ${{ inputs.uploadArtifacts }}
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
+7 -27
View File
@@ -17,39 +17,22 @@ on:
jobs:
build:
name: Intel
runs-on: macos-15-intel
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@v6
# full checkout with tags if we ARE uploading artifacts
- name: Checkout Repository with Tags
if: ${{ inputs.uploadArtifacts }}
uses: actions/checkout@v6
with:
fetch-depth: 0
fetch-tags: true
uses: actions/checkout@v4
- name: Install Package Dependencies
env:
HOMEBREW_NO_INSTALL_CLEANUP: 1
HOMEBREW_NO_ANALYTICS: 1
run: |
if ! brew install ninja nasm; then
brew update
brew install ninja nasm
fi
run: brew install cmake nasm ninja
- name: Setup sccache
uses: hendrikmuhs/[email protected].23
uses: hendrikmuhs/[email protected].13
with:
variant: sccache
key: macos-15-intel-${{ inputs.cachePrefix }}-${{ inputs.cmakePreset }}-${{ github.sha }}
restore-keys: macos-15-intel-${{ 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
@@ -64,9 +47,6 @@ jobs:
- name: Build Project
run: cmake --build build --parallel $((`sysctl -n hw.logicalcpu`))
- name: List libraries of gk
run: otool -L ./build/game/gk
- name: Run Tests
run: ./test.sh
@@ -79,7 +59,7 @@ jobs:
strip ./build/lsp/lsp
- name: Upload artifact
uses: actions/upload-artifact@v7
uses: actions/upload-artifact@v4
if: ${{ inputs.uploadArtifacts }}
with:
name: opengoal-macos-${{ inputs.cachePrefix }}
+14 -83
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,47 +28,30 @@ jobs:
# macOS
build_macos_intel:
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
build_macos_arm_rosetta:
needs:
- cut_release
name: "🍎 MacOS"
uses: ./.github/workflows/macos-build.yaml
with:
cmakePreset: "Release-macos-x86_64-clang-static"
cachePrefix: "static-arm"
uploadArtifacts: true
secrets: inherit
# Upload the Artifacts
upload_artifacts:
if: github.repository == 'open-goal/jak-project'
needs:
- cut_release
- build_windows_clang
- build_linux_clang
- build_macos_intel
- build_macos_arm_rosetta
name: "Upload Artifacts"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
ref: ${{ needs.cut_release.outputs.new_tag }}
- uses: actions/checkout@v4
- name: Prepare Artifact Folder
run: mkdir -p ./ci-artifacts/final
- uses: actions/download-artifact@v8
- uses: actions/download-artifact@v4
name: Download all Artifacts
with:
path: ./ci-artifacts/
@@ -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-static-arm ./
pushd ci-artifacts/macos-arm
TAG_VAL=${{ needs.cut_release.outputs.new_tag }}
tar czf ../final/opengoal-macos-arm-${TAG_VAL}.tar.gz .
popd
chmod +x ./ci-artifacts/opengoal-macos-static-arm/lsp/lsp
cp ./ci-artifacts/opengoal-macos-static-arm/lsp/lsp ./ci-artifacts/final/opengoal-lsp-macos-arm-${TAG_VAL}.bin
- name: Upload Assets
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
TAG_VAL=${{ 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
+2 -2
View File
@@ -10,7 +10,7 @@ jobs:
if: github.repository == 'open-goal/jak-project'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v4
with:
token: ${{ secrets.BOT_PAT }}
@@ -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@v8
uses: peter-evans/create-pull-request@v6
with:
token: ${{ secrets.BOT_PAT }}
author: 'OpenGOALBot <[email protected]>'
+4 -13
View File
@@ -22,18 +22,8 @@ jobs:
timeout-minutes: 60
steps:
# minimal checkout if we're NOT uploading artifacts
- name: Checkout Repository
if: ${{ ! inputs.uploadArtifacts }}
uses: actions/checkout@v6
# full checkout with tags if we ARE uploading artifacts
- name: Checkout Repository with Tags
if: ${{ inputs.uploadArtifacts }}
uses: actions/checkout@v6
with:
fetch-depth: 0
fetch-tags: true
uses: actions/checkout@v4
- name: Install NASM
# TODO - Simplify this with just the first command once choco 2.0 rolls out everywhere
@@ -46,7 +36,7 @@ jobs:
}
- name: Setup sccache
uses: hendrikmuhs/[email protected].23
uses: hendrikmuhs/[email protected].13
with:
variant: sccache
key: windows-2022-${{ inputs.cachePrefix }}-${{ inputs.cmakePreset }}-${{ github.sha }}
@@ -76,9 +66,10 @@ jobs:
run: ./build/bin/goalc-test.exe --gtest_color=yes --gtest_brief=0 --gtest_filter="-*MANUAL_TEST*"
- name: Upload artifact
uses: actions/upload-artifact@v7
uses: actions/upload-artifact@v4
if: ${{ inputs.uploadArtifacts }}
with:
name: opengoal-windows-${{ inputs.cachePrefix }}
if-no-files-found: error
path: ./build/bin
+3 -2
View File
@@ -18,7 +18,7 @@ jobs:
steps:
- name: Checkout Repository
uses: actions/checkout@v6
uses: actions/checkout@v4
- name: Install NASM
# TODO - Simplify this with just the first command once choco 2.0 rolls out everywhere
@@ -31,7 +31,7 @@ jobs:
}
- name: Setup sccache
uses: hendrikmuhs/[email protected].23
uses: hendrikmuhs/[email protected].13
with:
variant: sccache
key: windows-2022-${{ inputs.cachePrefix }}-${{ inputs.cmakePreset }}-${{ github.sha }}
@@ -62,3 +62,4 @@ jobs:
GTEST_OUTPUT: "xml:opengoal-test-report.xml"
run: |
./build/bin/goalc-test.exe --gtest_color=yes --gtest_brief=0 --gtest_filter="-*MANUAL_TEST*"
+3 -6
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
@@ -86,4 +83,4 @@ __pycache__/
/TODO.md
unifont-15.0.03.ttf
*.diff
goalc-report.html
goalc-report.html
+1 -65
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",
@@ -224,20 +211,6 @@
"-debug"
]
},
{
"type": "default",
"project": "CMakeLists.txt",
"projectTarget": "gk.exe (bin\\gk.exe)",
"name": "Game - Jak 3 - Runtime (release)",
"args": [
"-v",
"--game",
"jak3",
"--",
"-boot",
"-fakeiso"
]
},
{
"type": "default",
"project": "CMakeLists.txt",
@@ -260,17 +233,6 @@
"jak2"
]
},
{
"type": "default",
"project": "CMakeLists.txt",
"projectTarget": "goalc.exe (bin\\goalc.exe)",
"name": "REPL - Jak 3",
"args": [
"--user-auto",
"--game",
"jak3"
]
},
{
"type": "default",
"project": "CMakeLists.txt",
@@ -364,32 +326,6 @@
"--config-override \"{\\\"decompile_code\\\": false, \\\"levels_extract\\\": true, \\\"allowed_objects\\\": []}\""
]
},
{
"type": "default",
"project": "CMakeLists.txt",
"projectTarget": "decompiler.exe (bin\\decompiler.exe)",
"name": "Decompiler - Jak X",
"args": [
"${workspaceRoot}/decompiler/config/jakx/jakx_config.jsonc",
"${workspaceRoot}/iso_data",
"${workspaceRoot}/decompiler_out",
"--version",
"ntsc_v1"
]
},
{
"type": "default",
"project": "CMakeLists.txt",
"projectTarget": "decompiler.exe (bin\\decompiler.exe)",
"name": "Decompiler - Jak X - PAL",
"args": [
"${workspaceRoot}/decompiler/config/jakx/jakx_config.jsonc",
"${workspaceRoot}/iso_data",
"${workspaceRoot}/decompiler_out",
"--version",
"pal"
]
},
{
"type": "default",
"project": "CMakeLists.txt",
@@ -432,7 +368,7 @@
"projectTarget": "extractor.exe (bin\\extractor.exe)",
"name": "Tools - Extractor - Full",
"args": [
"D:\\ISOs\\Jak\\Temp\\bad.iso"
"\"E:\\ISOs\\Jak\\Jak 1.iso\""
]
},
{
+4 -22
View File
@@ -5,31 +5,13 @@
"version": "0.2.0",
"configurations": [
{
"name": "Run C++ Tests LLDB",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/build/goalc-test",
"args": [
"--gtest_brief=0",
"--gtest_filter=*CodeTester*",
"--gtest_break_on_failure"
],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,
"MIMode": "lldb"
},
{
"name": "Append File Docs",
"name": "run python script",
"type": "python",
"request": "launch",
"program": "${workspaceFolder}/scripts/ci/lint-characters.py",
"program": "${workspaceFolder}/scripts/gsrc/compare-compilation-outputs.py",
"console": "integratedTerminal",
"cwd": "${workspaceFolder}",
"args": [
"--fix"
]
"args": []
},
]
}
}
+1 -5
View File
@@ -8,9 +8,5 @@
"editor.wordBasedSuggestions": "matchingDocuments",
"editor.snippetSuggestions": "top"
},
"cmake.configureOnOpen": false,
"files.associations": {
"xhash": "cpp",
"vector": "cpp"
}
"cmake.configureOnOpen": false
}
-77
View File
@@ -1,77 +0,0 @@
// Project-local debug tasks
//
// For more documentation on how to configure debug tasks,
// see: https://zed.dev/docs/debugger
[
{
"label": "Run Debugger - Jak X",
// "build": "Build - gk",
"program": "$ZED_WORKTREE_ROOT/out/build/Debug/bin/decompiler.exe",
"args": [
"./decompiler/config/jakx/jakx_config.jsonc",
"./iso_data",
"./decompiler_out",
"--version ntsc_v1",
"--config-override",
"{\"decompile_code\": true, \"levels_extract\": false}",
],
"request": "launch",
"adapter": "CodeLLDB",
},
{
"label": "Game - Jak 1 (Windows)",
"build": "Build - gk",
"program": "$ZED_WORKTREE_ROOT/out/build/Debug/bin/gk.exe",
"args": ["-v", "--game", "jak1", "--", "-fakeiso", "-debug"],
"request": "launch",
"adapter": "CodeLLDB",
},
{
"label": "Game - Jak 2 (Windows)",
"build": "Build - gk",
"program": "$ZED_WORKTREE_ROOT/out/build/Debug/bin/gk.exe",
"args": ["-v", "--game", "jak2", "--", "-fakeiso", "-debug"],
"request": "launch",
"adapter": "CodeLLDB",
},
{
"label": "Game - Jak 3 (Windows)",
"build": "Build - gk",
"program": "$ZED_WORKTREE_ROOT/out/build/Debug/bin/gk.exe",
"args": ["-v", "--game", "jak3", "--", "-fakeiso", "-debug"],
"request": "launch",
"adapter": "CodeLLDB",
},
{
"label": "REPL - Jak 1 (Windows)",
"build": "Build - goalc",
"program": "$ZED_WORKTREE_ROOT/out/build/Debug/bin/goalc.exe",
"args": ["--user-auto", "--game", "jak1"],
"request": "launch",
"adapter": "CodeLLDB",
},
{
"label": "REPL - Jak 2 (Windows)",
"build": "Build - goalc",
"program": "$ZED_WORKTREE_ROOT/out/build/Debug/bin/goalc.exe",
"args": ["--user-auto", "--game", "jak2"],
"request": "launch",
"adapter": "CodeLLDB",
},
{
"label": "REPL - Jak 3 (Windows)",
"build": "Build - goalc",
"program": "$ZED_WORKTREE_ROOT/out/build/Debug/bin/goalc.exe",
"args": ["--user-auto", "--game", "jak3"],
"request": "launch",
"adapter": "CodeLLDB",
},
{
"label": "Tests - Unit - Draft Only (Windows)",
"build": "Build - goalc-test",
"program": "$ZED_WORKTREE_ROOT/out/build/Debug/bin/goalc-test.exe",
"args": ["--gtest_brief=0", "--gtest_filter=\"*Draft*\""],
"request": "launch",
"adapter": "CodeLLDB",
},
]
-111
View File
@@ -1,111 +0,0 @@
// Project tasks configuration. See https://zed.dev/docs/tasks for documentation.
[
{
"label": "Generate CMake - Release",
"command": "task gen-cmake-release",
},
{
"label": "Generate CMake - Debug",
"command": "task gen-cmake-debug",
},
{
"label": "Build Project - Release",
"command": "task build-release",
},
{
"label": "Build Project - Debug",
"command": "task build-debug",
},
{
"label": "Build - goalc",
"command": "task build-debug",
"env": {
"CMAKE_BUILD_ADDITIONAL_ARGS": "--target goalc",
},
"cwd": "$ZED_WORKTREE_ROOT",
},
{
"label": "Build - goalc-test",
"command": "task build-debug",
"env": {
"CMAKE_BUILD_ADDITIONAL_ARGS": "--target goalc-test",
},
"cwd": "$ZED_WORKTREE_ROOT",
},
{
"label": "Build - gk",
"command": "task build-debug",
"env": {
"CMAKE_BUILD_ADDITIONAL_ARGS": "--target gk",
},
"cwd": "$ZED_WORKTREE_ROOT",
},
{
"label": "Tests - Unit - Brief",
"command": "task unit-tests",
"env": {
"TEST_FILTER": "--gtest_brief=0",
},
},
{
"label": "Tests - Unit - Verbose",
"command": "task unit-tests",
"env": {
"TEST_FILTER": "--gtest_brief=1",
},
},
{
"label": "Tests - Unit - Type Consistency",
"command": "task unit-tests",
"env": {
"TEST_FILTER": "--gtest_brief=0 --gtest_filter=\"*TypeConsistency*\"",
},
},
{
"label": "Tests - Unit - WithGameTests",
"command": "task unit-tests",
"env": {
"TEST_FILTER": "--gtest_brief=0 --gtest_filter=\"*WithGameTests*\"",
},
},
{
"label": "Tests - Offline Tests",
"command": "task offline-tests-fast",
},
{
"label": "Tests - Formatter",
"command": "task unit-tests",
"env": {
"TEST_FILTER": "--gtest_brief=0 --gtest_filter=\"*FormatterTests*\"",
},
},
{
"label": "Run - Game (Jak 1)",
"command": "task run-game",
"env": {
"GAME": "jak1",
},
},
{
"label": "Run - Game (Jak 2)",
"command": "task run-game",
"env": {
"GAME": "jak2",
},
},
{
"label": "Run - Game (Jak 3)",
"command": "task run-game",
"env": {
"GAME": "jak3",
},
},
{
"label": "Run - Decompiler",
"command": "task decomp",
},
{
"label": "Format",
"command": "task format",
},
]
+14 -39
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)
@@ -32,19 +31,6 @@ if (EXISTS "${CMAKE_CURRENT_BINARY_DIR}/compile_commands.json" )
"${PROJECT_SOURCE_DIR}/build/compile_commands.json")
endif()
# NOTE - for SDL, i think SDL3 regressed this - https://github.com/libsdl-org/SDL/pull/6455
# a more recent issue - https://github.com/libsdl-org/SDL/issues/12078
if (APPLE)
enable_language(OBJC)
execute_process(
COMMAND xcrun --show-sdk-path
OUTPUT_VARIABLE MACOSX_SYSROOT
OUTPUT_STRIP_TRAILING_WHITESPACE
)
# Tell CMake to use it
set(CMAKE_OSX_SYSROOT "${MACOSX_SYSROOT}" CACHE PATH "macOS SDK path" FORCE)
endif()
# Setup compiler flags
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
message(STATUS "Clang Detected - Setting Defaults")
@@ -57,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")
@@ -70,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
@@ -134,12 +116,11 @@ elseif(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
-Wsign-promo \
-fdiagnostics-color=always"
)
# TODO - make a proper flag for arm compiling
if (CMAKE_APPLE_SILICON_PROCESSOR STREQUAL "x86_64")
# pin to AVX for macOS, hopefully all macOS runners have atleast this architecture
# technically speaking, SSE4 is the cutoff for Apple Silicon so...only a matter of time!
if(NOT CMAKE_CXX_COMPILER_TARGET STREQUAL "arm64-apple-darwin")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mavx")
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native -mcrc")
endif()
# additional c++ flags for release mode for our projects
@@ -189,15 +170,16 @@ endif()
function(build_third_party_lib dir_name target_name)
add_subdirectory(third-party/${dir_name} EXCLUDE_FROM_ALL)
# Convert all public include dirs to SYSTEM
get_target_property(INCLUDES ${target_name} INTERFACE_INCLUDE_DIRECTORIES)
if(INCLUDES)
set_target_properties(${target_name} PROPERTIES
INTERFACE_SYSTEM_INCLUDE_DIRECTORIES "${INCLUDES}"
)
if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
# For Microsoft Visual C++ Compiler (MSVC)
target_compile_options(${target_name} PRIVATE /w)
elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
# For GNU Compiler Collection (GCC) or Clang
target_compile_options(${target_name} PRIVATE -w)
endif()
endfunction()
# Dependencies and Libraries
# includes relative to top level jak-project folder
include_directories(./)
@@ -210,9 +192,6 @@ include_directories(SYSTEM third-party/inja)
# TODO - probably integrate with ZSTD since we have it already
set(CURL_USE_LIBSSH2 OFF)
set(CURL_ZLIB OFF)
# suddenly became enabled on macOS atleast, only needed for unicode URLs
# wasn't being properly statically linked
set(USE_LIBIDN2 OFF)
if(WIN32)
set(CURL_USE_SCHANNEL ON) # native Windows SSL support
elseif(APPLE)
@@ -270,9 +249,9 @@ build_third_party_lib(zstd libzstd_static)
# build SDL
include(SDLOptions)
if(STATICALLY_LINK)
build_third_party_lib(SDL SDL3-static)
build_third_party_lib(SDL SDL2-static)
else()
build_third_party_lib(SDL SDL3-shared)
build_third_party_lib(SDL SDL2)
endif()
# build imgui
@@ -304,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)
+9 -63
View File
@@ -62,22 +62,12 @@
"name": "base-linux-debug",
"hidden": true,
"inherits": "base",
"binaryDir": "${sourceDir}/build/Debug/bin",
"binaryDir": "${sourceDir}/build/Release/bin",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"CMAKE_INSTALL_PREFIX": "${sourceDir}/build/install/${presetName}"
}
},
{
"name": "base-macos-debug",
"hidden": true,
"inherits": "base",
"binaryDir": "${sourceDir}/build/Debug/bin",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"CMAKE_INSTALL_PREFIX": "${sourceDir}/out/install/${presetName}"
}
},
{
"name": "base-macos-release",
"hidden": true,
@@ -88,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,
@@ -185,38 +159,16 @@
"inherits": ["base-linux-release", "base-clang"]
},
{
"name": "Debug-macos-arm64-clang",
"displayName": "MacOS ARM64 Debug (clang)",
"description": "Build for ARM64 with Clang as Debug",
"inherits": ["base-macos-arm64", "base-macos-debug", "base-clang"]
"name": "Release-macos-clang",
"displayName": "MacOS Release (clang)",
"description": "Build with Clang as Release without Debug Symbols",
"inherits": ["base-macos-release", "base-clang"]
},
{
"name": "Release-macos-arm64-clang",
"displayName": "MacOS ARM64 Release (clang)",
"description": "Build for ARM64 with Clang as Release without Debug Symbols",
"inherits": ["base-macos-release", "base-macos-arm64", "base-clang"]
},
{
"name": "Release-macos-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"
@@ -241,12 +193,6 @@
"ZYDIS_BUILD_SHARED_LIB": "OFF"
}
},
{
"name": "Debug-linux-clang",
"displayName": "Linux Release (clang)",
"description": "Build with Clang as Release with Debug Symbols",
"inherits": ["base-linux-debug", "base-clang"]
},
{
"name": "Debug-linux-clang-static",
"displayName": "Linux Static Release (clang)",
+1 -1
View File
@@ -1,6 +1,6 @@
ISC License
Copyright (c) 2020-2026 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
+300 -31
View File
@@ -13,7 +13,7 @@
## Please read first <!-- omit from toc -->
> [!IMPORTANT]
> Our repositories on GitHub are for development of the project and tracking active issues. Most of the information you will find here pertains to setting up the project for development purposes and is not relevant to the end-user.
> Our repositories on GitHub are primarily for development of the project and tracking active issues. Most of the information you will find here pertains to setting up the project for development purposes and is not relevant to the end-user.
For a setup guide on how to install and play the game there is the following video that you can check out: https://youtu.be/K84UUMnkJc4
@@ -22,27 +22,45 @@ For questions or additional information pertaining to the project, we have a Dis
Additionally, you can find further documentation and answers to **frequently asked questions** on the project's main website: https://opengoal.dev
> [!WARNING]
> **Do not use this decompilation project without the use of your own legally purchased copy of the game.** OpenGOAL does not include any assets from the original games, so you must provide your own legitimately obtained PS2 copy of the game. OpenGOAL supports every retail PAL, NTSC, and NTSC-J build, including Greatest Hits copies. Please note that does NOT include any of the later releases (PS3/PS4/PS5).
> **Do not use this decompilation project without providing your own legally purchased copy of the game.** We do not distribute any assets from the game - you must use your own legitimately obtained PS2 copy of the game. We support every retail PAL, NTSC, and NTSC-J build, including Greatest Hits copies.
- [Project Description](#project-description)
- [Current Status](#current-status)
- [Methodology](#methodology)
- [Setting up a Development Environment](#setting-up-a-development-environment)
- [OS Setup](#os-setup)
- [Editor Setup](#editor-setup)
- [Docker](#docker)
- [Linux](#linux)
- [Ubuntu (20.04)](#ubuntu-2004)
- [Arch](#arch)
- [Fedora](#fedora)
- [Windows](#windows)
- [Required Software](#required-software)
- [Using Visual Studio](#using-visual-studio)
- [MacOS](#macos)
- [Intel Based](#intel-based)
- [Apple Silicon](#apple-silicon)
- [VSCode](#vscode)
- [Building and Debugging](#building-and-debugging)
- [Building and Running the Game](#building-and-running-the-game)
- [Extract Assets](#extract-assets)
- [Build the Game (Running the Compiler)](#build-the-game-running-the-compiler)
- [Build the Game](#build-the-game)
- [Run the Game](#run-the-game)
- [Connecting the REPL to the Game](#connecting-the-repl-to-the-game)
- [Running the Game Without Auto-Booting](#running-the-game-without-auto-booting)
- [Interacting with the Game](#interacting-with-the-game)
- [Technical Project Overview](#technical-project-overview)
- [`goalc`](#goalc)
- [Running the compiler](#running-the-compiler)
- [`decompiler`](#decompiler)
- [Running the decompiler](#running-the-decompiler)
- [`goal_src/`](#goal_src)
- [`game` runtime](#game-runtime)
## Project Description
The project's goal is to port the original trilogy (Jak 1 -> Jak 3) to PC. Over 98% of the games were written in GOAL, a custom LISP language developed by Naughty Dog. Our strategy is:
This project is to port the original Jak and Daxter and Jak II to PC. Over 98% of the games are written in GOAL, a custom Lisp language developed by Naughty Dog. Our strategy is:
- decompile the original game code into human-readable GOAL code
- develop our own compiler for GOAL and recompile the game code for x86-64
- develop our own compiler for GOAL and recompile game code for x86-64
- create a tool to extract game assets into formats that can be easily viewed or modified
- create tools to repack game assets into a format that our port uses.
@@ -52,50 +70,217 @@ Our objectives are:
- try to match things from the original game and development as possible. For example, the original GOAL compiler supported live modification of code while the game is running, so we do the same, even though it's not required for just porting the game.
- support modifications. It should be possible to make edits to the code without everything else breaking.
At the moment we support **x86_64** on Windows, Linux and macOS (via Rosetta translation). There are no plans to ever make a mobile release.
We support both Linux and Windows on x86-64.
> We do not support, or plan to support the ARM architecture. This means that this will not run on devices such as an M1 Mac or a mobile device.
### Current Status
- Jak 1 has been considered in a polished, complete state for years at this point.
- Jak 2 is considered in beta due to a few issues we are aware of that need fixing, however to the casual user, the game is essentially complete.
- Jak 3 has a good amount of work left to do.
Jak 1 is largely playable from start to finish with a handful of bugs that are continually being ironed out. Jak 2 is in development.
![](./docs/img/promosmall1.png)
![](./docs/img/promosmall2.png)
YouTube playlist showcasing some of the early progress for Jak 1:
YouTube playlist:
https://www.youtube.com/playlist?list=PLWx9T30aAT50cLnCTY1SAbt2TtWQzKfXX
### Methodology
To assist with decompiling, we've built a decompiler that can process GOAL code and unpack game assets. We manually specify function types and locations where we believe the original code had type casts (or where they feel appropriate) until the decompilation succeeds, then we clean up the output of the decompiled code by adding comments and adjusting formatting, then save it in `goal_src/`.
To help with decompiling, we've built a decompiler that can process GOAL code and unpack game assets. We manually specify function types and locations where we believe the original code had type casts (or where they feel appropriate) until the decompiler succeeds, then we clean up the output of the decompiled code by adding comments and adjusting formatting, then save it in `goal_src`.
Our decompiler is designed specifically for processing the output of the original GOAL compiler. As a result, when given correct casts, it often produces code that can be directly fed into a compiler and works perfectly. This is continually tested as part of our unit tests.
## Setting up a Development Environment
The remainder of this README is aimed at people interested in building the project from source, typically with the intention of contributing as a developer.
The remainder of this README is catered towards people interested in building the project from source, typically with the intention on contributing as a developer.
If this does not sound like you and you just want to play the game, refer to the above section [Quick Start](#quick-start)
### OS Setup
### Docker
- [Windows](/docs/setup/system/windows.md)
- [Linux](/docs/setup/system/linux.md)
- [MacOS](/docs/setup/system/macos.md)
- [Docker](/docs/setup/system/docker.md)
All three Linux systems are supported using Docker.
### Editor Setup
Pick your supported prefered flavour of linux and build your chosen image
You can of course use whatever editor you want, but here is some documentation that should help you get started on some of the editor's we have used and have written about:
```
docker build -f docker/(Arch|Fedora|Ubuntu)/Dockerfile -t jak .
```
- [Visual Studio (Windows)](/docs/setup/dev/vs.md)
- [Visual Studio Code](/docs/setup/dev/vscode.md)
- [Zed](/docs/setup/dev/zed.md)
This will create an image with all required dependencies and already built.
```
docker run -v "$(pwd)"/build:/home/jak/jak-project/build -it jak bash
```
Note: If you change the content of the `build/` directory you'll need to rerun the `build` command. Alternatively you can get the build via `docker cp`.
This will link your `build/` folder to the images so can validate your build or test it on an external device.
Docker images can be linked into your IDE (e.g. CLion) to help with codesniffing, static analysis, run tests and continuous build.
Unfortunately you'll still need task runner on your local machine to run the game or instead, manually run the game via the commands found in `Taskfile.yml`.
### Linux
#### Ubuntu (20.04)
Install packages and init repository:
```sh
sudo apt install gcc make cmake build-essential g++ nasm clang-format libxrandr-dev libxinerama-dev libxcursor-dev libpulse-dev libxi-dev python libgl1-mesa-dev libssl-dev
sudo sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b /usr/local/bin
```
Compile:
```sh
cmake -B build && cmake --build build -j 8
```
Run tests:
```sh
./test.sh
```
Note: we have found that `clang` and `lld` are significantly faster to compile and link than `gcc`, generate faster code, and have better warning messages. To install these:
```sh
sudo apt install lld clang
```
and run `cmake` (in a fresh build directory) with:
```sh
cmake -DCMAKE_SHARED_LINKER_FLAGS="-fuse-ld=lld" -DCMAKE_EXE_LINKER_FLAGS="-fuse-ld=lld" -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ ..
```
#### Arch
Install packages and init repository:
```sh
sudo pacman -S cmake libpulse base-devel nasm python libx11 libxrandr libxinerama libxcursor libxi
yay -S go-task
```
For Arch only, replace `task` with `go-task` in the rest of the instructions.
Compile:
```sh
cmake -B build && cmake --build build -j 8
```
Run tests:
```sh
./test.sh
```
#### Fedora
Install packages and init repository:
```sh
sudo dnf install cmake python lld clang nasm libX11-devel libXrandr-devel libXinerama-devel libXcursor-devel libXi-devel pulseaudio-libs-devel mesa-libGL-devel
sudo sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b /usr/local/bin
```
Compile with `clang`:
```sh
cmake -DCMAKE_SHARED_LINKER_FLAGS="-fuse-ld=lld" -DCMAKE_EXE_LINKER_FLAGS="-fuse-ld=lld" -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -B build
cmake --build build -j$(nproc)
```
Run tests:
```sh
./test.sh
```
### Windows
#### Required Software
We primarily use Visual Studio on Windows for C++ development. Download the latest community edition from [here](https://visualstudio.microsoft.com/vs/). At the time of writing this is Visual Studio 2022.
You will require the `Desktop development with C++` workload. This can be selected during the installation, or after via the `Visual Studio Installer`, modifying the Visual Studio Installation.
On Windows, it's recommended to use a package manager, we use Scoop. Follow the steps on the bottom of the homepage [here](https://scoop.sh/) to get it.
Once Scoop is installed, run the following commands:
```sh
scoop install git llvm nasm python task
```
#### Using Visual Studio
Clone the repository by running the following command in your folder of choice.
```sh
git clone https://github.com/open-goal/jak-project.git
```
This will create a `jak-project` folder, open the project as a CMake project via Visual Studio.
![](./docs/img/windows/open-project.png)
Then build the entire project as `Windows Release (clang)`. You can also press Ctrl+Shift+B as a hotkey for Build All. We currently prefer `clang` on Windows as opposed to `msvc`, though it should work as well!
![](./docs/img/windows/release-build.png)
![](./docs/img/windows/build-all.png)
### MacOS
> 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:
```bash
xcode-select --install
```
#### 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-clang
cmake --build build --parallel $((`sysctl -n hw.logicalcpu`))
```
#### 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-clang
cmake --build build --parallel $((`sysctl -n hw.logicalcpu`))
```
You may have to add the MacOS SDK to your `LIBRARY_PATH`:
- `export LIBRARY_PATH="$LIBRARY_PATH:/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib"`
### VSCode
If you either don't want to or cannot use Visual Studio for working with the C++ project, VSCode is a good alternatively.
The `clangd` extension is [recommended](https://marketplace.visualstudio.com/items?itemName=llvm-vs-code-extensions.vscode-clangd) and requires `clangd` to be on your `$PATH`. If you can run `clangd` in a terminal successfully then you should be good to go.
Once you generate your CMake for the first time the clangd LSP should be able to index the project and give you intellisense.
#### Building and Debugging
TODO - Consider Contributing Documentation :)
### Building and Running the Game
Getting a running game involves 4 main steps:
Getting a running game involves 4 steps:
1. Build C++ tools (follow Getting Started steps above for your platform)
2. Extract assets from the game
@@ -104,16 +289,25 @@ Getting a running game involves 4 main steps:
#### Extract Assets
First, we have to setup our environment so we know which game and version we are operating with. For the black label version of Jak 1 we would run the following:
First, setup your settings so the following scripts know which game you are using, and which version. For the black label version of the game, run the following in a terminal:
```sh
task set-game-jak1
task set-decomp-ntscv1 # or for example for PAL, `task set-decomp-pal`
task set-decomp-ntscv1
```
For other versions of the game, you will need to use a different `-set-decomp-<VERSION>` command. An example for the PAL version:
```sh
task set-game-jak1
task set-decomp-pal
```
> Run `task --list` to see the other available options
Next, ensure you extract your ISO file contents into the relevant `iso_data/<game-name>` folder. In the case of Jak 1 this is `iso_data/jak1`.
> At the time of writing, only Jak 1 is expected to work end-to-end!
The first step is to extract your ISO file contents into the `iso_data/<game-name>` folder. In the case of Jak 1 this is `iso_data/jak1`.
Once this is done, open a terminal in the `jak-project` folder and run the following:
@@ -121,7 +315,7 @@ Once this is done, open a terminal in the `jak-project` folder and run the follo
task extract
```
#### Build the Game (Running the Compiler)
#### Build the Game
The next step is to build the game itself. To do so, in the same terminal run the following:
@@ -158,7 +352,7 @@ g > (mi)
#### Run the Game
Finally the game can be launched. Open a second terminal from the `jak-project` directory and run the following:
Finally the game can be ran. Open a second terminal from the `jak-project` directory and run the following:
```sh
task boot-game
@@ -214,6 +408,81 @@ gc> (test-play)
gc>
```
#### Interacting with the Game
In the graphics window, you can use the period key to bring up the debug menu. Controllers also work, using the same mapping as the original game.
Check out the `pc_debug`, `examples` and `pc` folders under `goal_src` for some examples of GOAL code we wrote. The debug files that are not loaded automatically by the engine have instructions for how to run them.
## Technical Project Overview
Some more detail about the various components of the project can be found [here](/docs/project-overview.md)
There are four main components to the project.
1. `goalc` - the GOAL compiler for x86-64
2. `decompiler` - our decompiler
3. `goal_src/` - the folder containing all OpenGOAL / GOOS code
4. `game` - aka the runtime written in C++
Let's break down each component.
### `goalc`
Our implementation of GOAL is called OpenGOAL.
All of the compiler source code is in `goalc/`. The compiler is controlled through a prompt which can be used to enter commands to compile, connect to a running GOAL program for interaction, run the OpenGOAL debugger, or, if you are connected to a running GOAL program, can be used as a REPL to run code interactively. In addition to compiling code files, the compiler has features to pack and build data files.
#### Running the compiler
**Environment Agnostic**
If you have installed `task` as recommended above, you can run the compiler with `task repl`
**Linux**
To run the compiler on Linux, there is a script `scripts/shell/gc.sh`.
**Windows**
On Windows, there is a `scripts/batch/gc.bat` scripts and a `scripts/batch/gc-no-lt.bat` script, the latter of which will not attempt to automatically attach to a running target.
### `decompiler`
The second component to the project is the decompiler.
The decompiler will output code and other data intended to be inspected by humans in the `decompiler_out` folder. Files in this folder will not be used by the compiler.
#### Running the decompiler
You must have a copy of the PS2 game and place all files from the DVD inside a folder corresponding to the game within `iso_data` folder (`jak1` for Jak 1 Black Label, etc.), as seen in this picture:
![](./docs/img/iso_data-help.png)
The decompiler will extract assets to the `assets` folder. These assets will be used by the compiler when building the port, and you may want to turn asset extraction off after running it once.
**Environment Agnostic**
If you have installed `task` as recommended above, you can run the compiler with `task decomp`
**Linux**
To run, you can use `scripts/shell/decomp.sh` to run the decompiler
**Windows**
To run, you can use `scripts/shell/decomp-jak1.bat` to run the decompiler
### `goal_src/`
The game source code, written in OpenGOAL, is located in `goal_src`. All GOAL and GOOS code should be in this folder.
### `game` runtime
The final component is the "runtime", located in `game`. This is the part of the game that's written in C++.
In the port, that includes:
- The "C Kernel", which contains the GOAL linker and some low-level GOAL language features. GOAL has a completely custom dynamically linked object file format so in order to load the first GOAL code, you need a linker written in C++. Some low-level functions for memory allocation, communicating with the I/O Processor, symbol table, strings, and the type system are also implemented in C, as these are required for the linker. It also listens for incoming messages from the compiler and passes them to the running game. This also initializes the game, by initializing the PS2 hardware, allocating the GOAL heaps, loading the GOAL kernel off of the DVD, and executing the kernel dispatcher function. This is in the `game/kernel` folder. This should be as close as possible to the game, and all differences should be noted with a comment.
- Implementation of Sony's standard library. GOAL code can call C library functions, and Naughty Dog used some Sony library functions to access files, memory cards, controllers, and communicate with the separate I/O Processor. The library functions are in `game/sce`. Implementations of library features specific to the PC port are located in `game/system`.
- The I/O Processor driver, OVERLORD. The PS2 had a separate CPU called the I/O Processor (IOP) that was directly connected to the DVD drive hardware and the sound hardware. Naughty Dog created a custom driver for the IOP that handled streaming data off of the DVD. It is much more complicated than I first expected. It's located in `game/overlord`. Like the C kernel, we try to keep this as close as possible to the actual game.
- Sound code. Naughty Dog used a third party library for sound called `989SND`. Code for the library and an interface for it is located in `game/sound`.
- PC specific graphics code. We have a functional OpenGL renderer and context that can create a game window and display graphics on it. The specific renderers used by the game however are mostly implemented. Aside from post-processing effects, everything in the game is rendered. This is located in `game/graphics`. While many liberties will be taken to make this work, the end result should very closely match the actual game.
- Extra assets used by the port in some fashion, located in `game/assets`. These include extra text files, icons, etc.
+41 -95
View File
@@ -10,35 +10,33 @@ dotenv:
tasks:
# SETTINGS / CONFIGURATION
settings:
- "{{.PYTHON}} ./scripts/tasks/update-env.py --info"
- 'python ./scripts/tasks/update-env.py --info'
set-game-jak1:
- "{{.PYTHON}} ./scripts/tasks/update-env.py --game jak1"
- 'python ./scripts/tasks/update-env.py --game jak1'
set-game-jak2:
- "{{.PYTHON}} ./scripts/tasks/update-env.py --game jak2"
- 'python ./scripts/tasks/update-env.py --game jak2'
set-game-jak3:
- "{{.PYTHON}} ./scripts/tasks/update-env.py --game jak3"
set-game-jakx:
- "{{.PYTHON}} ./scripts/tasks/update-env.py --game jakx"
- 'python ./scripts/tasks/update-env.py --game jak3'
set-decomp-ntscv1:
desc: "aka black label"
cmds:
- "{{.PYTHON}} ./scripts/tasks/update-env.py --decomp_config ntscv1"
- 'python ./scripts/tasks/update-env.py --decomp_config ntscv1'
set-decomp-ntscv2:
desc: "aka red label"
cmds:
- "{{.PYTHON}} ./scripts/tasks/update-env.py --decomp_config ntscv2"
- 'python ./scripts/tasks/update-env.py --decomp_config ntscv2'
set-decomp-pal:
desc: "PAL region version"
cmds:
- "{{.PYTHON}} ./scripts/tasks/update-env.py --decomp_config pal"
- 'python ./scripts/tasks/update-env.py --decomp_config pal'
set-decomp-ntscjp:
desc: "NTSC-J region version"
cmds:
- "{{.PYTHON}} ./scripts/tasks/update-env.py --decomp_config ntscjp"
- 'python ./scripts/tasks/update-env.py --decomp_config ntscjp'
set-decomp-ntscko:
desc: "NTSC-K region version"
cmds:
- "{{.PYTHON}} ./scripts/tasks/update-env.py --decomp_config ntscko"
- 'python ./scripts/tasks/update-env.py --decomp_config ntscko'
# GENERAL
extract:
desc: "Extracts the game's assets from './iso_data' with the set decompiler config"
@@ -46,7 +44,7 @@ tasks:
- sh: test -f {{.DECOMP_BIN_RELEASE_DIR}}/decompiler{{.EXE_FILE_EXTENSION}}
msg: "Couldn't locate decompiler executable in '{{.DECOMP_BIN_RELEASE_DIR}}/decompiler'"
cmds:
- '{{.DECOMP_BIN_RELEASE_DIR}}/decompiler "./decompiler/config/{{.DECOMP_CONFIG}}" "./iso_data" "./decompiler_out" --version "{{.DECOMP_CONFIG_VERSION}}" --config-override ''{"decompile_code": false, "levels_extract": true, "allowed_objects": []}'''
- "{{.DECOMP_BIN_RELEASE_DIR}}/decompiler \"./decompiler/config/{{.DECOMP_CONFIG}}\" \"./iso_data\" \"./decompiler_out\" --version \"{{.DECOMP_CONFIG_VERSION}}\" --config-override '{\"decompile_code\": false, \"levels_extract\": true, \"allowed_objects\": []}'"
boot-game:
desc: "Boots the game, it will fail if it's not already compiled!"
preconditions:
@@ -69,35 +67,6 @@ tasks:
cmds:
- "{{.GK_BIN_RELEASE_DIR}}/gk -v --game {{.GAME}} -- -fakeiso -debug"
# DEVELOPMENT
clean-cmake:
desc: "Cleans up any existing cmake artifacts"
cmds:
- cmd: "{{.PYTHON}} ./scripts/tasks/delete-file-or-folder.py --path ./build"
- cmd: "{{.PYTHON}} ./scripts/tasks/delete-file-or-folder.py --path ./out/build"
gen-cmake:
desc: "Generate the CMake"
cmds:
- "cmake {{.CMAKE_GEN_BUILD_DIR_DEBUG}} --preset={{.CMAKE_PRESET}}"
gen-cmake-release:
desc: "Generate the CMake"
cmds:
- "cmake {{.CMAKE_GEN_BUILD_DIR_RELEASE}} --preset={{.DEFAULT_CMAKE_RELEASE_PRESET}}"
gen-cmake-debug:
desc: "Generate the CMake"
cmds:
- "cmake {{.CMAKE_GEN_BUILD_DIR_DEBUG}} --preset={{.DEFAULT_CMAKE_DEBUG_PRESET}}"
build:
desc: "Build the project using the generated CMake"
cmds:
- "cmake {{.CMAKE_BUILD_DIR_DEBUG}} --parallel 8"
build-release:
desc: "Build the project using the generated CMake"
cmds:
- "cmake {{.CMAKE_BUILD_DIR_RELEASE}} --parallel 8"
build-debug:
desc: "Build the project using the generated CMake"
cmds:
- "cmake {{.CMAKE_BUILD_DIR_DEBUG}} --parallel 8"
repl:
desc: "Start the REPL"
preconditions:
@@ -114,9 +83,9 @@ tasks:
format:
desc: "Format code"
cmds:
- cmd: "{{.PYTHON}} ./scripts/cpp/format-includes.py"
- cmd: "{{.PYTHON}} ./scripts/ci/lint-trailing-whitespace.py --fix"
- cmd: "{{.PYTHON}} ./third-party/run-clang-format/run-clang-format.py -r common decompiler game goalc test tools lsp -i"
- cmd: python ./scripts/cpp/format-includes.py
- cmd: python ./scripts/ci/lint-trailing-whitespace.py --fix
- cmd: python ./third-party/run-clang-format/run-clang-format.py -r common decompiler game goalc test tools lsp -i
- task: format-json
format-gsrc:
desc: "Run formatter on gsrc file"
@@ -126,63 +95,54 @@ tasks:
cmds:
- "{{.FORMATTER_BIN_RELEASE_DIR}}/formatter --write --file '{{.FILE}}'"
# DECOMPILING
disasm:
cmds:
- '{{.DECOMP_BIN_RELEASE_DIR}}/decompiler "./decompiler/config/{{.DECOMP_CONFIG}}" "./iso_data" "./decompiler_out" --version "{{.DECOMP_CONFIG_VERSION}}" --config-override ''{"disassemble_code": true, "dump_function_metadata": true, "levels_extract": false}'''
decomp-no-override:
cmds:
- '{{.DECOMP_BIN_RELEASE_DIR}}/decompiler "./decompiler/config/{{.DECOMP_CONFIG}}" "./iso_data" "./decompiler_out" --version "{{.DECOMP_CONFIG_VERSION}}"'
decomp:
cmds:
- '{{.DECOMP_BIN_RELEASE_DIR}}/decompiler "./decompiler/config/{{.DECOMP_CONFIG}}" "./iso_data" "./decompiler_out" --version "{{.DECOMP_CONFIG_VERSION}}" --config-override ''{"decompile_code": true, "levels_extract": false}'''
- "{{.DECOMP_BIN_RELEASE_DIR}}/decompiler \"./decompiler/config/{{.DECOMP_CONFIG}}\" \"./iso_data\" \"./decompiler_out\" --version \"{{.DECOMP_CONFIG_VERSION}}\" --config-override '{\"decompile_code\": true, \"levels_extract\": false}'"
decomp-file:
cmds:
- '{{.DECOMP_BIN_RELEASE_DIR}}/decompiler "./decompiler/config/{{.DECOMP_CONFIG}}" "./iso_data" "./decompiler_out" --version "{{.DECOMP_CONFIG_VERSION}}" --config-override ''{"decompile_code": true, "levels_extract": false, "allowed_objects": ["{{.FILE}}"]}'''
- "{{.DECOMP_BIN_RELEASE_DIR}}/decompiler \"./decompiler/config/{{.DECOMP_CONFIG}}\" \"./iso_data\" \"./decompiler_out\" --version \"{{.DECOMP_CONFIG_VERSION}}\" --config-override '{\"decompile_code\": true, \"levels_extract\": false, \"allowed_objects\": [\"{{.FILE}}\"]}'"
decomp-clean:
cmds:
- '{{.PYTHON}} ./scripts/tasks/clean-decomp.py --game "{{.GAME}}"'
- python ./scripts/tasks/clean-decomp.py --game "{{.GAME}}"
lint-gsrc-file:
cmds:
- '{{.PYTHON}} ./scripts/gsrc/lint-gsrc-file.py --game {{.GAME}} --file "{{.FILE}}"'
- python ./scripts/gsrc/lint-gsrc-file.py --game {{.GAME}} --file "{{.FILE}}"
update-gsrc:
cmds:
- '{{.PYTHON}} ./scripts/gsrc/update-gsrc-via-refs.py --game "{{.GAME}}" --decompiler "{{.DECOMP_BIN_RELEASE_DIR}}/decompiler" --decompiler_config {{.DECOMP_CONFIG}} --version {{.DECOMP_CONFIG_VERSION}}'
- python ./scripts/gsrc/update-gsrc-via-refs.py --game "{{.GAME}}" --decompiler "{{.DECOMP_BIN_RELEASE_DIR}}/decompiler" --decompiler_config {{.DECOMP_CONFIG}} --version {{.DECOMP_CONFIG_VERSION}}
update-gsrc-glob:
cmds:
- '{{.PYTHON}} ./scripts/gsrc/update-gsrc-via-refs.py --game "{{.GAME}}" --file_pattern "{{.GLOB}}" --decompiler "{{.DECOMP_BIN_RELEASE_DIR}}/decompiler" --decompiler_config {{.DECOMP_CONFIG}} --version {{.DECOMP_CONFIG_VERSION}}'
- python ./scripts/gsrc/update-gsrc-via-refs.py --game "{{.GAME}}" --file_pattern "{{.GLOB}}" --decompiler "{{.DECOMP_BIN_RELEASE_DIR}}/decompiler" --decompiler_config {{.DECOMP_CONFIG}} --version {{.DECOMP_CONFIG_VERSION}}
update-gsrc-file:
cmds:
- task: decomp-file
- '{{.PYTHON}} ./scripts/gsrc/update-from-decomp.py --game "{{.GAME}}" --file "{{.FILE}}"'
- python ./scripts/gsrc/update-from-decomp.py --game "{{.GAME}}" --file "{{.FILE}}"
- task: lint-gsrc-file
copy-common-naming:
cmds:
- '{{.PYTHON}} ./scripts/gsrc/copy-common-naming.py --file "{{.FILE}}" --decompiler "{{.DECOMP_BIN_RELEASE_DIR}}/decompiler"'
- python ./scripts/gsrc/copy-common-naming.py --file "{{.FILE}}" --decompiler "{{.DECOMP_BIN_RELEASE_DIR}}/decompiler"
- task: format-json
copy-common-naming-from-refs:
cmds:
- '{{.PYTHON}} ./scripts/gsrc/copy-common-naming.py --update-names-from-refs --decompiler "{{.DECOMP_BIN_RELEASE_DIR}}/decompiler"'
- python ./scripts/gsrc/copy-common-naming.py --update-names-from-refs --decompiler "{{.DECOMP_BIN_RELEASE_DIR}}/decompiler"
- task: format-json
# ASSET RIPPING
rip-textures:
cmds:
- '{{.DECOMP_BIN_RELEASE_DIR}}/decompiler "./decompiler/config/{{.DECOMP_CONFIG}}" "./iso_data" "./decompiler_out" --version "{{.DECOMP_CONFIG_VERSION}}" --config-override ''{"decompile_code": false, "levels_extract": true, "save_texture_pngs": true}'''
- "{{.DECOMP_BIN_RELEASE_DIR}}/decompiler \"./decompiler/config/{{.DECOMP_CONFIG}}\" \"./iso_data\" \"./decompiler_out\" --version \"{{.DECOMP_CONFIG_VERSION}}\" --config-override '{\"decompile_code\": false, \"levels_extract\": true, \"save_texture_pngs\": true}'"
rip-levels:
cmds:
- '{{.DECOMP_BIN_RELEASE_DIR}}/decompiler "./decompiler/config/{{.DECOMP_CONFIG}}" "./iso_data" "./decompiler_out" --version "{{.DECOMP_CONFIG_VERSION}}" --config-override ''{"decompile_code": false, "levels_extract": true, "rip_levels": true}'''
- "{{.DECOMP_BIN_RELEASE_DIR}}/decompiler \"./decompiler/config/{{.DECOMP_CONFIG}}\" \"./iso_data\" \"./decompiler_out\" --version \"{{.DECOMP_CONFIG_VERSION}}\" --config-override '{\"decompile_code\": false, \"levels_extract\": true, \"rip_levels\": true}'"
rip-collision:
cmds:
- '{{.DECOMP_BIN_RELEASE_DIR}}/decompiler "./decompiler/config/{{.DECOMP_CONFIG}}" "./iso_data" "./decompiler_out" --version "{{.DECOMP_CONFIG_VERSION}}" --config-override ''{"decompile_code": false, "levels_extract": true, "extract_collision": true, "rip_collision": true}'''
rip-audio:
cmds:
- '{{.DECOMP_BIN_RELEASE_DIR}}/decompiler "./decompiler/config/{{.DECOMP_CONFIG}}" "./iso_data" "./decompiler_out" --version "{{.DECOMP_CONFIG_VERSION}}" --config-override ''{"decompile_code": false, "levels_extract": true, "rip_streamed_audio": true}'''
- "{{.DECOMP_BIN_RELEASE_DIR}}/decompiler \"./decompiler/config/{{.DECOMP_CONFIG}}\" \"./iso_data\" \"./decompiler_out\" --version \"{{.DECOMP_CONFIG_VERSION}}\" --config-override '{\"decompile_code\": false, \"levels_extract\": true, \"extract_collision\": true, \"rip_collision\": true}'"
# TOOLS
analyze-ee-memory:
cmds:
- '{{.PYTHON}} ./scripts/tasks/extract-zip.py --file "{{.FILE}}" --out ./savestate_out/'
- "{{.MEMDUMP_BIN_RELEASE_DIR}}/memory_dump_tool ./savestate_out/eeMemory.bin --output-path ./ --game {{.GAME}} > ee-analysis.log"
- python ./scripts/tasks/extract-zip.py --file "{{.FILE}}" --out ./savestate_out/
- '{{.MEMDUMP_BIN_RELEASE_DIR}}/memory_dump_tool ./savestate_out/eeMemory.bin --output-path ./ --game {{.GAME}} > ee-analysis.log'
watch-pcsx2:
# {{.PYTHON}} -m pip install -U "watchdog[watchmedo]"
# python -m pip install -U "watchdog[watchmedo]"
cmds:
- watchmedo shell-command --drop --patterns="*.p2s" --recursive --command='task analyze-ee-memory FILE="${watch_src_path}"' "{{.SAVESTATE_DIR}}"
vars:
@@ -190,59 +150,45 @@ tasks:
type-search:
desc: Just an example to show it running
cmds:
- '{{.TYPESEARCH_BIN_RELEASE_DIR}}/type_searcher --output-path ./search-results.json --game {{.GAME}} --fields ''[{"type":"int16","offset":2},{"type":"int16","offset":4}]'''
- "{{.TYPESEARCH_BIN_RELEASE_DIR}}/type_searcher --output-path ./search-results.json --game {{.GAME}} --fields '[{\"type\":\"int16\",\"offset\":2},{\"type\":\"int16\",\"offset\":4}]'"
update-treesitter:
desc: Updates locally built tree-sitter rules
cmds:
- cd ../tree-sitter-opengoal && yarn gen
- '{{.PYTHON}} ./scripts/tasks/cp.py --src "../tree-sitter-opengoal/src/*" --dest "./third-party/tree-sitter/tree-sitter-opengoal"'
- '{{.PYTHON}} ./scripts/tasks/cp.py --src "../tree-sitter-opengoal/grammar.js" --dest "./third-party/tree-sitter/tree-sitter-opengoal"'
- python ./scripts/tasks/cp.py --src "../tree-sitter-opengoal/src/*" --dest "./third-party/tree-sitter/tree-sitter-opengoal"
- python ./scripts/tasks/cp.py --src "../tree-sitter-opengoal/grammar.js" --dest "./third-party/tree-sitter/tree-sitter-opengoal"
fix-translations:
desc: Finds and tries to fix invalid translation Characters
cmds:
- "{{.PYTHON}} ./scripts/ci/lint-autoglottonyms.py --fix"
- "{{.PYTHON}} ./scripts/ci/lint-characters.py --fix"
- python ./scripts/ci/lint-characters.py --fix
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"
- python ./scripts/ci/lint-trailing-whitespace.py
# TESTS
unit-tests:
cmds:
- "{{.GOALCTEST_BIN_DEBUG_DIR}}/goalc-test{{.EXE_FILE_EXTENSION}} {{.TEST_FILTER}}"
offline-tests: # ran by jenkins
cmds:
- '{{.OFFLINETEST_BIN_RELEASE_DIR}}/offline-test{{.EXE_FILE_EXTENSION}} --iso_data_path "./iso_data/{{.GAME}}" --game {{.GAME}} --fail-on-cmp'
- '{{.OFFLINETEST_BIN_RELEASE_DIR}}/offline-test --iso_data_path "./iso_data/{{.GAME}}" --game {{.GAME}} --fail-on-cmp'
offline-test-file:
cmds:
- '{{.OFFLINETEST_BIN_RELEASE_DIR}}/offline-test{{.EXE_FILE_EXTENSION}} --iso_data_path "./iso_data/{{.GAME}}" --game {{.GAME}} --file {{.FILE}}'
- '{{.OFFLINETEST_BIN_RELEASE_DIR}}/offline-test --iso_data_path "./iso_data/{{.GAME}}" --game {{.GAME}} --file {{.FILE}}'
offline-tests-fast:
cmds:
- '{{.OFFLINETEST_BIN_RELEASE_DIR}}/offline-test{{.EXE_FILE_EXTENSION}} --iso_data_path "./iso_data/{{.GAME}}" --game {{.GAME}} --pretty-print --num_threads 8 --dump_current_output --fail-on-cmp'
- '{{.OFFLINETEST_BIN_RELEASE_DIR}}/offline-test --iso_data_path "./iso_data/{{.GAME}}" --game {{.GAME}} --pretty-print --num_threads 32 --dump_current_output --fail-on-cmp'
# TODO - amalgamate offline-tests and this task, run twice if the previous step fails
update-ref-tests:
cmds:
- cmd: "{{.PYTHON}} ./scripts/tasks/delete-file-or-folder.py --path failures"
- cmd: '{{.OFFLINETEST_BIN_RELEASE_DIR}}/offline-test --iso_data_path "./iso_data/{{.GAME}}" --game {{.GAME}} --pretty-print --num_threads 8 --dump_current_output --fail-on-cmp'
- cmd: python ./scripts/tasks/delete-file-or-folder.py --path failures
- cmd: '{{.OFFLINETEST_BIN_RELEASE_DIR}}/offline-test --iso_data_path "./iso_data/{{.GAME}}" --game {{.GAME}} --pretty-print --num_threads 32 --dump_current_output --fail-on-cmp'
ignore_error: true
- "{{.PYTHON}} ./scripts/update_decomp_reference.py ./failures ./test/decompiler/reference/ --game {{.GAME}}"
- python ./scripts/update_decomp_reference.py ./failures ./test/decompiler/reference/ --game {{.GAME}}
- task: offline-tests-fast
update-ref-file:
cmds:
- cmd: "{{.PYTHON}} ./scripts/tasks/delete-file-or-folder.py --path failures"
- cmd: python ./scripts/tasks/delete-file-or-folder.py --path failures
- cmd: '{{.OFFLINETEST_BIN_RELEASE_DIR}}/offline-test --iso_data_path "./iso_data/{{.GAME}}" --file {{.FILE}} --game {{.GAME}} --dump_current_output --fail-on-cmp'
ignore_error: true
- "{{.PYTHON}} ./scripts/update_decomp_reference.py ./failures ./test/decompiler/reference/ --game {{.GAME}}"
- python ./scripts/update_decomp_reference.py ./failures ./test/decompiler/reference/ --game {{.GAME}}
- task: offline-test-file
type-test:
cmds:
- cmd: '{{.GOALCTEST_BIN_RELEASE_DIR}}/goalc-test --gtest_brief=0 --gtest_filter="*{{.TYPE_CONSISTENCY_TEST_FILTER}}*" --gtest_break_on_failure'
tests-filtered:
cmds:
- cmd: '{{.GOALCTEST_BIN_RELEASE_DIR}}/goalc-test --gtest_brief=0 --gtest_filter="*{{.FILTER}}*" --gtest_break_on_failure'
+1 -13
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()
@@ -83,11 +76,7 @@ add_library(common
util/dialogs.cpp
util/diff.cpp
util/FileUtil.cpp
util/font/dbs/font_db_jak1.cpp
util/font/dbs/font_db_jak2.cpp
util/font/dbs/font_db_jak3.cpp
util/font/font_utils_korean.cpp
util/font/font_utils.cpp
util/FontUtils.cpp
util/FrameLimiter.cpp
util/json_util.cpp
util/os.cpp
@@ -99,7 +88,6 @@ add_library(common
util/Timer.cpp
util/unicode_util.cpp
util/gltf_util.cpp
util/image_resize.cpp
versions/versions.cpp
)
+3 -4
View File
@@ -3,7 +3,7 @@
#include "common/log/log.h"
#include "common/util/BinaryWriter.h"
#include "fmt/format.h"
#include "fmt/core.h"
/*!
* Write a wave file from a vector of samples.
@@ -57,8 +57,7 @@ void write_wave_file(const std::vector<s16>& left_samples,
}
std::pair<std::vector<s16>, std::vector<s16>> decode_adpcm(BinaryReader& reader,
const bool stereo,
const u32 version) {
const bool stereo) {
std::vector<s16> left_samples;
std::vector<s16> right_samples;
s32 left_sample_prev[2] = {0, 0};
@@ -86,7 +85,7 @@ std::pair<std::vector<s16>, std::vector<s16>> decode_adpcm(BinaryReader& reader,
break;
}
if (stereo && bytes_read == (version == 3 ? 0x1000 : 0x2000)) {
if (stereo && bytes_read == 0x2000) {
// switch streams
processing_left_chunk = !processing_left_chunk;
bytes_read = 0;
+1 -3
View File
@@ -34,8 +34,6 @@ void write_wave_file(const std::vector<s16>& left_samples,
s32 sample_rate,
const fs::path& name);
std::pair<std::vector<s16>, std::vector<s16>> decode_adpcm(BinaryReader& reader,
const bool mono,
const u32 version);
std::pair<std::vector<s16>, std::vector<s16>> decode_adpcm(BinaryReader& reader, const bool mono);
std::vector<u8> encode_adpcm(const std::vector<s16>& samples);
+1 -1
View File
@@ -11,7 +11,7 @@
#include "common/goal_constants.h"
#include "common/util/Timer.h"
#include "fmt/format.h"
#include "fmt/core.h"
#ifdef __linux
#include <fcntl.h>
+1 -1
View File
@@ -19,7 +19,7 @@
#include <stdio.h>
#include <string.h>
#include "fmt/format.h"
#include "fmt/core.h"
#include "common/log/log.h"
// clang-format on
+1 -1
View File
@@ -5,7 +5,7 @@
#include "common/cross_sockets/XSocket.h"
#include "common/log/log.h"
#include "fmt/format.h"
#include "fmt/core.h"
// clang-format off
#ifdef _WIN32
+1 -1
View File
@@ -4,7 +4,7 @@
#include "common/cross_sockets/XSocket.h"
#include "common/common_types.h"
#include "fmt/format.h"
#include "fmt/core.h"
#ifdef _WIN32
#define NOMINMAX
+19 -33
View File
@@ -3,9 +3,14 @@
#include <algorithm>
#include <functional>
#ifndef __aarch64__
#include "xmmintrin.h"
#else
#include "third-party/sse2neon/sse2neon.h"
#endif
#include "common/log/log.h"
#include "common/util/Assert.h"
#include "common/util/simd_util.h"
namespace tfrag3 {
@@ -88,8 +93,10 @@ math::Vector3f vopmsub(math::Vector3f acc, math::Vector3f a, math::Vector3f b) {
}
/*!
* Compute the normal transformation for a TIE from the TIE matrix. This will return properly scaled
* normals.
* Compute the normal transformation for a TIE from the TIE matrix.
* Note that this isn't identical to the original game - we're missing the vf14 scaling factor
* For now, I just set this to 1, then normalize in the shader. Though I think we could avoid
* this by figuring out the value of vf14 here (I am just too lazy right now).
*/
std::array<math::Vector3f, 3> tie_normal_transform_v2(const std::array<math::Vector4f, 4>& m) {
// let:
@@ -179,21 +186,11 @@ std::array<math::Vector3f, 3> tie_normal_transform_v2(const std::array<math::Vec
// sqc2 vf12, -80(t8)
}
s16 saturate_for_s10(s16 s10) {
// our error should be 1 or less as an s8, or 4 as a s10.
ASSERT(s10 >= -520 && s10 < 520);
if (s10 < -512) {
return -512;
}
if (s10 > 511) {
return 511;
}
return s10;
}
u32 pack_to_gl_normal(s16 nx, s16 ny, s16 nz) {
return (saturate_for_s10(nx) & 0x3ff) | ((saturate_for_s10(ny) & 0x3ff) << 10) |
((saturate_for_s10(nz) & 0x3ff) << 20);
ASSERT(nx >= -512 && nx <= 511);
ASSERT(ny >= -512 && ny <= 511);
ASSERT(nz >= -512 && nz <= 511);
return (nx & 0x3ff) | ((ny & 0x3ff) << 10) | ((nz & 0x3ff) << 20);
}
/*!
@@ -205,10 +202,10 @@ u32 unpack_tie_normal(const std::array<math::Vector3f, 3>& mat, s8 nx, s8 ny, s8
nrm += mat[0] * nx;
nrm += mat[1] * ny;
nrm += mat[2] * nz;
// game used signed 8-bit normals, but OpenGL uses signed 10-bit
// multiply by 2^2 = 4
nrm *= 4;
// convert to s16 for OpenGL renderer
// nrm /= 0x100; // number from EE asm
// nrm *= 0x200; // for normalized s10 -> float conversion by OpenGL.
nrm *= 2; // for normalized s10 -> float conversion by OpenGL.
auto as_int = nrm.cast<s16>();
@@ -307,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());
}
}
@@ -411,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);
}
@@ -857,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
@@ -2,7 +2,7 @@
#include "common/util/Assert.h"
#include "fmt/format.h"
#include "fmt/core.h"
std::string DmaTag::print() const {
std::string result;
+2 -2
View File
@@ -11,7 +11,7 @@
#include "common/common_types.h"
#include "common/util/Assert.h"
#include "fmt/format.h"
#include "fmt/core.h"
struct DmaStats {
double sync_time_ms = 0;
@@ -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
@@ -6,7 +6,7 @@
#include "common/log/log.h"
#include "common/util/Timer.h"
#include "fmt/format.h"
#include "fmt/core.h"
/*!
* Convert a DMA chain to an array of bytes that can be directly fed to VIF.
+1
View File
@@ -2,6 +2,7 @@
#include "common/util/Assert.h"
#include "fmt/core.h"
#include "fmt/format.h"
std::string reg_descriptor_name(GifTag::RegisterDescriptor reg) {
+2 -2
View File
@@ -6,12 +6,12 @@
#include "common/formatter/rules/rule_config.h"
#include "common/log/log.h"
#include "common/util/FileUtil.h"
#include "common/util/ast_util.h"
#include "common/util/string_util.h"
#include "tree_sitter/api.h"
#include "fmt/format.h"
#include "fmt/ranges.h"
#include "fmt/core.h"
// Declare the `tree_sitter_opengoal` function, which is
// implemented by the `tree-sitter-opengoal` library.
+2 -2
View File
@@ -2,7 +2,7 @@
#include "common/util/string_util.h"
#include "fmt/format.h"
#include "fmt/core.h"
std::string get_source_code(const std::string& source, const TSNode& node) {
uint32_t start = ts_node_start_byte(node);
@@ -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) {
+1 -1
View File
@@ -46,7 +46,7 @@ class FormatterTreeNode {
FormatterTreeNode() = default;
FormatterTreeNode(const std::string& source, const TSNode& node);
FormatterTreeNode(const Metadata& _metadata) : metadata(_metadata) {};
FormatterTreeNode(const Metadata& _metadata) : metadata(_metadata){};
bool is_list() const { return !token.has_value(); }
std::string token_str() const {
+1 -1
View File
@@ -4,7 +4,7 @@
#include "common/util/string_util.h"
#include "fmt/format.h"
#include "fmt/core.h"
namespace formatter_rules {
-44
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,16 +253,12 @@ 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)},
{"defun-debug", new_flow_rule(3)},
{"defbehavior", new_flow_rule(4)},
{"if", new_inlineable_flow_rule(2)},
{"aif", new_inlineable_flow_rule(2)},
{"#if", new_inlineable_flow_rule(2)},
{"define", new_permissive_flow_rule()},
{"def-mips2c", new_permissive_flow_rule()},
@@ -306,14 +269,10 @@ const std::unordered_map<std::string, FormFormattingConfig> opengoal_form_config
{"declare-type", new_permissive_flow_rule()},
{"defmacro", new_function_rule(3)},
{"desfun", new_function_rule(3)},
{"def-actor", new_flow_rule(2, true)},
{"defskelgroup", new_flow_rule(2, true)},
{"defpartgroup", new_flow_rule(2, true)},
{"defpart", new_flow_rule(2, true)},
{"defstate", new_defstate_rule(3, true)},
{"defevent", new_flow_rule(2)},
{"event", new_flow_rule(1)},
{"defpost", new_flow_rule(2)},
{"behavior", new_flow_rule(2)},
{"dotimes", new_flow_rule(2)},
{"dolist", new_flow_rule(2)},
@@ -322,15 +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)},
{"awhen", 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)},
+1 -1
View File
@@ -9,7 +9,7 @@
#include "common/util/FileUtil.h"
#include "common/common_types.h"
#include "fmt/format.h"
#include "fmt/core.h"
#include "third-party/json.hpp"
#ifdef OS_POSIX
+1 -1
View File
@@ -47,7 +47,7 @@ class GlobalProfiler {
};
struct ScopedEvent {
ScopedEvent(GlobalProfiler* _prof) : prof(_prof) {};
ScopedEvent(GlobalProfiler* _prof) : prof(_prof){};
ScopedEvent(const ScopedEvent&) = delete;
ScopedEvent& operator=(const ScopedEvent&) = delete;
GlobalProfiler* prof = nullptr;
-11
View File
@@ -71,15 +71,6 @@ constexpr int LEVEL_MAX = 10;
constexpr int LEVEL_TOTAL = LEVEL_MAX + 1;
} // namespace jak3
namespace jakx {
// for now, we don't have the ability to extend the size of the symbol table
constexpr s32 GOAL_MAX_SYMBOLS = 0x4000;
// amount of levels in level heap
constexpr int LEVEL_MAX = 10;
// total amount of levels, including ones outside level heap (default-level)
constexpr int LEVEL_TOTAL = LEVEL_MAX + 1;
} // namespace jakx
constexpr s32 max_symbols(GameVersion version) {
switch (version) {
case GameVersion::Jak1:
@@ -88,8 +79,6 @@ constexpr s32 max_symbols(GameVersion version) {
return jak2::GOAL_MAX_SYMBOLS;
case GameVersion::Jak3:
return jak3::GOAL_MAX_SYMBOLS;
case GameVersion::JakX:
return jakx::GOAL_MAX_SYMBOLS;
}
}
+15 -7
View File
@@ -16,9 +16,7 @@
#include "common/util/string_util.h"
#include "common/util/unicode_util.h"
#include "fmt/args.h"
#include "fmt/base.h"
#include "fmt/format.h"
#include "fmt/core.h"
namespace goos {
Interpreter::Interpreter(const std::string& username) {
@@ -1771,16 +1769,26 @@ Object Interpreter::eval_format(const Object& form,
throw_eval_error(form, "format string must be a string");
}
fmt::dynamic_format_arg_store<fmt::format_context> arg_store;
// Note: this might be relying on internal implementation details of libfmt to work properly
// and isn't a great solution.
std::vector<fmt::basic_format_arg<fmt::format_context>> args2;
std::vector<std::string> strings;
for (size_t i = 2; i < args.unnamed.size(); i++) {
if (args.unnamed.at(i).is_string()) {
arg_store.push_back(args.unnamed.at(i).as_string()->data);
strings.push_back(args.unnamed.at(i).as_string()->data);
} else {
arg_store.push_back(args.unnamed.at(i).print());
strings.push_back(args.unnamed.at(i).print());
}
}
auto formatted = fmt::vformat(format_str.as_string()->data, arg_store);
for (auto& x : strings) {
args2.push_back(fmt::detail::make_arg<fmt::format_context>(x));
}
auto formatted =
fmt::vformat(format_str.as_string()->data,
fmt::format_args(args2.data(), static_cast<unsigned>(args2.size())));
if (truthy(dest)) {
lg::print("{}", formatted.c_str());
}
+1 -1
View File
@@ -47,7 +47,7 @@
#include "common/util/crc32.h"
#include "common/util/print_float.h"
#include "fmt/format.h"
#include "fmt/core.h"
namespace goos {
+1 -15
View File
@@ -57,8 +57,6 @@
#include "common/util/Assert.h"
#include "common/util/crc32.h"
#include "fmt/format.h"
namespace goos {
/*!
@@ -236,14 +234,10 @@ class Object {
ObjectType type = ObjectType::INVALID;
private:
bool disallow_hex_for_int = false;
public:
std::string print() const {
switch (type) {
case ObjectType::INTEGER:
return disallow_hex_for_int ? fmt::format("{}", integer_obj.value) : integer_obj.print();
return integer_obj.print();
case ObjectType::FLOAT:
return float_obj.print();
case ObjectType::CHAR:
@@ -284,14 +278,6 @@ class Object {
return o;
}
static Object make_integer_no_hex(IntType value) {
Object o;
o.type = ObjectType::INTEGER;
o.integer_obj.value = value;
o.disallow_hex_for_int = true;
return o;
}
static Object make_float(FloatType value) {
Object o;
o.type = ObjectType::FLOAT;
+1 -1
View File
@@ -1,6 +1,6 @@
#include "ParseHelpers.h"
#include "fmt/format.h"
#include "fmt/core.h"
namespace goos {
+1 -1
View File
@@ -15,7 +15,7 @@
#include "common/goos/PrettyPrinter2.h"
#include "common/util/Assert.h"
#include "fmt/format.h"
#include "fmt/core.h"
namespace pretty_print {
+5 -4
View File
@@ -3,6 +3,7 @@
#include "common/common_types.h"
#include "common/util/Assert.h"
#include "fmt/core.h"
#include "fmt/format.h"
namespace pretty_print {
@@ -294,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") {
@@ -340,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) {
+1 -1
View File
@@ -6,7 +6,7 @@
#include "common/goos/Object.h"
#include "common/util/print_float.h"
#include "fmt/format.h"
#include "fmt/core.h"
namespace pretty_print {
namespace {
+55 -12
View File
@@ -13,10 +13,9 @@
#include "common/log/log.h"
#include "common/util/FileUtil.h"
#include "common/util/font/font_utils.h"
#include "common/util/FontUtils.h"
#include "fmt/format.h"
#include "fmt/ranges.h"
#include "fmt/core.h"
namespace goos {
@@ -156,6 +155,39 @@ Reader::Reader() {
for (const char* c = bonus; *c; c++) {
m_valid_symbols_chars[(int)*c] = true;
}
// table of characters that are valid in source code:
for (auto& x : m_valid_source_text_chars) {
x = false;
}
for (int i = ' '; i <= '~'; i++) {
m_valid_source_text_chars[i] = true;
}
m_valid_source_text_chars[(int)'\n'] = true;
m_valid_source_text_chars[(int)'\t'] = true;
m_valid_source_text_chars[(int)'\r'] = true;
// allow every character that gets transformed to something else
for (auto& [version, font] : g_font_banks) {
for (auto& remap : *font->encode_info()) {
for (auto rc : remap.chars) {
m_valid_source_text_chars[(u8)rc] = true;
}
}
for (auto& remap : *font->replace_info()) {
for (auto rc : remap.to) {
m_valid_source_text_chars[(u8)rc] = true;
}
for (auto rc : remap.from) {
m_valid_source_text_chars[(u8)rc] = true;
}
}
}
m_valid_source_text_chars[0] = false;
}
bool Reader::is_valid_source_char(char c) const {
return m_valid_source_text_chars[(u8)c];
}
/*!
@@ -233,6 +265,17 @@ Object Reader::internal_read(std::shared_ptr<SourceText> text,
fmt::format("Text file {} has invalid encoding", text->get_description()));
}
// validate the input
for (int offset = check_encoding ? 3 : 0; offset < text->get_size(); offset++) {
if (!is_valid_source_char(text->get_text()[offset])) {
// failed.
int line_number = text->get_line_idx(offset) + 1;
throw std::runtime_error(fmt::format("Invalid character found on line {} of {}: 0x{:x}",
line_number, text->get_description(),
(u8)text->get_text()[offset]));
}
}
// first create stream
TextStream ts(text);
@@ -257,6 +300,15 @@ Object Reader::internal_read(std::shared_ptr<SourceText> text,
}
}
bool Reader::check_string_is_valid(const std::string& str) const {
for (auto c : str) {
if (!is_valid_source_char(c)) {
return false;
}
}
return true;
}
/*!
* Given a stream starting at the first character of a token, get the token. Doesn't consume
* whitespace at the end and leaves the stream on the first character after the token.
@@ -852,13 +904,4 @@ std::string get_readable_string(const char* in) {
}
return result;
}
std::string get_byte_string(const char* in) {
std::string result;
while (*in) {
result += fmt::format("\\c{:02x}", uint8_t(*in));
in++;
}
return result;
}
} // namespace goos
+4 -1
View File
@@ -75,6 +75,7 @@ class Reader {
const std::optional<std::string>& string_name = {});
std::optional<Object> read_from_stdin(const std::string& prompt, REPL::Wrapper& repl);
Object read_from_file(const std::vector<std::string>& file_path, bool check_encoding = false);
bool check_string_is_valid(const std::string& str) const;
SymbolTable symbolTable;
TextDb db;
@@ -100,10 +101,12 @@ class Reader {
void add_reader_macro(const std::string& shortcut, std::string replacement);
bool m_valid_symbols_chars[256];
bool m_valid_source_text_chars[256];
bool is_valid_source_char(char c) const;
std::unordered_map<std::string, std::string> m_reader_macros;
};
std::string get_byte_string(const char* in);
std::string get_readable_string(const char* in);
} // namespace goos
+1 -1
View File
@@ -15,7 +15,7 @@
#include "common/util/FileUtil.h"
#include "fmt/format.h"
#include "fmt/core.h"
namespace goos {
+1 -1
View File
@@ -41,7 +41,7 @@ class SourceText {
// want
virtual bool terminate_compiler_error() { return true; }
virtual ~SourceText() {};
virtual ~SourceText(){};
protected:
void build_offsets();
+2 -2
View File
@@ -8,7 +8,7 @@
#include <string>
#include "fmt/color.h"
#include "fmt/format.h"
#include "fmt/core.h"
namespace lg {
@@ -72,7 +72,7 @@ void print(const std::string& format, Args&&... args) {
}
template <typename... Args>
void print(const fmt::text_style& ts, const std::string& format, Args&&... args) {
std::string formatted_message = fmt::vformat(ts, format, fmt::make_format_args(args...));
std::string formatted_message = fmt::format(ts, format, std::forward<Args>(args)...);
internal::log_print(formatted_message.c_str());
}
+1 -12
View File
@@ -2,7 +2,7 @@
#include <cmath>
#include "fmt/format.h"
#include "fmt/core.h"
namespace math {
@@ -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 -1
View File
@@ -2,7 +2,7 @@
#include "common/versions/versions.h"
#include "fmt/format.h"
#include "fmt/core.h"
namespace REPL {
void to_json(json& j, const Config& obj) {
+1 -2
View File
@@ -29,7 +29,7 @@ void from_json(const json& j, KeyBind& obj);
// TODO - per-game config
struct Config {
GameVersion game_version;
Config(GameVersion _game_version) : game_version(_game_version) {};
Config(GameVersion _game_version) : game_version(_game_version){};
// this is the default REPL configuration
int nrepl_port = 8181;
@@ -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) {
+1 -1
View File
@@ -4,7 +4,7 @@
#include "common/cross_sockets/XSocket.h"
#include "common/versions/versions.h"
#include "fmt/format.h"
#include "fmt/core.h"
#ifdef _WIN32
#define NOMINMAX
+1 -1
View File
@@ -4,7 +4,7 @@
#include "common/cross_sockets/XSocket.h"
#include "common/versions/versions.h"
#include "fmt/format.h"
#include "fmt/core.h"
#ifdef _WIN32
#define NOMINMAX
+11 -20
View File
@@ -6,8 +6,7 @@
#include "common/versions/versions.h"
#include "fmt/color.h"
#include "fmt/format.h"
#include "fmt/ranges.h"
#include "fmt/core.h"
#include "third-party/replxx/include/replxx.hxx"
namespace REPL {
@@ -42,17 +41,8 @@ void Wrapper::print_welcome_message(const std::vector<std::string>& loaded_proje
message += fmt::format(fmt::emphasis::bold | fg(fmt::color::orange), " . --- .");
message +=
fmt::format(" Project Path: {}\n",
fmt::styled(file_util::get_jak_project_dir().string(), fg(fmt::color::gray)));
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::styled(effective_iso_path, fg(fmt::color::gray)));
message += fmt::format(fmt::emphasis::bold | fg(fmt::color::orange), " --. .--: :--. .--");
message += " nREPL:";
if (!nrepl_alive) {
message += fmt::format(fg(fmt::color::red), "DISABLED\n");
@@ -60,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::styled(search_dir_string, fg(fmt::color::gray)));
message += fmt::format(fmt::emphasis::bold | fg(fmt::color::orange), " .-=====-. .-=====-");
message += fmt::format(" {} or {} for basic help and usage\n",
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",
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);
}
+3 -7
View File
@@ -5,7 +5,7 @@
#include "common/util/FileUtil.h"
#include "common/util/json_util.h"
#include "fmt/format.h"
#include "fmt/core.h"
void open_subtitle_project(const std::string& project_kind,
const std::string& file_path,
@@ -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", "fi-FI"}}};
{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) {
@@ -5,7 +5,7 @@
#include "subtitles_v2.h"
#include "fmt/format.h"
#include "fmt/core.h"
void to_json(json& j, const SubtitleCutsceneLineMetadataV1& obj) {
json_serialize(frame_start);
@@ -5,7 +5,7 @@
#include "subtitles_v1.h"
#include "fmt/format.h"
#include "fmt/core.h"
void to_json(json& j, const SubtitleLineMetadata& obj) {
json_serialize(frame_start);
@@ -93,57 +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},
{"ottsel-voice-before-outro", 36},
{"ottsel-voice", 37},
{"krew", 38},
{"baron", 39},
{"scherr", 40},
{"arey", 41},
{"baldwin", 42},
{"schimpf", 43},
{"martinsen", 44},
{"phillips", 45},
{"yates", 46},
};
GameSubtitlePackage read_json_files_v2(const GameSubtitleDefinitionFile& file_info) {
GameSubtitlePackage package;
SubtitleFile lang_lines;
@@ -307,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; });
@@ -340,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,
@@ -2,7 +2,7 @@
#include "common/serialization/subtitles/subtitles.h"
#include "common/util/Assert.h"
#include "common/util/font/font_utils.h"
#include "common/util/FontUtils.h"
#include "common/util/json_util.h"
struct SubtitleLineMetadata {
@@ -124,6 +124,7 @@ class GameSubtitleBank {
std::optional<std::string> m_file_base_path;
std::map<std::string, GameSubtitleSceneInfo> m_base_scenes;
std::map<std::string, GameSubtitleSceneInfo> m_lang_scenes;
std::map<std::string, GameSubtitleSceneInfo> m_scenes;
bool scene_exists(const std::string& name) const { return m_scenes.find(name) != m_scenes.end(); }
GameSubtitleSceneInfo new_scene_from_meta(
+12 -37
View File
@@ -2,7 +2,6 @@
#include "common/goos/ParseHelpers.h"
#include "common/goos/Reader.h"
#include "common/util/font/font_utils_korean.h"
int64_t get_int(const goos::Object& obj) {
if (obj.is_int()) {
@@ -45,7 +44,7 @@ std::string get_string(const goos::Object& x) {
void parse_text_goal(const goos::Object& data,
GameTextDB& db,
const GameTextDefinitionFile& /*file_info*/) {
GameTextFontBank* font = nullptr;
const GameTextFontBank* font = nullptr;
std::vector<std::shared_ptr<GameTextBank>> banks;
std::string possible_group_name;
@@ -123,15 +122,9 @@ void parse_text_goal(const goos::Object& data,
if (b_i >= int(banks.size())) {
throw std::runtime_error(fmt::format("Too many strings in text id #x{:x}", id));
}
if (font->is_language_id_korean(b_i)) {
// korean changes differently!
auto line = font->convert_utf8_to_game_korean(entry.as_string()->data);
banks[b_i]->set_line(id, line);
} else {
auto line = font->convert_utf8_to_game(entry.as_string()->data);
banks[b_i]->set_line(id, line);
}
b_i++;
auto line = font->convert_utf8_to_game(entry.as_string()->data);
banks[b_i++]->set_line(id, line);
} else {
throw std::runtime_error(fmt::format("Non-string value in text id #x{:x}", id));
}
@@ -172,15 +165,8 @@ void parse_text_goal(const goos::Object& data,
throw std::runtime_error(fmt::format("Too many strings in text id #x{:x}", id));
}
if (font->is_language_id_korean(i)) {
// handle korean differently!
auto line = font->convert_utf8_to_game_korean(entry.as_string()->data);
banks[i]->set_line(id, line);
} else {
auto line = font->convert_utf8_to_game(entry.as_string()->data);
banks[i]->set_line(id, line);
}
i++;
auto line = font->convert_utf8_to_game(entry.as_string()->data);
banks[i++]->set_line(id, line);
} else {
throw std::runtime_error(fmt::format("Non-string value in text id #x{:x}", id));
}
@@ -244,20 +230,15 @@ void parse_text_json(const nlohmann::json& json,
} else {
bank = db.bank_by_id(file_info.group_name.value(), file_info.language_id);
}
GameTextFontBank* font = get_font_bank(file_info.text_version);
const GameTextFontBank* font = get_font_bank(file_info.text_version);
// Parse the file
for (const auto& [text_id, text_value] : json.items()) {
auto line_id = std::stoi(text_id, nullptr, 16);
if (text_value.is_string()) {
// single line replacement
if (font->is_language_id_korean(file_info.language_id)) {
auto line = font->convert_utf8_to_game_korean(text_value);
bank->set_line(line_id, line);
} else {
auto line = font->convert_utf8_to_game(text_value);
bank->set_line(line_id, line);
}
auto line = font->convert_utf8_to_game(text_value);
// TODO - lint duplicate line definitions across text files
bank->set_line(line_id, line);
} else if (text_value.is_array()) {
// multi-line replacement starting from line_id
// (e.g. for Jak 1 credits, start from x0b00)
@@ -266,14 +247,8 @@ void parse_text_json(const nlohmann::json& json,
throw std::runtime_error(fmt::format(
"Non string provided for line {} / text id #x{} of _credits", idx, line_id));
}
if (font->is_language_id_korean(file_info.language_id)) {
auto line = font->convert_utf8_to_game_korean(raw_line);
bank->set_line(line_id++, line); // increment line_id
} else {
auto line = font->convert_utf8_to_game(raw_line);
bank->set_line(line_id++, line); // increment line_id
}
auto line = font->convert_utf8_to_game(raw_line);
bank->set_line(line_id++, line); // increment line_id
}
} else {
// Unexpected value type
+1 -1
View File
@@ -11,7 +11,7 @@
#include "common/goos/Object.h"
#include "common/log/log.h"
#include "common/util/Assert.h"
#include "common/util/font/font_utils.h"
#include "common/util/FontUtils.h"
#include "common/util/json_util.h"
#include "common/versions/versions.h"
-176
View File
@@ -324,180 +324,6 @@ constexpr int FIX_SYM_NETWORK_BOOTSTRAP = 0x294;
} // namespace jak3_symbols
namespace jakx_symbols {
constexpr int FIX_SYM_EMPTY_CAR = -0x8;
constexpr int S7_OFF_FIX_SYM_EMPTY_PAIR = -0x6 - 1;
constexpr int FIX_SYM_EMPTY_CDR = -0x4;
constexpr int FIX_SYM_FALSE = 0x0; // GOAL boolean #f (note that this is equal to the $s7 register)
constexpr int FIX_SYM_TRUE = 0x4; // GOAL boolean #t
constexpr int FIX_SYM_FUNCTION_TYPE = 0x8;
constexpr int FIX_SYM_BASIC = 0xc;
constexpr int FIX_SYM_STRING_TYPE = 0x10;
constexpr int FIX_SYM_SYMBOL_TYPE = 0x14;
constexpr int FIX_SYM_TYPE_TYPE = 0x18;
constexpr int FIX_SYM_OBJECT_TYPE = 0x1c;
constexpr int FIX_SYM_LINK_BLOCK = 0x20;
constexpr int FIX_SYM_INTEGER = 0x24;
constexpr int FIX_SYM_SINTEGER = 0x28;
constexpr int FIX_SYM_UINTEGER = 0x2c;
constexpr int FIX_SYM_BINTEGER = 0x30;
constexpr int FIX_SYM_INT8 = 0x34;
constexpr int FIX_SYM_INT16 = 0x38;
constexpr int FIX_SYM_INT32 = 0x3c;
constexpr int FIX_SYM_INT64 = 0x40;
constexpr int FIX_SYM_INT128 = 0x44;
constexpr int FIX_SYM_UINT8 = 0x48;
constexpr int FIX_SYM_UINT16 = 0x4c;
constexpr int FIX_SYM_UINT32 = 0x50;
constexpr int FIX_SYM_UINT64 = 0x54;
constexpr int FIX_SYM_UINT128 = 0x58;
constexpr int FIX_SYM_FLOAT = 0x5c;
constexpr int FIX_SYM_PROCESS_TREE = 0x60;
constexpr int FIX_SYM_PROCESS_TYPE = 0x64;
constexpr int FIX_SYM_THREAD = 0x68;
constexpr int FIX_SYM_STRUCTURE = 0x6c;
constexpr int FIX_SYM_PAIR_TYPE = 0x70;
constexpr int FIX_SYM_POINTER = 0x74;
constexpr int FIX_SYM_NUMBER = 0x78;
constexpr int FIX_SYM_ARRAY = 0x7c;
constexpr int FIX_SYM_VU_FUNCTION = 0x80;
constexpr int FIX_SYM_CONNECTABLE = 0x84;
constexpr int FIX_SYM_STACK_FRAME = 0x88;
constexpr int FIX_SYM_FILE_STREAM = 0x8c;
constexpr int FIX_SYM_HEAP = 0x90;
constexpr int FIX_SYM_NOTHING_FUNC = 0x94;
constexpr int FIX_SYM_DELETE_BASIC = 0x98;
constexpr int FIX_SYM_STATIC = 0x9c;
constexpr int FIX_SYM_GLOBAL_HEAP = 0xa0;
constexpr int FIX_SYM_DEBUG = 0xa4;
constexpr int FIX_SYM_LOADING_LEVEL = 0xa8;
constexpr int FIX_SYM_LOADING_PACKAGE = 0xac;
constexpr int FIX_SYM_PROCESS_LEVEL_HEAP = 0xb0;
constexpr int FIX_SYM_STACK = 0xb4;
constexpr int FIX_SYM_SCRATCH = 0xb8;
constexpr int FIX_SYM_SCRATCH_TOP = 0xbc;
constexpr int FIX_SYM_ZERO_FUNC = 0xc0;
constexpr int FIX_SYM_ASIZE_OF_BASIC_FUNC = 0xc4;
constexpr int FIX_SYM_COPY_BASIC_FUNC = 0xc8; // bugged name
constexpr int FIX_SYM_LEVEL = 0xcc;
constexpr int FIX_SYM_ART_GROUP = 0xd0;
constexpr int FIX_SYM_TEXTURE_PAGE_DIR = 0xd4;
constexpr int FIX_SYM_TEXTURE_PAGE = 0xd8;
constexpr int FIX_SYM_SOUND = 0xdc;
constexpr int FIX_SYM_DGO = 0xe0;
constexpr int FIX_SYM_TOP_LEVEL = 0xe4;
constexpr int FIX_SYM_QUOTE = 0xe8;
constexpr int FIX_SYM_LISTENER_LINK_BLOCK = 0xec;
constexpr int FIX_SYM_LISTENER_FUNCTION = 0xf0;
constexpr int FIX_SYM_STACK_TOP = 0xf4;
constexpr int FIX_SYM_STACK_BASE = 0xf8;
constexpr int FIX_SYM_STACK_SIZE = 0xfc;
constexpr int FIX_SYM_KERNEL_FUNCTION = 0x100;
constexpr int FIX_SYM_KERNEL_PACKAGES = 0x104;
constexpr int FIX_SYM_KERNEL_BOOT_MESSAGE = 0x108;
constexpr int FIX_SYM_KERNEL_BOOT_MODE = 0x10c;
constexpr int FIX_SYM_KERNEL_BOOT_LEVEL = 0x110;
constexpr int FIX_SYM_KERNEL_BOOT_ART_GROUP = 0x114;
constexpr int FIX_SYM_KERNEL_DEBUG = 0x118;
constexpr int FIX_SYM_KERNEL_VERSION = 0x11c;
constexpr int FIX_SYM_KERNEL_DISPATCHER = 0x120;
constexpr int FIX_SYM_SYNC_DISPATCHER = 0x124;
constexpr int FIX_SYM_PRINT_COLLUMN = 0x128;
constexpr int FIX_SYM_DEBUG_SEGMENT = 300;
constexpr int FIX_SYM_ENABLE_METHOD_SET = 0x130;
constexpr int FIX_SYM_SQL_RESULT = 0x134;
constexpr int FIX_SYM_COLLAPSE_QUOTE = 0x138;
constexpr int FIX_SYM_LEVEL_TYPE_LIST = 0x13C;
constexpr int FIX_SYM_DECI_COUNT = 0x140;
constexpr int FIX_SYM_USER = 0x144;
constexpr int FIX_SYM_VIDEO_MODE = 0x148;
constexpr int FIX_SYM_BOOT_VIDEO_MODE = 0x14C;
constexpr int FIX_SYM_BOOT = 0x150;
constexpr int FIX_SYM_DEMO = 0x154;
constexpr int FIX_SYM_DEMO_SHARED = 0x158;
constexpr int FIX_SYM_PREVIEW = 0x15C;
constexpr int FIX_SYM_KIOSK = 0x160;
constexpr int FIX_SYM_PLAY_BOOT = 0x164;
constexpr int FIX_SYM_SIN = 0x168;
constexpr int FIX_SYM_COS = 0x16C;
constexpr int FIX_SYM_PUT_DISPLAY_ENV = 0x170;
constexpr int FIX_SYM_SYNCV = 0x174;
constexpr int FIX_SYM_SYNC_PATH = 0x178;
constexpr int FIX_SYM_RESET_PATH = 0x17C;
constexpr int FIX_SYM_RESET_GRAPH = 0x180;
constexpr int FIX_SYM_DMA_SYNC = 0x184;
constexpr int FIX_SYM_GS_PUT_IMR = 0x188;
constexpr int FIX_SYM_GS_GET_IMR = 0x18C;
constexpr int FIX_SYM_GS_STORE_IMAGE = 400;
constexpr int FIX_SYM_FLUSH_CACHE = 0x194;
constexpr int FIX_SYM_CPAD_OPEN = 0x198;
constexpr int FIX_SYM_CPAD_GET_DATA = 0x19C;
constexpr int FIX_SYM_MOUSE_GET_DATA = 0x1A0;
constexpr int FIX_SYM_KEYBD_GET_DATA = 0x1A4;
constexpr int FIX_SYM_INSTALL_HANDLER = 0x1A8;
constexpr int FIX_SYM_INSTALL_DEBUG_HANDLER = 0x1AC;
constexpr int FIX_SYM_FILE_STREAM_OPEN = 0x1B0;
constexpr int FIX_SYM_FILE_STREAM_CLOSE = 0x1B4;
constexpr int FIX_SYM_FILE_STREAM_LENGTH = 0x1B8;
constexpr int FIX_SYM_FILE_STREAM_SEEK = 0x1BC;
constexpr int FIX_SYM_FILE_STREAM_READ = 0x1C0;
constexpr int FIX_SYM_FILE_STREAM_WRITE = 0x1C4;
constexpr int FIX_SYM_SCF_GET_LANGUAGE = 0x1C8;
constexpr int FIX_SYM_SCF_GET_TIME = 0x1CC;
constexpr int FIX_SYM_SCF_GET_ASPECT = 0x1D0;
constexpr int FIX_SYM_SCF_GET_VOLUME = 0x1D4;
constexpr int FIX_SYM_SCF_GET_TERRITORY = 0x1D8;
constexpr int FIX_SYM_SCF_GET_TIMEOUT = 0x1DC;
constexpr int FIX_SYM_SCF_GET_INACTIVE_TIMEOUT = 0x1E0;
constexpr int FIX_SYM_DMA_TO_IOP = 0x1E4;
constexpr int FIX_SYM_KERNEL_SHUTDOWN = 0x1E8;
constexpr int FIX_SYM_AYBABTU = 0x1EC;
constexpr int FIX_SYM_STRING_TO_SYMBOL = 0x1F0;
constexpr int FIX_SYM_SYMBOL_TO_STRING = 500;
constexpr int FIX_SYM_PRINT = 0x1F8;
constexpr int FIX_SYM_INSPECT = 0x1FC;
constexpr int FIX_SYM_LOAD = 0x200;
constexpr int FIX_SYM_LOADB = 0x204;
constexpr int FIX_SYM_LOADO = 0x208;
constexpr int FIX_SYM_UNLOAD = 0x20C;
constexpr int FIX_SYM_FORMAT = 0x210;
constexpr int FIX_SYM_MALLOC = 0x214;
constexpr int FIX_SYM_KMALLOC = 0x218;
constexpr int FIX_SYM_KMEMOPEN = 0x21C;
constexpr int FIX_SYM_KMEMCLOSE = 0x220;
constexpr int FIX_SYM_NEW_DYNAMIC_STRUCTURE = 0x224;
constexpr int FIX_SYM_METHOD_SET = 0x228;
constexpr int FIX_SYM_LINK = 0x22C;
constexpr int FIX_SYM_LINK_BUSY = 0x230;
constexpr int FIX_SYM_LINK_RESET = 0x234;
constexpr int FIX_SYM_LINK_BEGIN = 0x238;
constexpr int FIX_SYM_LINK_RESUME = 0x23C;
constexpr int FIX_SYM_DGO_LOAD = 0x240;
constexpr int FIX_SYM_SQL_QUERY = 0x244;
constexpr int FIX_SYM_MC_RUN = 0x248;
constexpr int FIX_SYM_MC_FORMAT = 0x24C;
constexpr int FIX_SYM_MC_UNFORMAT = 0x250;
constexpr int FIX_SYM_MC_CREATE_FILE = 0x254;
constexpr int FIX_SYM_MC_SAVE = 600;
constexpr int FIX_SYM_MC_LOAD = 0x25C;
constexpr int FIX_SYM_MC_CHECK_RESULT = 0x260;
constexpr int FIX_SYM_MC_GET_SLOT_INFO = 0x264;
constexpr int FIX_SYM_MC_MAKEFILE = 0x268;
constexpr int FIX_SYM_KSET_LANGUAGE = 0x26C;
constexpr int FIX_SYM_RPC_CALL = 0x270;
constexpr int FIX_SYM_RPC_BUSY = 0x274;
constexpr int FIX_SYM_TEST_LOAD_DGO_C = 0x278;
constexpr int FIX_SYM_SYMLINK2 = 0x27c;
constexpr int FIX_SYM_SYMLINK3 = 0x280;
constexpr int FIX_SYM_ULTIMATE_MEMCPY = 0x284;
constexpr int FIX_SYM_PLAY = 0x288;
constexpr int FIX_SYM_SYMBOL_STRING = 0x28c;
constexpr int FIX_SYM_KERNEL_SYMBOL_WARNINGS = 0x290;
constexpr int FIX_SYM_NETWORK_BOOTSTRAP = 0x294;
} // namespace jakx_symbols
constexpr int false_symbol_offset() {
return jak1_symbols::FIX_SYM_FALSE;
}
@@ -508,7 +334,6 @@ constexpr int true_symbol_offset(GameVersion version) {
return jak1_symbols::FIX_SYM_TRUE;
case GameVersion::Jak2:
case GameVersion::Jak3:
case GameVersion::JakX:
return jak2_symbols::FIX_SYM_TRUE;
}
}
@@ -519,7 +344,6 @@ constexpr int empty_pair_offset_from_s7(GameVersion version) {
return jak1_symbols::FIX_SYM_EMPTY_PAIR;
case GameVersion::Jak2:
case GameVersion::Jak3:
case GameVersion::JakX:
// minus 1 for the symbol table pointer's offset.
return jak2_symbols::S7_OFF_FIX_SYM_EMPTY_PAIR;
}
+1 -1
View File
@@ -10,7 +10,7 @@
#include "common/log/log.h"
#include "common/util/Assert.h"
#include "fmt/format.h"
#include "fmt/core.h"
namespace {
std::string reg_kind_to_string(RegClass kind) {
+1 -1
View File
@@ -9,7 +9,7 @@
#include "common/log/log.h"
#include "fmt/format.h"
#include "fmt/core.h"
namespace {
// debug prints for the reverse lookup
+1 -1
View File
@@ -7,7 +7,7 @@
#include <stdexcept>
#include "fmt/format.h"
#include "fmt/core.h"
bool TypeTag::operator==(const TypeTag& other) const {
return name == other.name && value == other.value;
+1 -2
View File
@@ -15,7 +15,7 @@
#include "common/util/math_util.h"
#include "fmt/color.h"
#include "fmt/format.h"
#include "fmt/core.h"
namespace {
template <typename... Args>
@@ -1100,7 +1100,6 @@ void TypeSystem::add_builtin_types(GameVersion version) {
break;
case GameVersion::Jak2:
case GameVersion::Jak3:
case GameVersion::JakX:
symbol_type = add_builtin_structure("object", "symbol", true);
symbol_type->override_offset(1);
break;
+1 -1
View File
@@ -13,7 +13,7 @@
#include "common/util/BitUtils.h"
#include "common/util/string_util.h"
#include "fmt/format.h"
#include "fmt/core.h"
namespace {
const goos::Object& car(const goos::Object* x) {
+1 -1
View File
@@ -13,7 +13,7 @@
#include "common/type_system/state.h"
#include "common/util/string_util.h"
#include "fmt/format.h"
#include "fmt/core.h"
/*!
* Missing Features
-3
View File
@@ -43,8 +43,5 @@
#define ASSERT(EX) ((void)0)
#define ASSERT_MSG(EXPR, STR) ((void)0)
#define ASSERT_NOT_REACHED() ((void)0)
#define ASSERT_NOT_REACHED_MSG(STR) ((void)0)
#define ASSERT_EQ_IMM(EXPR, EXPECTED) ((void)0)
#endif
+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);
}
+1 -1
View File
@@ -22,7 +22,7 @@
// This disables the use of PCLMULQDQ which is probably ok, but let's just be safe and disable it
// because nobody will care if png compression is 10% slower.
#define FPNG_NO_SSE 1
#include "fmt/format.h"
#include "fmt/core.h"
#include "third-party/fpng/fpng.cpp"
#include "third-party/fpng/fpng.h"
#include "third-party/lzokay/lzokay.hpp"
File diff suppressed because it is too large. Load diff
+98
View File
@@ -0,0 +1,98 @@
#pragma once
/*!
* @file FontUtils.h
*
* Code for handling text and strings in Jak 1's "large font" format.
*
* MAKE SURE THIS FILE IS ENCODED IN UTF-8!!! The various strings here depend on it.
* Always verify the encoding if string detection suddenly goes awry.
*/
#include <map>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include "common/common_types.h"
#include "common/versions/versions.h"
// version of the game text file's text encoding. Not real, but we need to differentiate them
// somehow, since the encoding changes.
enum class GameTextVersion {
JAK1_V1 = 10, // jak 1 (ntsc-u v1)
JAK1_V2 = 11, // jak 1 (pal+)
JAK2 = 20, // jak 2
JAK3 = 30, // jak 3
JAKX = 40 // jak x
};
extern const std::unordered_map<std::string, GameTextVersion> sTextVerEnumMap;
const std::string& get_text_version_name(GameTextVersion version);
GameTextVersion get_text_version_from_name(const std::string& name);
/*!
* What bytes a set of characters (UTF-8) correspond to. You can convert to and fro.
*/
struct EncodeInfo {
std::string chars;
std::vector<u8> bytes;
};
/*!
* Replace an unconventional string of characters with/from something more readable.
* For example, turns Ñ into N + ~ + a bunch of modifiers.
*/
struct ReplaceInfo {
std::string from;
std::string to;
};
/*!
* All the information to convert UTF-8 text into game text.
*/
class GameTextFontBank {
GameTextVersion m_version; // the version of the game text. we determine this ourselves.
std::vector<EncodeInfo>* m_encode_info;
std::vector<ReplaceInfo>* m_replace_info;
std::unordered_set<char>* m_passthrus;
const EncodeInfo* find_encode_to_utf8(const char* in) const;
const EncodeInfo* find_encode_to_game(const std::string& in, int off = 0) const;
const ReplaceInfo* find_replace_to_utf8(const std::string& in, int off = 0) const;
const ReplaceInfo* find_replace_to_game(const std::string& in, int off = 0) const;
std::string replace_to_utf8(std::string& str) const;
std::string replace_to_game(std::string& str) const;
std::string encode_utf8_to_game(std::string& str) const;
public:
GameTextFontBank(GameTextVersion version,
std::vector<EncodeInfo>* encode_info,
std::vector<ReplaceInfo>* replace_info,
std::unordered_set<char>* passthrus);
const std::vector<EncodeInfo>* encode_info() const { return m_encode_info; }
const std::vector<ReplaceInfo>* replace_info() const { return m_replace_info; }
const std::unordered_set<char>* passthrus() const { return m_passthrus; }
GameTextVersion version() const { return m_version; }
// TODO - methods would help make this code a lot better for different game versions
// hacking it for now
bool valid_char_range(const char in) const;
std::string convert_utf8_to_game(std::string str, bool escape = false) const;
std::string convert_game_to_utf8(const char* in) const;
};
extern GameTextFontBank g_font_bank_jak1_v1;
extern GameTextFontBank g_font_bank_jak1_v2;
extern GameTextFontBank g_font_bank_jak2;
extern std::map<GameTextVersion, GameTextFontBank*> g_font_banks;
const GameTextFontBank* get_font_bank(GameTextVersion version);
const GameTextFontBank* get_font_bank_from_game_version(GameVersion version);
const GameTextFontBank* get_font_bank(const std::string& name);
bool font_bank_exists(GameTextVersion version);
+1 -26
View File
@@ -36,9 +36,6 @@ class Trie {
// Get all objects starting with the given prefix.
std::vector<T*> lookup_prefix(const std::string& str) const;
// Finds the longest prefix match starting at offset `off` in string `in`.
const T* find_longest_prefix(const std::string& in, int off) const;
// Get all nodes in the tree.
std::vector<T*> get_all_nodes() const;
~Trie();
@@ -146,23 +143,6 @@ class Trie {
}
}
}
const T* find_longest_prefix(const std::string& in, int off) const {
const Node* node = this;
const T* best = nullptr;
for (int j = off; j < (int)in.size(); ++j) {
unsigned char c = static_cast<unsigned char>(in[j]);
node = node->children[c];
if (!node) {
break;
}
if (node->value) {
best = node->value;
}
}
return best;
}
};
Node m_root;
@@ -202,14 +182,9 @@ std::vector<T*> Trie<T>::lookup_prefix(const std::string& str) const {
return m_root.lookup_prefix(str.c_str());
}
template <typename T>
const T* Trie<T>::find_longest_prefix(const std::string& in, int off) const {
return m_root.find_longest_prefix(in, off);
}
template <typename T>
std::vector<T*> Trie<T>::get_all_nodes() const {
std::vector<T*> result;
m_root.get_all_children(result);
return result;
}
}
+1 -1
View File
@@ -5,7 +5,7 @@
#include "common/util/Assert.h"
#include "fmt/format.h"
#include "fmt/core.h"
#include "third-party/zstd/lib/zstd.h"
namespace compression {
+4 -4
View File
@@ -10,16 +10,17 @@ u32 crc32(const u8* data, size_t size);
#ifdef __aarch64__
#include <arm_acle.h>
// Computes CRC32C
inline u32 crc32(const u8* data, size_t size) {
u32 result = 0xffffffff;
while (size >= 4) {
result = __crc32cw(result, *reinterpret_cast<const u32*>(data));
u32 x;
memcpy(&x, data, 4);
data += 4;
size -= 4;
result = __crc32w(result, x);
}
while (size) {
result = __crc32cb(result, *data);
result = __crc32b(result, *data);
data++;
size--;
}
@@ -27,7 +28,6 @@ inline u32 crc32(const u8* data, size_t size) {
}
#else
#include <immintrin.h>
// Computes CRC32C
inline u32 crc32(const u8* data, size_t size) {
u32 result = 0xffffffff;
while (size >= 4) {
+2 -3
View File
@@ -5,7 +5,7 @@
#include "common/util/Assert.h"
#include "common/versions/versions.h"
#include "fmt/format.h"
#include "fmt/core.h"
/*!
* Assert false if the char[] has non-null data after the null terminated string.
@@ -25,8 +25,7 @@ std::string get_object_file_name(const std::string& original_name, const u8* dat
const std::string art_group_text_strings[] = {
fmt::format("/src/next/data/art-group{}/", versions::jak1::ART_FILE_VERSION),
fmt::format("/src/jak2/final/art-group{}/", versions::jak2::ART_FILE_VERSION),
fmt::format("/src/jak3/final/art-group{}/", versions::jak3::ART_FILE_VERSION),
fmt::format("/src/jakx/final/art-group{}/", versions::jakx::ART_FILE_VERSION)};
fmt::format("/src/jak3/final/art-group{}/", versions::jak3::ART_FILE_VERSION)};
const std::string suffix = "-ag.go";
for (auto& art_group_text : art_group_text_strings) {
-597
View File
@@ -1,597 +0,0 @@
#include "font_db_jak1.h"
std::unordered_set<char> passthrus_jak1 = {'~', ' ', ',', '.', '-', '+', '(', ')', '!', ':', '?',
'=', '%', '*', '/', '#', ';', '<', '>', '@', '[', '_'};
std::vector<EncodeInfo> encode_info_jak1 = {
// random
{"ˇ", "\x10"}, // caron
{"`", "\x11"}, // grave accent
{"'", "\x12"}, // apostrophe
{"^", "\x13"}, // circumflex
{"<TIL>", "\x14"}, // tilde
{"¨", "\x15"}, // umlaut
{"º", "\x16"}, // numero/overring
{"¡", "\x17"}, // inverted exclamation mark
{"¿", "\x18"}, // inverted question mark
{"海", "\x1a"}, // umi
{"Æ", "\x1b"}, // aesc
{"界", "\x1c"}, // kai
{"Ç", "\x1d"}, // c-cedilla
{"学", "\x1e"}, // gaku
{"ß", "\x1f"}, // eszett
{"ワ", "\x24"}, // wa
{"ヲ", "\x26"}, // wo
{"ン", "\x27"}, // -n
{"岩", "\x5c"}, // iwa
{"旧", "\x5d"}, // kyuu
{"空", "\x5e"}, // sora
//{"掘", "\x5f"}, // horu
{"ヮ", "\x60"}, // -wa
{"撃", "\x61"}, // utsu
{"賢", "\x62"}, // kashikoi
{"湖", "\x63"}, // mizuumi
{"口", "\x64"}, // kuchi
{"行", "\x65"}, // iku
{"合", "\x66"}, // ai
{"士", "\x67"}, // shi
{"寺", "\x68"}, // tera
{"山", "\x69"}, // yama
{"者", "\x6a"}, // mono
{"所", "\x6b"}, // tokoro
{"書", "\x6c"}, // kaku
{"小", "\x6d"}, // shou
{"沼", "\x6e"}, // numa
{"上", "\x6f"}, // ue
{"城", "\x70"}, // shiro
{"場", "\x71"}, // ba
{"出", "\x72"}, // shutsu
{"闇", "\x73"}, // yami
{"遺", "\x74"}, // nokosu
{"黄", "\x75"}, // ki
{"屋", "\x76"}, // ya
{"下", "\x77"}, // shita
{"家", "\x78"}, // ie
{"火", "\x79"}, // hi
{"花", "\x7a"}, // hana
{"レ", "\x7b"}, // re
{"Œ", "\x7c"}, // oe
{"ロ", "\x7d"}, // ro
{"青", "\x7f"}, // ao
{"・", "\x90"}, // nakaguro
{"゛", "\x91"}, // dakuten
{"゜", "\x92"}, // handakuten
{"ー", "\x93"}, // chouompu
{"『", "\x94"}, // nijuukagikakko left
{"』", "\x95"}, // nijuukagikakko right
// hiragana
{"ぁ", "\x96"}, // -a
{"あ", "\x97"}, // a
{"ぃ", "\x98"}, // -i
{"い", "\x99"}, // i
{"ぅ", "\x9a"}, // -u
{"う", "\x9b"}, // u
{"ぇ", "\x9c"}, // -e
{"え", "\x9d"}, // e
{"ぉ", "\x9e"}, // -o
{"お", "\x9f"}, // o
{"か", "\xa0"}, // ka
{"き", "\xa1"}, // ki
{"く", "\xa2"}, // ku
{"け", "\xa3"}, // ke
{"こ", "\xa4"}, // ko
{"さ", "\xa5"}, // sa
{"し", "\xa6"}, // shi
{"す", "\xa7"}, // su
{"せ", "\xa8"}, // se
{"そ", "\xa9"}, // so
{"た", "\xaa"}, // ta
{"ち", "\xab"}, // chi
{"っ", "\xac"}, // sokuon
{"つ", "\xad"}, // tsu
{"て", "\xae"}, // te
{"と", "\xaf"}, // to
{"な", "\xb0"}, // na
{"に", "\xb1"}, // ni
{"ぬ", "\xb2"}, // nu
{"ね", "\xb3"}, // ne
{"の", "\xb4"}, // no
{"は", "\xb5"}, // ha
{"ひ", "\xb6"}, // hi
{"ふ", "\xb7"}, // hu
{"へ", "\xb8"}, // he
{"ほ", "\xb9"}, // ho
{"ま", "\xba"}, // ma
{"み", "\xbb"}, // mi
{"む", "\xbc"}, // mu
{"め", "\xbd"}, // me
{"も", "\xbe"}, // mo
{"ゃ", "\xbf"}, // youon ya
{"や", "\xc0"}, // ya
{"ゅ", "\xc1"}, // youon yu
{"ゆ", "\xc2"}, // yu
{"ょ", "\xc3"}, // youon yo
{"よ", "\xc4"}, // yo
{"ら", "\xc5"}, // ra
{"り", "\xc6"}, // ri
{"る", "\xc7"}, // ru
{"れ", "\xc8"}, // re
{"ろ", "\xc9"}, // ro
{"ゎ", "\xca"}, // -wa
{"わ", "\xcb"}, // wa
{"を", "\xcc"}, // wo
{"ん", "\xcd"}, // -n
// katakana
{"ァ", "\xce"}, // -a
{"ア", "\xcf"}, // a
{"ィ", "\xd0"}, // -i
{"イ", "\xd1"}, // i
{"ゥ", "\xd2"}, // -u
{"ウ", "\xd3"}, // u
{"ェ", "\xd4"}, // -e
{"エ", "\xd5"}, // e
{"ォ", "\xd6"}, // -o
{"オ", "\xd7"}, // o
{"カ", "\xd8"}, // ka
{"キ", "\xd9"}, // ki
{"ク", "\xda"}, // ku
{"ケ", "\xdb"}, // ke
{"コ", "\xdc"}, // ko
{"サ", "\xdd"}, // sa
{"シ", "\xde"}, // shi
{"ス", "\xdf"}, // su
{"セ", "\xe0"}, // se
{"ソ", "\xe1"}, // so
{"タ", "\xe2"}, // ta
{"チ", "\xe3"}, // chi
{"ッ", "\xe4"}, // sokuon
{"ツ", "\xe5"}, // tsu
{"テ", "\xe6"}, // te
{"ト", "\xe7"}, // to
{"ナ", "\xe8"}, // na
{"ニ", "\xe9"}, // ni
{"ヌ", "\xea"}, // nu
{"ネ", "\xeb"}, // ne
{"ノ", "\xec"}, // no
{"ハ", "\xed"}, // ha
{"ヒ", "\xee"}, // hi
{"フ", "\xef"}, // hu
{"ヘ", "\xf0"}, // he
{"ホ", "\xf1"}, // ho
{"マ", "\xf2"}, // ma
{"ミ", "\xf3"}, // mi
{"ム", "\xf4"}, // mu
{"メ", "\xf5"}, // me
{"モ", "\xf6"}, // mo
{"ャ", "\xf7"}, // youon ya
{"ヤ", "\xf8"}, // ya
{"ュ", "\xf9"}, // youon yu
{"ユ", "\xfa"}, // yu
{"ョ", "\xfb"}, // youon yo
{"ヨ", "\xfc"}, // yo
{"ラ", "\xfd"}, // ra
{"リ", "\xfe"}, // ri
{"ル", "\xff"}, // ru
// kanji 2
{"宝", "\x1\x01"}, // takara
{"石", "\x1\x10"}, // ishi
{"赤", "\x1\x11"}, // aka
{"跡", "\x1\x12"}, // ato
{"川", "\x1\x13"}, // kawa
{"戦", "\x1\x14"}, // ikusa
{"村", "\x1\x15"}, // mura
{"隊", "\x1\x16"}, // tai
{"台", "\x1\x17"}, // utena
{"長", "\x1\x18"}, // osa
{"鳥", "\x1\x19"}, // tori
{"艇", "\x1\x1a"}, // tei
{"洞", "\x1\x1b"}, // hora
{"道", "\x1\x1c"}, // michi
{"発", "\x1\x1d"}, // hatsu
{"飛", "\x1\x1e"}, // tobu
{"噴", "\x1\x1f"}, // fuku
{"池", "\x1\xa0"}, // ike
{"中", "\x1\xa1"}, // naka
{"塔", "\x1\xa2"}, // tou
{"島", "\x1\xa3"}, // shima
{"部", "\x1\xa4"}, // bu
{"砲", "\x1\xa5"}, // hou
{"産", "\x1\xa6"}, // san
{"眷", "\x1\xa7"}, // kaerimiru
{"力", "\x1\xa8"}, // chikara
{"緑", "\x1\xa9"}, // midori
{"岸", "\x1\xaa"}, // kishi
{"像", "\x1\xab"}, // zou
{"谷", "\x1\xac"}, // tani
{"心", "\x1\xad"}, // kokoro
{"森", "\x1\xae"}, // mori
{"水", "\x1\xaf"}, // mizu
{"船", "\x1\xb0"}, // fune
{"™", "\x1\xb1"}, // trademark
};
std::vector<ReplaceInfo> replace_info_jak1 = {
// other
{"A~Y~-21H~-5Vº~Z", "Å"},
{"N~Y~-6Hº~Z~+10H", "Nº"},
{"O~Y~-16H~-1V/~Z", "Ø"},
{"A~Y~-6H~+3V,~Z", "Ą"},
{"E~Y~-6H~+2V,~Z", "Ę"},
{"L~Y~-16H~+0V/~Z", "Ł"},
{"Z~Y~-21H~-5Vº~Z", "Ż"},
{"E~Y~-20H~-5Vº~Z", "Ė"},
{"C~Y~-20H~-4Vˇ~Z", "Č"},
{"D~Y~-20H~-4Vˇ~Z", "Ď"},
{"S~Y~-22H~-4Vˇ~Z", "Š"},
{"Z~Y~-22H~-4Vˇ~Z", "Ž"},
{"U~Y~-13H~+2V,~Z", "Ų"},
{"U~Y~-18H~-10V-~Z", "Ū"},
{"D~Y~-25H~-1V-~Z", "Đ"},
{"I~Y~-8H~+1V,~Z", "Į"},
// czech specific
{"U~Y~-23H~-5Vº~Z", "Ů"},
// tildes
{"N~Y~-22H~-4V<TIL>~Z", "Ñ"},
{"A~Y~-21H~-5V<TIL>~Z", "Ã"}, // custom
{"O~Y~-22H~-4V<TIL>~Z", "Õ"}, // custom
// acute accents
{"A~Y~-21H~-5V'~Z", "Á"},
{"E~Y~-22H~-5V'~Z", "É"},
{"I~Y~-19H~-5V'~Z", "Í"},
{"O~Y~-22H~-4V'~Z", "Ó"},
{"U~Y~-24H~-3V'~Z", "Ú"},
{"C~Y~-21H~-5V'~Z", "Ć"},
{"N~Y~-21H~-5V'~Z", "Ń"},
{"S~Y~-21H~-5V'~Z", "Ś"},
{"Z~Y~-21H~-5V'~Z", "Ź"},
// czech specific
{"Y~Y~-25H~-4V'~Z", "Ý"},
// double acute accents
{"O~Y~-28H~-4V'~-9H'~Z", "Ő"}, // custom
{"U~Y~-27H~-4V'~-12H'~Z", "Ű"}, // custom
// circumflex
{"A~Y~-20H~-4V^~Z", "Â"}, // custom
{"E~Y~-20H~-5V^~Z", "Ê"},
{"I~Y~-19H~-5V^~Z", "Î"},
{"O~Y~-20H~-4V^~Z", "Ô"}, // custom
{"U~Y~-24H~-3V^~Z", "Û"},
// grave accents
{"A~Y~-21H~-5V`~Z", "À"},
{"E~Y~-22H~-5V`~Z", "È"},
{"I~Y~-19H~-5V`~Z", "Ì"},
{"O~Y~-22H~-4V`~Z", "Ò"}, // custom
{"U~Y~-24H~-3V`~Z", "Ù"},
// umlaut
{"A~Y~-21H~-5V¨~Z", "Ä"},
{"E~Y~-20H~-5V¨~Z", "Ë"},
{"I~Y~-19H~-5V¨~Z", "Ï"}, // custom
{"O~Y~-22H~-4V¨~Z", "Ö"},
{"O~Y~-22H~-3V¨~Z", "ö"}, // dumb
{"U~Y~-22H~-3V¨~Z", "Ü"},
// caron - Ǎ ǎ Ě ě Ǧ ǧ Ǐ ǐ Ǒ ǒ Ǔ ǔ Y̌ y̌
{"A~Y~-20H~-4Vˇ~Z", "Ǎ"},
{"E~Y~-20H~-5Vˇ~Z", "Ě"},
{"G~Y~-20H~-5Vˇ~Z", "Ǧ"},
{"I~Y~-19H~-5Vˇ~Z", "Ǐ"},
{"O~Y~-20H~-4Vˇ~Z", "Ǒ"},
{"U~Y~-24H~-3Vˇ~Z", "Ǔ"},
{"Y~Y~-24H~-3Vˇ~Z", "Y̌"},
// czech specific - Č Ň Ř Š Ž Ť
{"C~Y~-25H~-9Vˇ~Z", "Č"},
{"N~Y~-23H~-5Vˇ~Z", "Ň"},
{"R~Y~-24H~-5Vˇ~Z", "Ř"},
{"S~Y~-24H~-5Vˇ~Z", "Š"},
{"T~Y~-23H~-5Vˇ~Z", "Ť"},
{"Z~Y~-23H~-5Vˇ~Z", "Ž"},
// dakuten katakana
{"~Yウ~Z゛", "ヴ"},
{"~Yカ~Z゛", "ガ"},
{"~Yキ~Z゛", "ギ"},
{"~Yク~Z゛", "グ"},
{"~Yケ~Z゛", "ゲ"},
{"~Yコ~Z゛", "ゴ"},
{"~Yサ~Z゛", "ザ"},
{"~Yシ~Z゛", "ジ"},
{"~Yス~Z゛", "ズ"},
{"~Yセ~Z゛", "ゼ"},
{"~Yソ~Z゛", "ゾ"},
{"~Yタ~Z゛", "ダ"},
{"~Yチ~Z゛", "ヂ"},
{"~Yツ~Z゛", "ヅ"},
{"~Yテ~Z゛", "デ"},
{"~Yト~Z゛", "ド"},
{"~Yハ~Z゛", "バ"},
{"~Yヒ~Z゛", "ビ"},
{"~Yフ~Z゛", "ブ"},
{"~Yヘ~Z゛", "ベ"},
{"~Yホ~Z゛", "ボ"},
// handakuten katakana
{"~Yハ~Z゜", "パ"},
{"~Yヒ~Z゜", "ピ"},
{"~Yフ~Z゜", "プ"},
{"~Yヘ~Z゜", "ペ"},
{"~Yホ~Z゜", "ポ"},
// dakuten hiragana
{"~Yか~Z゛", "が"},
{"~Yき~Z゛", "ぎ"},
{"~Yく~Z゛", "ぐ"},
{"~Yけ~Z゛", "げ"},
{"~Yこ~Z゛", "ご"},
{"~Yさ~Z゛", "ざ"},
{"~Yし~Z゛", "じ"},
{"~Yす~Z゛", "ず"},
{"~Yせ~Z゛", "ぜ"},
{"~Yそ~Z゛", "ぞ"},
{"~Yた~Z゛", "だ"},
{"~Yち~Z゛", "ぢ"},
{"~Yつ~Z゛", "づ"},
{"~Yて~Z゛", "で"},
{"~Yと~Z゛", "ど"},
{"~Yは~Z゛", "ば"},
{"~Yひ~Z゛", "び"},
{"~Yふ~Z゛", "ぶ"},
{"~Yへ~Z゛", "べ"},
{"~Yほ~Z゛", "ぼ"},
// handakuten hiragana
{"~Yは~Z゜", "ぱ"},
{"~Yひ~Z゜", "ぴ"},
{"~Yふ~Z゜", "ぷ"},
{"~Yへ~Z゜", "ぺ"},
{"~Yほ~Z゜", "ぽ"},
// japanese punctuation
{",~+8H", "、"},
{"~+8H ", " "},
// (hack) special case kanji
{"~~", "世"},
// playstation buttons
{"~Y~22L<~Z~Y~27L*~Z~Y~1L>~Z~Y~23L[~Z~+26H", "<PAD_X>"},
{"~Y~22L<~Z~Y~26L;~Z~Y~1L>~Z~Y~23L[~Z~+26H", "<PAD_TRIANGLE>"},
{"~Y~22L<~Z~Y~25L@~Z~Y~1L>~Z~Y~23L[~Z~+26H", "<PAD_CIRCLE>"},
{"~Y~22L<~Z~Y~24L#~Z~Y~1L>~Z~Y~23L[~Z~+26H", "<PAD_SQUARE>"}, // custom
};
std::vector<EncodeInfo> encode_info_jak1_v2 = {
// random
{"_", "\x03"}, // large space
{"ˇ", "\x10"}, // caron
{"`", "\x11"}, // grave accent
{"'", "\x12"}, // apostrophe
{"^", "\x13"}, // circumflex
{"<TIL>", "\x14"}, // tilde
{"¨", "\x15"}, // umlaut
{"º", "\x16"}, // numero/overring
{"¡", "\x17"}, // inverted exclamation mark
{"¿", "\x18"}, // inverted question mark
{"海", "\x1a"}, // umi
{"Æ", "\x1b"}, // aesc
{"界", "\x1c"}, // kai
{"Ç", "\x1d"}, // c-cedilla
{"学", "\x1e"}, // gaku
{"ß", "\x1f"}, // eszett
{"ワ", "\x24"}, // wa
{"ヲ", "\x26"}, // wo
{"ン", "\x27"}, // -n
{"岩", "\x5c"}, // iwa
{"旧", "\x5d"}, // kyuu
{"空", "\x5e"}, // sora
{"掘", "\x5f"}, // horu
{"ヮ", "\x60"}, // -wa
{"撃", "\x61"}, // utsu
{"賢", "\x62"}, // kashikoi
{"湖", "\x63"}, // mizuumi
{"口", "\x64"}, // kuchi
{"行", "\x65"}, // iku
{"合", "\x66"}, // ai
{"士", "\x67"}, // shi
{"寺", "\x68"}, // tera
{"山", "\x69"}, // yama
{"者", "\x6a"}, // mono
{"所", "\x6b"}, // tokoro
{"書", "\x6c"}, // kaku
{"小", "\x6d"}, // shou
{"沼", "\x6e"}, // numa
{"上", "\x6f"}, // ue
{"城", "\x70"}, // shiro
{"場", "\x71"}, // ba
{"出", "\x72"}, // shutsu
{"闇", "\x73"}, // yami
{"遺", "\x74"}, // nokosu
{"黄", "\x75"}, // ki
{"屋", "\x76"}, // ya
{"下", "\x77"}, // shita
{"家", "\x78"}, // ie
{"火", "\x79"}, // hi
{"花", "\x7a"}, // hana
{"レ", "\x7b"}, // re
{"Œ", "\x7c"}, // oe
{"ロ", "\x7d"}, // ro
{"青", "\x7f"}, // ao
{"・", "\x90"}, // nakaguro
{"゛", "\x91"}, // dakuten
{"゜", "\x92"}, // handakuten
{"ー", "\x93"}, // chouompu
{"『", "\x94"}, // nijuukagikakko left
{"』", "\x95"}, // nijuukagikakko right
// hiragana
{"ぁ", "\x96"}, // -a
{"あ", "\x97"}, // a
{"ぃ", "\x98"}, // -i
{"い", "\x99"}, // i
{"ぅ", "\x9a"}, // -u
{"う", "\x9b"}, // u
{"ぇ", "\x9c"}, // -e
{"え", "\x9d"}, // e
{"ぉ", "\x9e"}, // -o
{"お", "\x9f"}, // o
{"か", "\xa0"}, // ka
{"き", "\xa1"}, // ki
{"く", "\xa2"}, // ku
{"け", "\xa3"}, // ke
{"こ", "\xa4"}, // ko
{"さ", "\xa5"}, // sa
{"し", "\xa6"}, // shi
{"す", "\xa7"}, // su
{"せ", "\xa8"}, // se
{"そ", "\xa9"}, // so
{"た", "\xaa"}, // ta
{"ち", "\xab"}, // chi
{"っ", "\xac"}, // sokuon
{"つ", "\xad"}, // tsu
{"て", "\xae"}, // te
{"と", "\xaf"}, // to
{"な", "\xb0"}, // na
{"に", "\xb1"}, // ni
{"ぬ", "\xb2"}, // nu
{"ね", "\xb3"}, // ne
{"の", "\xb4"}, // no
{"は", "\xb5"}, // ha
{"ひ", "\xb6"}, // hi
{"ふ", "\xb7"}, // hu
{"へ", "\xb8"}, // he
{"ほ", "\xb9"}, // ho
{"ま", "\xba"}, // ma
{"み", "\xbb"}, // mi
{"む", "\xbc"}, // mu
{"め", "\xbd"}, // me
{"も", "\xbe"}, // mo
{"ゃ", "\xbf"}, // youon ya
{"や", "\xc0"}, // ya
{"ゅ", "\xc1"}, // youon yu
{"ゆ", "\xc2"}, // yu
{"ょ", "\xc3"}, // youon yo
{"よ", "\xc4"}, // yo
{"ら", "\xc5"}, // ra
{"り", "\xc6"}, // ri
{"る", "\xc7"}, // ru
{"れ", "\xc8"}, // re
{"ろ", "\xc9"}, // ro
{"ゎ", "\xca"}, // -wa
{"わ", "\xcb"}, // wa
{"を", "\xcc"}, // wo
{"ん", "\xcd"}, // -n
// katakana
{"ァ", "\xce"}, // -a
{"ア", "\xcf"}, // a
{"ィ", "\xd0"}, // -i
{"イ", "\xd1"}, // i
{"ゥ", "\xd2"}, // -u
{"ウ", "\xd3"}, // u
{"ェ", "\xd4"}, // -e
{"エ", "\xd5"}, // e
{"ォ", "\xd6"}, // -o
{"オ", "\xd7"}, // o
{"カ", "\xd8"}, // ka
{"キ", "\xd9"}, // ki
{"ク", "\xda"}, // ku
{"ケ", "\xdb"}, // ke
{"コ", "\xdc"}, // ko
{"サ", "\xdd"}, // sa
{"シ", "\xde"}, // shi
{"ス", "\xdf"}, // su
{"セ", "\xe0"}, // se
{"ソ", "\xe1"}, // so
{"タ", "\xe2"}, // ta
{"チ", "\xe3"}, // chi
{"ッ", "\xe4"}, // sokuon
{"ツ", "\xe5"}, // tsu
{"テ", "\xe6"}, // te
{"ト", "\xe7"}, // to
{"ナ", "\xe8"}, // na
{"ニ", "\xe9"}, // ni
{"ヌ", "\xea"}, // nu
{"ネ", "\xeb"}, // ne
{"ノ", "\xec"}, // no
{"ハ", "\xed"}, // ha
{"ヒ", "\xee"}, // hi
{"フ", "\xef"}, // hu
{"ヘ", "\xf0"}, // he
{"ホ", "\xf1"}, // ho
{"マ", "\xf2"}, // ma
{"ミ", "\xf3"}, // mi
{"ム", "\xf4"}, // mu
{"メ", "\xf5"}, // me
{"モ", "\xf6"}, // mo
{"ャ", "\xf7"}, // youon ya
{"ヤ", "\xf8"}, // ya
{"ュ", "\xf9"}, // youon yu
{"ユ", "\xfa"}, // yu
{"ョ", "\xfb"}, // youon yo
{"ヨ", "\xfc"}, // yo
{"ラ", "\xfd"}, // ra
{"リ", "\xfe"}, // ri
{"ル", "\xff"}, // ru
// kanji 2
{"宝", "\x1\x01"}, // takara
{"石", "\x1\x10"}, // ishi
{"赤", "\x1\x11"}, // aka
{"跡", "\x1\x12"}, // ato
{"川", "\x1\x13"}, // kawa
{"戦", "\x1\x14"}, // ikusa
{"村", "\x1\x15"}, // mura
{"隊", "\x1\x16"}, // tai
{"台", "\x1\x17"}, // utena
{"長", "\x1\x18"}, // osa
{"鳥", "\x1\x19"}, // tori
{"艇", "\x1\x1a"}, // tei
{"洞", "\x1\x1b"}, // hora
{"道", "\x1\x1c"}, // michi
{"発", "\x1\x1d"}, // hatsu
{"飛", "\x1\x1e"}, // tobu
{"噴", "\x1\x1f"}, // fuku
{"池", "\x1\xa0"}, // ike
{"中", "\x1\xa1"}, // naka
{"塔", "\x1\xa2"}, // tou
{"島", "\x1\xa3"}, // shima
{"部", "\x1\xa4"}, // bu
{"砲", "\x1\xa5"}, // hou
{"産", "\x1\xa6"}, // san
{"眷", "\x1\xa7"}, // kaerimiru
{"力", "\x1\xa8"}, // chikara
{"緑", "\x1\xa9"}, // midori
{"岸", "\x1\xaa"}, // kishi
{"像", "\x1\xab"}, // zou
{"谷", "\x1\xac"}, // tani
{"心", "\x1\xad"}, // kokoro
{"森", "\x1\xae"}, // mori
{"水", "\x1\xaf"}, // mizu
{"船", "\x1\xb0"}, // fune
{"™", "\x1\xb1"}, // trademark
};
GameTextFontBank g_font_bank_jak1_v1(GameTextVersion::JAK1_V1,
&encode_info_jak1,
&replace_info_jak1,
&passthrus_jak1);
GameTextFontBank g_font_bank_jak1_v2(GameTextVersion::JAK1_V2,
&encode_info_jak1_v2,
&replace_info_jak1,
&passthrus_jak1);
-25
View File
@@ -1,25 +0,0 @@
#pragma once
#include "common/util/font/font_utils.h"
/*!
* ===========================
* GAME TEXT FONT BANK - JAK 1
* ===========================
* This font is used in:
* - Jak & Daxter: The Precursor Legacy (Black Label)
*/
extern GameTextFontBank g_font_bank_jak1_v1;
/*!
* ================================
* GAME TEXT FONT BANK - JAK 1 (v2)
* ================================
* This font is used in:
* - Jak & Daxter: The Precursor Legacy (PAL)
* - ジャックXダクスター ~ 旧世界の遺産
* - Jak & Daxter: The Precursor Legacy (NTSC-U v2)
*
* It is the same as v1, but _ has been fixed and no longer overlaps 掘
*/
extern GameTextFontBank g_font_bank_jak1_v2;
-904
View File
@@ -1,904 +0,0 @@
#include "font_db_jak2.h"
std::unordered_set<char> passthrus_jak2 = {'~', ' ', ',', '.', '-', '+', '(', ')',
'!', ':', '?', '=', '%', '*', '/', '#',
';', '<', '>', '@', '[', '_', ']'};
std::vector<ReplaceInfo> replace_info_jak2 = {
// other
{"A~Y~-21H~-5Vº~Z", "Å"},
{"N~Y~-6Hº~Z~+10H", "Nº"},
// portuguese
{"~+4Vç~-4V", "ç"},
{"O~Y~-25H~-1V/~Z", "Ø"},
{"o~Y~-23H~+4V/~Z", "ø"},
{"A~Y~-13H~+8V,~Z", "Ą"},
{"a~Y~-8H~+6V,~Z", "ą"},
{"E~Y~-6H~+8V,~Z", "Ę"},
{"e~Y~-10H~+7V,~Z", "ę"},
{"L~Y~-21H~+0V/~Z", "Ł"},
{"l~Y~-16H~+0V/~Z", "ł"}, // TODO - this one is ugly, font character addition (small slash)
{"Z~Y~-25H~-11Vº~Z", "Ż"},
{"z~Y~-23H~-5Vº~Z", "ż"},
{"a~Y~-25H~-5Vº~Z", "å"},
{"S~Y~-21H~-5V'~Z", "Ś"},
{"s~Y~-25H~-5V'~Z", "ś"},
{"n~Y~-25H~-5V'~Z", "ń"},
{"c~Y~-25H~-5V'~Z", "ć"},
{"o~Y~-25H~-4V<TIL>~Z", "õ"},
{"a~Y~-25H~-4V<TIL>~Z", "ã"},
{"O~Y~-28H~-4V'~-9H'~Z", "Ő"},
{"U~Y~-27H~-4V'~-12H'~Z", "Ű"},
{"o~Y~-28H~-4V'~-9H'~Z", "ő"},
{"u~Y~-28H~-4V'~-9H'~Z", "ű"},
{"E~Y~-22H~-11Vº~Z", "Ė"},
{"e~Y~-25H~-5Vº~Z", "ė"},
{"C~Y~-27H~-10Vˇ~Z", "Č"},
{"c~Y~-25H~-5Vˇ~Z", "č"},
{"D~Y~-27H~-10Vˇ~Z", "Ď"},
{"S~Y~-24H~-10Vˇ~Z", "Š"},
{"s~Y~-22H~-4Vˇ~Z", "š"},
{"Z~Y~-25H~-10Vˇ~Z", "Ž"},
{"z~Y~-23H~-4Vˇ~Z", "ž"},
{"U~Y~-15H~+5V,~Z", "Ų"},
{"u~Y~-15H~+5V,~Z", "ų"},
{"U~Y~-20H~-18V-~Z", "Ū"},
{"u~Y~-18H~-15V-~Z", "ū"},
{"D~Y~-28H~-1V-~Z", "Đ"},
{"d~Y~-13H~-10V-~Z", "đ"},
{"I~Y~-8H~+4V,~Z", "Į"},
{"i~Y~-8H~+4V,~Z", "į"},
// czech specific
{"U~Y~-24H~-7Vº~Z", "Ů"},
{"u~Y~-23H~-5Vº~Z", "ů"},
{"t~Y~-7H~-21V,~Z", "ť"},
// tildes
{"N~Y~-22H~-4V<TIL>~Z", "Ñ"},
{"n~Y~-24H~-4V<TIL>~Z", "ñ"},
{"A~Y~-21H~-5V<TIL>~Z", "Ã"},
{"O~Y~-22H~-4V<TIL>~Z", "Õ"},
// acute accents
{"A~Y~-21H~-5V'~Z", "Á"},
{"A~Y~-26H~-8V'~Z", "<Á_V2>"}, // unfortunate...
{"a~Y~-25H~-5V'~Z", "á"},
{"E~Y~-23H~-9V'~Z", "É"},
{"e~Y~-26H~-5V'~Z", "é"},
{"I~Y~-19H~-8V'~Z", "Í"},
{"i~Y~-19H~-8V'~Z", "í"},
{"O~Y~-22H~-4V'~Z", "Ó"},
{"o~Y~-26H~-4V'~Z", "ó"},
{"U~Y~-25H~-8V'~Z", "Ú"},
{"u~Y~-24H~-3V'~Z", "ú"},
{"Z~Y~-24H~-3V'~Z", "Ź"},
{"z~Y~-24H~-3V'~Z", "ź"},
// czech specific
{"Y~Y~-26H~-5V'~Z", "Ý"},
{"~+7Vy~-7V~Y~-24H~-3V'~Z", "ý"},
// circumflex
{"A~Y~-20H~-4V^~Z", "Â"},
{"a~Y~-24H~-5V^~Z", "â"},
{"E~Y~-20H~-5V^~Z", "Ê"},
{"e~Y~-25H~-4V^~Z", "ê"},
{"I~Y~-19H~-5V^~Z", "Î"},
{"i~Y~-19H~-8V^~Z", "î"},
{"O~Y~-20H~-4V^~Z", "Ô"},
{"o~Y~-25H~-4V^~Z", "ô"},
{"U~Y~-24H~-3V^~Z", "Û"},
{"u~Y~-23H~-3V^~Z", "û"},
// grave accents
{"A~Y~-26H~-8V`~Z", "À"},
{"a~Y~-25H~-5V`~Z", "à"},
{"E~Y~-23H~-9V`~Z", "È"},
{"e~Y~-26H~-5V`~Z", "è"},
{"I~Y~-19H~-5V`~Z", "Ì"},
{"i~Y~-19H~-8V`~Z", "ì"},
{"O~Y~-22H~-4V`~Z", "Ò"},
{"o~Y~-26H~-4V`~Z", "ò"},
{"U~Y~-24H~-3V`~Z", "Ù"},
{"u~Y~-24H~-3V`~Z", "ù"},
// umlaut
{"A~Y~-26H~-8V¨~Z", "Ä"},
{"a~Y~-25H~-5V¨~Z", "ä"},
{"E~Y~-20H~-5V¨~Z", "Ë"},
{"e~Y~-25H~-5V¨~Z", "ë"},
{"I~Y~-19H~-5V¨~Z", "Ï"},
{"i~Y~-26H~-4V¨~Z", "ï"},
{"O~Y~-26H~-8V¨~Z", "Ö"},
{"o~Y~-26H~-4V¨~Z", "ö"},
{"U~Y~-25H~-8V¨~Z", "Ü"},
{"u~Y~-24H~-3V¨~Z", "ü"},
// caron - Ǎ ǎ Ě ě Ǧ ǧ Ǐ ǐ Ǒ ǒ Ǔ ǔ Y̌ y̌
{"A~Y~-25H~-9Vˇ~Z", "Ǎ"},
{"a~Y~-24H~-5Vˇ~Z", "ǎ"},
{"E~Y~-22H~-8Vˇ~Z", "Ě"},
{"e~Y~-25H~-4Vˇ~Z", "ě"},
{"G~Y~-24H~-8Vˇ~Z", "Ǧ"},
{"~+7Vg~-7V~Y~-25H~-4Vˇ~Z", "ǧ"},
{"I~Y~-19H~-8Vˇ~Z", "Ǐ"},
{"i~Y~-19H~-8Vˇ~Z", "ǐ"},
{"O~Y~-25H~-7Vˇ~Z", "Ǒ"},
{"o~Y~-25H~-4Vˇ~Z", "ǒ"},
{"U~Y~-25H~-6Vˇ~Z", "Ǔ"},
{"u~Y~-24H~-3Vˇ~Z", "ǔ"},
{"Y~Y~-25H~-5Vˇ~Z", "Y̌"},
{"~+7Vy~-7V~Y~-25H~-3Vˇ~Z", "y̌"},
// czech specific - Č č Ň ň Ř ř Š š Ž ž Ť
{"C~Y~-25H~-9Vˇ~Z", "Č"},
{"c~Y~-24H~-5Vˇ~Z", "č"},
{"N~Y~-25H~-9Vˇ~Z", "Ň"},
{"n~Y~-24H~-5Vˇ~Z", "ň"},
{"R~Y~-25H~-9Vˇ~Z", "Ř"},
{"r~Y~-22H~-5Vˇ~Z", "ř"},
{"S~Y~-25H~-9Vˇ~Z", "Š"},
{"s~Y~-22H~-5Vˇ~Z", "š"},
{"T~Y~-24H~-7Vˇ~Z", "Ť"},
{"Z~Y~-25H~-9Vˇ~Z", "Ž"},
{"z~Y~-24H~-5Vˇ~Z", "ž"},
// dakuten katakana
{"~Yウ~Z゛", "ヴ"},
{"~Yカ~Z゛", "ガ"},
{"~Yキ~Z゛", "ギ"},
{"~Yク~Z゛", "グ"},
{"~Yケ~Z゛", "ゲ"},
{"~Yコ~Z゛", "ゴ"},
{"~Yサ~Z゛", "ザ"},
{"~Yシ~Z゛", "ジ"},
{"~Yス~Z゛", "ズ"},
{"~Yセ~Z゛", "ゼ"},
{"~Yソ~Z゛", "ゾ"},
{"~Yタ~Z゛", "ダ"},
{"~Yチ~Z゛", "ヂ"},
{"~Yツ~Z゛", "ヅ"},
{"~Yテ~Z゛", "デ"},
{"~Yト~Z゛", "ド"},
{"~Yハ~Z゛", "バ"},
{"~Yヒ~Z゛", "ビ"},
{"~Yフ~Z゛", "ブ"},
{"~Yヘ~Z゛", "ベ"},
{"~Yホ~Z゛", "ボ"},
// handakuten katakana
{"~Yハ~Z゜", "パ"},
{"~Yヒ~Z゜", "ピ"},
{"~Yフ~Z゜", "プ"},
{"~Yヘ~Z゜", "ペ"},
{"~Yホ~Z゜", "ポ"},
// dakuten hiragana
{"~Yか~Z゛", "が"},
{"~Yき~Z゛", "ぎ"},
{"~Yく~Z゛", "ぐ"},
{"~Yけ~Z゛", "げ"},
{"~Yこ~Z゛", "ご"},
{"~Yさ~Z゛", "ざ"},
{"~Yし~Z゛", "じ"},
{"~Yす~Z゛", "ず"},
{"~Yせ~Z゛", "ぜ"},
{"~Yそ~Z゛", "ぞ"},
{"~Yた~Z゛", "だ"},
{"~Yち~Z゛", "ぢ"},
{"~Yつ~Z゛", "づ"},
{"~Yて~Z゛", "で"},
{"~Yと~Z゛", "ど"},
{"~Yは~Z゛", "ば"},
{"~Yひ~Z゛", "び"},
{"~Yふ~Z゛", "ぶ"},
{"~Yへ~Z゛", "べ"},
{"~Yほ~Z゛", "ぼ"},
// handakuten hiragana
{"~Yは~Z゜", "ぱ"},
{"~Yひ~Z゜", "ぴ"},
{"~Yふ~Z゜", "ぷ"},
{"~Yへ~Z゜", "ぺ"},
{"~Yほ~Z゜", "ぽ"},
// japanese punctuation
{",~+8H", "、"},
{"~+8H ", " "},
// playstation buttons
// - face
{"~Y~22L<~Z~Y~27L*~Z~Y~1L>~Z~Y~23L[~Z~+26H", "<PAD_X>"},
{"~Y~22L<~Z~Y~26L;~Z~Y~1L>~Z~Y~23L[~Z~+26H", "<PAD_TRIANGLE>"},
{"~Y~22L<~Z~Y~25L@~Z~Y~1L>~Z~Y~23L[~Z~+26H", "<PAD_CIRCLE>"},
{"~Y~22L<~Z~Y~24L#~Z~Y~1L>~Z~Y~23L[~Z~+26H", "<PAD_SQUARE>"},
// - dpad
{"~Y~22L<PAD_PART_DPAD_L>~Z~3L~+17H~-13V<PAD_PART_DPAD_U>~Z~22L~+17H~+14V<PAD_PART_DPAD_D>~Z~"
"22L~+32H<PAD_PART_DPAD_R>~Z~+56H",
"<PAD_DPAD_UP>"},
{"~Y~22L<PAD_PART_DPAD_L>~Z~3L~+17H~-13V<PAD_PART_DPAD_U>~Z~3L~+17H~+14V<PAD_PART_DPAD_D>~Z~"
"22L~+32H<PAD_PART_DPAD_R>~Z~+56H",
"<PAD_DPAD_DOWN>"},
{"~Y~22L<PAD_PART_DPAD_L>~Z~22L~+17H~-13V<PAD_PART_DPAD_U>~Z~22L~+17H~+14V<PAD_PART_DPAD_D>~Z~"
"22L~+32H<PAD_PART_DPAD_R>~Z~+56H",
"<PAD_DPAD_ANY>"},
// - shoulder
{"~Y~22L~-2H~-12V<PAD_PART_SHOULDER_TOP_LEFT><PAD_PART_SHOULDER_TOP_RIGHT>~Z~22L~-2H~+17V<PAD_"
"PART_SHOULDER_BOTTOM_LEFT><PAD_PART_SHOULDER_BOTTOM_RIGHT>~Z~1L~+4H~+3V<PAD_PART_L1_NAME>~Z~+"
"38H",
"<PAD_L1>"},
{"~Y~22L~-2H~-12V<PAD_PART_SHOULDER_TOP_LEFT><PAD_PART_SHOULDER_TOP_RIGHT>~Z~22L~-2H~+17V<PAD_"
"PART_SHOULDER_BOTTOM_LEFT><PAD_PART_SHOULDER_BOTTOM_RIGHT>~Z~1L~+6H~+3V<PAD_PART_R1_NAME>~Z~+"
"38H",
"<PAD_R1>"},
{"~Y~22L~-2H~-6V<PAD_PART_TRIGGER_TOP_LEFT><PAD_PART_TRIGGER_TOP_RIGHT>~Z~22L~-2H~+16V<PAD_"
"PART_TRIGGER_BOTTOM_LEFT><PAD_PART_TRIGGER_BOTTOM_RIGHT>~Z~1L~+5H~-2V<PAD_PART_R2_NAME>~Z~+"
"38H",
"<PAD_R2>"},
{"~Y~22L~-2H~-6V<PAD_PART_TRIGGER_TOP_LEFT><PAD_PART_TRIGGER_TOP_RIGHT>~Z~22L~-2H~+16V<PAD_"
"PART_TRIGGER_BOTTOM_LEFT><PAD_PART_TRIGGER_BOTTOM_RIGHT>~Z~1L~+5H~-2V<PAD_PART_L2_NAME>~Z~+"
"38H",
"<PAD_L2>"},
// - analog
{"~1L~+8H~Y<PAD_PART_STICK>~Z~6L~-16H<PAD_PART_STICK_LEFT>~Z~+16h~6L<PAD_PART_STICK_RIGHT>~Z~"
"6L~-15V<PAD_PART_STICK_DOWN>~Z~+13V~6L<PAD_PART_STICK_UP>~Z~-10H~+9V~6L<PAD_PART_STICK_UP_"
"LEFT>~Z~+10H~+9V~6L<PAD_PART_STICK_UP_RIGHT>~Z~-10H~-11V~6L<PAD_PART_STICK_DOWN_LEFT>~Z~+10H~"
"-11V~6L<PAD_PART_STICK_DOWN_RIGHT>~Z~+32H",
"<PAD_ANALOG_ANY>"},
{"~Y~1L~+8H<PAD_PART_STICK>~Z~6L~-8H<PAD_PART_STICK_LEFT>~Z~+24H~6L<PAD_PART_STICK_RIGHT>~Z~+"
"40H",
"<PAD_ANALOG_LEFT_RIGHT>"},
{"~Y~1L<PAD_PART_STICK>~Z~6L~-15V<PAD_PART_STICK_DOWN>~Z~+13V~6L<PAD_PART_STICK_UP>~Z~+26H",
"<PAD_ANALOG_UP_DOWN>"},
// icons
{"~Y~6L<~Z~Y~1L>~Z~Y~23L[~Z~+26H", "<ICON_MISSION_COMPLETE>"},
{"~Y~3L<~Z~Y~1L>~Z~Y~23L[~Z~+26H", "<ICON_MISSION_TODO>"},
// flags
{"~Y~6L<FLAG_PART_VERT_STRIPE_LARGE>~Z~+15H~1L<FLAG_PART_VERT_STRIPE_LARGE>~Z~+30H~3L<FLAG_"
"PART_VERT_STRIPE_LARGE>~Z~+45H",
"<FLAG_ITALIAN>"},
{"~Y~5L<FLAG_PART_FILL>~Z~3L<FLAG_PART_TOP_BOTTOM_STRIPE>~]~-1H~Y~5L<FLAG_PART_FILL>~Z~3L<FLAG_"
"PART_TOP_BOTTOM_STRIPE>~Z~+26H",
"<FLAG_SPAIN>"},
{"~Y~39L~~~Z~3L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~5L<FLAG_PART_HORZ_STRIPE_BOTTOM>~]~-1H~Y~39L~~~"
"Z~3L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~5L<FLAG_PART_HORZ_STRIPE_BOTTOM>~Z~+26H",
"<FLAG_GERMAN>"},
{"~Y~7L<FLAG_PART_VERT_STRIPE_LARGE>~Z~+15H~1L<FLAG_PART_VERT_STRIPE_LARGE>~Z~+30H~3L<FLAG_"
"PART_VERT_STRIPE_LARGE>~Z~+47H",
"<FLAG_FRANCE>"},
{"~Y~1L<FLAG_PART_FILL>~Z~3L<FLAG_PART_UK_CROSS_LEFT>~Z~7L<FLAG_PART_UK_FILL_LEFT>~]~-1H~Y~1L<"
"FLAG_PART_FILL>~Z~3L<FLAG_PART_UK_CROSS_RIGHT>~Z~7L<FLAG_PART_UK_FILL_RIGHT>~Z~+26H",
"<FLAG_UK>"},
{"~Y~1L<FLAG_PART_FILL>~Z~3L<FLAG_PART_USA_STRIPES_LEFT>~Z~7L<FLAG_PART_USA_STARS>~]~-1H~Y~1L<"
"FLAG_PART_FILL>~Z~3L<FLAG_PART_USA_STRIPES_RIGHT>~Z~+26H",
"<FLAG_USA>"},
{"~Y~1L<FLAG_PART_FILL>~Z~39L<FLAG_PART_KOREA_TRIGRAMS_LEFT>~]~-1H~Y~1L<FLAG_PART_FILL>~Z~39L<"
"FLAG_PART_KOREA_TRIGRAMS_RIGHT>~Z~-11H~7L<FLAG_PART_KOREA_CIRCLE_FILL>~Z~-11H~3L<FLAG_PART_"
"KOREA_CIRCLE_TOP>~Z~+26H",
"<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>~]~-2H~Y~1L<FLAG_PART_FILL>~Z~3L<FLAG_"
"PART_TOP_BOTTOM_STRIPE>~Z~-10H~1L<FLAG_PART_VERT_STRIPE_LEFT>~Z~-5H~1L<FLAG_PART_VERT_STRIPE_"
"LEFT>~Z~-23H~7L<FLAG_PART_VERT_STRIPE_RIGHT>~Z~-22H~7L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~7L"
"<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~+26H",
"<FLAG_NORWAY>"},
{"~Y~1L<FLAG_PART_FILL>~Z~7L<FLAG_PART_TOP_BOTTOM_STRIPE>~]~-2H~Y~1L<FLAG_PART_FILL>~Z~7L<FLAG_"
"PART_TOP_BOTTOM_STRIPE>~Z~-10H~1L<FLAG_PART_VERT_STRIPE_LEFT>~Z~-5H~1L<FLAG_PART_VERT_STRIPE_"
"LEFT>~Z~-23H~3L<FLAG_PART_VERT_STRIPE_RIGHT>~Z~-22H~3L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~3L"
"<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~+26H",
"<FLAG_ICELAND>"},
{"~Y~6L<FLAG_PART_VERT_STRIPE_LARGE>~Z~+15H~3L<FLAG_PART_VERT_STRIPE_LARGE>~Z~+30H~3L<FLAG_"
"PART_VERT_STRIPE_LARGE>~Z~+4H~+2V~5L<FLAG_PART_KOREA_CIRCLE_FILL>~Z~+47H",
"<FLAG_PORTUGUAL>"},
{"~Y~3L~~~Z~1L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~7L<FLAG_PART_HORZ_STRIPE_BOTTOM>~]~-2H~Y~3L~~"
"~Z~1L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~7L<FLAG_PART_HORZ_STRIPE_BOTTOM>~Z~+26H",
"<FLAG_DUTCH>"},
{"~Y~26L<FLAG_PART_FILL>~]~-1H~Y~26L<FLAG_PART_FILL>~Z~-10H~-3V~5L<PAD_PART_DPAD_D>~Z~-10H"
"~+6V~5L<PAD_PART_DPAD_U>~Z~-5H~+1V~5L<PAD_PART_DPAD_L>~Z~-14H~+1V~5L<PAD_PART_DPAD_R>~Z"
"~-11H~+1V~7L<FLAG_PART_KOREA_CIRCLE_FILL>~Z~+26H",
"<FLAG_BRAZIL>"},
{"~Y~3L~~~Z~1L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~26L<FLAG_PART_HORZ_STRIPE_BOTTOM>~]~-2H~Y~3L~~"
"~Z~1L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~26L<FLAG_PART_HORZ_STRIPE_BOTTOM>~Z~+26H",
"<FLAG_HUNGARY>"},
{"~Y~3L<FLAG_PART_FILL>~Z~5L<FLAG_PART_USA_STRIPES_RIGHT>~]~-2H~Y~3L<FLAG_PART_FILL>~Z~5L"
"<FLAG_PART_USA_STRIPES_RIGHT>~Z~+26H",
"<FLAG_CATALAN>"},
{"~Y~1L<FLAG_PART_FILL>~Z~3L<FLAG_PART_HORZ_STRIPE_BOTTOM>~Z~-5V~3L<FLAG_PART_HORZ_STRIPE"
"_BOTTOM>~]~-2H~+5V~Y~1L<FLAG_PART_FILL>~Z~3L<FLAG_PART_HORZ_STRIPE_BOTTOM>~Z~-5V~3L"
"<FLAG_PART_HORZ_STRIPE_BOTTOM>~Z~+26H",
"<FLAG_POLAND>"},
{"~Y~5L~~~Z~26L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~3L<FLAG_PART_HORZ_STRIPE_BOTTOM>~]~-2H~Y~5L~~"
"~Z~26L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~3L<FLAG_PART_HORZ_STRIPE_BOTTOM>~Z~+26H",
"<FLAG_LITHUANIA>"},
{"~Y~1L<FLAG_PART_FILL>~]~-2H~Y~1L<FLAG_PART_FILL>~Z~3L<FLAG_PART_HORZ_STRIPE_BOTTOM>~Z~-5V~3L"
"<FLAG_PART_HORZ_STRIPE_BOTTOM>~Z~-22H~3L<FLAG_PART_HORZ_STRIPE_BOTTOM>~Z~-22H~-5V~3L"
"<FLAG_PART_HORZ_STRIPE_BOTTOM>~Z~-23H~7L<FLAG_PART_VERT_STRIPE_LEFT>~Z~-26H~-3V~7L"
"<PAD_PART_DPAD_D>~Z~+6V~-26H~7L<PAD_PART_DPAD_U>~Z~-21H~+1V~7L<PAD_PART_DPAD_L>~Z~+26H",
"<FLAG_CZECH>"},
{"~Y~3L~~~Z~1L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~7L<FLAG_PART_HORZ_STRIPE_BOTTOM>~]~-1H~Y~3L~~"
"~Z~1L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~7L<FLAG_PART_HORZ_STRIPE_BOTTOM>~Z~-11H~+2V~3L"
"<FLAG_PART_JAPAN_SUN>~Z~-9H~+2V~1L+~Z~-8V~-8H~7L-~Z~-8V~-3H~7L-~Z~+26H",
"<FLAG_CROATIA>"},
{"~Y~1L<FLAG_PART_FILL>~Z~21L<FLAG_PART_UK_CROSS_LEFT>~Z~1L<FLAG_PART_HORZ_STRIPE_MIDDLE>"
"~Z~1L<FLAG_PART_HORZ_STRIPE_BOTTOM>~]~-1H~Y~1L<FLAG_PART_FILL>~Z~21L<FLAG_PART_UK_CROSS_"
"RIGHT>~Z~1L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~-4H~1L<FLAG_PART_VERT_STRIPE_LEFT>~Z~1L~~"
"~Z~-11H~7L<FLAG_PART_KOREA_CIRCLE_FILL>~Z~-8V~-8H~3L-~Z~-8V~-4H~3L-~Z~+26H",
"<FLAG_GALICIA>"},
// korean jamo -- only relevant for the language selection since
// non-korean languages don't run through the `convert-korean-text` function and hence the
// encoding is "normal"
{"~Y~Z\\c03.~Z\\c03\\c1a~Z\\c03\\cc8~Y~Z\\c03œ~Z\\c03k~Z\\c03\\cde~Y~Z\\c03\\c0f~Z\\c03ç",
"<LANGUAGE_KOREAN>",
"~Y~Z\x03.~Z\x03\x1a~Z\x03\xc8~Y~Z\x03œ~Z\x03k~Z\x03\xde~Y~Z\x03\x0f~Z\x03ç"},
// weird stuff
// - descenders
{"~+7Vp~-7V", "p"},
{"~+7Vy~-7V", "y"},
{"~+7Vg~-7V", "g"},
{"~+7Vq~-7V", "q"},
{"~+1Vj~-1V", "j"},
{"\\\\",
"~%"}, // this is 2 slashes, duplicated because we use an escape sequence when decompiling
// - symbols and ligatures
{"~-4H~-3V<SOMETHING>~+3V~-4H",
"<SUPERSCRIPT_QUOTE>"}, // used for the 4<__> place in spanish. the 5th uses the same
// character but looks different...?
{"~Y~-6Hº~Z~+10H", "°"},
// Color / Emphasis
{"~[~0L", "<COLOR_DEFAULT>"},
{"~[~1L", "<COLOR_WHITE>"},
{"~[~2L", "<COLOR_TRANSPARENT>"},
{"~[~3L", "<COLOR_RED>"},
{"~[~4L", "<COLOR_ORANGE>"},
{"~[~5L", "<COLOR_YELLOW>"},
{"~[~6L", "<COLOR_GREEN>"},
{"~[~7L", "<COLOR_BLUE>"},
{"~[~8L", "<COLOR_CYAN>"},
{"~[~9L", "<COLOR_PINK>"},
{"~[~10L", "<COLOR_MENU-SELECTED>"},
{"~[~11L", "<COLOR_MENU-SELECTED-PARENT>"},
{"~[~12L", "<COLOR_MENU>"},
{"~[~13L", "<COLOR_MENU-PARENT>"},
{"~[~14L", "<COLOR_MENU-FUNC-BAD>"},
{"~[~15L", "<COLOR_MENU-FLAG-ON>"},
{"~[~16L", "<COLOR_MENU-FLAG-ON-PARENT>"},
{"~[~17L", "<COLOR_MENU-FLAG-OFF>"},
{"~[~18L", "<COLOR_MENU-FLAG-OFF-PARENT>"},
{"~[~19L", "<COLOR_MENU-INVALID>"},
{"~[~20L", "<COLOR_FLAT-YELLOW>"},
{"~[~21L", "<COLOR_COLOR-21>"},
{"~[~22L", "<COLOR_PAD-BACK>"},
{"~[~23L", "<COLOR_PAD-SHINE>"},
{"~[~24L", "<COLOR_PAD-SQUARE>"},
{"~[~25L", "<COLOR_PAD-CIRCLE>"},
{"~[~26L", "<COLOR_PAD-TRIANGLE>"},
{"~[~27L", "<COLOR_PAD-CROSS>"},
{"~[~28L", "<COLOR_PROGRESS-OLD-BLUE>"},
{"~[~29L", "<COLOR_PROGRESS-OLD-YELLOW>"},
{"~[~30L", "<COLOR_PROGRESS-OLD-SELECTED>"},
{"~[~31L", "<COLOR_PROGRESS-OLD-PERCENT>"},
{"~[~32L", "<COLOR_PROGRESS>"},
{"~[~33L", "<COLOR_PROGRESS-SELECTED>"},
{"~[~34L", "<COLOR_PROGRESS-FORCE-SELECTED>"},
{"~[~35L", "<COLOR_PROGRESS-OPTION-OFF>"},
{"~[~36L", "<COLOR_COLOR-36>"},
{"~[~37L", "<COLOR_CREDITS-STAFF-TITLE-1>"},
{"~[~38L", "<COLOR_CREDITS-STAFF-TITLE-2>"},
{"~[~39L", "<COLOR_COLOR-39>"}};
std::vector<EncodeInfo> encode_info_jak2 = {
{"ˇ", "\x10"}, // caron
{"`", "\x11"}, // grave accent
{"'", "\x12"}, // apostrophe
{"^", "\x13"}, // circumflex
{"<TIL>", "\x14"}, // tilde
{"¨", "\x15"}, // umlaut
{"º", "\x16"}, // numero/overring
{"¡", "\x17"}, // inverted exclamation mark
{"¿", "\x18"}, // inverted question mark
{"<SOMETHING>", "\x19"},
{"ç", "\x1d"}, // c-cedilla
{"Ç", "\x1e"}, // c-cedilla
{"ß", "\x1f"}, // eszett
{"œ", "\x5e"}, // ligature o+e
{"<FLAG_PART_HORZ_STRIPE_MIDDLE>", "\x7f"},
{"<FLAG_PART_HORZ_STRIPE_BOTTOM>", "\x80"},
{"<FLAG_PART_VERT_STRIPE_LARGE>", "\x81"},
{"<FLAG_PART_VERT_STRIPE_RIGHT>", "\x82"},
{"<FLAG_PART_VERT_STRIPE_LEFT>", "\x83"},
{"<FLAG_PART_VERT_STRIPE_MIDDLE>", "\x84"},
{"<FLAG_PART_FILL>", "\x85"},
{"<FLAG_PART_JAPAN_SUN>", "\x86"},
{"<FLAG_PART_KOREA_TRIGRAMS_LEFT>", "\x87"},
{"<FLAG_PART_KOREA_TRIGRAMS_RIGHT>", "\x88"},
{"<FLAG_PART_KOREA_CIRCLE_TOP>", "\x89"},
{"<FLAG_PART_KOREA_CIRCLE_FILL>", "\x8a"},
{"<FLAG_PART_TOP_BOTTOM_STRIPE>", "\x8b"},
{"<FLAG_PART_UK_CROSS_LEFT>", "\x8c"},
{"<FLAG_PART_UK_CROSS_RIGHT>", "\x8d"},
{"<FLAG_PART_UK_FILL_LEFT>", "\x8e"},
{"<FLAG_PART_UK_FILL_RIGHT>", "\x8f"},
{"<FLAG_PART_USA_STRIPES_RIGHT>", "\x90"},
{"<PAD_PART_STICK>", "\x91"},
{"<PAD_PART_SELECT>", "\x92"},
{"<PAD_PART_TRIGGER_BACK>", "\x93"},
{"<PAD_PART_R1_NAME>", "\x94"},
{"<PAD_PART_L1_NAME>", "\x95"},
{"<PAD_PART_R2_NAME>", "\x96"},
{"<PAD_PART_L2_NAME>", "\x97"},
{"<PAD_PART_STICK_UP>", "\x98"},
{"<PAD_PART_STICK_UP_RIGHT>", "\x99"},
{"<FLAG_PART_USA_STRIPES_LEFT>", "\x9a"},
{"<FLAG_PART_USA_STARS>", "\x9b"},
{"<PAD_PART_STICK_DOWN>", "\x9c"},
{"<PAD_PART_STICK_DOWN_LEFT>", "\x9d"},
{"<PAD_PART_STICK_LEFT>", "\x9e"},
{"<PAD_PART_STICK_UP_LEFT>", "\x9f"},
{"<PAD_PART_DPAD_D>", "\xa0"},
{"<PAD_PART_DPAD_L>", "\xa1"},
{"<PAD_PART_DPAD_U>", "\xa2"},
{"<PAD_PART_DPAD_R>", "\xa3"},
{"<PAD_PART_STICK_RIGHT>", "\xa4"},
{"<PAD_PART_STICK_DOWN_RIGHT>", "\xa5"},
{"<PAD_PART_SHOULDER_TOP_LEFT>", "\xa6"},
{"<PAD_PART_SHOULDER_TOP_RIGHT>", "\xa7"},
{"<PAD_PART_TRIGGER_TOP_LEFT>", "\xa8"},
{"<PAD_PART_TRIGGER_TOP_RIGHT>", "\xa9"},
{"<PAD_PART_TRIGGER_SHIM1>", "\xaa"},
{"<PAD_PART_TRIGGER_SHIM2>", "\xab"},
{"<PAD_PART_SHOULDER_SHIM2>", "\xac"},
{"<PAD_PART_SHOULDER_BOTTOM_LEFT>", "\xb0"},
{"<PAD_PART_SHOULDER_BOTTOM_RIGHT>", "\xb1"},
{"<PAD_PART_TRIGGER_BOTTOM_LEFT>", "\xb2"},
{"<PAD_PART_TRIGGER_BOTTOM_RIGHT>", "\xb3"},
// {"入", "\x1\x00"}},
// {"年", "\x1\x01"}},
// punctuation
{"・", "\x1\x10"},
{"゛", "\x1\x11"},
{"゜", "\x1\x12"},
{"ー", "\x1\x13"},
{"『", "\x1\x14"},
{"』", "\x1\x15"},
// hiragana
{"ぁ", "\x1\x16"}, // -a
{"あ", "\x1\x17"}, // a
{"ぃ", "\x1\x18"}, // -i
{"い", "\x1\x19"}, // i
{"ぅ", "\x1\x1a"}, // -u
{"う", "\x1\x1b"}, // u
{"ぇ", "\x1\x1c"}, // -e
{"え", "\x1\x1d"}, // e
{"ぉ", "\x1\x1e"}, // -o
{"お", "\x1\x1f"}, // o
{"か", "\x1\x20"}, // ka
{"き", "\x1\x21"}, // ki
{"く", "\x1\x22"}, // ku
{"け", "\x1\x23"}, // ke
{"こ", "\x1\x24"}, // ko
{"さ", "\x1\x25"}, // sa
{"し", "\x1\x26"}, // shi
{"す", "\x1\x27"}, // su
{"せ", "\x1\x28"}, // se
{"そ", "\x1\x29"}, // so
{"た", "\x1\x2a"}, // ta
{"ち", "\x1\x2b"}, // chi
{"っ", "\x1\x2c"}, // sokuon
{"つ", "\x1\x2d"}, // tsu
{"て", "\x1\x2e"}, // te
{"と", "\x1\x2f"}, // to
{"な", "\x1\x30"}, // na
{"に", "\x1\x31"}, // ni
{"ぬ", "\x1\x32"}, // nu
{"ね", "\x1\x33"}, // ne
{"の", "\x1\x34"}, // no
{"は", "\x1\x35"}, // ha
{"ひ", "\x1\x36"}, // hi
{"ふ", "\x1\x37"}, // fu
{"へ", "\x1\x38"}, // he
{"ほ", "\x1\x39"}, // ho
{"ま", "\x1\x3a"}, // ma
{"み", "\x1\x3b"}, // mi
{"む", "\x1\x3c"}, // mu
{"め", "\x1\x3d"}, // me
{"も", "\x1\x3e"}, // mo
{"ゃ", "\x1\x3f"}, // youon ya
{"や", "\x1\x40"}, // ya
{"ゅ", "\x1\x41"}, // youon yu
{"ゆ", "\x1\x42"}, // yu
{"ょ", "\x1\x43"}, // youon yo
{"よ", "\x1\x44"}, // yo
{"ら", "\x1\x45"}, // ra
{"り", "\x1\x46"}, // ri
{"る", "\x1\x47"}, // ru
{"れ", "\x1\x48"}, // re
{"ろ", "\x1\x49"}, // ro
{"ゎ", "\x1\x4a"}, // -wa
{"わ", "\x1\x4b"}, // wa
{"を", "\x1\x4c"}, // wo
{"ん", "\x1\x4d"}, // -n
// katakana
{"ァ", "\x1\x4e"}, // -a
{"ア", "\x1\x4f"}, // a
{"ィ", "\x1\x50"}, // -i
{"イ", "\x1\x51"}, // i
{"ゥ", "\x1\x52"}, // -u
{"ウ", "\x1\x53"}, // u
{"ェ", "\x1\x54"}, // -e
{"エ", "\x1\x55"}, // e
{"ォ", "\x1\x56"}, // -o
{"オ", "\x1\x57"}, // o
{"カ", "\x1\x58"}, // ka
{"キ", "\x1\x59"}, // ki
{"ク", "\x1\x5a"}, // ku
{"ケ", "\x1\x5b"}, // ke
{"コ", "\x1\x5c"}, // ko
{"サ", "\x1\x5d"}, // sa
{"シ", "\x1\x5e"}, // shi
{"ス", "\x1\x5f"}, // su
{"セ", "\x1\x60"}, // se
{"ソ", "\x1\x61"}, // so
{"タ", "\x1\x62"}, // ta
{"チ", "\x1\x63"}, // chi
{"ッ", "\x1\x64"}, // sokuon
{"ツ", "\x1\x65"}, // tsu
{"テ", "\x1\x66"}, // te
{"ト", "\x1\x67"}, // to
{"ナ", "\x1\x68"}, // na
{"ニ", "\x1\x69"}, // ni
{"ヌ", "\x1\x6a"}, // nu
{"ネ", "\x1\x6b"}, // ne
{"ノ", "\x1\x6c"}, // no
{"ハ", "\x1\x6d"}, // ha
{"ヒ", "\x1\x6e"}, // hi
{"フ", "\x1\x6f"}, // fu
{"ヘ", "\x1\x70"}, // he
{"ホ", "\x1\x71"}, // ho
{"マ", "\x1\x72"}, // ma
{"ミ", "\x1\x73"}, // mi
{"ム", "\x1\x74"}, // mu
{"メ", "\x1\x75"}, // me
{"モ", "\x1\x76"}, // mo
{"ャ", "\x1\x77"}, // youon ya
{"ヤ", "\x1\x78"}, // ya
{"ュ", "\x1\x79"}, // youon yu
{"ユ", "\x1\x7a"}, // yu
{"ョ", "\x1\x7b"}, // youon yo
{"ヨ", "\x1\x7c"}, // yo
{"ラ", "\x1\x7d"}, // ra
{"リ", "\x1\x7e"}, // ri
{"ル", "\x1\x7f"}, // ru
{"レ", "\x1\x80"}, // re
{"ロ", "\x1\x81"}, // ro
{"ヮ", "\x1\x82"}, // -wa
{"ワ", "\x1\x83"}, // wa
{"ヲ", "\x1\x84"}, // wo
{"ン", "\x1\x85"}, // -n
{"位", "\x1\x8c"},
{"遺", "\x1\x8d"},
{"院", "\x1\x8e"},
{"映", "\x1\x8f"},
{"衛", "\x1\x90"},
{"応", "\x1\x91"},
{"下", "\x1\x92"},
{"画", "\x1\x93"},
{"解", "\x1\x94"},
{"開", "\x1\x95"},
{"外", "\x1\x96"},
{"害", "\x1\x97"},
{"蓋", "\x1\x98"},
{"完", "\x1\x99"},
{"換", "\x1\x9a"},
{"監", "\x1\x9b"},
{"間", "\x1\x9c"},
{"器", "\x1\x9d"},
{"記", "\x1\x9e"},
{"逆", "\x1\x9f"},
{"救", "\x1\xa0"},
{"金", "\x1\xa1"},
{"空", "\x1\xa2"},
{"掘", "\x1\xa3"},
{"警", "\x1\xa4"},
{"迎", "\x1\xa5"},
{"撃", "\x1\xa6"},
{"建", "\x1\xa7"},
{"源", "\x1\xa8"},
{"現", "\x1\xa9"},
{"言", "\x1\xaa"},
{"限", "\x1\xab"},
{"個", "\x1\xac"},
{"庫", "\x1\xad"},
{"後", "\x1\xae"},
{"語", "\x1\xaf"},
{"護", "\x1\xb0"},
{"交", "\x1\xb1"},
{"功", "\x1\xb2"},
{"向", "\x1\xb3"},
{"工", "\x1\xb4"},
{"攻", "\x1\xb5"},
{"溝", "\x1\xb6"},
{"行", "\x1\xb7"},
{"鉱", "\x1\xb8"},
{"降", "\x1\xb9"},
{"合", "\x1\xba"},
{"告", "\x1\xbb"},
{"獄", "\x1\xbc"},
{"彩", "\x1\xbd"},
{"作", "\x1\xbe"},
{"山", "\x1\xbf"},
{"使", "\x1\xc0"},
{"始", "\x1\xc1"},
{"試", "\x1\xc2"},
{"字", "\x1\xc3"},
{"寺", "\x1\xc4"},
{"時", "\x1\xc5"},
{"示", "\x1\xc6"},
{"自", "\x1\xc7"},
{"式", "\x1\xc8"},
{"矢", "\x1\xc9"},
{"射", "\x1\xca"},
{"者", "\x1\xcb"},
{"守", "\x1\xcc"},
{"手", "\x1\xcd"},
{"終", "\x1\xce"},
{"週", "\x1\xcf"},
{"出", "\x1\xd0"},
{"所", "\x1\xd1"},
{"書", "\x1\xd2"},
{"勝", "\x1\xd3"},
{"章", "\x1\xd4"},
{"上", "\x1\xd5"},
{"乗", "\x1\xd6"},
{"場", "\x1\xd7"},
{"森", "\x1\xd8"},
{"進", "\x1\xd9"},
{"人", "\x1\xda"},
{"水", "\x1\xdb"},
{"数", "\x1\xdc"},
{"制", "\x1\xdd"},
{"性", "\x1\xde"},
{"成", "\x1\xdf"},
{"聖", "\x1\xe0"},
{"石", "\x1\xe1"},
{"跡", "\x1\xe2"},
{"先", "\x1\xe3"},
{"戦", "\x1\xe4"},
{"船", "\x1\xe5"},
{"選", "\x1\xe6"},
{"走", "\x1\xe7"},
{"送", "\x1\xe8"},
{"像", "\x1\xe9"},
{"造", "\x1\xea"},
{"続", "\x1\xeb"},
{"対", "\x1\xec"},
{"袋", "\x1\xed"},
{"台", "\x1\xee"},
{"弾", "\x1\xef"},
{"地", "\x1\xf0"},
{"中", "\x1\xf1"},
{"敵", "\x1\xf2"},
{"転", "\x1\xf3"},
{"電", "\x1\xf4"},
{"塔", "\x1\xf5"},
{"頭", "\x1\xf6"},
{"動", "\x1\xf7"},
{"内", "\x1\xf8"},
{"日", "\x1\xf9"},
{"入", "\x1\xfa"},
{"年", "\x1\xfb"},
{"能", "\x1\xfc"},
{"廃", "\x1\xfd"},
{"排", "\x1\xfe"},
{"敗", "\x1\xff"},
{"発", "\x2\x10"},
{"反", "\x2\x11"},
{"必", "\x2\x12"},
{"表", "\x2\x13"},
{"武", "\x2\x14"},
{"壁", "\x2\x15"},
{"墓", "\x2\x16"},
{"放", "\x2\x17"},
{"方", "\x2\x18"},
{"砲", "\x2\x19"},
{"妨", "\x2\x1a"},
{"北", "\x2\x1b"},
{"本", "\x2\x1c"},
{"幕", "\x2\x1d"},
{"無", "\x2\x1e"},
{"迷", "\x2\x1f"},
{"面", "\x2\x20"},
{"戻", "\x2\x21"},
{"紋", "\x2\x22"},
{"薬", "\x2\x23"},
{"輸", "\x2\x24"},
{"勇", "\x2\x25"},
{"友", "\x2\x26"},
{"遊", "\x2\x27"},
{"容", "\x2\x28"},
{"要", "\x2\x29"},
{"利", "\x2\x2a"},
{"了", "\x2\x2b"},
{"量", "\x2\x2c"},
{"力", "\x2\x2d"},
{"練", "\x2\x2e"},
{"連", "\x2\x2f"},
{"録", "\x2\x30"},
{"話", "\x2\x31"},
{"墟", "\x2\x32"},
{"脱", "\x2\x33"},
// {"成", "\x2\x34"},
{"旗", "\x2\x35"},
{"破", "\x2\x36"},
{"壊", "\x2\x37"},
{"全", "\x2\x38"},
{"滅", "\x2\x39"},
{"機", "\x2\x3a"},
{"仲", "\x2\x3b"},
{"渓", "\x2\x3c"},
{"谷", "\x2\x3d"},
{"優", "\x2\x3e"},
{"探", "\x2\x3f"},
{"部", "\x2\x40"},
{"索", "\x2\x41"},
// {"乗", "\x2\x42"},
{"前", "\x2\x43"},
{"右", "\x2\x44"},
{"左", "\x2\x45"},
{"会", "\x2\x46"},
{"高", "\x2\x47"},
{"低", "\x2\x48"},
{"押", "\x2\x49"},
{"切", "\x2\x4a"},
{"替", "\x2\x4b"},
// {"対", "\x2\x4c"},
{"秒", "\x2\x4d"},
{"箱", "\x2\x4e"},
{"泳", "\x2\x4f"},
{"~", "\x2\x50"},
{"闇", "\x2\x56"},
{"以", "\x2\x57"},
{"屋", "\x2\x58"},
{"俺", "\x2\x59"},
{"化", "\x2\x5a"},
{"界", "\x2\x5b"},
{"感", "\x2\x5c"},
{"気", "\x2\x5d"},
{"却", "\x2\x5e"},
{"曲", "\x2\x5f"},
{"継", "\x2\x60"},
{"権", "\x2\x61"},
{"見", "\x2\x62"},
{"古", "\x2\x63"},
{"好", "\x2\x64"},
// {"高", "\x2\x65"},
{"才", "\x2\x66"},
{"士", "\x2\x67"},
{"子", "\x2\x68"},
{"次", "\x2\x69"},
{"主", "\x2\x6a"},
{"種", "\x2\x6b"},
{"讐", "\x2\x6c"},
{"女", "\x2\x6d"},
{"小", "\x2\x6e"},
{"焼", "\x2\x6f"},
{"証", "\x2\x70"},
{"神", "\x2\x71"},
{"身", "\x2\x72"},
{"寸", "\x2\x73"},
{"世", "\x2\x74"},
{"想", "\x2\x75"},
{"退", "\x2\x76"},
{"第", "\x2\x77"},
{"着", "\x2\x78"},
{"天", "\x2\x79"},
{"倒", "\x2\x7a"},
{"到", "\x2\x7b"},
{"突", "\x2\x7c"},
{"爆", "\x2\x7d"},
{"番", "\x2\x7e"},
{"負", "\x2\x7f"},
{"復", "\x2\x80"},
{"物", "\x2\x81"},
{"眠", "\x2\x82"},
{"予", "\x2\x83"},
{"用", "\x2\x84"},
{"落", "\x2\x85"},
{"緑", "\x2\x86"},
{"封", "\x2\x88"},
{"印", "\x2\x89"},
{"扉", "\x2\x8a"},
{"最", "\x2\x8b"},
{"刻", "\x2\x8c"},
{"足", "\x2\x8d"},
};
std::unordered_map<std::string, std::vector<std::string>> jamo_glyph_mappings_jak2 = {
{"0x06", {"ᄀ"}}, {"0x07", {"ᄁ"}}, {"0x08", {"ᄂ"}}, {"0x09", {"ᄃ"}},
{"0x0a", {"ᄄ"}}, {"0x0b", {"ᄅ"}}, {"0x0c", {"ᄆ"}}, {"0x0d", {"ᄇ"}},
{"0x0e", {"ᄈ"}}, {"0x0f", {"ᄋ"}}, {"0x10", {"ᄌ"}}, {"0x11", {"ᄍ"}},
{"0x12", {"ᄏ"}}, {"0x13", {"ᄐ"}}, {"0x14", {"ᄑ"}}, {"0x15", {"ᅡ"}},
{"0x16", {"ᅣ"}}, {"0x17", {"ᅵ"}}, {"0x18", {"ᅥ"}}, {"0x19", {"ᅧ"}},
{"0x1a", {"ᅡ"}}, {"0x1b", {"ᅣ"}}, {"0x1c", {"ᅵ"}}, {"0x1d", {"ᅥ"}},
{"0x1e", {"ᅧ"}}, {"0x1f", {"ᄂ"}}, {"0x20", {"ᄉ"}}, {"0x21", {"ᄊ"}},
{"0x22", {"ᅥ"}}, {"0x23", {"ᅧ"}}, {"0x24", {"ᅥ"}}, {"0x25", {"ᅧ"}},
{"0x26", {"ᄃ"}}, {"0x27", {"ᄄ"}}, {"0x28", {"ᄅ"}}, {"0x29", {"ᄐ"}},
{"0x2a", {"ᄑ"}}, {"0x2b", {"ᅧ"}}, {"0x2c", {"ᅧ"}}, {"0x2d", {"ᄎ"}},
{"0x2e", {"ᄒ"}}, {"0x2f", {"ᅥ"}}, {"0x30", {"ᅧ"}}, {"0x31", {"ᅥ"}},
{"0x32", {"ᅧ"}}, {"0x33", {"ᄀ"}}, {"0x34", {"ᄁ"}}, {"0x35", {"ᄂ"}},
{"0x36", {"ᄃ"}}, {"0x37", {"ᄄ"}}, {"0x38", {"ᄅ"}}, {"0x39", {"ᄆ"}},
{"0x3a", {"ᄇ"}}, {"0x3b", {"ᄈ"}}, {"0x3c", {"ᄋ"}}, {"0x3d", {"ᄌ"}},
{"0x3e", {"ᄍ"}}, {"0x3f", {"ᄏ"}}, {"0x40", {"ᄐ"}}, {"0x41", {"ᄑ"}},
{"0x42", {"ᅢ"}}, {"0x43", {"ᅤ"}}, {"0x44", {"ᅦ"}}, {"0x45", {"ᅨ"}},
{"0x46", {"ᅢ"}}, {"0x47", {"ᅤ"}}, {"0x48", {"ᅦ"}}, {"0x49", {"ᅨ"}},
{"0x4a", {"ᄂ"}}, {"0x4b", {"ᄉ"}}, {"0x4c", {"ᄊ"}}, {"0x4d", {"ᅦ"}},
{"0x4e", {"ᅨ"}}, {"0x4f", {"ᅦ"}}, {"0x50", {"ᅨ"}}, {"0x51", {"ᄃ"}},
{"0x52", {"ᄄ"}}, {"0x53", {"ᄅ"}}, {"0x54", {"ᄐ"}}, {"0x55", {"ᄑ"}},
{"0x56", {"ᅨ"}}, {"0x57", {"ᅨ"}}, {"0x58", {"ᄎ"}}, {"0x59", {"ᄒ"}},
{"0x5a", {"ᅦ"}}, {"0x5b", {"ᅨ"}}, {"0x5c", {"ᅦ"}}, {"0x5d", {"ᅨ"}},
{"0x5e", {"ᄀ"}}, {"0x5f", {"ᄏ"}}, {"0x60", {"ᅩ"}}, {"0x61", {"ᅭ"}},
{"0x62", {"ᅩ"}}, {"0x63", {"ᅭ"}}, {"0x64", {"ᄁ", "ᅫ"}}, {"0x65", {"ᄁ", "ᅩ"}},
{"0x66", {"ᄁ", "ᅩ"}}, {"0x67", {"ᄁ", "ᅭ"}}, {"0x68", {"ᄁ"}}, {"0x69", {"ᄂ"}},
{"0x6a", {"ᅳ"}}, {"0x6b", {"ᅮ"}}, {"0x6c", {"ᅲ"}}, {"0x6d", {"ᅳ"}},
{"0x6e", {"ᅮ"}}, {"0x6f", {"ᅲ"}}, {"0x70", {"ᄃ"}}, {"0x71", {"ᄄ"}},
{"0x72", {"ᄅ"}}, {"0x73", {"ᄆ"}}, {"0x74", {"ᄇ"}}, {"0x75", {"ᄈ"}},
{"0x76", {"ᄉ"}}, {"0x77", {"ᄊ"}}, {"0x78", {"ᄋ"}}, {"0x79", {"ᄌ"}},
{"0x7a", {"ᄍ"}}, {"0x7b", {"ᄎ"}}, {"0x7c", {"ᄐ"}}, {"0x7d", {"ᄑ"}},
{"0x7e", {"ᄒ"}}, {"0x7f", {"ᅩ"}}, {"0x80", {"ᅭ"}}, {"0x81", {"ᅳ"}},
{"0x82", {"ᅩ"}}, {"0x83", {"ᅭ"}}, {"0x84", {"ᅳ"}}, {"0x85", {"ᅮ"}},
{"0x86", {"ᅲ"}}, {"0x87", {"ᅮ"}}, {"0x88", {"ᅲ"}}, {"0x89", {"ᅮ", "ᆫ"}},
{"0x8a", {"ᅲ", "ᆫ"}}, {"0x8b", {"ᄀ"}}, {"0x8c", {"ᄏ"}}, {"0x8d", {"ᅩ"}},
{"0x8e", {"ᅩ"}}, {"0x8f", {"ᄁ", "ᅩ"}}, {"0x90", {"ᄁ", "ᅩ"}}, {"0x91", {"ᄁ"}},
{"0x92", {"ᄂ"}}, {"0x93", {"ᄃ"}}, {"0x94", {"ᄄ"}}, {"0x95", {"ᄅ"}},
{"0x96", {"ᄆ"}}, {"0x97", {"ᄇ"}}, {"0x98", {"ᄈ"}}, {"0x99", {"ᄉ"}},
{"0x9a", {"ᄊ"}}, {"0x9b", {"ᄋ"}}, {"0x9c", {"ᄌ"}}, {"0x9d", {"ᄍ"}},
{"0x9e", {"ᄎ"}}, {"0x9f", {"ᄐ"}}, {"0xa0", {"ᄑ"}}, {"0xa1", {"ᄒ"}},
{"0xa2", {"ᅩ"}}, {"0xa3", {"ᅳ"}}, {"0xa4", {"ᅩ"}}, {"0xa5", {"ᅳ"}},
{"0xa6", {"ᅡ"}}, {"0xa7", {"ᅵ"}}, {"0xa8", {"ᅡ"}}, {"0xa9", {"ᅵ"}},
{"0xaa", {"ᅯ"}}, {"0xab", {"ᅱ"}}, {"0xac", {"ᅯ"}}, {"0xad", {"ᅱ"}},
{"0xae", {"ᄀ"}}, {"0xaf", {"ᄏ"}}, {"0xb0", {"ᅫ"}}, {"0xb1", {"ᅫ"}},
{"0xb2", {"ᄆ"}}, {"0xb3", {"ᄁ"}}, {"0xb4", {"ᄂ"}}, {"0xb5", {"ᄃ"}},
{"0xb6", {"ᄄ"}}, {"0xb7", {"ᄅ"}}, {"0xb8", {"ᄇ"}}, {"0xb9", {"ᄉ"}},
{"0xba", {"ᄊ"}}, {"0xbb", {"ᄋ"}}, {"0xbc", {"ᄌ"}}, {"0xbd", {"ᄍ"}},
{"0xbe", {"ᄎ"}}, {"0xbf", {"ᄐ"}}, {"0xc0", {"ᄒ"}}, {"0xc1", {"ᅫ"}},
{"0xc2", {"ᅫ"}}, {"0xc3", {"ᅰ"}}, {"0xc4", {"ᅰ"}}, {"0xc5", {"ᆨ"}},
{"0xc6", {"ᆩ"}}, {"0xc7", {"ᆪ"}}, {"0xc8", {"ᆫ"}}, {"0xc9", {"ᆬ"}},
{"0xca", {"ᆭ"}}, {"0xcb", {"ᆮ"}}, {"0xcc", {"ᆯ"}}, {"0xcd", {"ᆰ"}},
{"0xce", {"ᆱ"}}, {"0xcf", {"ᆲ"}}, {"0xd0", {"ᆴ"}}, {"0xd1", {"ᆶ"}},
{"0xd2", {"ᆷ"}}, {"0xd3", {"ᆸ"}}, {"0xd4", {"ᆹ"}}, {"0xd5", {"ᆺ"}},
{"0xd6", {"ᆻ"}}, {"0xd7", {"ᆼ"}}, {"0xd8", {"ᆽ"}}, {"0xd9", {"ᆾ"}},
{"0xda", {"ᆿ"}}, {"0xdb", {"ᇀ"}}, {"0xdc", {"ᇁ"}}, {"0xdd", {"ᇂ"}},
{"0xde", {"ᆨ"}}, {"0xdf", {"ᆩ"}}, {"0xe0", {"ᆪ"}}, {"0xe1", {"ᆫ"}},
{"0xe2", {"ᆭ"}}, {"0xe3", {"ᆮ"}}, {"0xe4", {"ᆯ"}}, {"0xe5", {"ᆰ"}},
{"0xe6", {"ᆱ"}}, {"0xe7", {"ᆳ"}}, {"0xe8", {"ᆴ"}}, {"0xe9", {"ᆵ"}},
{"0xea", {"ᆶ"}}, {"0xeb", {"ᆷ"}}, {"0xec", {"ᆸ"}}, {"0xed", {"ᆺ"}},
{"0xee", {"ᆼ"}}, {"0xef", {"ᆽ"}}, {"0xf0", {"ᆾ"}}, {"0xf1", {"ᆿ"}},
{"0xf2", {"ᇀ"}}, {"0xf3", {"ᇁ"}}, {"0xf4", {"ᇂ"}}, {"0xf5", {"ᆨ"}},
{"0xf6", {"ᆫ"}}, {"0xf7", {"ᆯ"}}, {"0xf8", {"ᆱ"}}, {"0xf9", {"ᆷ"}},
{"0xfa", {"ᆸ"}}, {"0xfb", {"ᆺ"}}, {"0xfc", {"ᆻ"}}, {"0xfd", {"ᆼ"}},
{"0xfe", {"ᆨ"}}, {"0xff", {"ᆫ"}}, {"extra_0x86", {"ᆯ"}}, {"extra_0x87", {"ᆷ"}},
{"extra_0x88", {"ᆸ"}}, {"extra_0x89", {"ᆺ"}}, {"extra_0x8a", {"ᆻ"}}, {"extra_0x8b", {"ᆼ"}},
};
GameTextFontBank g_font_bank_jak2(GameTextVersion::JAK2,
&encode_info_jak2,
&replace_info_jak2,
&passthrus_jak2);
-16
View File
@@ -1,16 +0,0 @@
#pragma once
#include "common/util/font/font_utils.h"
extern std::unordered_map<std::string, std::vector<std::string>> jamo_glyph_mappings_jak2;
/*!
* ================================
* GAME TEXT FONT BANK - JAK 2
* ================================
* This font is used in:
* - Jak II
* - Jak II: Renegade
* - ジャックXダクスター2
*/
extern GameTextFontBank g_font_bank_jak2;
-938
View File
@@ -1,938 +0,0 @@
#include "font_db_jak3.h"
std::unordered_set<char> passthrus_jak3 = {'~', ' ', ',', '.', '-', '+', '(', ')',
'!', ':', '?', '=', '%', '*', '/', '#',
';', '<', '>', '@', '[', '_', ']'};
std::vector<ReplaceInfo> replace_info_jak3 = {
// other
{"A~Y~-21H~-5Vº~Z", "Å"},
{"N~Y~-6Hº~Z~+10H", "Nº"},
// portuguese
{"~+4Vç~-4V", "ç"},
{"O~Y~-25H~-1V/~Z", "Ø"},
{"o~Y~-23H~+4V/~Z", "ø"},
{"A~Y~-13H~+8V,~Z", "Ą"},
{"a~Y~-8H~+6V,~Z", "ą"},
{"E~Y~-6H~+8V,~Z", "Ę"},
{"e~Y~-10H~+7V,~Z", "ę"},
{"L~Y~-21H~+0V/~Z", "Ł"},
{"l~Y~-16H~+0V/~Z", "ł"}, // TODO - this one is ugly, font character addition (small slash)
{"Z~Y~-25H~-11Vº~Z", "Ż"},
{"z~Y~-23H~-5Vº~Z", "ż"},
{"a~Y~-25H~-5Vº~Z", "å"},
{"S~Y~-21H~-5V'~Z", "Ś"},
{"s~Y~-25H~-5V'~Z", "ś"},
{"n~Y~-25H~-5V'~Z", "ń"},
{"c~Y~-25H~-5V'~Z", "ć"},
{"o~Y~-25H~-4V<TIL>~Z", "õ"},
{"a~Y~-25H~-4V<TIL>~Z", "ã"},
{"O~Y~-28H~-4V'~-9H'~Z", "Ő"},
{"U~Y~-27H~-4V'~-12H'~Z", "Ű"},
{"o~Y~-28H~-4V'~-9H'~Z", "ő"},
{"u~Y~-28H~-4V'~-9H'~Z", "ű"},
{"E~Y~-22H~-11Vº~Z", "Ė"},
{"e~Y~-25H~-5Vº~Z", "ė"},
{"C~Y~-27H~-10Vˇ~Z", "Č"},
{"c~Y~-25H~-5Vˇ~Z", "č"},
{"D~Y~-27H~-10Vˇ~Z", "Ď"},
{"S~Y~-24H~-10Vˇ~Z", "Š"},
{"s~Y~-22H~-4Vˇ~Z", "š"},
{"Z~Y~-25H~-10Vˇ~Z", "Ž"},
{"z~Y~-23H~-4Vˇ~Z", "ž"},
{"U~Y~-15H~+5V,~Z", "Ų"},
{"u~Y~-15H~+5V,~Z", "ų"},
{"U~Y~-20H~-18V-~Z", "Ū"},
{"u~Y~-18H~-15V-~Z", "ū"},
{"D~Y~-28H~-1V-~Z", "Đ"},
{"d~Y~-13H~-10V-~Z", "đ"},
{"I~Y~-8H~+4V,~Z", "Į"},
{"i~Y~-8H~+4V,~Z", "į"},
// czech specific
{"U~Y~-24H~-7Vº~Z", "Ů"},
{"u~Y~-23H~-5Vº~Z", "ů"},
{"t~Y~-7H~-21V,~Z", "ť"},
// tildes
{"N~Y~-22H~-4V<TIL>~Z", "Ñ"},
{"n~Y~-24H~-4V<TIL>~Z", "ñ"},
{"A~Y~-21H~-5V<TIL>~Z", "Ã"},
{"O~Y~-22H~-4V<TIL>~Z", "Õ"},
// acute accents
{"A~Y~-21H~-5V'~Z", "Á"},
{"A~Y~-26H~-8V'~Z", "<Á_V2>"}, // unfortunate...
{"a~Y~-25H~-5V'~Z", "á"},
{"E~Y~-23H~-9V'~Z", "É"},
{"e~Y~-26H~-5V'~Z", "é"},
{"I~Y~-19H~-8V'~Z", "Í"},
{"i~Y~-19H~-8V'~Z", "í"},
{"O~Y~-22H~-4V'~Z", "Ó"},
{"o~Y~-26H~-4V'~Z", "ó"},
{"U~Y~-25H~-8V'~Z", "Ú"},
{"u~Y~-24H~-3V'~Z", "ú"},
{"Z~Y~-24H~-3V'~Z", "Ź"},
{"z~Y~-24H~-3V'~Z", "ź"},
// czech specific
{"Y~Y~-26H~-5V'~Z", "Ý"},
{"~+7Vy~-7V~Y~-24H~-3V'~Z", "ý"},
// circumflex
{"A~Y~-20H~-4V^~Z", "Â"},
{"a~Y~-24H~-5V^~Z", "â"},
{"E~Y~-20H~-5V^~Z", "Ê"},
{"e~Y~-25H~-4V^~Z", "ê"},
{"I~Y~-19H~-5V^~Z", "Î"},
{"i~Y~-19H~-8V^~Z", "î"},
{"O~Y~-20H~-4V^~Z", "Ô"},
{"o~Y~-25H~-4V^~Z", "ô"},
{"U~Y~-24H~-3V^~Z", "Û"},
{"u~Y~-23H~-3V^~Z", "û"},
// grave accents
{"A~Y~-26H~-8V`~Z", "À"},
{"a~Y~-25H~-5V`~Z", "à"},
{"E~Y~-23H~-9V`~Z", "È"},
{"e~Y~-26H~-5V`~Z", "è"},
{"I~Y~-19H~-5V`~Z", "Ì"},
{"i~Y~-19H~-8V`~Z", "ì"},
{"O~Y~-22H~-4V`~Z", "Ò"},
{"o~Y~-26H~-4V`~Z", "ò"},
{"U~Y~-24H~-3V`~Z", "Ù"},
{"u~Y~-24H~-3V`~Z", "ù"},
// umlaut
{"A~Y~-26H~-8V¨~Z", "Ä"},
{"a~Y~-25H~-5V¨~Z", "ä"},
{"E~Y~-20H~-5V¨~Z", "Ë"},
{"e~Y~-25H~-5V¨~Z", "ë"},
{"I~Y~-19H~-5V¨~Z", "Ï"},
{"i~Y~-26H~-4V¨~Z", "ï"},
{"O~Y~-26H~-8V¨~Z", "Ö"},
{"o~Y~-26H~-4V¨~Z", "ö"},
{"U~Y~-25H~-8V¨~Z", "Ü"},
{"u~Y~-24H~-3V¨~Z", "ü"},
// caron - Ǎ ǎ Ě ě Ǧ ǧ Ǐ ǐ Ǒ ǒ Ǔ ǔ Y̌ y̌
{"A~Y~-25H~-9Vˇ~Z", "Ǎ"},
{"a~Y~-24H~-5Vˇ~Z", "ǎ"},
{"E~Y~-22H~-8Vˇ~Z", "Ě"},
{"e~Y~-25H~-4Vˇ~Z", "ě"},
{"G~Y~-24H~-8Vˇ~Z", "Ǧ"},
{"~+7Vg~-7V~Y~-25H~-4Vˇ~Z", "ǧ"},
{"I~Y~-19H~-8Vˇ~Z", "Ǐ"},
{"i~Y~-19H~-8Vˇ~Z", "ǐ"},
{"O~Y~-25H~-7Vˇ~Z", "Ǒ"},
{"o~Y~-25H~-4Vˇ~Z", "ǒ"},
{"U~Y~-25H~-6Vˇ~Z", "Ǔ"},
{"u~Y~-24H~-3Vˇ~Z", "ǔ"},
{"Y~Y~-25H~-5Vˇ~Z", "Y̌"},
{"~+7Vy~-7V~Y~-25H~-3Vˇ~Z", "y̌"},
// czech specific - Č č Ň ň Ř ř Š š Ž ž Ť
{"C~Y~-25H~-9Vˇ~Z", "Č"},
{"c~Y~-24H~-5Vˇ~Z", "č"},
{"N~Y~-25H~-9Vˇ~Z", "Ň"},
{"n~Y~-24H~-5Vˇ~Z", "ň"},
{"R~Y~-25H~-9Vˇ~Z", "Ř"},
{"r~Y~-22H~-5Vˇ~Z", "ř"},
{"S~Y~-25H~-9Vˇ~Z", "Š"},
{"s~Y~-22H~-5Vˇ~Z", "š"},
{"T~Y~-24H~-7Vˇ~Z", "Ť"},
{"Z~Y~-25H~-9Vˇ~Z", "Ž"},
{"z~Y~-24H~-5Vˇ~Z", "ž"},
// dakuten katakana
{"~Yウ~Z゛", "ヴ"},
{"~Yカ~Z゛", "ガ"},
{"~Yキ~Z゛", "ギ"},
{"~Yク~Z゛", "グ"},
{"~Yケ~Z゛", "ゲ"},
{"~Yコ~Z゛", "ゴ"},
{"~Yサ~Z゛", "ザ"},
{"~Yシ~Z゛", "ジ"},
{"~Yス~Z゛", "ズ"},
{"~Yセ~Z゛", "ゼ"},
{"~Yソ~Z゛", "ゾ"},
{"~Yタ~Z゛", "ダ"},
{"~Yチ~Z゛", "ヂ"},
{"~Yツ~Z゛", "ヅ"},
{"~Yテ~Z゛", "デ"},
{"~Yト~Z゛", "ド"},
{"~Yハ~Z゛", "バ"},
{"~Yヒ~Z゛", "ビ"},
{"~Yフ~Z゛", "ブ"},
{"~Yヘ~Z゛", "ベ"},
{"~Yホ~Z゛", "ボ"},
// handakuten katakana
{"~Yハ~Z゜", "パ"},
{"~Yヒ~Z゜", "ピ"},
{"~Yフ~Z゜", "プ"},
{"~Yヘ~Z゜", "ペ"},
{"~Yホ~Z゜", "ポ"},
// dakuten hiragana
{"~Yか~Z゛", "が"},
{"~Yき~Z゛", "ぎ"},
{"~Yく~Z゛", "ぐ"},
{"~Yけ~Z゛", "げ"},
{"~Yこ~Z゛", "ご"},
{"~Yさ~Z゛", "ざ"},
{"~Yし~Z゛", "じ"},
{"~Yす~Z゛", "ず"},
{"~Yせ~Z゛", "ぜ"},
{"~Yそ~Z゛", "ぞ"},
{"~Yた~Z゛", "だ"},
{"~Yち~Z゛", "ぢ"},
{"~Yつ~Z゛", "づ"},
{"~Yて~Z゛", "で"},
{"~Yと~Z゛", "ど"},
{"~Yは~Z゛", "ば"},
{"~Yひ~Z゛", "び"},
{"~Yふ~Z゛", "ぶ"},
{"~Yへ~Z゛", "べ"},
{"~Yほ~Z゛", "ぼ"},
// handakuten hiragana
{"~Yは~Z゜", "ぱ"},
{"~Yひ~Z゜", "ぴ"},
{"~Yふ~Z゜", "ぷ"},
{"~Yへ~Z゜", "ぺ"},
{"~Yほ~Z゜", "ぽ"},
// japanese punctuation
{",~+8H", "、"},
{"~+8H ", " "},
// playstation buttons
// - face
{"~Y~22L<~Z~Y~27L*~Z~Y~1L>~Z~Y~23L[~Z~+26H", "<PAD_X>"},
{"~Y~22L<~Z~Y~26L;~Z~Y~1L>~Z~Y~23L[~Z~+26H", "<PAD_TRIANGLE>"},
{"~Y~22L<~Z~Y~25L@~Z~Y~1L>~Z~Y~23L[~Z~+26H", "<PAD_CIRCLE>"},
{"~Y~22L<~Z~Y~24L#~Z~Y~1L>~Z~Y~23L[~Z~+26H", "<PAD_SQUARE>"},
// - dpad
{"~Y~22L<PAD_PART_DPAD_L>~Z~3L~+17H~-13V<PAD_PART_DPAD_U>~Z~22L~+17H~+14V<PAD_PART_DPAD_D>~Z~"
"22L~+32H<PAD_PART_DPAD_R>~Z~+56H",
"<PAD_DPAD_UP>"},
{"~Y~22L<PAD_PART_DPAD_L>~Z~3L~+17H~-13V<PAD_PART_DPAD_U>~Z~3L~+17H~+14V<PAD_PART_DPAD_D>~Z~"
"22L~+32H<PAD_PART_DPAD_R>~Z~+56H",
"<PAD_DPAD_DOWN>"},
{"~Y~22L<PAD_PART_DPAD_L>~Z~22L~+17H~-13V<PAD_PART_DPAD_U>~Z~22L~+17H~+14V<PAD_PART_DPAD_D>~Z~"
"22L~+32H<PAD_PART_DPAD_R>~Z~+56H",
"<PAD_DPAD_ANY>"},
// - shoulder
{"~Y~22L~-2H~-12V<PAD_PART_SHOULDER_TOP_LEFT><PAD_PART_SHOULDER_TOP_RIGHT>~Z~22L~-2H~+17V<PAD_"
"PART_SHOULDER_BOTTOM_LEFT><PAD_PART_SHOULDER_BOTTOM_RIGHT>~Z~1L~+4H~+3V<PAD_PART_L1_NAME>~Z~+"
"38H",
"<PAD_L1>"},
{"~Y~22L~-2H~-12V<PAD_PART_SHOULDER_TOP_LEFT><PAD_PART_SHOULDER_TOP_RIGHT>~Z~22L~-2H~+17V<PAD_"
"PART_SHOULDER_BOTTOM_LEFT><PAD_PART_SHOULDER_BOTTOM_RIGHT>~Z~1L~+6H~+3V<PAD_PART_R1_NAME>~Z~+"
"38H",
"<PAD_R1>"},
{"~Y~22L~-2H~-6V<PAD_PART_TRIGGER_TOP_LEFT><PAD_PART_TRIGGER_TOP_RIGHT>~Z~22L~-2H~+16V<PAD_"
"PART_TRIGGER_BOTTOM_LEFT><PAD_PART_TRIGGER_BOTTOM_RIGHT>~Z~1L~+5H~-2V<PAD_PART_R2_NAME>~Z~+"
"38H",
"<PAD_R2>"},
{"~Y~22L~-2H~-6V<PAD_PART_TRIGGER_TOP_LEFT><PAD_PART_TRIGGER_TOP_RIGHT>~Z~22L~-2H~+16V<PAD_"
"PART_TRIGGER_BOTTOM_LEFT><PAD_PART_TRIGGER_BOTTOM_RIGHT>~Z~1L~+5H~-2V<PAD_PART_L2_NAME>~Z~+"
"38H",
"<PAD_L2>"},
// - analog
{"~1L~+8H~Y<PAD_PART_STICK>~Z~6L~-16H<PAD_PART_STICK_LEFT>~Z~+16h~6L<PAD_PART_STICK_RIGHT>~Z~"
"6L~-15V<PAD_PART_STICK_DOWN>~Z~+13V~6L<PAD_PART_STICK_UP>~Z~-10H~+9V~6L<PAD_PART_STICK_UP_"
"LEFT>~Z~+10H~+9V~6L<PAD_PART_STICK_UP_RIGHT>~Z~-10H~-11V~6L<PAD_PART_STICK_DOWN_LEFT>~Z~+10H~"
"-11V~6L<PAD_PART_STICK_DOWN_RIGHT>~Z~+32H",
"<PAD_ANALOG_ANY>"},
{"~Y~1L~+8H<PAD_PART_STICK>~Z~6L~-8H<PAD_PART_STICK_LEFT>~Z~+24H~6L<PAD_PART_STICK_RIGHT>~Z~+"
"40H",
"<PAD_ANALOG_LEFT_RIGHT>"},
{"~Y~1L<PAD_PART_STICK>~Z~6L~-15V<PAD_PART_STICK_DOWN>~Z~+13V~6L<PAD_PART_STICK_UP>~Z~+26H",
"<PAD_ANALOG_UP_DOWN>"},
// icons
{"~Y~6L<~Z~Y~1L>~Z~Y~23L[~Z~+26H", "<ICON_MISSION_COMPLETE>"},
{"~Y~3L<~Z~Y~1L>~Z~Y~23L[~Z~+26H", "<ICON_MISSION_TODO>"},
// flags
{"~Y~6L<FLAG_PART_VERT_STRIPE_LARGE>~Z~+15H~1L<FLAG_PART_VERT_STRIPE_LARGE>~Z~+30H~3L<FLAG_"
"PART_VERT_STRIPE_LARGE>~Z~+45H",
"<FLAG_ITALIAN>"},
{"~Y~5L<FLAG_PART_FILL>~Z~3L<FLAG_PART_TOP_BOTTOM_STRIPE>~]~-1H~Y~5L<FLAG_PART_FILL>~Z~3L<FLAG_"
"PART_TOP_BOTTOM_STRIPE>~Z~+26H",
"<FLAG_SPAIN>"},
{"~Y~39L~~~Z~3L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~5L<FLAG_PART_HORZ_STRIPE_BOTTOM>~]~-1H~Y~39L~~~"
"Z~3L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~5L<FLAG_PART_HORZ_STRIPE_BOTTOM>~Z~+26H",
"<FLAG_GERMAN>"},
{"~Y~7L<FLAG_PART_VERT_STRIPE_LARGE>~Z~+15H~1L<FLAG_PART_VERT_STRIPE_LARGE>~Z~+30H~3L<FLAG_"
"PART_VERT_STRIPE_LARGE>~Z~+47H",
"<FLAG_FRANCE>"},
{"~Y~1L<FLAG_PART_FILL>~Z~3L<FLAG_PART_UK_CROSS_LEFT>~Z~7L<FLAG_PART_UK_FILL_LEFT>~]~-1H~Y~1L<"
"FLAG_PART_FILL>~Z~3L<FLAG_PART_UK_CROSS_RIGHT>~Z~7L<FLAG_PART_UK_FILL_RIGHT>~Z~+26H",
"<FLAG_UK>"},
{"~Y~1L<FLAG_PART_FILL>~Z~3L<FLAG_PART_USA_STRIPES_LEFT>~Z~7L<FLAG_PART_USA_STARS>~]~-1H~Y~1L<"
"FLAG_PART_FILL>~Z~3L<FLAG_PART_USA_STRIPES_RIGHT>~Z~+26H",
"<FLAG_USA>"},
{"~Y~1L<FLAG_PART_FILL>~Z~39L<FLAG_PART_KOREA_TRIGRAMS_LEFT>~]~-1H~Y~1L<FLAG_PART_FILL>~Z~39L<"
"FLAG_PART_KOREA_TRIGRAMS_RIGHT>~Z~-11H~7L<FLAG_PART_KOREA_CIRCLE_FILL>~Z~-11H~3L<FLAG_PART_"
"KOREA_CIRCLE_TOP>~Z~+26H",
"<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>~]~-2H~Y~1L<FLAG_PART_FILL>~Z~3L<FLAG_"
"PART_TOP_BOTTOM_STRIPE>~Z~-10H~1L<FLAG_PART_VERT_STRIPE_LEFT>~Z~-5H~1L<FLAG_PART_VERT_STRIPE_"
"LEFT>~Z~-23H~7L<FLAG_PART_VERT_STRIPE_RIGHT>~Z~-22H~7L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~7L"
"<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~+26H",
"<FLAG_NORWAY>"},
{"~Y~1L<FLAG_PART_FILL>~Z~7L<FLAG_PART_TOP_BOTTOM_STRIPE>~]~-2H~Y~1L<FLAG_PART_FILL>~Z~7L<FLAG_"
"PART_TOP_BOTTOM_STRIPE>~Z~-10H~1L<FLAG_PART_VERT_STRIPE_LEFT>~Z~-5H~1L<FLAG_PART_VERT_STRIPE_"
"LEFT>~Z~-23H~3L<FLAG_PART_VERT_STRIPE_RIGHT>~Z~-22H~3L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~3L"
"<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~+26H",
"<FLAG_ICELAND>"},
{"~Y~6L<FLAG_PART_VERT_STRIPE_LARGE>~Z~+15H~3L<FLAG_PART_VERT_STRIPE_LARGE>~Z~+30H~3L<FLAG_"
"PART_VERT_STRIPE_LARGE>~Z~+4H~5L<FLAG_PART_PORTUGUAL_1>~Z~+2H~3L<FLAG_PART_PORTUGUAL_2>~Z~+"
"2H~1L<FLAG_PART_PORTUGUAL_3>~Z~+47H",
"<FLAG_PORTUGUAL>"},
{"~Y~3L~~~Z~1L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~7L<FLAG_PART_HORZ_STRIPE_BOTTOM>~]~-2H~Y~3L~~"
"~Z~1L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~7L<FLAG_PART_HORZ_STRIPE_BOTTOM>~Z~+26H",
"<FLAG_DUTCH>"},
{"~Y~26L<FLAG_PART_FILL>~]~-1H~Y~26L<FLAG_PART_FILL>~Z~-10H~-3V~5L<PAD_PART_DPAD_D>~Z~-10H"
"~+6V~5L<PAD_PART_DPAD_U>~Z~-5H~+1V~5L<PAD_PART_DPAD_L>~Z~-14H~+1V~5L<PAD_PART_DPAD_R>~Z"
"~-11H~+1V~7L<FLAG_PART_KOREA_CIRCLE_FILL>~Z~+26H",
"<FLAG_BRAZIL>"},
{"~Y~3L~~~Z~1L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~26L<FLAG_PART_HORZ_STRIPE_BOTTOM>~]~-2H~Y~3L~~"
"~Z~1L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~26L<FLAG_PART_HORZ_STRIPE_BOTTOM>~Z~+26H",
"<FLAG_HUNGARY>"},
{"~Y~3L<FLAG_PART_FILL>~Z~5L<FLAG_PART_USA_STRIPES_RIGHT>~]~-2H~Y~3L<FLAG_PART_FILL>~Z~5L"
"<FLAG_PART_USA_STRIPES_RIGHT>~Z~+26H",
"<FLAG_CATALAN>"},
{"~Y~1L<FLAG_PART_FILL>~Z~3L<FLAG_PART_HORZ_STRIPE_BOTTOM>~Z~-5V~3L<FLAG_PART_HORZ_STRIPE"
"_BOTTOM>~]~-2H~+5V~Y~1L<FLAG_PART_FILL>~Z~3L<FLAG_PART_HORZ_STRIPE_BOTTOM>~Z~-5V~3L"
"<FLAG_PART_HORZ_STRIPE_BOTTOM>~Z~+26H",
"<FLAG_POLAND>"},
{"~Y~5L~~~Z~26L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~3L<FLAG_PART_HORZ_STRIPE_BOTTOM>~]~-2H~Y~5L~~"
"~Z~26L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~3L<FLAG_PART_HORZ_STRIPE_BOTTOM>~Z~+26H",
"<FLAG_LITHUANIA>"},
{"~Y~1L<FLAG_PART_FILL>~]~-2H~Y~1L<FLAG_PART_FILL>~Z~3L<FLAG_PART_HORZ_STRIPE_BOTTOM>~Z~-5V~3L"
"<FLAG_PART_HORZ_STRIPE_BOTTOM>~Z~-22H~3L<FLAG_PART_HORZ_STRIPE_BOTTOM>~Z~-22H~-5V~3L"
"<FLAG_PART_HORZ_STRIPE_BOTTOM>~Z~-23H~7L<FLAG_PART_VERT_STRIPE_LEFT>~Z~-26H~-3V~7L"
"<PAD_PART_DPAD_D>~Z~+6V~-26H~7L<PAD_PART_DPAD_U>~Z~-21H~+1V~7L<PAD_PART_DPAD_L>~Z~+26H",
"<FLAG_CZECH>"},
{"~Y~3L~~~Z~1L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~7L<FLAG_PART_HORZ_STRIPE_BOTTOM>~]~-1H~Y~3L~~"
"~Z~1L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~7L<FLAG_PART_HORZ_STRIPE_BOTTOM>~Z~-11H~+2V~3L"
"<FLAG_PART_JAPAN_SUN>~Z~-9H~+2V~1L+~Z~-8V~-8H~7L-~Z~-8V~-3H~7L-~Z~+26H",
"<FLAG_CROATIA>"},
{"~Y~1L<FLAG_PART_FILL>~Z~21L<FLAG_PART_UK_CROSS_LEFT>~Z~1L<FLAG_PART_HORZ_STRIPE_MIDDLE>"
"~Z~1L<FLAG_PART_HORZ_STRIPE_BOTTOM>~]~-1H~Y~1L<FLAG_PART_FILL>~Z~21L<FLAG_PART_UK_CROSS_"
"RIGHT>~Z~1L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~-4H~1L<FLAG_PART_VERT_STRIPE_LEFT>~Z~1L~~"
"~Z~-11H~7L<FLAG_PART_KOREA_CIRCLE_FILL>~Z~-8V~-8H~3L-~Z~-8V~-4H~3L-~Z~+26H",
"<FLAG_GALICIA>"},
// korean jamo -- only relevant for the language selection since
// non-korean languages don't run through the `convert-korean-text` function and hence the
// encoding is "normal"
{
"~Y~Z\\c03.~Z\\c03\\c1a~Z\\c03О~Y~Z\\c03œ~Z\\c03k~Z\\c03г~Y~Z\\c03\\c0f~Z\\c03ç",
"<LANGUAGE_KOREAN>",
"~Y~Z\x03.~Z\x03\x1a~Z\x03О~Y~Z\x03œ~Z\x03k~Z\x03г~Y~Z\x03\x0f~Z\x03ç",
},
// weird stuff
// - descenders
{"~+7Vp~-7V", "p"},
{"~+7Vy~-7V", "y"},
{"~+7Vg~-7V", "g"},
{"~+7Vq~-7V", "q"},
{"~+1Vj~-1V", "j"},
// - cryllic
{"~+2Vд~-2V", "д"},
{"~+4Vу~-4V", "у"},
{"~+4Vр~-4V", "р"},
{"~+3Vф~-3V", "ф"},
{"~+2Vц~-2V", "ц"},
{"~+2VД~-2V", "Д"},
{"~+2Vщ~-2V", "щ"},
{"\\\\",
"~%"}, // this is 2 slashes, duplicated because we use an escape sequence when decompiling
// - symbols and ligatures
{"~-4H~-3V<SOMETHING>~+3V~-4H",
"<SUPERSCRIPT_QUOTE>"}, // used for the 4<__> place in spanish. the 5th uses the same
// character but looks different...?
{"~Y~-6Hº~Z~+10H", "°"},
// Color / Emphasis
{"~[~0L", "<COLOR_DEFAULT>"},
{"~[~1L", "<COLOR_WHITE>"},
{"~[~2L", "<COLOR_TRANSPARENT>"},
{"~[~3L", "<COLOR_RED>"},
{"~[~4L", "<COLOR_ORANGE>"},
{"~[~5L", "<COLOR_YELLOW>"},
{"~[~6L", "<COLOR_GREEN>"},
{"~[~7L", "<COLOR_BLUE>"},
{"~[~8L", "<COLOR_CYAN>"},
{"~[~9L", "<COLOR_PINK>"},
{"~[~10L", "<COLOR_MENU-SELECTED>"},
{"~[~11L", "<COLOR_MENU-SELECTED-PARENT>"},
{"~[~12L", "<COLOR_MENU>"},
{"~[~13L", "<COLOR_MENU-PARENT>"},
{"~[~14L", "<COLOR_MENU-FUNC-BAD>"},
{"~[~15L", "<COLOR_MENU-FLAG-ON>"},
{"~[~16L", "<COLOR_MENU-FLAG-ON-PARENT>"},
{"~[~17L", "<COLOR_MENU-FLAG-OFF>"},
{"~[~18L", "<COLOR_MENU-FLAG-OFF-PARENT>"},
{"~[~19L", "<COLOR_MENU-INVALID>"},
{"~[~20L", "<COLOR_FLAT-YELLOW>"},
{"~[~21L", "<COLOR_COLOR-21>"},
{"~[~22L", "<COLOR_PAD-BACK>"},
{"~[~23L", "<COLOR_PAD-SHINE>"},
{"~[~24L", "<COLOR_PAD-SQUARE>"},
{"~[~25L", "<COLOR_PAD-CIRCLE>"},
{"~[~26L", "<COLOR_PAD-TRIANGLE>"},
{"~[~27L", "<COLOR_PAD-CROSS>"},
{"~[~28L", "<COLOR_PROGRESS-OLD-BLUE>"},
{"~[~29L", "<COLOR_PROGRESS-OLD-YELLOW>"},
{"~[~30L", "<COLOR_PROGRESS-OLD-SELECTED>"},
{"~[~31L", "<COLOR_PROGRESS-OLD-PERCENT>"},
{"~[~32L", "<COLOR_PROGRESS>"},
{"~[~33L", "<COLOR_PROGRESS-SELECTED>"},
{"~[~34L", "<COLOR_PROGRESS-FORCE-SELECTED>"},
{"~[~35L", "<COLOR_PROGRESS-OPTION-OFF>"},
{"~[~36L", "<COLOR_COLOR-36>"},
{"~[~37L", "<COLOR_CREDITS-STAFF-TITLE-1>"},
{"~[~38L", "<COLOR_CREDITS-STAFF-TITLE-2>"},
{"~[~39L", "<COLOR_COLOR-39>"}};
std::vector<EncodeInfo> encode_info_jak3 = {
{"ˇ", "\x10"}, // caron
{"`", "\x11"}, // grave accent
{"'", "\x12"}, // apostrophe
{"^", "\x13"}, // circumflex
{"<TIL>", "\x14"}, // tilde
{"¨", "\x15"}, // umlaut
{"º", "\x16"}, // numero/overring
{"¡", "\x17"}, // inverted exclamation mark
{"¿", "\x18"}, // inverted question mark
{"<SOMETHING>", "\x19"},
{"ç", "\x1d"}, // c-cedilla
{"Ç", "\x1e"}, // c-cedilla
{"ß", "\x1f"}, // eszett
{"œ", "\x5e"}, // ligature o+e
{"<FLAG_PART_HORZ_STRIPE_MIDDLE>", "\x7f"},
{"<FLAG_PART_HORZ_STRIPE_BOTTOM>", "\x80"},
{"<FLAG_PART_VERT_STRIPE_LARGE>", "\x81"},
{"<FLAG_PART_VERT_STRIPE_RIGHT>", "\x82"},
{"<FLAG_PART_VERT_STRIPE_LEFT>", "\x83"},
{"<FLAG_PART_VERT_STRIPE_MIDDLE>", "\x84"},
{"<FLAG_PART_FILL>", "\x85"},
{"<FLAG_PART_JAPAN_SUN>", "\x86"},
{"<FLAG_PART_KOREA_TRIGRAMS_LEFT>", "\x87"},
{"<FLAG_PART_KOREA_TRIGRAMS_RIGHT>", "\x88"},
{"<FLAG_PART_KOREA_CIRCLE_TOP>", "\x89"},
{"<FLAG_PART_KOREA_CIRCLE_FILL>", "\x8a"},
{"<FLAG_PART_TOP_BOTTOM_STRIPE>", "\x8b"},
{"<FLAG_PART_UK_CROSS_LEFT>", "\x8c"},
{"<FLAG_PART_UK_CROSS_RIGHT>", "\x8d"},
{"<FLAG_PART_UK_FILL_LEFT>", "\x8e"},
{"<FLAG_PART_UK_FILL_RIGHT>", "\x8f"},
{"<FLAG_PART_USA_STRIPES_RIGHT>", "\x90"},
{"<PAD_PART_STICK>", "\x91"},
{"<PAD_PART_SELECT>", "\x92"},
{"<PAD_PART_TRIGGER_BACK>", "\x93"},
{"<PAD_PART_R1_NAME>", "\x94"},
{"<PAD_PART_L1_NAME>", "\x95"},
{"<PAD_PART_R2_NAME>", "\x96"},
{"<PAD_PART_L2_NAME>", "\x97"},
{"<PAD_PART_STICK_UP>", "\x98"},
{"<PAD_PART_STICK_UP_RIGHT>", "\x99"},
{"<FLAG_PART_USA_STRIPES_LEFT>", "\x9a"},
{"<FLAG_PART_USA_STARS>", "\x9b"},
{"<PAD_PART_STICK_DOWN>", "\x9c"},
{"<PAD_PART_STICK_DOWN_LEFT>", "\x9d"},
{"<PAD_PART_STICK_LEFT>", "\x9e"},
{"<PAD_PART_STICK_UP_LEFT>", "\x9f"},
{"<PAD_PART_DPAD_D>", "\xa0"},
{"<PAD_PART_DPAD_L>", "\xa1"},
{"<PAD_PART_DPAD_U>", "\xa2"},
{"<PAD_PART_DPAD_R>", "\xa3"},
{"<PAD_PART_STICK_RIGHT>", "\xa4"},
{"<PAD_PART_STICK_DOWN_RIGHT>", "\xa5"},
{"<PAD_PART_SHOULDER_TOP_LEFT>", "\xa6"},
{"<PAD_PART_SHOULDER_TOP_RIGHT>", "\xa7"},
{"<PAD_PART_TRIGGER_TOP_LEFT>", "\xa8"},
{"<PAD_PART_TRIGGER_TOP_RIGHT>", "\xa9"},
{"<PAD_PART_TRIGGER_SHIM1>", "\xaa"},
{"<PAD_PART_TRIGGER_SHIM2>", "\xab"},
{"<PAD_PART_SHOULDER_SHIM2>", "\xac"},
{"<PAD_PART_SHOULDER_BOTTOM_LEFT>", "\xb0"},
{"<PAD_PART_SHOULDER_BOTTOM_RIGHT>", "\xb1"},
{"<PAD_PART_TRIGGER_BOTTOM_LEFT>", "\xb2"},
{"<PAD_PART_TRIGGER_BOTTOM_RIGHT>", "\xb3"},
{"<FLAG_PART_PORTUGUAL_1>", "\xb4"},
{"<FLAG_PART_PORTUGUAL_2>", "\xb5"},
{"<FLAG_PART_PORTUGUAL_3>", "\xb6"},
// b7 have something...anything use it?
// cryllic
// - uppercase
{"А", "\xba"},
{"Б", "\xbb"},
{"В", "\xbc"},
{"Г", "\xbd"},
{"Д", "\xbe"},
{"Е", "\xbf"},
// "Ё" - if ever used in subtitles, likely uses the accents at the end
{"Ж", "\xc0"},
{"З", "\xc1"},
{"И", "\xc2"},
// blank (c3)
// c4
// "Й" - if ever used in subtitles, likely uses the accents at the end
{"К", "\xc4"},
{"Л", "\xc5"},
{"М", "\xc6"},
{"Н", "\xc7"},
{"О", "\xc8"},
{"П", "\xc9"},
{"Р", "\xca"},
{"С", "\xcb"},
{"Т", "\xcc"},
// blank (cd)
// ce
{"У", "\xce"},
{"Ф", "\xcf"},
{"Х", "\xd0"},
{"Ц", "\xd1"},
{"Ч", "\xd2"},
{"Ш", "\xd3"},
{"Щ", "\xd4"},
{"Ъ", "\xd5"},
{"Ы", "\xd6"},
{"Ь", "\xd7"},
// d8
{"Э", "\xd8"},
{"Ю", "\xd9"},
{"Я", "\xda"},
// - lowercase
{"а", "\xdb"},
{"б", "\xdc"},
{"в", "\xdd"},
{"г", "\xde"},
{"д", "\xdf"},
{"е", "\xe0"},
{"ё", "\xe1"},
// e2
{"ж", "\xe2"},
{"з", "\xe3"},
{"и", "\xe4"},
{"й", "\xe5"},
{"к", "\xe6"},
{"л", "\xe7"},
{"м", "\xe8"},
{"н", "\xe9"},
{"о", "\xea"},
{"п", "\xeb"},
// ec
{"р", "\xec"},
{"с", "\xed"},
{"т", "\xee"},
{"у", "\xef"},
{"ф", "\xf0"},
{"х", "\xf1"},
{"ц", "\xf2"},
{"ч", "\xf3"},
{"ш", "\xf4"},
{"щ", "\xf5"},
// f6
{"ъ", "\xf6"},
{"ы", "\xf7"},
{"ь", "\xf8"},
{"э", "\xf9"},
{"ю", "\xfa"},
{"я", "\xfb"},
// - extra accents
{"RU-TODO-1",
"\xfc"}, // NOTE: they never used this in the game text, maybe in subtitles though
{"RU-TODO-2",
"\xfd"}, // NOTE: they never used this in the game text, maybe in subtitles though
// {"入", "\x1\x00"}},
// {"年", "\x1\x01"}},
// punctuation
{"・", "\x1\x10"},
{"゛", "\x1\x11"},
{"゜", "\x1\x12"},
{"ー", "\x1\x13"},
{"『", "\x1\x14"},
{"』", "\x1\x15"},
// hiragana
{"ぁ", "\x1\x16"}, // -a
{"あ", "\x1\x17"}, // a
{"ぃ", "\x1\x18"}, // -i
{"い", "\x1\x19"}, // i
{"ぅ", "\x1\x1a"}, // -u
{"う", "\x1\x1b"}, // u
{"ぇ", "\x1\x1c"}, // -e
{"え", "\x1\x1d"}, // e
{"ぉ", "\x1\x1e"}, // -o
{"お", "\x1\x1f"}, // o
{"か", "\x1\x20"}, // ka
{"き", "\x1\x21"}, // ki
{"く", "\x1\x22"}, // ku
{"け", "\x1\x23"}, // ke
{"こ", "\x1\x24"}, // ko
{"さ", "\x1\x25"}, // sa
{"し", "\x1\x26"}, // shi
{"す", "\x1\x27"}, // su
{"せ", "\x1\x28"}, // se
{"そ", "\x1\x29"}, // so
{"た", "\x1\x2a"}, // ta
{"ち", "\x1\x2b"}, // chi
{"っ", "\x1\x2c"}, // sokuon
{"つ", "\x1\x2d"}, // tsu
{"て", "\x1\x2e"}, // te
{"と", "\x1\x2f"}, // to
{"な", "\x1\x30"}, // na
{"に", "\x1\x31"}, // ni
{"ぬ", "\x1\x32"}, // nu
{"ね", "\x1\x33"}, // ne
{"の", "\x1\x34"}, // no
{"は", "\x1\x35"}, // ha
{"ひ", "\x1\x36"}, // hi
{"ふ", "\x1\x37"}, // fu
{"へ", "\x1\x38"}, // he
{"ほ", "\x1\x39"}, // ho
{"ま", "\x1\x3a"}, // ma
{"み", "\x1\x3b"}, // mi
{"む", "\x1\x3c"}, // mu
{"め", "\x1\x3d"}, // me
{"も", "\x1\x3e"}, // mo
{"ゃ", "\x1\x3f"}, // youon ya
{"や", "\x1\x40"}, // ya
{"ゅ", "\x1\x41"}, // youon yu
{"ゆ", "\x1\x42"}, // yu
{"ょ", "\x1\x43"}, // youon yo
{"よ", "\x1\x44"}, // yo
{"ら", "\x1\x45"}, // ra
{"り", "\x1\x46"}, // ri
{"る", "\x1\x47"}, // ru
{"れ", "\x1\x48"}, // re
{"ろ", "\x1\x49"}, // ro
{"ゎ", "\x1\x4a"}, // -wa
{"わ", "\x1\x4b"}, // wa
{"を", "\x1\x4c"}, // wo
{"ん", "\x1\x4d"}, // -n
// katakana
{"ァ", "\x1\x4e"}, // -a
{"ア", "\x1\x4f"}, // a
{"ィ", "\x1\x50"}, // -i
{"イ", "\x1\x51"}, // i
{"ゥ", "\x1\x52"}, // -u
{"ウ", "\x1\x53"}, // u
{"ェ", "\x1\x54"}, // -e
{"エ", "\x1\x55"}, // e
{"ォ", "\x1\x56"}, // -o
{"オ", "\x1\x57"}, // o
{"カ", "\x1\x58"}, // ka
{"キ", "\x1\x59"}, // ki
{"ク", "\x1\x5a"}, // ku
{"ケ", "\x1\x5b"}, // ke
{"コ", "\x1\x5c"}, // ko
{"サ", "\x1\x5d"}, // sa
{"シ", "\x1\x5e"}, // shi
{"ス", "\x1\x5f"}, // su
{"セ", "\x1\x60"}, // se
{"ソ", "\x1\x61"}, // so
{"タ", "\x1\x62"}, // ta
{"チ", "\x1\x63"}, // chi
{"ッ", "\x1\x64"}, // sokuon
{"ツ", "\x1\x65"}, // tsu
{"テ", "\x1\x66"}, // te
{"ト", "\x1\x67"}, // to
{"ナ", "\x1\x68"}, // na
{"ニ", "\x1\x69"}, // ni
{"ヌ", "\x1\x6a"}, // nu
{"ネ", "\x1\x6b"}, // ne
{"ノ", "\x1\x6c"}, // no
{"ハ", "\x1\x6d"}, // ha
{"ヒ", "\x1\x6e"}, // hi
{"フ", "\x1\x6f"}, // fu
{"ヘ", "\x1\x70"}, // he
{"ホ", "\x1\x71"}, // ho
{"マ", "\x1\x72"}, // ma
{"ミ", "\x1\x73"}, // mi
{"ム", "\x1\x74"}, // mu
{"メ", "\x1\x75"}, // me
{"モ", "\x1\x76"}, // mo
{"ャ", "\x1\x77"}, // youon ya
{"ヤ", "\x1\x78"}, // ya
{"ュ", "\x1\x79"}, // youon yu
{"ユ", "\x1\x7a"}, // yu
{"ョ", "\x1\x7b"}, // youon yo
{"ヨ", "\x1\x7c"}, // yo
{"ラ", "\x1\x7d"}, // ra
{"リ", "\x1\x7e"}, // ri
{"ル", "\x1\x7f"}, // ru
{"レ", "\x1\x80"}, // re
{"ロ", "\x1\x81"}, // ro
{"ヮ", "\x1\x82"}, // -wa
{"ワ", "\x1\x83"}, // wa
{"ヲ", "\x1\x84"}, // wo
{"ン", "\x1\x85"}, // -n
{"位", "\x1\x8c"},
{"遺", "\x1\x8d"},
{"院", "\x1\x8e"},
{"映", "\x1\x8f"},
{"衛", "\x1\x90"},
{"応", "\x1\x91"},
{"下", "\x1\x92"},
{"画", "\x1\x93"},
{"解", "\x1\x94"},
{"開", "\x1\x95"},
{"外", "\x1\x96"},
{"害", "\x1\x97"},
{"蓋", "\x1\x98"},
{"完", "\x1\x99"},
{"換", "\x1\x9a"},
{"監", "\x1\x9b"},
{"間", "\x1\x9c"},
{"器", "\x1\x9d"},
{"記", "\x1\x9e"},
{"逆", "\x1\x9f"},
{"救", "\x1\xa0"},
{"金", "\x1\xa1"},
{"空", "\x1\xa2"},
{"掘", "\x1\xa3"},
{"警", "\x1\xa4"},
{"迎", "\x1\xa5"},
{"撃", "\x1\xa6"},
{"建", "\x1\xa7"},
{"源", "\x1\xa8"},
{"現", "\x1\xa9"},
{"言", "\x1\xaa"},
{"限", "\x1\xab"},
{"個", "\x1\xac"},
{"庫", "\x1\xad"},
{"後", "\x1\xae"},
{"語", "\x1\xaf"},
{"護", "\x1\xb0"},
{"交", "\x1\xb1"},
{"功", "\x1\xb2"},
{"向", "\x1\xb3"},
{"工", "\x1\xb4"},
{"攻", "\x1\xb5"},
{"溝", "\x1\xb6"},
{"行", "\x1\xb7"},
{"鉱", "\x1\xb8"},
{"降", "\x1\xb9"},
{"合", "\x1\xba"},
{"告", "\x1\xbb"},
{"獄", "\x1\xbc"},
{"彩", "\x1\xbd"},
{"作", "\x1\xbe"},
{"山", "\x1\xbf"},
{"使", "\x1\xc0"},
{"始", "\x1\xc1"},
{"試", "\x1\xc2"},
{"字", "\x1\xc3"},
{"寺", "\x1\xc4"},
{"時", "\x1\xc5"},
{"示", "\x1\xc6"},
{"自", "\x1\xc7"},
{"式", "\x1\xc8"},
{"矢", "\x1\xc9"},
{"射", "\x1\xca"},
{"者", "\x1\xcb"},
{"守", "\x1\xcc"},
{"手", "\x1\xcd"},
{"終", "\x1\xce"},
{"週", "\x1\xcf"},
{"出", "\x1\xd0"},
{"所", "\x1\xd1"},
{"書", "\x1\xd2"},
{"勝", "\x1\xd3"},
{"章", "\x1\xd4"},
{"上", "\x1\xd5"},
{"乗", "\x1\xd6"},
{"場", "\x1\xd7"},
{"森", "\x1\xd8"},
{"進", "\x1\xd9"},
{"人", "\x1\xda"},
{"水", "\x1\xdb"},
{"数", "\x1\xdc"},
{"制", "\x1\xdd"},
{"性", "\x1\xde"},
{"成", "\x1\xdf"},
{"聖", "\x1\xe0"},
{"石", "\x1\xe1"},
{"跡", "\x1\xe2"},
{"先", "\x1\xe3"},
{"戦", "\x1\xe4"},
{"船", "\x1\xe5"},
{"選", "\x1\xe6"},
{"走", "\x1\xe7"},
{"送", "\x1\xe8"},
{"像", "\x1\xe9"},
{"造", "\x1\xea"},
{"続", "\x1\xeb"},
{"対", "\x1\xec"},
{"袋", "\x1\xed"},
{"台", "\x1\xee"},
{"弾", "\x1\xef"},
{"地", "\x1\xf0"},
{"中", "\x1\xf1"},
{"敵", "\x1\xf2"},
{"転", "\x1\xf3"},
{"電", "\x1\xf4"},
{"塔", "\x1\xf5"},
{"頭", "\x1\xf6"},
{"動", "\x1\xf7"},
{"内", "\x1\xf8"},
{"日", "\x1\xf9"},
{"入", "\x1\xfa"},
{"年", "\x1\xfb"},
{"能", "\x1\xfc"},
{"廃", "\x1\xfd"},
{"排", "\x1\xfe"},
{"敗", "\x1\xff"},
{"発", "\x2\x10"},
{"反", "\x2\x11"},
{"必", "\x2\x12"},
{"表", "\x2\x13"},
{"武", "\x2\x14"},
{"壁", "\x2\x15"},
{"墓", "\x2\x16"},
{"放", "\x2\x17"},
{"方", "\x2\x18"},
{"砲", "\x2\x19"},
{"妨", "\x2\x1a"},
{"北", "\x2\x1b"},
{"本", "\x2\x1c"},
{"幕", "\x2\x1d"},
{"無", "\x2\x1e"},
{"迷", "\x2\x1f"},
{"面", "\x2\x20"},
{"戻", "\x2\x21"},
{"紋", "\x2\x22"},
{"薬", "\x2\x23"},
{"輸", "\x2\x24"},
{"勇", "\x2\x25"},
{"友", "\x2\x26"},
{"遊", "\x2\x27"},
{"容", "\x2\x28"},
{"要", "\x2\x29"},
{"利", "\x2\x2a"},
{"了", "\x2\x2b"},
{"量", "\x2\x2c"},
{"力", "\x2\x2d"},
{"練", "\x2\x2e"},
{"連", "\x2\x2f"},
{"録", "\x2\x30"},
{"話", "\x2\x31"},
{"墟", "\x2\x32"},
{"脱", "\x2\x33"},
// {"成", "\x2\x34"},
{"旗", "\x2\x35"},
{"破", "\x2\x36"},
{"壊", "\x2\x37"},
{"全", "\x2\x38"},
{"滅", "\x2\x39"},
{"機", "\x2\x3a"},
{"仲", "\x2\x3b"},
{"渓", "\x2\x3c"},
{"谷", "\x2\x3d"},
{"優", "\x2\x3e"},
{"探", "\x2\x3f"},
{"部", "\x2\x40"},
{"索", "\x2\x41"},
// {"乗", "\x2\x42"},
{"前", "\x2\x43"},
{"右", "\x2\x44"},
{"左", "\x2\x45"},
{"会", "\x2\x46"},
{"高", "\x2\x47"},
{"低", "\x2\x48"},
{"押", "\x2\x49"},
{"切", "\x2\x4a"},
{"替", "\x2\x4b"},
// {"対", "\x2\x4c"},
{"秒", "\x2\x4d"},
{"箱", "\x2\x4e"},
{"泳", "\x2\x4f"},
{"~", "\x2\x50"},
{"闇", "\x2\x56"},
{"以", "\x2\x57"},
{"屋", "\x2\x58"},
{"俺", "\x2\x59"},
{"化", "\x2\x5a"},
{"界", "\x2\x5b"},
{"感", "\x2\x5c"},
{"気", "\x2\x5d"},
{"却", "\x2\x5e"},
{"曲", "\x2\x5f"},
{"継", "\x2\x60"},
{"権", "\x2\x61"},
{"見", "\x2\x62"},
{"古", "\x2\x63"},
{"好", "\x2\x64"},
// {"高", "\x2\x65"},
{"才", "\x2\x66"},
{"士", "\x2\x67"},
{"子", "\x2\x68"},
{"次", "\x2\x69"},
{"主", "\x2\x6a"},
{"種", "\x2\x6b"},
{"讐", "\x2\x6c"},
{"女", "\x2\x6d"},
{"小", "\x2\x6e"},
{"焼", "\x2\x6f"},
{"証", "\x2\x70"},
{"神", "\x2\x71"},
{"身", "\x2\x72"},
{"寸", "\x2\x73"},
{"世", "\x2\x74"},
{"想", "\x2\x75"},
{"退", "\x2\x76"},
{"第", "\x2\x77"},
{"着", "\x2\x78"},
{"天", "\x2\x79"},
{"倒", "\x2\x7a"},
{"到", "\x2\x7b"},
{"突", "\x2\x7c"},
{"爆", "\x2\x7d"},
{"番", "\x2\x7e"},
{"負", "\x2\x7f"},
{"復", "\x2\x80"},
{"物", "\x2\x81"},
{"眠", "\x2\x82"},
{"予", "\x2\x83"},
{"用", "\x2\x84"},
{"落", "\x2\x85"},
{"緑", "\x2\x86"},
{"封", "\x2\x88"},
{"印", "\x2\x89"},
{"扉", "\x2\x8a"},
{"最", "\x2\x8b"},
{"刻", "\x2\x8c"},
{"足", "\x2\x8d"},
};
GameTextFontBank g_font_bank_jak3(GameTextVersion::JAK3,
&encode_info_jak3,
&replace_info_jak3,
&passthrus_jak3);
-14
View File
@@ -1,14 +0,0 @@
#pragma once
#include "common/util/font/font_utils.h"
/*!
* ================================
* GAME TEXT FONT BANK - JAK 3
* ================================
* This font is used in:
* - Jak 3
*/
// TODO cyrillic
// TODO - current just using the jak 2 stuff (hopefully it's identical?)
extern GameTextFontBank g_font_bank_jak3;
-888
View File
@@ -1,888 +0,0 @@
#include "font_db_jakx.h"
std::unordered_set<char> passthrus_jakx = {'~', ' ', ',', '.', '-', '+', '(', ')',
'!', ':', '?', '=', '%', '*', '/', '#',
';', '<', '>', '@', '[', '_', ']'};
std::vector<ReplaceInfo> replace_info_jakx = {
// other
{"A~Y~-21H~-5Vº~Z", "Å"},
{"N~Y~-6Hº~Z~+10H", "Nº"},
// portuguese
{"~+4Vç~-4V", "ç"},
{"O~Y~-25H~-1V/~Z", "Ø"},
{"o~Y~-23H~+4V/~Z", "ø"},
{"A~Y~-13H~+8V,~Z", "Ą"},
{"a~Y~-8H~+6V,~Z", "ą"},
{"E~Y~-6H~+8V,~Z", "Ę"},
{"e~Y~-10H~+7V,~Z", "ę"},
{"L~Y~-21H~+0V/~Z", "Ł"},
{"l~Y~-16H~+0V/~Z", "ł"}, // TODO - this one is ugly, font character addition (small slash)
{"Z~Y~-25H~-11Vº~Z", "Ż"},
{"z~Y~-23H~-5Vº~Z", "ż"},
{"a~Y~-25H~-5Vº~Z", "å"},
{"S~Y~-21H~-5V'~Z", "Ś"},
{"s~Y~-25H~-5V'~Z", "ś"},
{"n~Y~-25H~-5V'~Z", "ń"},
{"c~Y~-25H~-5V'~Z", "ć"},
{"o~Y~-25H~-4V<TIL>~Z", "õ"},
{"a~Y~-25H~-4V<TIL>~Z", "ã"},
{"O~Y~-28H~-4V'~-9H'~Z", "Ő"},
{"U~Y~-27H~-4V'~-12H'~Z", "Ű"},
{"o~Y~-28H~-4V'~-9H'~Z", "ő"},
{"u~Y~-28H~-4V'~-9H'~Z", "ű"},
{"E~Y~-22H~-11Vº~Z", "Ė"},
{"e~Y~-25H~-5Vº~Z", "ė"},
{"C~Y~-27H~-10Vˇ~Z", "Č"},
{"c~Y~-25H~-5Vˇ~Z", "č"},
{"D~Y~-27H~-10Vˇ~Z", "Ď"},
{"S~Y~-24H~-10Vˇ~Z", "Š"},
{"s~Y~-22H~-4Vˇ~Z", "š"},
{"Z~Y~-25H~-10Vˇ~Z", "Ž"},
{"z~Y~-23H~-4Vˇ~Z", "ž"},
{"U~Y~-15H~+5V,~Z", "Ų"},
{"u~Y~-15H~+5V,~Z", "ų"},
{"U~Y~-20H~-18V-~Z", "Ū"},
{"u~Y~-18H~-15V-~Z", "ū"},
{"D~Y~-28H~-1V-~Z", "Đ"},
{"d~Y~-13H~-10V-~Z", "đ"},
{"I~Y~-8H~+4V,~Z", "Į"},
{"i~Y~-8H~+4V,~Z", "į"},
// czech specific
{"U~Y~-24H~-7Vº~Z", "Ů"},
{"u~Y~-23H~-5Vº~Z", "ů"},
{"t~Y~-7H~-21V,~Z", "ť"},
// tildes
{"N~Y~-22H~-4V<TIL>~Z", "Ñ"},
{"n~Y~-24H~-4V<TIL>~Z", "ñ"},
{"A~Y~-21H~-5V<TIL>~Z", "Ã"},
{"O~Y~-22H~-4V<TIL>~Z", "Õ"},
// acute accents
{"A~Y~-21H~-5V'~Z", "Á"},
{"A~Y~-26H~-8V'~Z", "<Á_V2>"}, // unfortunate...
{"a~Y~-25H~-5V'~Z", "á"},
{"E~Y~-23H~-9V'~Z", "É"},
{"e~Y~-26H~-5V'~Z", "é"},
{"I~Y~-19H~-8V'~Z", "Í"},
{"i~Y~-19H~-8V'~Z", "í"},
{"O~Y~-22H~-4V'~Z", "Ó"},
{"o~Y~-26H~-4V'~Z", "ó"},
{"U~Y~-25H~-8V'~Z", "Ú"},
{"u~Y~-24H~-3V'~Z", "ú"},
{"Z~Y~-24H~-3V'~Z", "Ź"},
{"z~Y~-24H~-3V'~Z", "ź"},
// czech specific
{"Y~Y~-26H~-5V'~Z", "Ý"},
{"~+7Vy~-7V~Y~-24H~-3V'~Z", "ý"},
// circumflex
{"A~Y~-20H~-4V^~Z", "Â"},
{"a~Y~-24H~-5V^~Z", "â"},
{"E~Y~-20H~-5V^~Z", "Ê"},
{"e~Y~-25H~-4V^~Z", "ê"},
{"I~Y~-19H~-5V^~Z", "Î"},
{"i~Y~-19H~-8V^~Z", "î"},
{"O~Y~-20H~-4V^~Z", "Ô"},
{"o~Y~-25H~-4V^~Z", "ô"},
{"U~Y~-24H~-3V^~Z", "Û"},
{"u~Y~-23H~-3V^~Z", "û"},
// grave accents
{"A~Y~-26H~-8V`~Z", "À"},
{"a~Y~-25H~-5V`~Z", "à"},
{"E~Y~-23H~-9V`~Z", "È"},
{"e~Y~-26H~-5V`~Z", "è"},
{"I~Y~-19H~-5V`~Z", "Ì"},
{"i~Y~-19H~-8V`~Z", "ì"},
{"O~Y~-22H~-4V`~Z", "Ò"},
{"o~Y~-26H~-4V`~Z", "ò"},
{"U~Y~-24H~-3V`~Z", "Ù"},
{"u~Y~-24H~-3V`~Z", "ù"},
// umlaut
{"A~Y~-26H~-8V¨~Z", "Ä"},
{"a~Y~-25H~-5V¨~Z", "ä"},
{"E~Y~-20H~-5V¨~Z", "Ë"},
{"e~Y~-25H~-5V¨~Z", "ë"},
{"I~Y~-19H~-5V¨~Z", "Ï"},
{"i~Y~-26H~-4V¨~Z", "ï"},
{"O~Y~-26H~-8V¨~Z", "Ö"},
{"o~Y~-26H~-4V¨~Z", "ö"},
{"U~Y~-25H~-8V¨~Z", "Ü"},
{"u~Y~-24H~-3V¨~Z", "ü"},
// caron - Ǎ ǎ Ě ě Ǧ ǧ Ǐ ǐ Ǒ ǒ Ǔ ǔ Y̌ y̌
{"A~Y~-25H~-9Vˇ~Z", "Ǎ"},
{"a~Y~-24H~-5Vˇ~Z", "ǎ"},
{"E~Y~-22H~-8Vˇ~Z", "Ě"},
{"e~Y~-25H~-4Vˇ~Z", "ě"},
{"G~Y~-24H~-8Vˇ~Z", "Ǧ"},
{"~+7Vg~-7V~Y~-25H~-4Vˇ~Z", "ǧ"},
{"I~Y~-19H~-8Vˇ~Z", "Ǐ"},
{"i~Y~-19H~-8Vˇ~Z", "ǐ"},
{"O~Y~-25H~-7Vˇ~Z", "Ǒ"},
{"o~Y~-25H~-4Vˇ~Z", "ǒ"},
{"U~Y~-25H~-6Vˇ~Z", "Ǔ"},
{"u~Y~-24H~-3Vˇ~Z", "ǔ"},
{"Y~Y~-25H~-5Vˇ~Z", "Y̌"},
{"~+7Vy~-7V~Y~-25H~-3Vˇ~Z", "y̌"},
// czech specific - Č č Ň ň Ř ř Š š Ž ž Ť
{"C~Y~-25H~-9Vˇ~Z", "Č"},
{"c~Y~-24H~-5Vˇ~Z", "č"},
{"N~Y~-25H~-9Vˇ~Z", "Ň"},
{"n~Y~-24H~-5Vˇ~Z", "ň"},
{"R~Y~-25H~-9Vˇ~Z", "Ř"},
{"r~Y~-22H~-5Vˇ~Z", "ř"},
{"S~Y~-25H~-9Vˇ~Z", "Š"},
{"s~Y~-22H~-5Vˇ~Z", "š"},
{"T~Y~-24H~-7Vˇ~Z", "Ť"},
{"Z~Y~-25H~-9Vˇ~Z", "Ž"},
{"z~Y~-24H~-5Vˇ~Z", "ž"},
// dakuten katakana
{"~Yウ~Z゛", "ヴ"},
{"~Yカ~Z゛", "ガ"},
{"~Yキ~Z゛", "ギ"},
{"~Yク~Z゛", "グ"},
{"~Yケ~Z゛", "ゲ"},
{"~Yコ~Z゛", "ゴ"},
{"~Yサ~Z゛", "ザ"},
{"~Yシ~Z゛", "ジ"},
{"~Yス~Z゛", "ズ"},
{"~Yセ~Z゛", "ゼ"},
{"~Yソ~Z゛", "ゾ"},
{"~Yタ~Z゛", "ダ"},
{"~Yチ~Z゛", "ヂ"},
{"~Yツ~Z゛", "ヅ"},
{"~Yテ~Z゛", "デ"},
{"~Yト~Z゛", "ド"},
{"~Yハ~Z゛", "バ"},
{"~Yヒ~Z゛", "ビ"},
{"~Yフ~Z゛", "ブ"},
{"~Yヘ~Z゛", "ベ"},
{"~Yホ~Z゛", "ボ"},
// handakuten katakana
{"~Yハ~Z゜", "パ"},
{"~Yヒ~Z゜", "ピ"},
{"~Yフ~Z゜", "プ"},
{"~Yヘ~Z゜", "ペ"},
{"~Yホ~Z゜", "ポ"},
// dakuten hiragana
{"~Yか~Z゛", "が"},
{"~Yき~Z゛", "ぎ"},
{"~Yく~Z゛", "ぐ"},
{"~Yけ~Z゛", "げ"},
{"~Yこ~Z゛", "ご"},
{"~Yさ~Z゛", "ざ"},
{"~Yし~Z゛", "じ"},
{"~Yす~Z゛", "ず"},
{"~Yせ~Z゛", "ぜ"},
{"~Yそ~Z゛", "ぞ"},
{"~Yた~Z゛", "だ"},
{"~Yち~Z゛", "ぢ"},
{"~Yつ~Z゛", "づ"},
{"~Yて~Z゛", "で"},
{"~Yと~Z゛", "ど"},
{"~Yは~Z゛", "ば"},
{"~Yひ~Z゛", "び"},
{"~Yふ~Z゛", "ぶ"},
{"~Yへ~Z゛", "べ"},
{"~Yほ~Z゛", "ぼ"},
// handakuten hiragana
{"~Yは~Z゜", "ぱ"},
{"~Yひ~Z゜", "ぴ"},
{"~Yふ~Z゜", "ぷ"},
{"~Yへ~Z゜", "ぺ"},
{"~Yほ~Z゜", "ぽ"},
// japanese punctuation
{",~+8H", "、"},
{"~+8H ", " "},
// playstation buttons
// - face
{"~Y~22L<~Z~Y~27L*~Z~Y~1L>~Z~Y~23L[~Z~+26H", "<PAD_X>"},
{"~Y~22L<~Z~Y~26L;~Z~Y~1L>~Z~Y~23L[~Z~+26H", "<PAD_TRIANGLE>"},
{"~Y~22L<~Z~Y~25L@~Z~Y~1L>~Z~Y~23L[~Z~+26H", "<PAD_CIRCLE>"},
{"~Y~22L<~Z~Y~24L#~Z~Y~1L>~Z~Y~23L[~Z~+26H", "<PAD_SQUARE>"},
// - dpad
{"~Y~22L<PAD_PART_DPAD_L>~Z~3L~+17H~-13V<PAD_PART_DPAD_U>~Z~22L~+17H~+14V<PAD_PART_DPAD_D>~Z~"
"22L~+32H<PAD_PART_DPAD_R>~Z~+56H",
"<PAD_DPAD_UP>"},
{"~Y~22L<PAD_PART_DPAD_L>~Z~3L~+17H~-13V<PAD_PART_DPAD_U>~Z~3L~+17H~+14V<PAD_PART_DPAD_D>~Z~"
"22L~+32H<PAD_PART_DPAD_R>~Z~+56H",
"<PAD_DPAD_DOWN>"},
{"~Y~22L<PAD_PART_DPAD_L>~Z~22L~+17H~-13V<PAD_PART_DPAD_U>~Z~22L~+17H~+14V<PAD_PART_DPAD_D>~Z~"
"22L~+32H<PAD_PART_DPAD_R>~Z~+56H",
"<PAD_DPAD_ANY>"},
// - shoulder
{"~Y~22L~-2H~-12V<PAD_PART_SHOULDER_TOP_LEFT><PAD_PART_SHOULDER_TOP_RIGHT>~Z~22L~-2H~+17V<PAD_"
"PART_SHOULDER_BOTTOM_LEFT><PAD_PART_SHOULDER_BOTTOM_RIGHT>~Z~1L~+4H~+3V<PAD_PART_L1_NAME>~Z~+"
"38H",
"<PAD_L1>"},
{"~Y~22L~-2H~-12V<PAD_PART_SHOULDER_TOP_LEFT><PAD_PART_SHOULDER_TOP_RIGHT>~Z~22L~-2H~+17V<PAD_"
"PART_SHOULDER_BOTTOM_LEFT><PAD_PART_SHOULDER_BOTTOM_RIGHT>~Z~1L~+6H~+3V<PAD_PART_R1_NAME>~Z~+"
"38H",
"<PAD_R1>"},
{"~Y~22L~-2H~-6V<PAD_PART_TRIGGER_TOP_LEFT><PAD_PART_TRIGGER_TOP_RIGHT>~Z~22L~-2H~+16V<PAD_"
"PART_TRIGGER_BOTTOM_LEFT><PAD_PART_TRIGGER_BOTTOM_RIGHT>~Z~1L~+5H~-2V<PAD_PART_R2_NAME>~Z~+"
"38H",
"<PAD_R2>"},
{"~Y~22L~-2H~-6V<PAD_PART_TRIGGER_TOP_LEFT><PAD_PART_TRIGGER_TOP_RIGHT>~Z~22L~-2H~+16V<PAD_"
"PART_TRIGGER_BOTTOM_LEFT><PAD_PART_TRIGGER_BOTTOM_RIGHT>~Z~1L~+5H~-2V<PAD_PART_L2_NAME>~Z~+"
"38H",
"<PAD_L2>"},
// - analog
{"~1L~+8H~Y<PAD_PART_STICK>~Z~6L~-16H<PAD_PART_STICK_LEFT>~Z~+16h~6L<PAD_PART_STICK_RIGHT>~Z~"
"6L~-15V<PAD_PART_STICK_DOWN>~Z~+13V~6L<PAD_PART_STICK_UP>~Z~-10H~+9V~6L<PAD_PART_STICK_UP_"
"LEFT>~Z~+10H~+9V~6L<PAD_PART_STICK_UP_RIGHT>~Z~-10H~-11V~6L<PAD_PART_STICK_DOWN_LEFT>~Z~+10H~"
"-11V~6L<PAD_PART_STICK_DOWN_RIGHT>~Z~+32H",
"<PAD_ANALOG_ANY>"},
{"~Y~1L~+8H<PAD_PART_STICK>~Z~6L~-8H<PAD_PART_STICK_LEFT>~Z~+24H~6L<PAD_PART_STICK_RIGHT>~Z~+"
"40H",
"<PAD_ANALOG_LEFT_RIGHT>"},
{"~Y~1L<PAD_PART_STICK>~Z~6L~-15V<PAD_PART_STICK_DOWN>~Z~+13V~6L<PAD_PART_STICK_UP>~Z~+26H",
"<PAD_ANALOG_UP_DOWN>"},
// icons
{"~Y~6L<~Z~Y~1L>~Z~Y~23L[~Z~+26H", "<ICON_MISSION_COMPLETE>"},
{"~Y~3L<~Z~Y~1L>~Z~Y~23L[~Z~+26H", "<ICON_MISSION_TODO>"},
// flags
{"~Y~6L<FLAG_PART_VERT_STRIPE_LARGE>~Z~+15H~1L<FLAG_PART_VERT_STRIPE_LARGE>~Z~+30H~3L<FLAG_"
"PART_VERT_STRIPE_LARGE>~Z~+45H",
"<FLAG_ITALIAN>"},
{"~Y~5L<FLAG_PART_FILL>~Z~3L<FLAG_PART_TOP_BOTTOM_STRIPE>~]~-1H~Y~5L<FLAG_PART_FILL>~Z~3L<FLAG_"
"PART_TOP_BOTTOM_STRIPE>~Z~+26H",
"<FLAG_SPAIN>"},
{"~Y~39L~~~Z~3L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~5L<FLAG_PART_HORZ_STRIPE_BOTTOM>~]~-1H~Y~39L~~~"
"Z~3L<FLAG_PART_HORZ_STRIPE_MIDDLE>~Z~5L<FLAG_PART_HORZ_STRIPE_BOTTOM>~Z~+26H",
"<FLAG_GERMAN>"},
{"~Y~7L<FLAG_PART_VERT_STRIPE_LARGE>~Z~+15H~1L<FLAG_PART_VERT_STRIPE_LARGE>~Z~+30H~3L<FLAG_"
"PART_VERT_STRIPE_LARGE>~Z~+47H",
"<FLAG_FRANCE>"},
{"~Y~1L<FLAG_PART_FILL>~Z~3L<FLAG_PART_UK_CROSS_LEFT>~Z~7L<FLAG_PART_UK_FILL_LEFT>~]~-1H~Y~1L<"
"FLAG_PART_FILL>~Z~3L<FLAG_PART_UK_CROSS_RIGHT>~Z~7L<FLAG_PART_UK_FILL_RIGHT>~Z~+26H",
"<FLAG_UK>"},
{"~Y~1L<FLAG_PART_FILL>~Z~3L<FLAG_PART_USA_STRIPES_LEFT>~Z~7L<FLAG_PART_USA_STARS>~]~-1H~Y~1L<"
"FLAG_PART_FILL>~Z~3L<FLAG_PART_USA_STRIPES_RIGHT>~Z~+26H",
"<FLAG_USA>"},
{"~Y~1L<FLAG_PART_FILL>~Z~39L<FLAG_PART_KOREA_TRIGRAMS_LEFT>~]~-1H~Y~1L<FLAG_PART_FILL>~Z~39L<"
"FLAG_PART_KOREA_TRIGRAMS_RIGHT>~Z~-11H~7L<FLAG_PART_KOREA_CIRCLE_FILL>~Z~-11H~3L<FLAG_PART_"
"KOREA_CIRCLE_TOP>~Z~+26H",
"<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
{"~+7Vp~-7V", "p"},
{"~+7Vy~-7V", "y"},
{"~+7Vg~-7V", "g"},
{"~+7Vq~-7V", "q"},
{"~+1Vj~-1V", "j"},
// - cryllic
{"~+2Vд~-2V", "д"},
{"~+4Vу~-4V", "у"},
{"~+4Vр~-4V", "р"},
{"~+3Vф~-3V", "ф"},
{"~+2Vц~-2V", "ц"},
{"~+2VД~-2V", "Д"},
{"~+2Vщ~-2V", "щ"},
{"\\\\",
"~%"}, // this is 2 slashes, duplicated because we use an escape sequence when decompiling
// - symbols and ligatures
{"~-4H~-3V<SOMETHING>~+3V~-4H",
"<SUPERSCRIPT_QUOTE>"}, // used for the 4<__> place in spanish. the 5th uses the same
// character but looks different...?
{"~Y~-6Hº~Z~+10H", "°"},
// Color / Emphasis
{"~[~0L", "<COLOR_DEFAULT>"},
{"~[~1L", "<COLOR_WHITE>"},
{"~[~2L", "<COLOR_TRANSPARENT>"},
{"~[~3L", "<COLOR_RED>"},
{"~[~4L", "<COLOR_ORANGE>"},
{"~[~5L", "<COLOR_YELLOW>"},
{"~[~6L", "<COLOR_GREEN>"},
{"~[~7L", "<COLOR_BLUE>"},
{"~[~8L", "<COLOR_CYAN>"},
{"~[~9L", "<COLOR_PINK>"},
{"~[~10L", "<COLOR_MENU-SELECTED>"},
{"~[~11L", "<COLOR_MENU-SELECTED-PARENT>"},
{"~[~12L", "<COLOR_MENU>"},
{"~[~13L", "<COLOR_MENU-PARENT>"},
{"~[~14L", "<COLOR_MENU-FUNC-BAD>"},
{"~[~15L", "<COLOR_MENU-FLAG-ON>"},
{"~[~16L", "<COLOR_MENU-FLAG-ON-PARENT>"},
{"~[~17L", "<COLOR_MENU-FLAG-OFF>"},
{"~[~18L", "<COLOR_MENU-FLAG-OFF-PARENT>"},
{"~[~19L", "<COLOR_MENU-INVALID>"},
{"~[~20L", "<COLOR_FLAT-YELLOW>"},
{"~[~21L", "<COLOR_COLOR-21>"},
{"~[~22L", "<COLOR_PAD-BACK>"},
{"~[~23L", "<COLOR_PAD-SHINE>"},
{"~[~24L", "<COLOR_PAD-SQUARE>"},
{"~[~25L", "<COLOR_PAD-CIRCLE>"},
{"~[~26L", "<COLOR_PAD-TRIANGLE>"},
{"~[~27L", "<COLOR_PAD-CROSS>"},
{"~[~28L", "<COLOR_PROGRESS-OLD-BLUE>"},
{"~[~29L", "<COLOR_PROGRESS-OLD-YELLOW>"},
{"~[~30L", "<COLOR_PROGRESS-OLD-SELECTED>"},
{"~[~31L", "<COLOR_PROGRESS-OLD-PERCENT>"},
{"~[~32L", "<COLOR_PROGRESS>"},
{"~[~33L", "<COLOR_PROGRESS-SELECTED>"},
{"~[~34L", "<COLOR_PROGRESS-FORCE-SELECTED>"},
{"~[~35L", "<COLOR_PROGRESS-OPTION-OFF>"},
{"~[~36L", "<COLOR_COLOR-36>"},
{"~[~37L", "<COLOR_CREDITS-STAFF-TITLE-1>"},
{"~[~38L", "<COLOR_CREDITS-STAFF-TITLE-2>"},
{"~[~39L", "<COLOR_COLOR-39>"}};
// TODO - cryllic
std::vector<EncodeInfo> encode_info_jakx = {
{"ˇ", "\x10"}, // caron
{"`", "\x11"}, // grave accent
{"'", "\x12"}, // apostrophe
{"^", "\x13"}, // circumflex
{"<TIL>", "\x14"}, // tilde
{"¨", "\x15"}, // umlaut
{"º", "\x16"}, // numero/overring
{"¡", "\x17"}, // inverted exclamation mark
{"¿", "\x18"}, // inverted question mark
{"<SOMETHING>", "\x19"},
{"ç", "\x1d"}, // c-cedilla
{"Ç", "\x1e"}, // c-cedilla
{"ß", "\x1f"}, // eszett
{"œ", "\x5e"}, // ligature o+e
{"<FLAG_PART_HORZ_STRIPE_MIDDLE>", "\x7f"},
{"<FLAG_PART_HORZ_STRIPE_BOTTOM>", "\x80"},
{"<FLAG_PART_VERT_STRIPE_LARGE>", "\x81"},
{"<FLAG_PART_VERT_STRIPE_RIGHT>", "\x82"},
{"<FLAG_PART_VERT_STRIPE_LEFT>", "\x83"},
{"<FLAG_PART_VERT_STRIPE_MIDDLE>", "\x84"},
{"<FLAG_PART_FILL>", "\x85"},
{"<FLAG_PART_JAPAN_SUN>", "\x86"},
{"<FLAG_PART_KOREA_TRIGRAMS_LEFT>", "\x87"},
{"<FLAG_PART_KOREA_TRIGRAMS_RIGHT>", "\x88"},
{"<FLAG_PART_KOREA_CIRCLE_TOP>", "\x89"},
{"<FLAG_PART_KOREA_CIRCLE_FILL>", "\x8a"},
{"<FLAG_PART_TOP_BOTTOM_STRIPE>", "\x8b"},
{"<FLAG_PART_UK_CROSS_LEFT>", "\x8c"},
{"<FLAG_PART_UK_CROSS_RIGHT>", "\x8d"},
{"<FLAG_PART_UK_FILL_LEFT>", "\x8e"},
{"<FLAG_PART_UK_FILL_RIGHT>", "\x8f"},
{"<FLAG_PART_USA_STRIPES_RIGHT>", "\x90"},
{"<PAD_PART_STICK>", "\x91"},
{"<PAD_PART_SELECT>", "\x92"},
{"<PAD_PART_TRIGGER_BACK>", "\x93"},
{"<PAD_PART_R1_NAME>", "\x94"},
{"<PAD_PART_L1_NAME>", "\x95"},
{"<PAD_PART_R2_NAME>", "\x96"},
{"<PAD_PART_L2_NAME>", "\x97"},
{"<PAD_PART_STICK_UP>", "\x98"},
{"<PAD_PART_STICK_UP_RIGHT>", "\x99"},
{"<FLAG_PART_USA_STRIPES_LEFT>", "\x9a"},
{"<FLAG_PART_USA_STARS>", "\x9b"},
{"<PAD_PART_STICK_DOWN>", "\x9c"},
{"<PAD_PART_STICK_DOWN_LEFT>", "\x9d"},
{"<PAD_PART_STICK_LEFT>", "\x9e"},
{"<PAD_PART_STICK_UP_LEFT>", "\x9f"},
{"<PAD_PART_DPAD_D>", "\xa0"},
{"<PAD_PART_DPAD_L>", "\xa1"},
{"<PAD_PART_DPAD_U>", "\xa2"},
{"<PAD_PART_DPAD_R>", "\xa3"},
{"<PAD_PART_STICK_RIGHT>", "\xa4"},
{"<PAD_PART_STICK_DOWN_RIGHT>", "\xa5"},
{"<PAD_PART_SHOULDER_TOP_LEFT>", "\xa6"},
{"<PAD_PART_SHOULDER_TOP_RIGHT>", "\xa7"},
{"<PAD_PART_TRIGGER_TOP_LEFT>", "\xa8"},
{"<PAD_PART_TRIGGER_TOP_RIGHT>", "\xa9"},
{"<PAD_PART_TRIGGER_SHIM1>", "\xaa"},
{"<PAD_PART_TRIGGER_SHIM2>", "\xab"},
{"<PAD_PART_SHOULDER_SHIM2>", "\xac"},
{"<PAD_PART_SHOULDER_BOTTOM_LEFT>", "\xb0"},
{"<PAD_PART_SHOULDER_BOTTOM_RIGHT>", "\xb1"},
{"<PAD_PART_TRIGGER_BOTTOM_LEFT>", "\xb2"},
{"<PAD_PART_TRIGGER_BOTTOM_RIGHT>", "\xb3"},
// cryllic
// - uppercase
{"А", "\xba"},
{"Б", "\xbb"},
{"В", "\xbc"},
{"Г", "\xbd"},
{"Д", "\xbe"},
{"Е", "\xbf"},
// "Ё" - if ever used in subtitles, likely uses the accents at the end
{"Ж", "\xc0"},
{"З", "\xc1"},
{"И", "\xc2"},
// blank (c3)
// c4
// "Й" - if ever used in subtitles, likely uses the accents at the end
{"К", "\xc4"},
{"Л", "\xc5"},
{"М", "\xc6"},
{"Н", "\xc7"},
{"О", "\xc8"},
{"П", "\xc9"},
{"Р", "\xca"},
{"С", "\xcb"},
{"Т", "\xcc"},
// blank (cd)
// ce
{"У", "\xce"},
{"Ф", "\xcf"},
{"Х", "\xd0"},
{"Ц", "\xd1"},
{"Ч", "\xd2"},
{"Ш", "\xd3"},
{"Щ", "\xd4"},
{"Ъ", "\xd5"},
{"Ы", "\xd6"},
{"Ь", "\xd7"},
// d8
{"Э", "\xd8"},
{"Ю", "\xd9"},
{"Я", "\xda"},
// - lowercase
{"а", "\xdb"},
{"б", "\xdc"},
{"в", "\xdd"},
{"г", "\xde"},
{"д", "\xdf"},
{"е", "\xe0"},
{"ё", "\xe1"},
// e2
{"ж", "\xe2"},
{"з", "\xe3"},
{"и", "\xe4"},
{"й", "\xe5"},
{"к", "\xe6"},
{"л", "\xe7"},
{"м", "\xe8"},
{"н", "\xe9"},
{"о", "\xea"},
{"п", "\xeb"},
// ec
{"р", "\xec"},
{"с", "\xed"},
{"т", "\xee"},
{"у", "\xef"},
{"ф", "\xf0"},
{"х", "\xf1"},
{"ц", "\xf2"},
{"ч", "\xf3"},
{"ш", "\xf4"},
{"щ", "\xf5"},
// f6
{"ъ", "\xf6"},
{"ы", "\xf7"},
{"ь", "\xf8"},
{"э", "\xf9"},
{"ю", "\xfa"},
{"я", "\xfb"},
// - extra accents
{"RU-TODO-1",
"\xfc"}, // NOTE: they never used this in the game text, maybe in subtitles though
{"RU-TODO-2",
"\xfd"}, // NOTE: they never used this in the game text, maybe in subtitles though
// {"入", "\x1\x00"}},
// {"年", "\x1\x01"}},
// punctuation
{"・", "\x1\x10"},
{"゛", "\x1\x11"},
{"゜", "\x1\x12"},
{"ー", "\x1\x13"},
{"『", "\x1\x14"},
{"』", "\x1\x15"},
// hiragana
{"ぁ", "\x1\x16"}, // -a
{"あ", "\x1\x17"}, // a
{"ぃ", "\x1\x18"}, // -i
{"い", "\x1\x19"}, // i
{"ぅ", "\x1\x1a"}, // -u
{"う", "\x1\x1b"}, // u
{"ぇ", "\x1\x1c"}, // -e
{"え", "\x1\x1d"}, // e
{"ぉ", "\x1\x1e"}, // -o
{"お", "\x1\x1f"}, // o
{"か", "\x1\x20"}, // ka
{"き", "\x1\x21"}, // ki
{"く", "\x1\x22"}, // ku
{"け", "\x1\x23"}, // ke
{"こ", "\x1\x24"}, // ko
{"さ", "\x1\x25"}, // sa
{"し", "\x1\x26"}, // shi
{"す", "\x1\x27"}, // su
{"せ", "\x1\x28"}, // se
{"そ", "\x1\x29"}, // so
{"た", "\x1\x2a"}, // ta
{"ち", "\x1\x2b"}, // chi
{"っ", "\x1\x2c"}, // sokuon
{"つ", "\x1\x2d"}, // tsu
{"て", "\x1\x2e"}, // te
{"と", "\x1\x2f"}, // to
{"な", "\x1\x30"}, // na
{"に", "\x1\x31"}, // ni
{"ぬ", "\x1\x32"}, // nu
{"ね", "\x1\x33"}, // ne
{"の", "\x1\x34"}, // no
{"は", "\x1\x35"}, // ha
{"ひ", "\x1\x36"}, // hi
{"ふ", "\x1\x37"}, // fu
{"へ", "\x1\x38"}, // he
{"ほ", "\x1\x39"}, // ho
{"ま", "\x1\x3a"}, // ma
{"み", "\x1\x3b"}, // mi
{"む", "\x1\x3c"}, // mu
{"め", "\x1\x3d"}, // me
{"も", "\x1\x3e"}, // mo
{"ゃ", "\x1\x3f"}, // youon ya
{"や", "\x1\x40"}, // ya
{"ゅ", "\x1\x41"}, // youon yu
{"ゆ", "\x1\x42"}, // yu
{"ょ", "\x1\x43"}, // youon yo
{"よ", "\x1\x44"}, // yo
{"ら", "\x1\x45"}, // ra
{"り", "\x1\x46"}, // ri
{"る", "\x1\x47"}, // ru
{"れ", "\x1\x48"}, // re
{"ろ", "\x1\x49"}, // ro
{"ゎ", "\x1\x4a"}, // -wa
{"わ", "\x1\x4b"}, // wa
{"を", "\x1\x4c"}, // wo
{"ん", "\x1\x4d"}, // -n
// katakana
{"ァ", "\x1\x4e"}, // -a
{"ア", "\x1\x4f"}, // a
{"ィ", "\x1\x50"}, // -i
{"イ", "\x1\x51"}, // i
{"ゥ", "\x1\x52"}, // -u
{"ウ", "\x1\x53"}, // u
{"ェ", "\x1\x54"}, // -e
{"エ", "\x1\x55"}, // e
{"ォ", "\x1\x56"}, // -o
{"オ", "\x1\x57"}, // o
{"カ", "\x1\x58"}, // ka
{"キ", "\x1\x59"}, // ki
{"ク", "\x1\x5a"}, // ku
{"ケ", "\x1\x5b"}, // ke
{"コ", "\x1\x5c"}, // ko
{"サ", "\x1\x5d"}, // sa
{"シ", "\x1\x5e"}, // shi
{"ス", "\x1\x5f"}, // su
{"セ", "\x1\x60"}, // se
{"ソ", "\x1\x61"}, // so
{"タ", "\x1\x62"}, // ta
{"チ", "\x1\x63"}, // chi
{"ッ", "\x1\x64"}, // sokuon
{"ツ", "\x1\x65"}, // tsu
{"テ", "\x1\x66"}, // te
{"ト", "\x1\x67"}, // to
{"ナ", "\x1\x68"}, // na
{"ニ", "\x1\x69"}, // ni
{"ヌ", "\x1\x6a"}, // nu
{"ネ", "\x1\x6b"}, // ne
{"ノ", "\x1\x6c"}, // no
{"ハ", "\x1\x6d"}, // ha
{"ヒ", "\x1\x6e"}, // hi
{"フ", "\x1\x6f"}, // fu
{"ヘ", "\x1\x70"}, // he
{"ホ", "\x1\x71"}, // ho
{"マ", "\x1\x72"}, // ma
{"ミ", "\x1\x73"}, // mi
{"ム", "\x1\x74"}, // mu
{"メ", "\x1\x75"}, // me
{"モ", "\x1\x76"}, // mo
{"ャ", "\x1\x77"}, // youon ya
{"ヤ", "\x1\x78"}, // ya
{"ュ", "\x1\x79"}, // youon yu
{"ユ", "\x1\x7a"}, // yu
{"ョ", "\x1\x7b"}, // youon yo
{"ヨ", "\x1\x7c"}, // yo
{"ラ", "\x1\x7d"}, // ra
{"リ", "\x1\x7e"}, // ri
{"ル", "\x1\x7f"}, // ru
{"レ", "\x1\x80"}, // re
{"ロ", "\x1\x81"}, // ro
{"ヮ", "\x1\x82"}, // -wa
{"ワ", "\x1\x83"}, // wa
{"ヲ", "\x1\x84"}, // wo
{"ン", "\x1\x85"}, // -n
{"位", "\x1\x8c"},
{"遺", "\x1\x8d"},
{"院", "\x1\x8e"},
{"映", "\x1\x8f"},
{"衛", "\x1\x90"},
{"応", "\x1\x91"},
{"下", "\x1\x92"},
{"画", "\x1\x93"},
{"解", "\x1\x94"},
{"開", "\x1\x95"},
{"外", "\x1\x96"},
{"害", "\x1\x97"},
{"蓋", "\x1\x98"},
{"完", "\x1\x99"},
{"換", "\x1\x9a"},
{"監", "\x1\x9b"},
{"間", "\x1\x9c"},
{"器", "\x1\x9d"},
{"記", "\x1\x9e"},
{"逆", "\x1\x9f"},
{"救", "\x1\xa0"},
{"金", "\x1\xa1"},
{"空", "\x1\xa2"},
{"掘", "\x1\xa3"},
{"警", "\x1\xa4"},
{"迎", "\x1\xa5"},
{"撃", "\x1\xa6"},
{"建", "\x1\xa7"},
{"源", "\x1\xa8"},
{"現", "\x1\xa9"},
{"言", "\x1\xaa"},
{"限", "\x1\xab"},
{"個", "\x1\xac"},
{"庫", "\x1\xad"},
{"後", "\x1\xae"},
{"語", "\x1\xaf"},
{"護", "\x1\xb0"},
{"交", "\x1\xb1"},
{"功", "\x1\xb2"},
{"向", "\x1\xb3"},
{"工", "\x1\xb4"},
{"攻", "\x1\xb5"},
{"溝", "\x1\xb6"},
{"行", "\x1\xb7"},
{"鉱", "\x1\xb8"},
{"降", "\x1\xb9"},
{"合", "\x1\xba"},
{"告", "\x1\xbb"},
{"獄", "\x1\xbc"},
{"彩", "\x1\xbd"},
{"作", "\x1\xbe"},
{"山", "\x1\xbf"},
{"使", "\x1\xc0"},
{"始", "\x1\xc1"},
{"試", "\x1\xc2"},
{"字", "\x1\xc3"},
{"寺", "\x1\xc4"},
{"時", "\x1\xc5"},
{"示", "\x1\xc6"},
{"自", "\x1\xc7"},
{"式", "\x1\xc8"},
{"矢", "\x1\xc9"},
{"射", "\x1\xca"},
{"者", "\x1\xcb"},
{"守", "\x1\xcc"},
{"手", "\x1\xcd"},
{"終", "\x1\xce"},
{"週", "\x1\xcf"},
{"出", "\x1\xd0"},
{"所", "\x1\xd1"},
{"書", "\x1\xd2"},
{"勝", "\x1\xd3"},
{"章", "\x1\xd4"},
{"上", "\x1\xd5"},
{"乗", "\x1\xd6"},
{"場", "\x1\xd7"},
{"森", "\x1\xd8"},
{"進", "\x1\xd9"},
{"人", "\x1\xda"},
{"水", "\x1\xdb"},
{"数", "\x1\xdc"},
{"制", "\x1\xdd"},
{"性", "\x1\xde"},
{"成", "\x1\xdf"},
{"聖", "\x1\xe0"},
{"石", "\x1\xe1"},
{"跡", "\x1\xe2"},
{"先", "\x1\xe3"},
{"戦", "\x1\xe4"},
{"船", "\x1\xe5"},
{"選", "\x1\xe6"},
{"走", "\x1\xe7"},
{"送", "\x1\xe8"},
{"像", "\x1\xe9"},
{"造", "\x1\xea"},
{"続", "\x1\xeb"},
{"対", "\x1\xec"},
{"袋", "\x1\xed"},
{"台", "\x1\xee"},
{"弾", "\x1\xef"},
{"地", "\x1\xf0"},
{"中", "\x1\xf1"},
{"敵", "\x1\xf2"},
{"転", "\x1\xf3"},
{"電", "\x1\xf4"},
{"塔", "\x1\xf5"},
{"頭", "\x1\xf6"},
{"動", "\x1\xf7"},
{"内", "\x1\xf8"},
{"日", "\x1\xf9"},
{"入", "\x1\xfa"},
{"年", "\x1\xfb"},
{"能", "\x1\xfc"},
{"廃", "\x1\xfd"},
{"排", "\x1\xfe"},
{"敗", "\x1\xff"},
{"発", "\x2\x10"},
{"反", "\x2\x11"},
{"必", "\x2\x12"},
{"表", "\x2\x13"},
{"武", "\x2\x14"},
{"壁", "\x2\x15"},
{"墓", "\x2\x16"},
{"放", "\x2\x17"},
{"方", "\x2\x18"},
{"砲", "\x2\x19"},
{"妨", "\x2\x1a"},
{"北", "\x2\x1b"},
{"本", "\x2\x1c"},
{"幕", "\x2\x1d"},
{"無", "\x2\x1e"},
{"迷", "\x2\x1f"},
{"面", "\x2\x20"},
{"戻", "\x2\x21"},
{"紋", "\x2\x22"},
{"薬", "\x2\x23"},
{"輸", "\x2\x24"},
{"勇", "\x2\x25"},
{"友", "\x2\x26"},
{"遊", "\x2\x27"},
{"容", "\x2\x28"},
{"要", "\x2\x29"},
{"利", "\x2\x2a"},
{"了", "\x2\x2b"},
{"量", "\x2\x2c"},
{"力", "\x2\x2d"},
{"練", "\x2\x2e"},
{"連", "\x2\x2f"},
{"録", "\x2\x30"},
{"話", "\x2\x31"},
{"墟", "\x2\x32"},
{"脱", "\x2\x33"},
// {"成", "\x2\x34"},
{"旗", "\x2\x35"},
{"破", "\x2\x36"},
{"壊", "\x2\x37"},
{"全", "\x2\x38"},
{"滅", "\x2\x39"},
{"機", "\x2\x3a"},
{"仲", "\x2\x3b"},
{"渓", "\x2\x3c"},
{"谷", "\x2\x3d"},
{"優", "\x2\x3e"},
{"探", "\x2\x3f"},
{"部", "\x2\x40"},
{"索", "\x2\x41"},
// {"乗", "\x2\x42"},
{"前", "\x2\x43"},
{"右", "\x2\x44"},
{"左", "\x2\x45"},
{"会", "\x2\x46"},
{"高", "\x2\x47"},
{"低", "\x2\x48"},
{"押", "\x2\x49"},
{"切", "\x2\x4a"},
{"替", "\x2\x4b"},
// {"対", "\x2\x4c"},
{"秒", "\x2\x4d"},
{"箱", "\x2\x4e"},
{"泳", "\x2\x4f"},
{"~", "\x2\x50"},
{"闇", "\x2\x56"},
{"以", "\x2\x57"},
{"屋", "\x2\x58"},
{"俺", "\x2\x59"},
{"化", "\x2\x5a"},
{"界", "\x2\x5b"},
{"感", "\x2\x5c"},
{"気", "\x2\x5d"},
{"却", "\x2\x5e"},
{"曲", "\x2\x5f"},
{"継", "\x2\x60"},
{"権", "\x2\x61"},
{"見", "\x2\x62"},
{"古", "\x2\x63"},
{"好", "\x2\x64"},
// {"高", "\x2\x65"},
{"才", "\x2\x66"},
{"士", "\x2\x67"},
{"子", "\x2\x68"},
{"次", "\x2\x69"},
{"主", "\x2\x6a"},
{"種", "\x2\x6b"},
{"讐", "\x2\x6c"},
{"女", "\x2\x6d"},
{"小", "\x2\x6e"},
{"焼", "\x2\x6f"},
{"証", "\x2\x70"},
{"神", "\x2\x71"},
{"身", "\x2\x72"},
{"寸", "\x2\x73"},
{"世", "\x2\x74"},
{"想", "\x2\x75"},
{"退", "\x2\x76"},
{"第", "\x2\x77"},
{"着", "\x2\x78"},
{"天", "\x2\x79"},
{"倒", "\x2\x7a"},
{"到", "\x2\x7b"},
{"突", "\x2\x7c"},
{"爆", "\x2\x7d"},
{"番", "\x2\x7e"},
{"負", "\x2\x7f"},
{"復", "\x2\x80"},
{"物", "\x2\x81"},
{"眠", "\x2\x82"},
{"予", "\x2\x83"},
{"用", "\x2\x84"},
{"落", "\x2\x85"},
{"緑", "\x2\x86"},
{"封", "\x2\x88"},
{"印", "\x2\x89"},
{"扉", "\x2\x8a"},
{"最", "\x2\x8b"},
{"刻", "\x2\x8c"},
{"足", "\x2\x8d"},
};
GameTextFontBank g_font_bank_jakx(GameTextVersion::JAKX,
&encode_info_jakx,
&replace_info_jakx,
&passthrus_jakx);
-14
View File
@@ -1,14 +0,0 @@
#pragma once
#include "common/util/font/font_utils.h"
/*!
* ================================
* GAME TEXT FONT BANK - JAK X
* ================================
* This font is used in:
* - Jak X
*/
// TODO cyrillic
// TODO - current just using the jak 3 stuff (hopefully it's identical?)
extern GameTextFontBank g_font_bank_jak3;
-365
View File
@@ -1,365 +0,0 @@
/*!
* @file FontUtils.cpp
*
* Code for handling text and strings in Jak 1's "large font" format.
*
* MAKE SURE THIS FILE IS ENCODED IN UTF-8!!! The various strings here depend on it.
* Always verify the encoding if string detection suddenly goes awry.
*/
#include "font_utils.h"
#include <algorithm>
#include <stdexcept>
#include <string_view>
#include "common/util/Assert.h"
#include "common/util/FileUtil.h"
#include "common/util/font/dbs/font_db_jak1.h"
#include "common/util/font/dbs/font_db_jak2.h"
#include "common/util/font/dbs/font_db_jak3.h"
#include "common/util/font/font_utils_korean.h"
#include "common/util/string_util.h"
#include "common/versions/versions.h"
#include "fmt/format.h"
void from_json(const json& j, KoreanLookupEntry& obj) {
json_deserialize_if_exists(defaultGlyph);
json_deserialize_if_exists(alternatives);
}
std::map<GameTextVersion, GameTextFontBank*> g_font_banks = {
{GameTextVersion::JAK1_V1, &g_font_bank_jak1_v1},
{GameTextVersion::JAK1_V2, &g_font_bank_jak1_v2},
{GameTextVersion::JAK2, &g_font_bank_jak2},
{GameTextVersion::JAK3, &g_font_bank_jak3}};
const std::unordered_map<std::string, GameTextVersion> sTextVerEnumMap = {
{"jak1-v1", GameTextVersion::JAK1_V1},
{"jak1-v2", GameTextVersion::JAK1_V2},
{"jak2", GameTextVersion::JAK2},
{"jak3", GameTextVersion::JAK3}};
const std::string& get_text_version_name(GameTextVersion version) {
for (auto& [name, ver] : sTextVerEnumMap) {
if (ver == version) {
return name;
}
}
throw std::runtime_error(fmt::format("invalid text version {}", fmt::underlying(version)));
}
GameTextVersion get_text_version_from_name(const std::string& name) {
return sTextVerEnumMap.at(name);
}
GameTextFontBank::GameTextFontBank(GameTextVersion version,
std::vector<EncodeInfo>* encode_info,
std::vector<ReplaceInfo>* replace_info,
std::unordered_set<char>* passthrus)
: m_version(version), m_passthrus(passthrus) {
// Insert the encode and replacement info into a Trie, much faster lookups that way
for (const auto& encoding : *encode_info) {
m_encode_to_utf8_trie.insert(encoding.game_bytes, encoding);
m_encode_to_game_trie.insert(encoding.utf8, encoding);
}
for (const auto& replacement : *replace_info) {
m_replace_to_utf8_trie.insert(replacement.game_encoding, replacement);
m_replace_to_game_trie.insert(replacement.utf8_string, replacement);
}
}
bool GameTextFontBank::is_language_id_korean(const int language_id) const {
if (m_version == GameTextVersion::JAK2 && language_id == 6) {
return true;
} else if (m_version == GameTextVersion::JAK3 && language_id == 7) {
return true;
}
return false;
}
GameTextFontBank* get_font_bank(GameTextVersion version) {
return g_font_banks.at(version);
}
GameTextFontBank* get_font_bank_from_game_version(GameVersion version) {
if (version == GameVersion::Jak1) {
// Jak 1 has been patched to use V2
return get_font_bank(GameTextVersion::JAK1_V2);
} else if (version == GameVersion::Jak2) {
auto font_bank = get_font_bank(GameTextVersion::JAK2);
return font_bank;
} else if (version == GameVersion::Jak3) {
return get_font_bank(GameTextVersion::JAK3);
} else {
ASSERT_MSG(false, "Unsupported game for get_font_bank_from_game_version");
}
}
GameTextFontBank* get_font_bank(const std::string& name) {
if (auto it = sTextVerEnumMap.find(name); it == sTextVerEnumMap.end()) {
throw std::runtime_error(fmt::format("unknown text version {}", name));
} else {
return get_font_bank(it->second);
}
}
bool font_bank_exists(GameTextVersion version) {
return g_font_banks.find(version) != g_font_banks.cend();
}
std::string GameTextFontBank::replace_to_game(const std::string& str) const {
std::string newstr;
newstr.reserve(str.size());
for (int i = 0; i < str.length();) {
const ReplaceInfo* remap = m_replace_to_game_trie.find_longest_prefix(str, i);
if (!remap) {
newstr.push_back(str[i]);
i += 1;
} else {
if (!remap->utf8_alternative.empty()) {
newstr.append(remap->utf8_alternative);
} else {
newstr.append(remap->game_encoding);
}
i += remap->utf8_string.size();
}
}
return newstr;
}
std::string GameTextFontBank::encode_utf8_to_game(const std::string& str) const {
std::string newstr;
newstr.reserve(str.size());
for (int i = 0; i < str.length();) {
auto match = m_encode_to_game_trie.find_longest_prefix(str, i);
if (!match) {
newstr.push_back(str[i]);
i += 1;
} else {
for (auto b : match->game_bytes) {
newstr.push_back(b);
}
i += match->utf8.size();
}
}
return newstr;
}
/*!
* Turn a normal readable string into a string readable in the in-game font encoding and converts
* \cXX escape sequences
*/
std::string GameTextFontBank::convert_utf8_to_game(const std::string& str) const {
return encode_utf8_to_game(replace_to_game(str));
}
std::string GameTextFontBank::replace_to_utf8(const std::string& str) const {
std::string result;
result.reserve(str.size());
for (size_t i = 0; i < str.size();) {
const ReplaceInfo* remap = m_replace_to_utf8_trie.find_longest_prefix(str, i);
if (!remap) {
result.push_back(str[i]);
i += 1;
} else {
result.append(remap->utf8_string);
i += remap->game_encoding.size();
}
}
return result;
}
bool GameTextFontBank::valid_char_range(const char& in) const {
if (m_version == GameTextVersion::JAK1_V1 || m_version == GameTextVersion::JAK1_V2) {
return ((in >= '0' && in <= '9') || (in >= 'A' && in <= 'Z') ||
m_passthrus->find(in) != m_passthrus->end()) &&
in != '\\';
} else if (m_version == GameTextVersion::JAK2 || m_version == GameTextVersion::JAK3 ||
m_version == GameTextVersion::JAKX) {
return ((in >= '0' && in <= '9') || (in >= 'A' && in <= 'Z') || (in >= 'a' && in <= 'z') ||
m_passthrus->find(in) != m_passthrus->end()) &&
in != '\\';
}
return false;
}
std::string GameTextFontBank::encode_game_to_utf8(const std::string& str) const {
std::string newstr;
newstr.reserve(str.size());
for (size_t i = 0; i < str.size();) {
auto encoding = m_encode_to_utf8_trie.find_longest_prefix(str, i);
if (!encoding) {
// No match: copy valid characters as-is, or escape unknown bytes
unsigned char c = static_cast<unsigned char>(str[i]);
if (valid_char_range(c) || c == '\n' || c == '\t' || c == '\\' || c == '"') {
newstr.push_back(c);
} else {
newstr += fmt::format("\\c{:02x}", c);
}
++i;
} else {
// Found a match: append its UTF-8 sequence
newstr.append(encoding->utf8);
i += encoding->game_bytes.size(); // advance past matched game bytes
}
}
return newstr;
}
std::string GameTextFontBank::convert_game_to_utf8(const char* in) const {
// Encode and apply replacement ONCE
std::string decoded = replace_to_utf8(encode_game_to_utf8(in));
// Escape special characters while writing directly into result
std::string result;
result.reserve(decoded.size());
for (size_t i = 0; i < decoded.size(); ++i) {
char c = decoded[i];
if (c == '\n') {
result += "\\n";
} else if (c == '\t') {
result += "\\t";
} else if (c == '\\') {
if (i < decoded.size() - 1 && decoded[i + 1] == 'c') {
result.push_back(c); // preserve \cXX
} else {
result += "\\\\";
}
} else if (c == '"') {
result += "\\\"";
} else {
result.push_back(c);
}
}
return result;
}
std::string GameTextFontBank::convert_utf8_to_game_korean(const std::string& str) {
ASSERT_MSG(m_version == GameTextVersion::JAK2 || m_version == GameTextVersion::JAK3,
"Korean is not supported for any game other than Jak 2 and Jak 3 right now");
if (!m_korean_db.has_value()) {
const auto db_file_path =
file_util::get_file_path({"game/assets/fonts/jak2_jak3_korean_db.json"});
if (file_util::file_exists(db_file_path)) {
auto raw_data = file_util::read_text_file(db_file_path);
auto json_data = parse_commented_json(raw_data, "jak2_jak3_korean_db.json");
std::unordered_map<std::string, KoreanLookupOrientations> temp_db;
json_data.get_to(temp_db);
m_korean_db = temp_db;
}
}
std::string output;
output.reserve(str.size());
std::string non_korean_buffer = "";
size_t i = 0;
while (i < str.size()) {
char32_t cp = str_util::next_utf8_char(str, i);
if (font_util_korean::is_korean_syllable(cp)) {
// flush any non-korean buffer
if (!non_korean_buffer.empty()) {
output += 0x3;
// encode / remap it
output += encode_utf8_to_game(replace_to_game(non_korean_buffer));
non_korean_buffer = "";
}
// write out the korean character
output += font_util_korean::game_encode_korean_syllable(str, cp, m_korean_db.value());
} else {
non_korean_buffer += str_util::utf8_encode(cp);
}
}
// flush any non-korean buffer
if (!non_korean_buffer.empty()) {
output += 0x3;
// encode / remap it
output += encode_utf8_to_game(replace_to_game(non_korean_buffer));
non_korean_buffer = "";
}
return output;
}
std::string GameTextFontBank::convert_korean_game_to_utf8(const char* in) const {
ASSERT_MSG(m_version == GameTextVersion::JAK2 || m_version == GameTextVersion::JAK3,
"Korean is not supported for any game other than Jak 2 and Jak 3 right now");
// Korean strings are fully bitstrings, in other words, it's just a bunch of bytes
// Some info on the layout:
// - Every korean syllable block starts with a `4`
// - The following byte indicates how many glyphs are drawn for that syllable block
// - Each jamo that makes up the syllable block follows as a single byte
// - Unless the jamo is part of the "extra" texture page, in which case it's preceeded by a `5`.
// There are very few jamo that are and they are only applicable for the final consonant
// - The korean strings can contain non-korean characters. These are preceeded by a `3`
// - For example a space would be `3 20`
// - It might be more accurate to say that a 3 signifies "consume characters as normal until
// something else is encountered (ie. flags or more complex font encodings)"
std::string result;
std::string_view str(in);
u64 index = 0;
u8 curr_byte = 0;
bool in_syllable_block = false;
std::string jamo_buffer = "";
std::string non_korean_buffer = "";
int num_syllable_glyphs = 0;
while (index < str.length()) {
curr_byte = str.at(index);
// new syllable block
if (curr_byte == 4) {
in_syllable_block = true;
if (index + 1 < str.length()) {
num_syllable_glyphs = str.at(index + 1);
index++;
}
index++;
// flush any non-korean characters
if (!non_korean_buffer.empty()) {
// handle remap
std::string remapped_str = replace_to_utf8(encode_game_to_utf8(non_korean_buffer));
result += remapped_str;
non_korean_buffer = "";
}
continue;
}
if (in_syllable_block) {
// extra page
std::string glyph_key;
u8 hex_byte = curr_byte;
if (curr_byte == 5 && index + 1 < str.length()) {
hex_byte = str.at(index + 1);
glyph_key = fmt::format("extra_0x{:02x}", hex_byte);
index++;
} else {
glyph_key = fmt::format("0x{:02x}", hex_byte);
}
const auto jamo_list = jamo_glyph_mappings_jak2.find(glyph_key);
ASSERT_MSG(jamo_list != jamo_glyph_mappings_jak2.end(),
fmt::format("{} not found in jamo glyph lookup table", glyph_key));
for (const auto& jamo : jamo_list->second) {
jamo_buffer += jamo;
}
num_syllable_glyphs--;
if (num_syllable_glyphs == 0) {
in_syllable_block = false;
result += font_util_korean::compose_korean_containing_text(jamo_buffer);
jamo_buffer = "";
}
} else {
if (curr_byte != 0x3) {
non_korean_buffer.push_back(curr_byte);
}
}
index++;
}
// flush any non-korean characters
if (!non_korean_buffer.empty()) {
// handle remap
std::string remapped_str = replace_to_utf8(encode_game_to_utf8(non_korean_buffer));
result += remapped_str;
non_korean_buffer = "";
}
return result;
}
-105
View File
@@ -1,105 +0,0 @@
#pragma once
#include <map>
#include <optional>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include "common/common_types.h"
#include "common/util/Trie.h"
#include "common/util/font/font_utils_korean.h"
#include "common/util/json_util.h"
#include "common/versions/versions.h"
/*!
* What bytes a set of characters (UTF-8) correspond to. You can convert to and fro.
*/
struct EncodeInfo {
std::string utf8;
std::string game_bytes;
};
/*!
* Replace an unconventional string of characters with/from something more readable.
* For example, turns Ñ into N + ~ + a bunch of modifiers.
*/
struct ReplaceInfo {
std::string game_encoding;
std::string utf8_string;
// for some replacements, we want to replace with something different when going from utf8 than
// when we originally matched it this is mostly applicable for when we have to max a string with
// hex chars that have been converted into `\c00` format but we want to insert the actual raw hex
// bytes back.
std::string utf8_alternative = "";
};
// version of the game text file's text encoding. Not real, but we need to differentiate them
// somehow, since the encoding changes.
enum class GameTextVersion {
JAK1_V1 = 10, // jak 1 (ntsc-u v1)
JAK1_V2 = 11, // jak 1 (pal+)
JAK2 = 20, // jak 2
JAK3 = 30, // jak 3
JAKX = 40 // jak x
};
/*!
* All the information to convert UTF-8 text into game text.
*/
class GameTextFontBank {
GameTextVersion m_version; // the version of the game text. we determine this ourselves.
Trie<EncodeInfo> m_encode_to_utf8_trie;
Trie<EncodeInfo> m_encode_to_game_trie;
Trie<ReplaceInfo> m_replace_to_utf8_trie;
Trie<ReplaceInfo> m_replace_to_game_trie;
std::unordered_set<char>* m_passthrus;
// jamo=>6 orientations with their drawing info
std::optional<std::unordered_map<std::string, KoreanLookupOrientations>> m_korean_db =
std::nullopt;
std::string replace_to_utf8(const std::string& str) const;
std::string replace_to_game(const std::string& str) const;
std::string encode_utf8_to_game(const std::string& str) const;
std::string encode_game_to_utf8(const std::string& str) const;
public:
GameTextFontBank(GameTextVersion version,
std::vector<EncodeInfo>* encode_info,
std::vector<ReplaceInfo>* replace_info,
std::unordered_set<char>* passthrus);
const std::unordered_set<char>* passthrus() const { return m_passthrus; }
GameTextVersion version() const { return m_version; }
// TODO - methods would help make this code a lot better for different game versions
// hacking it for now
bool valid_char_range(const char& in) const;
bool is_language_id_korean(const int language_id) const;
std::string convert_utf8_to_game(const std::string& str) const;
std::string convert_game_to_utf8(const char* in) const;
std::string convert_utf8_to_game_korean(const std::string& str);
std::string convert_korean_game_to_utf8(const char* in) const;
};
extern const std::unordered_map<std::string, GameTextVersion> sTextVerEnumMap;
const std::string& get_text_version_name(GameTextVersion version);
GameTextVersion get_text_version_from_name(const std::string& name);
/*!
* ========================
* GAME TEXT FONT BANK LIST
* ========================
* The list of available font banks and a couple of helper functions.
*/
extern std::map<GameTextVersion, GameTextFontBank*> g_font_banks;
GameTextFontBank* get_font_bank(GameTextVersion version);
GameTextFontBank* get_font_bank_from_game_version(GameVersion version);
GameTextFontBank* get_font_bank(const std::string& name);
bool font_bank_exists(GameTextVersion version);
Loaded 100 of 8909 files, more files were not shown because too many files have changed in this diff. Show more